I have to admit, I am usually not the biggest fan of interpreted languages and high level programming. But in this case, they were very convenient.
This is thus a small article about what you can do in 3-4 hours with Matlab and a FTDI USB connectivity to your project. As an example, here is a project where my webcam output (well, kind of) gets displayed on my led matrix:
For quite some time now, on my projects, I have been using Matlab for various data processing operations, picture conversions...
and also communication with my embedded systems using FTDI USB to RS232 converters. Nothing more convenient that a simple fread() and fwrite() to import/export your data to/from your computer!
If you have read my blog, you may know that I have a 96*64 bi-color led matrix at my disposal. Until now, I was generating all the screen data on the fly and still hadn't implemented the possibility to directly write to the led matrix frame buffer through its USB port.
So yesterday I finally got the motivation to modify my FPSLIC code and optimize it to receive streamed data. As double-buffering was already implemented, the coding part was pretty quick!
To have a clear and simple application of this added functionality, I thought it would be nice to display some data coming from my computer... What kind of data? The obvious choice was the webcam feed.
This is where Matlab was very useful. In only 50 lines of code, I was able to show the edges detected from my webcam feed:
function output_args = webcam( input_args ) s = serial('COM3', 'Parity', 'none', 'ByteOrder', 'BigEndian', 'InputBufferSize', 2000000, 'OutputBufferSize', 1000000 , 'BaudRate', 520833, 'DataBits', 8, 'RequestToSend', 'off', 'StopBits', 1, 'ReadAsyncMode', 'continuous', 'FlowControl', 'none'); fopen(s); vid = videoinput('winvideo', 1, 'RGB24_160x120'); himage = preview(vid); buffer = uint8(zeros(768, 1)); for i=1:2000 %tic data = getsnapshot(vid); data = imresize(data, 64 96); data = rgb2gray(data); BW = edge(data,'canny'); %toc index_store = 1; %tic for x=1:96 for y=1:8 A = 0; for j=1:8 val = BW((y-1)*8 + j, 97 - x); A = A + val * 2^(8-j); end buffer(index_store) = A; index_store = index_store + 1; end end while(strcmp(s.TransferStatus, 'idle') == 0) index_store = index_store + 1; end fwrite(s,buffer,'uint8', 'async'); %toc %fprintf('\r\n'); end while(strcmp(s.TransferStatus, 'idle') == 0) index_store = index_store + 1; end fclose(s); delete(s); stoppreview(vid); closepreview(vid); end
As you see, everything is pretty simple here. Snapshots getting acquired, image resizing, conversion to B&W for edge detection and some compression for direct write to the frame buffer.
Of course, this code is based on the assumption that picture generation will not be faster than the link to the led matrix (which in my case is true). Actually in this mode, my led matrix constantly output its SYNC signal so frame synchronization could be implemented in the future.
Asynchronous sending to the serial port is used, and the whole buffer is put in the queue at once. Not doing so would considerably increase the loop execution time in synchronous mode, and in asynchronous mode active waiting should be used between each call to fwrite.
RS232 link speed is set to allow for 520833 / (96 * 64 * 2) = 42Hz refresh rate which is enough for what i want to do. Of course, the display is only bi-color with monochrome data for each color, so everything is simplified! Anyway, here is the final result:
This result is obtained with only using Matlab pre-existing functions, leaving the door opened to additional improvements. Anyway, I just wanted to let you know that with this kind of high level tools, it is very easy & quick to get nice results!