<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3623515592551780770</id><updated>2012-01-30T12:30:34.604-05:00</updated><category term='display'/><category term='board'/><category term='darlington'/><category term='omegle'/><category term='playstation'/><category term='eagle'/><category term='hacking'/><category term='coop'/><category term='eye'/><category term='Programming'/><category term='pcb'/><category term='atmega'/><category term='jansen'/><category term='register'/><category term='python'/><category term='coffee table'/><category term='shift'/><category term='mechanics'/><category term='layout'/><category term='code'/><category term='Parallax'/><category term='theo'/><category term='patch'/><category term='driver'/><category term='apache'/><category term='linux'/><category term='gspca'/><category term='simulation'/><category term='hack'/><category term='coop design challenge'/><category term='opencv'/><category term='man in the middle'/><category term='ps3'/><category term='diy'/><category term='camera'/><category term='php'/><category term='security'/><category term='texas instruments'/><category term='webcam'/><category term='etching'/><category term='TI'/><category term='Keyless Entry'/><category term='c'/><category term='matlab'/><category term='max'/><category term='thrun'/><category term='kinematics'/><category term='matrix'/><category term='Servo'/><category term='wathen'/><category term='server'/><category term='led'/><category term='RFID'/><category term='Door Unlocker'/><category term='john'/><category term='Basic Stamp'/><category term='ubuntu'/><category term='ov534'/><category term='msp430'/><category term='karmic'/><category term='max thrun'/><title type='text'>bear24rw</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-2901294828335217054</id><published>2011-08-26T00:10:00.008-04:00</published><updated>2011-08-26T00:16:32.907-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TI'/><category scheme='http://www.blogger.com/atom/ns#' term='msp430'/><category scheme='http://www.blogger.com/atom/ns#' term='coffee table'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='coop'/><category scheme='http://www.blogger.com/atom/ns#' term='coop design challenge'/><category scheme='http://www.blogger.com/atom/ns#' term='max thrun'/><category scheme='http://www.blogger.com/atom/ns#' term='thrun'/><category scheme='http://www.blogger.com/atom/ns#' term='texas instruments'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><title type='text'>RGB LED Coffee Table</title><content type='html'>This summer all the Co-ops at Texas Instruments were challenged with coming up with a project centered around a &lt;a target="new" href="http://ti.com/430value"&gt;value line MSP430&lt;/a&gt;. My group decided to build an RGB LED coffee table that pulsed visualization to music. We won 1st place!&lt;br /&gt;&lt;br /&gt;A write up of the project can be found &lt;a target="new" href="http://e2e.ti.com/group/msp430launchpad/m/project/447779.aspx"&gt;here&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;a target="new" href="http://e2e.ti.com/group/msp430launchpad/m/project/447779.aspx"&gt;&lt;img src="https://lh4.googleusercontent.com/-u1rAbqcEMO8/TjDwnB9TzgI/AAAAAAAABMU/UaEcguy1IzY/s400/CIMG3895.JPG" height="400" width="300" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-2901294828335217054?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/2901294828335217054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2011/08/rgb-led-coffee-table.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/2901294828335217054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/2901294828335217054'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2011/08/rgb-led-coffee-table.html' title='RGB LED Coffee Table'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh4.googleusercontent.com/-u1rAbqcEMO8/TjDwnB9TzgI/AAAAAAAABMU/UaEcguy1IzY/s72-c/CIMG3895.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-8523842852936678304</id><published>2010-08-11T22:01:00.016-04:00</published><updated>2011-01-10T17:19:12.224-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mechanics'/><category scheme='http://www.blogger.com/atom/ns#' term='jansen'/><category scheme='http://www.blogger.com/atom/ns#' term='theo'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><category scheme='http://www.blogger.com/atom/ns#' term='simulation'/><category scheme='http://www.blogger.com/atom/ns#' term='matlab'/><category scheme='http://www.blogger.com/atom/ns#' term='kinematics'/><title type='text'>Theo Jansen Matlab Simulation</title><content type='html'>My roommate had to do a simulation of a Jansen mechanism for his kinematics class. It sounded interesting so I gave it a try. Here is what I came up with:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4884166878/" title="Screenshot-14-cropped by bear24rw, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4073/4884166878_93557a0472.jpg" width="500" height="436" alt="Screenshot-14-cropped" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="480" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/lsl6992-tqA?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/lsl6992-tqA?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Doing a simulation of a mechanical linkage was something I had never done, nor even really thought about. I initially tried to express all the angles as functions of each other but this soon became insane (this could very well be due to the fact that I am in Electrical Engineering and have never taken a kinematics course before so I had no idea what the proper equations would even look like). After trying to simplify gigantic trig equations in wolframalpha.com and getting back stuff that was disgustingly crazy I resorted to my middle school way of solving equations I don't really understand: brute force. (I used to make programs on my TI-83 to brute force single (and even double) variable equations way back in the day)&lt;br /&gt;&lt;br /&gt;So there was only three things I really had values for: the length of the legs, the distance between the crank and the pivot, and the angle of the crank. So say the crank is at a certain angle and you know its length, you can find the end point x,y using simple sin and cos. Now the end of the crank (node 0) needs to be connected to node 1. Node 1 is a known length off the pivot, link_9. So basically what I do is rotate link_9 around the pivot until the distance between node 1 and node 0 are extremely close to the length of link_1. I find this really hard to explain still even after trying to do it many times. Basically I brute force the angle of a bar until the tip of the bar is a certain length away from the other bar it needs to connect to (the distance which I know, since I know the length of all the legs).&lt;br /&gt;&lt;br /&gt;Even though this method is absolutely confusing to explain in words it is extremely modular and dead simple to implement. The code is basically the same thing over and over again just with different bars and also some angle constraints (you know link_9 will always be between 45 and 135, roughly). Adding new bars is as simple as copy and pasting and changing the names of the variables. I can literally make any mechanism this way without doing a single line of hard coded trig.&lt;br /&gt;&lt;br /&gt;I found the paper linked below to be extremely helpful for providing good bar lengths. All the nodes and bars in my code are named the same as those in this paper&lt;br /&gt;&lt;a href="http://ujdigispace.uj.ac.za:8080/dspace/bitstream/10210/1738/Numerical.pdf"&gt;http://ujdigispace.uj.ac.za:8080/dspace/bitstream/10210/1738/39/Numerical.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Edit:&lt;/span&gt; For some reason the link does not work, to find the paper google: "Numerical kinematic and kinetic analysis of a new class of twelve bar linkage for walking machines"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: matlab"&gt;&lt;![CDATA[&lt;br /&gt;%Max Thrun&lt;br /&gt;%Simulation of Jensen Mechanism&lt;br /&gt;&lt;br /&gt;close all               %Clsoes windows&lt;br /&gt;clear all               %Clears all variables&lt;br /&gt;clc                     %Clear command window&lt;br /&gt;&lt;br /&gt;%Declare variables&lt;br /&gt;&lt;br /&gt;crank_r = 120;&lt;br /&gt;link_1 = 400;&lt;br /&gt;link_2 = 389;%400;&lt;br /&gt;link_3 = 275;&lt;br /&gt;link_4 = 400;&lt;br /&gt;link_5 = 275;&lt;br /&gt;link_6 = 400;&lt;br /&gt;link_7 = 275;&lt;br /&gt;link_8 = 275;&lt;br /&gt;link_9 = 275;&lt;br /&gt;link_10 = 275;&lt;br /&gt;link_11 = 412;%540;&lt;br /&gt;&lt;br /&gt;crank_x = 0;&lt;br /&gt;crank_y = 0;&lt;br /&gt;&lt;br /&gt;pin_x = crank_x - (286/1);&lt;br /&gt;pin_y = crank_y;&lt;br /&gt;&lt;br /&gt;node_1_x = pin_x;&lt;br /&gt;node_1_y = 5;&lt;br /&gt;&lt;br /&gt;link_9_t = 0;&lt;br /&gt;&lt;br /&gt;link_10_t = pi;&lt;br /&gt;link_11_t = pi;&lt;br /&gt;&lt;br /&gt;node_2_x = pin_x - link_9;&lt;br /&gt;node_2_y = pin_y;&lt;br /&gt;&lt;br /&gt;link_8_t = 3/4*pi;&lt;br /&gt;&lt;br /&gt;node_3_x = pin_x;&lt;br /&gt;node_3_y = pin_y - link_8;&lt;br /&gt;&lt;br /&gt;link_7_t = pi;&lt;br /&gt;&lt;br /&gt;node_4_x = pin_x - link_7;&lt;br /&gt;node_4_y = pin_y - link_3;&lt;br /&gt;&lt;br /&gt;link_5_t = 3/4*pi;&lt;br /&gt;&lt;br /&gt;node_5_y = pin_y - link_8 - link_5;&lt;br /&gt;node_5_x = pin_x;&lt;br /&gt;&lt;br /&gt;node_6_y = node_5_y;&lt;br /&gt;node_6_x = node_5_x;&lt;br /&gt;&lt;br /&gt;axis([-300 300 -300 300]);&lt;br /&gt;grid on                 %Display grid on plot&lt;br /&gt;xlabel('real axis');    %Give the xlabel&lt;br /&gt;ylabel('imag axis');    %Give the ylabel&lt;br /&gt;title('Example 1');     %Give the title of the plot&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;avi = moviein((8*pi+pi/2)*5);&lt;br /&gt;&lt;br /&gt;%Animation&lt;br /&gt;figure(3)&lt;br /&gt;&lt;br /&gt;i=0;&lt;br /&gt;&lt;br /&gt;x = [];&lt;br /&gt;y = [];&lt;br /&gt;&lt;br /&gt;for t=0:0.1:8*pi+pi/2+pi;&lt;br /&gt;&lt;br /&gt;    i = i + 1;&lt;br /&gt;&lt;br /&gt;    node_0_x = crank_x + crank_r*cos(t);&lt;br /&gt;    node_0_y = crank_y + crank_r*sin(t);&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    %&lt;br /&gt;    % NODE 1&lt;br /&gt;    %&lt;br /&gt;&lt;br /&gt;    dist = 10000000;&lt;br /&gt;    &lt;br /&gt;    for link_9_t=0:0.02:pi;&lt;br /&gt;        node_1_x = pin_x + link_9*cos(link_9_t);&lt;br /&gt;        node_1_y = pin_y + link_9*sin(link_9_t);&lt;br /&gt;&lt;br /&gt;        dist_tmp = sqrt((node_0_x-node_1_x)^2+(node_0_y-node_1_y)^2);&lt;br /&gt;&lt;br /&gt;        diff = abs(dist_tmp - link_1);&lt;br /&gt;&lt;br /&gt;        if (diff &lt; dist)&lt;br /&gt;            dist = diff;&lt;br /&gt;            theta = link_9_t;&lt;br /&gt;            %fprintf('New theta: %d  Diff: %d\n', theta, diff);&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    link_9_t = theta;&lt;br /&gt;    &lt;br /&gt;    node_1_x = pin_x + link_9*cos(link_9_t);&lt;br /&gt;    node_1_y = pin_y + link_9*sin(link_9_t);&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    %&lt;br /&gt;    % NODE 2&lt;br /&gt;    %&lt;br /&gt;    &lt;br /&gt;    dist = 10000000;&lt;br /&gt;    &lt;br /&gt;    for link_10_t=.75*pi:0.02:1.5*pi;&lt;br /&gt;        node_2_x = pin_x + link_10*cos(link_10_t);&lt;br /&gt;        node_2_y = pin_y + link_10*sin(link_10_t);&lt;br /&gt;    &lt;br /&gt;        dist_tmp = sqrt((node_2_x-node_1_x)^2+(node_2_y-node_1_y)^2);&lt;br /&gt;        &lt;br /&gt;        diff = abs(dist_tmp - link_2);&lt;br /&gt;        &lt;br /&gt;        if (diff &lt; dist)&lt;br /&gt;            dist = diff;&lt;br /&gt;            theta = link_10_t;&lt;br /&gt;            %fprintf('New theta: %d  Diff: %d\n', theta, diff);&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    link_10_t = theta;&lt;br /&gt;    &lt;br /&gt;    node_2_x = pin_x + link_10*cos(link_10_t);&lt;br /&gt;    node_2_y = pin_y + link_10*sin(link_10_t);&lt;br /&gt;    &lt;br /&gt;    %&lt;br /&gt;    % NODE 3&lt;br /&gt;    %&lt;br /&gt;    &lt;br /&gt;     dist = 10000000;&lt;br /&gt;    &lt;br /&gt;    for link_8_t=pi:0.02:2*pi;&lt;br /&gt;        node_3_x = pin_x + link_8*cos(link_8_t);&lt;br /&gt;        node_3_y = pin_y + link_8*sin(link_8_t);&lt;br /&gt;    &lt;br /&gt;        dist_tmp = sqrt((node_0_x-node_3_x)^2+(node_0_y-node_3_y)^2);&lt;br /&gt;        &lt;br /&gt;        diff = abs(dist_tmp - link_6);&lt;br /&gt;        &lt;br /&gt;        if (diff &lt; dist)&lt;br /&gt;            dist = diff;&lt;br /&gt;            theta = link_8_t;&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    link_8_t = theta;&lt;br /&gt;    &lt;br /&gt;    node_3_x = pin_x + link_8*cos(link_8_t);&lt;br /&gt;    node_3_y = pin_y + link_8*sin(link_8_t);&lt;br /&gt;    &lt;br /&gt;    %&lt;br /&gt;    % NODE 4&lt;br /&gt;    %&lt;br /&gt;    &lt;br /&gt;    dist = 10000000;&lt;br /&gt;    &lt;br /&gt;    for link_7_t=.75*pi:0.02:1.5*pi;&lt;br /&gt;        node_4_x = node_3_x + link_7*cos(link_7_t);&lt;br /&gt;        node_4_y = node_3_y + link_7*sin(link_7_t);&lt;br /&gt;    &lt;br /&gt;        dist_tmp = sqrt((node_4_x-node_2_x)^2+(node_4_y-node_2_y)^2);&lt;br /&gt;        &lt;br /&gt;        diff = abs(dist_tmp - link_3);&lt;br /&gt;        &lt;br /&gt;        if (diff &lt; dist)&lt;br /&gt;            dist = diff;&lt;br /&gt;            theta = link_7_t;&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    link_7_t = theta;&lt;br /&gt;    &lt;br /&gt;    node_4_x = node_3_x + link_7*cos(link_7_t);&lt;br /&gt;    node_4_y = node_3_y + link_7*sin(link_7_t);&lt;br /&gt;    &lt;br /&gt;    &lt;br /&gt;    %&lt;br /&gt;    % NODE 5&lt;br /&gt;    %&lt;br /&gt;    &lt;br /&gt;    dist = 10000000;&lt;br /&gt;    &lt;br /&gt;    for link_5_t=pi:0.02:2*pi;&lt;br /&gt;        node_5_x = node_3_x + link_5*cos(link_5_t);&lt;br /&gt;        node_5_y = node_3_y + link_5*sin(link_5_t);&lt;br /&gt;    &lt;br /&gt;        dist_tmp = sqrt((node_4_x-node_5_x)^2+(node_4_y-node_5_y)^2);&lt;br /&gt;       &lt;br /&gt;        diff = abs(dist_tmp - link_4);&lt;br /&gt;      &lt;br /&gt;        if (diff &lt; dist)&lt;br /&gt;            dist = diff;&lt;br /&gt;            theta = link_5_t;&lt;br /&gt;            %fprintf('New theta: %d  Diff: %d\n', theta, diff);&lt;br /&gt;        end&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    link_5_t = theta;&lt;br /&gt;&lt;br /&gt;    node_5_x = node_3_x + link_5*cos(link_5_t);&lt;br /&gt;    node_5_y = node_3_y + link_5*sin(link_5_t);&lt;br /&gt;&lt;br /&gt;    node_6_x = node_3_x + link_11*cos(link_5_t);&lt;br /&gt;    node_6_y = node_3_y + link_11*sin(link_5_t);&lt;br /&gt;&lt;br /&gt;    x(end+1) = node_6_x;&lt;br /&gt;    y(end+1) = node_6_y;&lt;br /&gt;&lt;br /&gt;    %&lt;br /&gt;    % DRAW&lt;br /&gt;    %&lt;br /&gt;&lt;br /&gt;    plot([crank_x pin_x], [crank_y pin_y],'black','linewidth',4); hold on       % crank to pin&lt;br /&gt;    plot([crank_x node_0_x], [crank_y node_0_y],'r','linewidth',4); hold on     % crank&lt;br /&gt;&lt;br /&gt;    plot([node_0_x node_1_x], [node_0_y node_1_y],'b','linewidth',4);           % link_1&lt;br /&gt;    plot([pin_x node_1_x], [pin_y node_1_y],'g','linewidth',4);                 % link_9&lt;br /&gt;&lt;br /&gt;    plot([pin_x node_2_x], [pin_y node_2_y],'g','linewidth', 4);                % link_10&lt;br /&gt;    plot([node_1_x node_2_x], [node_1_y node_2_y],'g','linewidth', 4);          % link_2&lt;br /&gt;&lt;br /&gt;    plot([node_0_x node_3_x], [node_0_y node_3_y],'b','linewidth',4);           % link_6&lt;br /&gt;    plot([pin_x node_3_x], [pin_y node_3_y],'r','linewidth',4);                 % link_8&lt;br /&gt;&lt;br /&gt;    plot([node_3_x node_4_x], [node_3_y node_4_y],'g','linewidth', 4);          % link_7&lt;br /&gt;    plot([node_2_x node_4_x], [node_2_y node_4_y],'r','linewidth', 4);          % link_3&lt;br /&gt;&lt;br /&gt;    plot([node_3_x node_5_x], [node_3_y node_5_y],'r','linewidth', 4);          % link_5&lt;br /&gt;    plot([node_4_x node_5_x], [node_4_y node_5_y],'b','linewidth', 4);          % link_4&lt;br /&gt;&lt;br /&gt;    plot([node_3_x node_6_x], [node_3_y node_6_y],'b','linewidth', 4);          % link_5&lt;br /&gt;&lt;br /&gt;    plot(x,y);&lt;br /&gt;&lt;br /&gt;    hold off            %So next plot will erase the current plot&lt;br /&gt;    axis([-900 600 -900 600]);&lt;br /&gt;    %pause(0.001)          %Stop execution for 0.1 sec so that the animation can be seen&lt;br /&gt;    avi(i) = getframe(gca);&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;movie2avi(avi,'jansen.avi','compression','cinepak') % or cinepak, indeo5&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-8523842852936678304?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/8523842852936678304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2010/08/theo-jansen-matlab-simulation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/8523842852936678304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/8523842852936678304'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2010/08/theo-jansen-matlab-simulation.html' title='Theo Jansen Matlab Simulation'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4073/4884166878_93557a0472_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-7880702550022819850</id><published>2010-08-11T18:52:00.014-04:00</published><updated>2010-08-13T13:22:06.761-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='webcam'/><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='camera'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><category scheme='http://www.blogger.com/atom/ns#' term='c'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='diy'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='opencv'/><title type='text'>Quick And Dirty Security Camera</title><content type='html'>When you're on the third floor of my house it's often nice to be able to see who is at the door when the doorbell rings. I wrote up this little program that takes a picture from a webcam every second and hosts the past five minutes of pictures on an apache server. The five minute limit was chosen purely because I only wanted to see who was at the door, not record a whole weeks worth and the fact that I wanted to store the pictures in ram and my server only has 1 GB.&lt;br /&gt;&lt;br /&gt;A picture of my setup:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4883791674/" title="CIMG3559_Labeled by bear24rw, on Flickr"&gt;&lt;img src="http://farm5.static.flickr.com/4143/4883791674_847451edb1.jpg" width="375" height="500" alt="CIMG3559_Labeled" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;main.c&lt;/span&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: c; toolbar: false;"&gt;&lt;![CDATA[&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;#include &lt;stdlib.h&gt;&lt;br /&gt;#include &lt;cv.h&gt;&lt;br /&gt;#include &lt;highgui.h&gt;&lt;br /&gt;#include &lt;time.h&gt;&lt;br /&gt;#include &lt;sys/resource.h&gt;&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;&lt;br /&gt; // Un-comment following line to set process priority&lt;br /&gt; //setpriority(PRIO_PROCESS, 0, -20);&lt;br /&gt;&lt;br /&gt; // Create directory to store pictures&lt;br /&gt; system("mkdir /tmp/cam");&lt;br /&gt;&lt;br /&gt; // Change the owner so that the apache server can see it&lt;br /&gt; system("chown pwner:pwner /tmp/cam");&lt;br /&gt;&lt;br /&gt; // Some variable for time&lt;br /&gt; struct tm *ptr;&lt;br /&gt; time_t lt;&lt;br /&gt;&lt;br /&gt; // String that holds the formatted time&lt;br /&gt; char str[80];&lt;br /&gt;&lt;br /&gt; // Array to hold image format settings&lt;br /&gt; int p[3];&lt;br /&gt;&lt;br /&gt; // Save PNG with best quality&lt;br /&gt; p[0] = CV_IMWRITE_PNG_COMPRESSION;&lt;br /&gt; p[1] = 9;&lt;br /&gt; p[2] = 0;&lt;br /&gt;&lt;br /&gt; // Save JPEG with 90 quality&lt;br /&gt; //p[0] = CV_IMWRITE_JPEG_QUALITY;&lt;br /&gt; //p[1] = 90;&lt;br /&gt;&lt;br /&gt; // Init webcam&lt;br /&gt; CvCapture *capture = cvCreateCameraCapture(0);&lt;br /&gt;&lt;br /&gt; IplImage* image;&lt;br /&gt;&lt;br /&gt; while (1) {&lt;br /&gt;&lt;br /&gt;  printf("Looping..\n");&lt;br /&gt;&lt;br /&gt;  // Get the frame&lt;br /&gt;  image = cvQueryFrame(capture);&lt;br /&gt;&lt;br /&gt;  // Flip Horiz and Vert&lt;br /&gt;  cvFlip(image, image, 1);&lt;br /&gt;  cvFlip(image, image, 0);&lt;br /&gt;&lt;br /&gt;  // Get current time&lt;br /&gt;  lt = time(NULL);&lt;br /&gt;  ptr = localtime(&amp;lt);&lt;br /&gt;&lt;br /&gt;  // Format time into filename with path&lt;br /&gt;  strftime(str, 100, "/tmp/cam/%y_%m_%d-%H_%M_%S.png", ptr);&lt;br /&gt;&lt;br /&gt;  // Save the frame into a file&lt;br /&gt;  cvSaveImage(str , image, p);&lt;br /&gt;&lt;br /&gt;  // Change owner of file&lt;br /&gt;  strftime(str, 100, "chown pwner:pwner /tmp/cam/%y_%m_%d-%H_%M_%S.png", ptr);&lt;br /&gt;  system(str);&lt;br /&gt;&lt;br /&gt;  // Only run through loop once a second&lt;br /&gt;  sleep(1);&lt;br /&gt;&lt;br /&gt;  // Remove files greater then 5 minutes old&lt;br /&gt;  system("find /tmp/cam/ -mmin +5 -exec rm {} \\;");&lt;br /&gt;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Compile with (note your library and include locations may be different):&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: bash; toolbar: false; gutter: false;"&gt;&lt;![CDATA[&lt;br /&gt;gcc main.c -o camcapture -I/usr/include/opencv -L/usr/lib -lcxcore -lcv -lcvaux -lhighgui&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;So basically:&lt;br /&gt;&lt;pre type="syntaxhighlighter" class="brush: text; toolbar: false;"&gt;&lt;br /&gt;Make /tmp/cam&lt;br /&gt;Init the camera&lt;br /&gt;Start looping forever&lt;br /&gt;Take a picture&lt;br /&gt;Record the time&lt;br /&gt;Save the picture&lt;br /&gt;Wait for a second&lt;br /&gt;Remove files older then 5 minutes&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have the process priority line commented out because when I had the niceness set at -20 it wouldn't run consistently every second. I didn't really play around with any other niceness' since the program only runs once a second and takes up 10 percent cpu for a brief moment.&lt;br /&gt;&lt;br /&gt;The php script just loops through all files in /tmp/cam and just spits them to the screen. list.php just shows all the files in a line. index.php loads list.php in an iframe. When you click on a picture in the list it reloads index.php with the selected picture full scale. &lt;br /&gt;&lt;br /&gt;This method has a serious flaw in that loading 300 or so pictures in one go is not quick task (even with /tmp mounted in ram), but it is fast enough for the purpose it serves.&lt;br /&gt;&lt;br /&gt;To get the images from /tmp/cam to the apache root directory I simply made a symlink called images which points to /tmp/cam&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;index.php&lt;/span&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: php; toolbar: false;"&gt;&lt;![CDATA[&lt;br /&gt;&lt;html&gt;&lt;br /&gt;&lt;head&gt;&lt;title&gt;Camera&lt;/title&gt;&lt;/head&gt;&lt;br /&gt;&lt;body bgcolor=#000000&gt;&lt;br /&gt;&lt;br /&gt;&lt;?php&lt;br /&gt; if ($_GET["image"] != "")&lt;br /&gt; {&lt;br /&gt;  echo "&lt;center&gt;&lt;img src='images/".$_GET["image"]."'&gt;&lt;/center&gt;&lt;br&gt;&lt;hr&gt;&lt;br&gt;";&lt;br /&gt; }&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe name="list" width="100%" height="300" frameborder=0 src="list.php"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;/body&gt;&lt;br /&gt;&lt;/html&gt;&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;list.php&lt;/span&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: php; toolbar: false;"&gt;&lt;![CDATA[&lt;br /&gt;&lt;html&gt;&lt;br /&gt;&lt;head&gt;&lt;br /&gt;&lt;style type="text/css"&gt;&lt;br /&gt;body, html {&lt;br /&gt;   margin: 0;&lt;br /&gt;   padding: 0;&lt;br /&gt;   height: 100%;&lt;br /&gt;}&lt;br /&gt;body {&lt;br /&gt;     white-space:nowrap; &lt;br /&gt;}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;/head&gt;&lt;br /&gt;&lt;body bgcolor=#000000&gt;&lt;br /&gt;&lt;?php&lt;br /&gt; $handle = opendir('/tmp/cam/');&lt;br /&gt; while (false !== ($file = readdir($handle)))&lt;br /&gt; {&lt;br /&gt;  echo "&lt;img style='border-style: none' width='250px' src='images/".$file."' onClick='top.location.href=\"index.php?image=".$file."\"'.&gt;";&lt;br /&gt; }&lt;br /&gt;?&gt;&lt;br /&gt;&lt;/body&gt;&lt;br /&gt;&lt;/html&gt;&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-7880702550022819850?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/7880702550022819850/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2010/08/quick-and-dirty-security-camera.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/7880702550022819850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/7880702550022819850'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2010/08/quick-and-dirty-security-camera.html' title='Quick And Dirty Security Camera'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4143/4883791674_847451edb1_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-4307225699202729138</id><published>2009-11-14T16:48:00.024-05:00</published><updated>2010-08-11T22:47:03.370-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='omegle'/><category scheme='http://www.blogger.com/atom/ns#' term='man in the middle'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><category scheme='http://www.blogger.com/atom/ns#' term='hack'/><title type='text'>Omegle.com Man In The Middle Attack</title><content type='html'>The other day my friend showed me this site &lt;a href="http://omegle.com"&gt;Omegle&lt;/a&gt;. It's a pretty cool site that anonymously pairs you up with a 'stranger' and you chat 1 on 1 with the ability to disconnect and find a new 'stranger' at any time. It's surprisingly addicting and fun. It claims to be completely anonymous and so to check this I decided to fire up &lt;a href="http://www.wireshark.org/"&gt;Wireshark&lt;/a&gt; and take a look at what information was getting passed to the server. I was surprised to find the method of communication extremely simple and completely unencrypted. When you connect to a person the process looks like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;You:&lt;/span&gt; POST omegle.com/start&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Omg:&lt;/span&gt; HTTP "123456"             &lt;span style="font-weight:bold;"&gt;&lt;-- random 6 digit 'username' (a-z A-Z 0-9 _ -)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;You:&lt;/span&gt; POST omegle.com/events?id=123456&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Omg:&lt;/span&gt; HTTP [["connected"]]&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;You:&lt;/span&gt; POST omegle.com/send?msg=hello&amp;id=123456&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Omg:&lt;/span&gt; HTTP win                  &lt;span style="font-weight:bold;"&gt;&lt;-- funny&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;You:&lt;/span&gt; POST omegle.com/events?id=123456&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Omg:&lt;/span&gt; HTTP [["gotMessage", "hey"]]     &lt;span style="font-weight:bold;"&gt;&lt;-- message from other person&lt;/span&gt;&lt;br /&gt;...&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;You:&lt;/span&gt; POST omegle.com/disconnect?id=123456 &lt;span style="font-weight:bold;"&gt;&lt;-- quit the chat&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Seeing this immediately sparked some thought. Can I request events for other users? Can I send messages to other users? Can I disconnect other users? It seemed all you needed to do was post the command with the user id you wanted to receive events for. As it turns out its almost even better. If you post for events using someone elses user id it will "implode" their chat:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4103478151/" title="Screenshot by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2491/4103478151_554efd56bd_o.png" width="466" height="62" alt="Screenshot" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Whats better is that the other person is still connected and they have no idea that their 'stranger' has been imploded. Now you can keep talking to the other person and they have no idea what just happened.&lt;br /&gt;&lt;br /&gt;There is one major problem with this however. According to:&lt;br /&gt;&lt;br /&gt;http://omegle.com/count&lt;br /&gt;&lt;br /&gt;there are on average only about 3k users online at a given time, but the number of possible user ids are&lt;br /&gt;&lt;br /&gt;(26+26+10+1+1)^6 = 68,719,476,736&lt;br /&gt;&lt;br /&gt;That is a terrible chance of you finding someone quickly. I actually started making a brute forcer (omegle_brute_force.py) but quickly realized that this was an ill fated attempted.&lt;br /&gt;&lt;br /&gt;So if you cant find the users, why not have the users come to you? I realized that Omegle would be prime for a classic &lt;a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack"&gt;man in the middle attack&lt;/a&gt;. The idea is super simple. I would connect to two strangers just like normal, but instead of me talking to them they would talk to each other &lt;span style="font-weight:bold;"&gt;through&lt;/span&gt; me. As long as I don't inject any messages or anything weird they should have no idea that I'm even there. Here is how the program looks:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4103393791/" title="omegle by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2625/4103393791_c83703f5fe.jpg" width="430" height="336" alt="omegle" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;As you can see I am having a legit connection to both client 1 and client 2, but I am transparently passing their messages right through me to the other person.&lt;br /&gt;&lt;br /&gt;Doing this was kinda tricky. Whenever you POST for events it blocks until the read is fulfilled. This means that with a single threaded program each person would have to take turns talking since the program would block every time I polled for their messages. Even most two threaded setups have the same problem. The solution I came up with I feel works pretty well. There are four total threads:&lt;br /&gt;&lt;br /&gt;1) Sending to client 1&lt;br /&gt;2) Receiving from client 1&lt;br /&gt;3) Sending to client 2&lt;br /&gt;4) Receiving from client 2&lt;br /&gt;&lt;br /&gt;Every time the receive thread gets a message it queues it into a stack, so that the sending thread can retrieve the message at its leisure. The result? It doesn't matter if a POST blocks because the sender thread can still work through the queue and the other threads can still send and receive messages.&lt;br /&gt;&lt;br /&gt;A classic man in the middle attack:&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4104149908/" title="Screenshot-2 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2527/4104149908_cedf54478d.jpg" width="500" height="420" alt="Screenshot-2" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;This has some interesting possibilities. I can send messages to one of the clients at the others behalf and the person will have no idea that I sent it. Also what about connecting more then 2 people together? There is no reason I couldn't connect multiple people together in a chat and maybe even append a user tag to each of their messages.&lt;br /&gt;&lt;br /&gt;Omegle is a pretty interesting site, and you gotta hand it to &lt;a href="http://omegler.blogspot.com/"&gt;Leif K-Brooks&lt;/a&gt; for (apparently) single handedly making such a propular site at only 18. I hope that he can implement some needed security to Omegle to prevent this kind of attack in the future.&lt;br /&gt;&lt;br /&gt;Download my programs &lt;span style="font-weight:bold;"&gt;&lt;a href="http://ucfilespace.uc.edu/~thrunml/omegle.zip"&gt;here&lt;/a&gt; [&lt;a href="http://bear24rw.gotdns.com:40/omegle.zip"&gt;mirror&lt;/a&gt;]&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;omegle_man_in_middle.py&lt;/span&gt; - program described above&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;omegle_brute_force.py&lt;/span&gt;  - attempts to guess user ids and post for events&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;omegle_class.py&lt;/span&gt;        - generic class for interacting with omegle&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;omegle_connect_view.py&lt;/span&gt; - connect to omegle and posts for events&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;omegle_multi_connect.py&lt;/span&gt; - connects to multiple people at once. proof of concept that multi connections can be made&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;omegle_send.py&lt;/span&gt;         - send messages using a user id&lt;br /&gt;&lt;br /&gt;EDIT:&lt;br /&gt;&lt;br /&gt;Found another omegle man in the middle attack written in perl [&lt;a href="http://thinkwaitfast.blogspot.com/2009/09/i-should-really-get-job-soon.html"&gt;here&lt;/a&gt;]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-4307225699202729138?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/4307225699202729138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2009/11/omeglecom-man-in-middle-attack.html#comment-form' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/4307225699202729138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/4307225699202729138'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2009/11/omeglecom-man-in-middle-attack.html' title='Omegle.com Man In The Middle Attack'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2625/4103393791_c83703f5fe_t.jpg' height='72' width='72'/><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-249059568814771117</id><published>2009-11-08T17:54:00.046-05:00</published><updated>2011-08-26T00:19:45.053-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ps3'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='karmic'/><category scheme='http://www.blogger.com/atom/ns#' term='ov534'/><category scheme='http://www.blogger.com/atom/ns#' term='eye'/><category scheme='http://www.blogger.com/atom/ns#' term='patch'/><category scheme='http://www.blogger.com/atom/ns#' term='playstation'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='driver'/><category scheme='http://www.blogger.com/atom/ns#' term='gspca'/><title type='text'>PS3 Eye Driver Patch</title><content type='html'>&lt;span style="font-weight:bold;"&gt;Update:&lt;/span&gt; A lot has happened since this was posted. The main line kernel now includes most of these fixes!&lt;br /&gt;&lt;br /&gt;I've had a &lt;a href="http://en.wikipedia.org/wiki/PlayStation_Eye"&gt;PS3 Eye&lt;/a&gt; lying around for a while but I hadn't gotten around to using it because when it first came out there were no drivers for it so it sat in my closet for almost a year. I decided to check out the current state of the PS3 Eye in Linux and was happy to find that there is now support in the 2.6.31 kernel. &lt;br /&gt;&lt;br /&gt;What I was disappointed to find out though was that there was no ability to select frame rate or control a lot of the image quality. Lucky there is &lt;a href="http://kaswy.free.fr/?q=en/node/54"&gt;patch&lt;/a&gt; that allows selection of frames rates all the way up to 125 fps and some image quality controls. I patched my driver and tried it out but found that the color of the image was way off and none of the given controls could fix this. &lt;br /&gt;&lt;br /&gt;I decided to do some research and add support for brightness, contrast, hue, and auto white balance.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4086925303/" title="before by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2592/4086925303_8104630ae6.jpg" width="500" height="230" alt="before" /&gt;&lt;/a&gt;&lt;br&gt;&lt;i&gt;With Kaswy's Patch&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/4087682316/" title="driver by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2713/4087682316_2eb1f2237d.jpg" width="500" height="213" alt="driver" /&gt;&lt;/a&gt;&lt;br&gt;&lt;i&gt;With my patch&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;I'm going to just supply the whole .c file instead of a patch since they are almost the same size. Applying the patch is almost the same as Kaswy's&lt;br /&gt;&lt;br /&gt;To apply:&lt;br /&gt;&lt;br /&gt;Install necessary packages:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ sudo apt-get install kernel-package libncurses5-dev wget bzip2 build-essential linux-source&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Extract kernel source code:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ sudo su&lt;br /&gt;$ cd /usr/src&lt;br /&gt;$ tar --bzip2 -xvf linux-source-2.6.(your version).tar.bz2&lt;br /&gt;$ ln -s linux-source-2.6.(your version) linux&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Replace driver:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ cd linux&lt;br /&gt;$ wget ucfilespace.uc.edu/~thrunml/ov534.c&lt;br /&gt;$ rm drivers/media/video/gspca/ov534.c&lt;br /&gt;$ mv ov534.c drivers/media/video/gspca/&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Recompile driver:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ cp /usr/src/linux-headers-$(uname -r)/Module.symvers /usr/src/linux&lt;br /&gt;$ make oldconfig&lt;br /&gt;$ make modules_prepare&lt;br /&gt;$ make SUBDIRS=drivers/media/video/gspca modules&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Install new driver:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ cp drivers/media/video/gspca/gspca_ov534.ko /lib/modules/$(uname -r)/kernel/drivers/media/video/gspca&lt;br /&gt;$ depmod&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Check to make sure it installed:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ modinfo gspca-ov534&lt;br /&gt;filename:       /lib/modules/2.6.31-14-generic/kernel/drivers/media/video/gspca/gspca_ov534.ko&lt;br /&gt;license:        GPL&lt;br /&gt;description:    GSPCA/OV534 USB Camera Driver(kaswy mod for MT use V0.5 / &lt;b&gt;bear24rw patch V0.1&lt;/b&gt;)&lt;br /&gt;author:         Antonio Ospite &lt;ospite@studenti.unina.it&gt;&lt;br /&gt;srcversion:     1F87820D2B0705822B61A16&lt;br /&gt;alias:          usb:v1415p2000d*dc*dsc*dp*ic*isc*ip*&lt;br /&gt;depends:        gspca_main&lt;br /&gt;vermagic:       2.6.31.4 SMP mod_unload modversions &lt;br /&gt;parm:           videomode: = xx //Set the videomode(see doc) (int)&lt;br /&gt;parm:           autogain: = [0|1] //Autogain (agc,aec,awb) (bool)&lt;br /&gt;parm:           gain: = [0..63] //main gain (int)&lt;br /&gt;parm:           awb: = [0|1] //Auto White Balance (bool)&lt;br /&gt;parm:           exposure: = [0..255] //Exposure (int)&lt;br /&gt;parm:           brightness: = [0..255] //Brightness (int)&lt;br /&gt;parm:           contrast: = [0..255] //Contrast (int)&lt;br /&gt;parm:           redblc: = [0..255] //Red Balance (int)&lt;br /&gt;parm:           blueblc: = [0..255] //Blue Balance (int)&lt;br /&gt;parm:           hue: = [0..255] //Hue (int)&lt;br /&gt;parm:           sharpness: = [0..63] //Sharpness (int)&lt;br /&gt;parm:           vflip: = [0|1] //Vertical flip (bool)&lt;br /&gt;parm:           hflip: = [0|1] //Horizontal mirror (bool)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now we can remove the one currently in use and load our new one:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ modprobe -r gspca-ov534&lt;br /&gt;$ modprobe gspca-ov534 videomode=10&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The available video modes are:&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;00: 640x480@15&lt;br /&gt;01: 640x480@30&lt;br /&gt;02: 640x480@40&lt;br /&gt;03: 640x480@50&lt;br /&gt;04: 640x480@60&lt;br /&gt;10: 320x240@30&lt;br /&gt;11: 320x240@40&lt;br /&gt;12: 320x240@50&lt;br /&gt;13: 320x240@60&lt;br /&gt;14: 320x240@75&lt;br /&gt;15: 320x240@100&lt;br /&gt;16: 320x240@125&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can adjust the image using guvcview&lt;br /&gt;&lt;pre class="brush: terminal; toolbar: false; gutter: false;"&gt;&lt;br /&gt;$ sudo apt-get install guvcview&lt;br /&gt;$ guvcview&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hopefully the main line driver gets patched soon with these enhancements.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-249059568814771117?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/249059568814771117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2009/11/ps3-eye-driver-patch.html#comment-form' title='87 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/249059568814771117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/249059568814771117'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2009/11/ps3-eye-driver-patch.html' title='PS3 Eye Driver Patch'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm3.static.flickr.com/2592/4086925303_8104630ae6_t.jpg' height='72' width='72'/><thr:total>87</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-3928132441856256669</id><published>2009-10-01T12:36:00.034-04:00</published><updated>2010-08-11T23:32:49.971-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='darlington'/><category scheme='http://www.blogger.com/atom/ns#' term='atmega'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='etching'/><category scheme='http://www.blogger.com/atom/ns#' term='john'/><category scheme='http://www.blogger.com/atom/ns#' term='display'/><category scheme='http://www.blogger.com/atom/ns#' term='thrun'/><category scheme='http://www.blogger.com/atom/ns#' term='shift'/><category scheme='http://www.blogger.com/atom/ns#' term='matrix'/><category scheme='http://www.blogger.com/atom/ns#' term='pcb'/><category scheme='http://www.blogger.com/atom/ns#' term='register'/><category scheme='http://www.blogger.com/atom/ns#' term='board'/><category scheme='http://www.blogger.com/atom/ns#' term='eagle'/><category scheme='http://www.blogger.com/atom/ns#' term='led'/><category scheme='http://www.blogger.com/atom/ns#' term='wathen'/><category scheme='http://www.blogger.com/atom/ns#' term='max'/><title type='text'>LED Matrix</title><content type='html'>Last year in one of my classes we were required to make an 'artefact' or something that reflects the interests of the class. Most people make posters and the past two quarters that's what my class did too. Posters however are static, usually boring, and don't reflect that fact that everyone in the class is an EE major. We decided posters are for noobs and decided to go off the wall a little and make an LED matrix display. Lucky one of my friends John Wathen already had this beautiful 16x24 Green SMD LED matrix that he built back in high school.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574348952/" title="P5271009 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3652/3574348952_c85af6167f.jpg" width="500" height="375" alt="P5271009" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573544803/" title="P5271014 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2452/3573544803_03000843fc.jpg" width="500" height="375" alt="P5271014" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;What we didn't have however was a driver for it. The driver we choose to design was highly inspired from &lt;a href="http://www.instructables.com/id/LED-matrix-using-shift-registers/"&gt;this one&lt;/a&gt;. The basic idea is that you use shift registers to sink the columns and a line driver of some sort to source the rows (we chose to use a &lt;a href="http://en.wikipedia.org/wiki/Darlington_transistor"&gt;Darlington array&lt;/a&gt;). &lt;br /&gt;&lt;br /&gt;There where a lot of changes from the Instructables design that that we had to make however. The matrix in the Instructables was a lot smaller than ours and used 8 IO lines to drive each row. Since our matrix has 16 rows this was completely infeasible using just an &lt;a href="http://www.atmel.com/dyn/products/Product_card.asp?part_id=3303"&gt;ATMega168&lt;/a&gt;. To solve this issue we choose to use a 4:16 &lt;a href="http://en.wikipedia.org/wiki/Multiplexer"&gt;de-mux&lt;/a&gt; to control all sixteen rows with only 4 IO pins. The de-mux combined with two 8 channel Darlington arrays provided the perfect interface to control all 16 rows. To sink the columns we choose to string three 8 Output &lt;a href="http://en.wikipedia.org/wiki/Shift_register"&gt;shift registers&lt;/a&gt;. Each shift register is rated to handle the current of the 8 LEDs that could possibly be on at one time.&lt;br /&gt;&lt;br /&gt;Some other features that we included on the driver board were 3 green LEDs, 3 push buttons, ISP header, TTL header. When all was said and done we ended up the the schematic shown below.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574373426/" title="rev_4 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2447/3574373426_503851b4e9.jpg" width="500" height="256" alt="rev_4" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;I know, you are probably looking at that and thinking, "Why are all the shift register outputs criss-crossed??". The reason for doing this is because the output pins on the chip are not exactly in a row so to assist in board layout the pins had to be crossed and mixed up so that the board layout would be nice. It's much easier to change the order of the columns in the program then it is on the board layout (in my opinion). We didn't want to etch a double sided board so a lot of effort went into laying as much of the circuit out on a single side. There were a few paths that could not be routed and were just jumped with wire (you'll see in picture below).&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3971619171/" title="board by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3528/3971619171_aefd2ebefe.jpg" width="500" height="404" alt="board" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Notice how there are a bunch of air-wires (yellow lines) that I couldn't figure out how to route, they are manually jumped when the board is put together.&lt;br /&gt;&lt;br /&gt;To etch the board we printed out the board layout 1:1 scale on glossy photo paper, it was than ironed onto a piece of copper clad. The idea is that the toner will stick to the copper clad and when the board is dipped in acid the acid will eat away at everything but the traces, since they are coved by the toner. I'm definitely not an expert in this area so ask John Wathen more about the process, he is basically a pro.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3575123202/" title="DSC_9192 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3321/3575123202_5d0d4d3b7a.jpg" width="500" height="332" alt="DSC_9192" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;Etching the board in acid&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3575122950/" title="DSC_9193 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3354/3575122950_15d5263874.jpg" width="500" height="332" alt="DSC_9193" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;Checking to see if its ready to be scrubbed&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3575123848/" title="DSC_9199 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3595/3575123848_e3d2ddf01a.jpg" width="500" height="332" alt="DSC_9199" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;Dirty traces&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3575124082/" title="DSC_9205 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2431/3575124082_465d0bd566.jpg" width="500" height="332" alt="DSC_9205" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;Scrubbing off the rest of the toner&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3575124516/" title="DSC_9217 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3624/3575124516_a745213afb.jpg" width="500" height="332" alt="DSC_9217" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;i&gt;The beautiful result, nice and shiny&lt;/i&gt;&lt;/center&gt;&lt;br /&gt;Now, let me just tell you that we did this in a public bathroom at school. So there were three guys in a bathroom with latex gloves, a camera, and tub of some green liquid. Trust me we got some weird looks.&lt;br /&gt;&lt;br /&gt;The next step was to drill all the holes. I don't remember exactly how many there were (John might) but there were a lot.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574352632/" title="IMAG0015 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3648/3574352632_aba3c639f7.jpg" width="500" height="375" alt="IMAG0015" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;After all the holes were drilled John soldered it all up.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574349530/" title="P5271010 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3559/3574349530_efda24867a.jpg" width="500" height="375" alt="P5271010" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574349852/" title="P5271011 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3658/3574349852_3a86d9270f.jpg" width="500" height="375" alt="P5271011" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;And the result!&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573545651/" title="P5271017 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3576/3573545651_5a0196498d.jpg" width="500" height="375" alt="P5271017" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574351302/" title="P5271015 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3322/3574351302_6a0e6b5ecf.jpg" width="500" height="375" alt="P5271015" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574350634/" title="P5271013 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2423/3574350634_ac9f937a3c.jpg" width="500" height="375" alt="P5271013" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573542359/" title="P5271008 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3593/3573542359_ea9cf699a6.jpg" width="500" height="375" alt="P5271008" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3574347398/" title="P5271007 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3410/3574347398_0e0d004da3.jpg" width="500" height="375" alt="P5271007" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573540181/" title="P5271004 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3600/3573540181_d861a7ddfa.jpg" width="500" height="375" alt="P5271004" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573540987/" title="P5271005 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3344/3573540987_a7371e6016.jpg" width="375" height="500" alt="P5271005" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573541779/" title="P5271006 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3564/3573541779_4f6ea4c3b9.jpg" width="375" height="500" alt="P5271006" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573546271/" title="P5271019 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2465/3573546271_f5ef0f8d60.jpg" width="375" height="500" alt="P5271019" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3573544803/" title="P5271014 by bear24rw, on Flickr"&gt;&lt;img src="http://farm3.static.flickr.com/2452/3573544803_03000843fc.jpg" width="500" height="375" alt="P5271014" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Now that the board was finished it was the moment of truth.&lt;br /&gt;&lt;br /&gt;Adam Steele lent me his programmer. Plugged it into my Xbuntu box, apt-get installed the avr tool-kit and the programmer was immediately recognized (NICE!). Flashed a simple program to flash the status LEDs and low and behold, IT WORKED! Next up, everything else. I started by modifying the program that the Intructables provided but quickly got frustrated by the way it worked. It treated each column as a bit in a byte and the rows as a byte, this made it extremely hard to visualize outputs to the display. Also I was using a de-mux and had 24 columns which the code did not easy support. So what do you do in this situation? REWRITE. &lt;br /&gt;&lt;br /&gt;An outline of how the new code works:&lt;br /&gt;&lt;br /&gt;The value for each pixel is stored in a 2D array 16x24, want to set the top left pixel? buffer[0][0] = 1; simple as that, much easier than dealing with it as an array of bytes. Okay, so it takes up more memory but IMO it is completely worth every bit (pun intended). &lt;br /&gt;&lt;br /&gt;The code starts by initializing the ports (pull-ups, in/out, etc) then it initializes timer1. To be completely honest the fill value for the timer was chosen by adjusting value, flashing, seeing if the refresh rate was noticeable. We ended up with OCR1A = 0x012C; as a good value.&lt;br /&gt;&lt;br /&gt;The code then falls into an While(1) where it sequentially calls functions to draw stuff on the screen, for example:&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: c"&gt;&lt;![CDATA[&lt;br /&gt;Spiral(5, 0);&lt;br /&gt;&lt;br /&gt;Tunnel(1);&lt;br /&gt;Tunnel(0);&lt;br /&gt;Tunnel(1);&lt;br /&gt;&lt;br /&gt;Erase_Rider(RIGHT, 10);&lt;br /&gt;Fill(LEFT, 10);&lt;br /&gt;&lt;br /&gt;Shift(UP, 16, 50);&lt;br /&gt;&lt;br /&gt;Erase_Rider(DOWN, 10);&lt;br /&gt;Erase_Rider(UP, 10);&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;All the high level functions (tunnel, spiral, shift, etc..) write to 'buffer'. When the timer interrupt goes off it calls the function shift_int() which reorders the columns into 'buffer_2' and then shifts them out to the shift registers. It then calls shift_mux() which jumps to the next row. So essentially we have a double buffered display.&lt;br /&gt;&lt;br /&gt;Once all the low level code was done it was all fun and games. It was really nice being at the point were all you had to work with is a 2D array. We ended up with the high level functions:&lt;br /&gt;&lt;br /&gt;&lt;script type="syntaxhighlighter" class="brush: c"&gt;&lt;![CDATA[&lt;br /&gt;void Delay_ms(int cnt)&lt;br /&gt;void Clear_Display(void)&lt;br /&gt;void Fill_Display(void)&lt;br /&gt;void Flash_Display(u8 cycles, u8 speed)&lt;br /&gt;void Col(u8 col, u8 state)&lt;br /&gt;void Row(u8 row, u8 state)&lt;br /&gt;void Fill_Col(u8 col, u8 dir, u8 speed, u8 state)&lt;br /&gt;void Fill_Row(u8 row, u8 dir, u8 speed, u8 state)&lt;br /&gt;void Fill(u8 dir, u8 speed)&lt;br /&gt;void Invert_Col(u8 col)&lt;br /&gt;void Invert_Row(u8 row)&lt;br /&gt;void Invert_Fill(u8 dir, u8 speed) &lt;br /&gt;void Erase_Rider(u8 dir, u8 speed)&lt;br /&gt;void Spiral(u8 speed, u8 state)&lt;br /&gt;void Tunnel(u8 state)&lt;br /&gt;void Invert(u8 count, u8 speed)&lt;br /&gt;void Draw_Line(u8 x1, u8 y1, u8 x2, u8 y2, u8 state)&lt;br /&gt;void Shift(u8 dir, u8 amount, u8 speed)&lt;br /&gt;void Scroll_Char (char myChar, u8 pos, u8 dir, u8 speed)&lt;br /&gt;void Box(u8 speed, u8 dir, u8 state) &lt;br /&gt;void Grid(u8 speed, u8 state)&lt;br /&gt;]]&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;It is so incredibly easy to make new functions when you are just manipulating a 2D array.&lt;br /&gt;&lt;br /&gt;A warning before you watch the videos, they were taken with a crappy point n shoot camera so they look incredibly choppy. In real life the display is incredibly fluid and smooth. The videos do it zero justice.&lt;br /&gt;&lt;center&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/VOljZt9pW5g&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/VOljZt9pW5g&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/zxe39Q0XnrA&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/zxe39Q0XnrA&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/center&gt;&lt;br /&gt;&lt;a href="https://ucfilespace.uc.edu/~thrunml/led_board.zip"&gt;Eagle Files &amp; Source Code&lt;/a&gt; [&lt;a href="http://bear24rw.gotdns.com:40/led_board.zip"&gt;Mirror&lt;/a&gt;]&lt;br /&gt;If you re-use the design or source (which I encourage you to do) please give credit where credit is due. Also note that the entire code was literally written in a one night programming marathon since we were extremely pressed (read: it was due the next day), so there are still many bugs. Also I take no responsibility for any damage if you use my design and code (had to put a disclaimer ;))&lt;br /&gt;&lt;br /&gt;Any questions regarding the design or the source code should be directed at me bear24rw . gmail.com&lt;br /&gt;Any questions regarding the construction of the board should be directed at John Wathen jmwathen . gmail.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-3928132441856256669?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/3928132441856256669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2009/10/led-matrix.html#comment-form' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/3928132441856256669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/3928132441856256669'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2009/10/led-matrix.html' title='LED Matrix'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3652/3574348952_c85af6167f_t.jpg' height='72' width='72'/><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3623515592551780770.post-2137749716190598899</id><published>2008-12-26T13:08:00.008-05:00</published><updated>2008-12-26T14:11:23.485-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Basic Stamp'/><category scheme='http://www.blogger.com/atom/ns#' term='Servo'/><category scheme='http://www.blogger.com/atom/ns#' term='RFID'/><category scheme='http://www.blogger.com/atom/ns#' term='Door Unlocker'/><category scheme='http://www.blogger.com/atom/ns#' term='Keyless Entry'/><category scheme='http://www.blogger.com/atom/ns#' term='Parallax'/><title type='text'>RFID Door Unlocker</title><content type='html'>Todays world is all about efficiency, this includes getting into your dorm room. Inspired by other door unlocking projects found around the Internet, especially the &lt;a href="http://www.engadget.com/2006/10/21/mit-student-hacks-his-dorm-room-door-lock/" target="new"&gt;MIT one&lt;/a&gt; that is practically famous, I decided it was time to outfit my own door with an RFID unlocker.&lt;br /&gt;&lt;br /&gt;Our dorms offer the unique benefit of having full length mirrors on the doors so I figured that suction cups would be the best way to go as they were easy to apply, remove and are non marking.&lt;br /&gt;&lt;br /&gt;Being that I already had a &lt;a href="http://www.parallax.com/Store/Microcontrollers/BASICStampProgrammingKits/tabid/136/CategoryID/11/List/0/SortField/0/Level/a/ProductID/294/Default.aspx"&gt;Basic Stamp&lt;/a&gt;, Parallax's &lt;a href="http://www.parallax.com/Store/Microcontrollers/BASICStampModules/tabid/134/txtSearch/RFID/List/1/ProductID/114/Default.aspx?SortField=ProductName%2cProductName"&gt;RFID reader&lt;/a&gt; seemed to be the obvious choice as it was the cheapest reader I could find and already had example code written for it.&lt;br /&gt;&lt;br /&gt;My initial plan involved just a servo, standoffs, and suction cups...&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3036473344/" target="new" title="door_lock by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3039/3036473344_337f9033ab.jpg" alt="door_lock" border="0" height="500" width="344" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Modeled in Autodesk Inventor...&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3036473518/" target="new" title="render_1 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3047/3036473518_32251d8445.jpg" alt="render_1" border="0" height="375" width="500" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;After some of the parts came in I set up a quick prototype to make sure the servo was even strong enough to flip the latch and that I could read the tag through the door. To attach the servo horn to the latch I tied a piece of string to the horn and taped it to the top of the latch, this is how it done in the final version as well. The reason for using string is so that you could still easily unlock the door with the key, it would just put slack in the string. The only fault with this method is that you cannot use the RFID tag to lock the door.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/mOO9eL6x8pg&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/mOO9eL6x8pg&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;I quickly realized that I had given no thought as to how I was going to mount all the electronics. As a result the servo remained like that on my door for weeks. As I was cleaning my desk one day I found this box and instantly realized that it was perfect for the door unlocker.&lt;br /&gt;&lt;br /&gt;Another quick mockup in Invetor to see if everything fit, and it did perectly..&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3040794161/" target="new" title="render_4 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3186/3040794161_eed27a5c5e.jpg" alt="render_4" border="0" height="375" width="500" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;Ordered some 6-32 screws and nuts from &lt;a href="http://www.mcmaster.com/"&gt;McMaster&lt;/a&gt; and started assembly.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3036474442/" target="new" title="PB120691 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3204/3036474442_f72043bdac.jpg" alt="PB120691" border="0" height="500" width="375" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3036474114/" target="new" title="PB120690 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3213/3036474114_459e5c5474.jpg" alt="PB120690" border="0" height="500" width="375" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The servo fits perfectly height wise, it sits against the bottom of the base when closed. Now that I had the servo and RFID reader mounted I needed to get some holes drilled for the suction cups and basic stamp. Due to my &lt;del&gt;procrastination&lt;/del&gt; studying the project sat on my desk for a week.&lt;br /&gt;&lt;br /&gt;I finally got around to drilling the holes and mounting the whole thing...&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3036476094/" title="PB160699 by bear24rw, on Flickr" target="new"&gt;&lt;img src="http://farm4.static.flickr.com/3176/3036476094_0a94c137c0.jpg" alt="PB160699" border="0" height="500" width="375" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3035641697/" target="new" title="PB160700 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3211/3035641697_28f36f8af4.jpg" alt="PB160700" border="0" height="500" width="375" /&gt;&lt;/a&gt;&lt;/center&gt;&lt;br /&gt;I used paper under the basic stamp to insulate it from the metal box.&lt;br /&gt;&lt;br /&gt;The assembly did not go without problems, however.&lt;br /&gt;&lt;br /&gt;The first major problem was when I went to reassemble the box after I put on the suction cups. I didn't take into consideration that the nuts would get in the way of the box closing. As you can see in the pictures I had to snip spaces in the box where the nuts were so the box would be able to close all the way.&lt;br /&gt;&lt;br /&gt;The second major problem was a weird one. The RFID reader was originally going to be mounted on the inside of the box. This box was perfect because the front was plastic and didn't interfere with the reader. The problem was, when I closed everything up in the box the range of the reader was almost cut in half and I couldn't read the tag through the door. However, if I pulled the box apart (like it is being shown in the above pictures) the tag could be read through the door. My best guess is electrical noise is causing this but I honestly did not want to spend any longer on this project, and there seemed little alternatives. I ended up just mounting the reader on the outside of the box. It does not really make any difference other then looks.Here is how it looks when it is all up and running.&lt;br /&gt;&lt;br /&gt;&lt;center&gt;&lt;a href="http://www.flickr.com/photos/bear24rw/3036474834/" target="new" title="PB150694 by bear24rw, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3236/3036474834_25907ddb65.jpg" alt="PB150694" border="0" height="500" width="375" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/zbAy0aqiAsU&amp;amp;hl=en&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/zbAy0aqiAsU&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;The basic stamp program can be downloaded &lt;a href="http://homepages.uc.edu/%7Ethrunml/rfid/rfid_unlocker.BS2"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3623515592551780770-2137749716190598899?l=bear24rw.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bear24rw.blogspot.com/feeds/2137749716190598899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bear24rw.blogspot.com/2008/12/rfid-door-unlocker.html#comment-form' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/2137749716190598899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3623515592551780770/posts/default/2137749716190598899'/><link rel='alternate' type='text/html' href='http://bear24rw.blogspot.com/2008/12/rfid-door-unlocker.html' title='RFID Door Unlocker'/><author><name>Max Thrun</name><uri>http://www.blogger.com/profile/18216963066514872707</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3039/3036473344_337f9033ab_t.jpg' height='72' width='72'/><thr:total>25</thr:total></entry></feed>
