Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : (MM) DMD by Freetronics
Author | Message | ||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
I have recently purchased a DMD ( Dot Matrix Display ), a Freetronics product, and wondered if I could get it to work with the Maximite. My goal was to write a MM library to use this device.. The web link is Freetronics DMD . It is a 32 x 16 Dot matrix of red led's , controlled by the SPI interface. I also purchased an Etherten (arduino) to test the DMD with. The DMD library helped me to understand how to send the commands. A lot of the code in the library was similar to the code available in MMBasic. For instance, LINE, BOX, CIRCLE etc. The Etherten allocated memory to map the display to, then mirrored the display through the SPI bus 4 rows every 5 ms. Rows 1,5,9,13 then on the next loop rows 2,6,10,14 etc for a total of 4 loops, giving a screen update of 20 ms. The display did not flicker, unless you changed the refresh rate to higher than 5ms. I decided to mirror the MM screen to the DMD. When I first started, I was reading 8 pixel's into an array variable, 4 per row (4x8=32) , with 16 rows. IE Dim row(17,4) [okay, so I added a little buffer at end to not step out of the array]. This took 102 ms just to read and build the array. The SPI routine , made up of four 8 bit commands per row (32 commands per write), took just on 10 ms to execute, so I had major flicker....with a total of 142ms per screen refresh. As Geoff had kindly sent me the 3.2 source, I added a function to tell me the position of the Video Buffer in memory. I called it MM.Video. I then used the peek() command to access the screen memory 8 bits at a time, and this sped up the routine for building the array from 102 ms to 12 ms. I then decided to send 16 bits per spi command and this resulted in the refresh rate to change from 142 ms to 32 ms. I still get flicker but not as bad as before.. I have done some videos, in the avi format [divx]. build array and loop display ,142 ms refresh rate 2.01 Mb Build buffer then loop the display, 14 ms refresh rate, then use external power for brighter display. 3.94 Mb Build array with peek(), and loop display, and move text, 8-9 ms refresh rate 3.13 Mb As above , but using external power to power display 1.85 Mb Here is my code, if anyone can help me speed it up... Option base 0
leadingzeroes$="000000000000000000" DMD_A = 16 ' D6 from etherten(arduino) DMD_B = 15 ' D7 from etherten(arduino) DMD_OE = 14 ' D9 from etherten(arduino) DMD_CLK = 20 ' D13 from etherten(arduino) DMD_SCLK = 17 ' D8 from etherten(arduino) DMD_R_Data = 19 ' D11 from etherten(arduino) DMD_T_Data = 18 ' D12 from etherten(arduino) Pin(DMD_A) = 0 SetPin DMD_A , 8 Pin(DMD_B) = 0 SetPin DMD_B , 8 Pin(DMD_OE) = 0 SetPin DMD_OE , 8 Pin(DMD_CLK) = 0 SetPin DMD_CLK , 8 Pin(DMD_SCLK) = 0 SetPin DMD_SCLK , 8 Pin(DMD_R_Data) = 1 SetPin DMD_R_Data , 8 SetPin DMD_T_Data , 2 DisplaysWide=1 DisplaysDown=1 Cls Dim row(17,4) videomem= MM.Video ' code added to source 3.2 by D Wyatt videomemlo = videomem And &h0000ffff videomemhi = ((videomem-videomemlo)\2^16) And &h0000ffff direction = 1 timing = 85 Timer=0 Do text$=Inkey$ If text$="q" Then End nextmove=Timer If nextmove >lastmove + timing Then Line (xpos,0)-(xpos,16),0 xpos=xpos+direction If xpos>30 Or xpos<1 Then direction = -direction Print@(xpos,0) "Maxi" Print@(xpos,8) "mite" lastmove=nextmove EndIf senddata1(0,0,1) senddata1(1,0,2) senddata1(0,1,3) senddata1(1,1,0) Loop Sub senddata1( a_pin , b_pin , displayrow) lastTimer =Timer For y= displayrow To 15 Step 4 row(y,4)=Peek(videomemhi,videomemlo+60*y) Xor &hff row(y,3)=Peek(videomemhi,videomemlo+60*y+1) Xor &hff row(y,2)=Peek(videomemhi,videomemlo+60*y+2) Xor &hff row(y,1)=Peek(videomemhi,videomemlo+60*y+3) Xor &hff Next y ' Print@(10,200) Timer Pin(DMD_A)= a_pin Pin(DMD_B)= b_pin Pin(DMD_OE) = 1 For showbits = 1 To 4 junk1 = SPI(DMD_T_Data, DMD_R_Data, DMD_CLK, row(12+displayrow,showbits)*2^8+row(8+displayrow,showbits), H, 0, 16) junk1 = SPI(DMD_T_Data, DMD_R_Data, DMD_CLK, row(4+displayrow,showbits)*2^8+row(displayrow,showbits), H, 0, 16) Next showbits Pin(DMD_OE) = 0 Pin(DMD_SCLK) = 1 Pin(DMD_SCLK) = 0 Print@(20,220) Timer-lasttimer End Sub Cheers Dennis Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
BobD Guru Joined: 07/12/2011 Location: AustraliaPosts: 935 |
Dennis, if nothing else, maybe you could convince GeoffG to include MM.Video as a permanent feature in future. I recall at least one request / suggestion previously that this would be a good idea. Bob |
||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
Doin' the Snoopy dance.... Just got my code down to less than 1 ms per line sequence timer output flickers between 0 and 1... ie 1,5, 9,13 2,6,10,14 3,7,11,15 4,8,12,16 added a SpiDMD(memhi,memlo,rx,tx,clk) function to the source speed defaults to 'H' mode defaults to '0' zero bits default to '32' NO Flicker at all....... MMBasic code follows Option base 0
leadingzeroes$="000000000000000000" ' for debugging purposes so all bin$() outputs lined up. DMD_A = 16 ' D6 from etherten(arduino) DMD_B = 15 ' D7 from etherten(arduino) DMD_OE = 14 ' D9 from etherten(arduino) DMD_CLK = 20 ' D13 from etherten(arduino) DMD_SCLK = 17 ' D8 from etherten(arduino) DMD_R_Data = 19 ' D11 from etherten(arduino) DMD_T_Data = 18 ' D12 from etherten(arduino) Pin(DMD_A) = 0 SetPin DMD_A , 8 Pin(DMD_B) = 0 SetPin DMD_B , 8 Pin(DMD_OE) = 0 SetPin DMD_OE , 8 Pin(DMD_CLK) = 0 SetPin DMD_CLK , 8 Pin(DMD_SCLK) = 0 SetPin DMD_SCLK , 8 Pin(DMD_R_Data) = 1 SetPin DMD_R_Data , 8 SetPin DMD_T_Data , 2 DisplaysWide=1 DisplaysDown=1 Cls ' Dim row(16,4) ' not needed anymore, get data straight from memory.. videomem= MM.Video ' code added to source 3.2C by D Wyatt offset = MM.Hres\8 ' support for vga / composite videomemlo = videomem And &h0000ffff videomemhi = ((videomem-videomemlo)\2^16) And &h0000ffff direction = 1 timing = 85 Timer=0 Do text$=Inkey$ If text$="q" Then End nextmove=Timer If nextmove >lastmove + timing Then Line (xpos,0)-(xpos,16),0 xpos=xpos+direction If xpos>30 Or xpos<1 Then direction = -direction Print@(xpos,0) "Maxi" Print@(xpos,8) "mite" lastmove=nextmove EndIf senddata1(0,0,1) ' sets chip on dmd board to display each set of lines.+ displayrow data senddata1(1,0,2) senddata1(0,1,3) senddata1(1,1,0) Loop Sub senddata1( a_pin , b_pin , displayrow) lastTimer =Timer Pin(DMD_A)= a_pin Pin(DMD_B)= b_pin Pin(DMD_OE) = 1 junk1 = SPIDMD( videomemhi, videomemlo + displayrow*offset, DMD_T_Data, DMD_R_Data, DMD_CLK) ' SPIDMD() code added to Source V3.2C by D Wyatt.. Pin(DMD_OE) = 0 Pin(DMD_SCLK) = 1 Pin(DMD_SCLK) = 0 Print@(20,220) Timer-lasttimer End Sub If anyone wishes to view my custom.c and custom.h source code then let me know and I will post it here... Now to work on the mmbasic code for multiple panels as they just daisy chain together... [edit] A short 9.9 Mb avi video Scrolling text [/edit] Cheers Dennis..... Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
donmck Guru Joined: 09/06/2011 Location: AustraliaPosts: 1313 |
Great work Dennis, Your link has an extra http in the link, should be: http://members.iinet.net.au/~dpwyatt/videos/DMDMarquee.avi I was wanting to do something like this, as I did one back in 89 for Silicon Chip: Used a z80 and assembly language. Was at a time when SC was just starting off, so we did this over 4 issues from March to June. I also created a tri-colo(u)r unit using the same principle with RED and Green LEDs. I have an old PDP-11/40 front panel that I had running flashing LEDs on the address and data lines using the Z80. This basically emulated a running PDP-11/40.We were going to set it up in DECs foyer at Box Hill at one stage. I would love to resurrect it on a MaxiMite-DuinoMite, and donate it to Science Works. Perhaps one day. Keep at it. I'll be very interested to see the final product. Don... https://www.dontronics.com |
||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
Sorry Don, the full colon : is missing from between the http and the // Normally I preview the post and test the links, guess I was too excited this time. Thanks for picking that up.. Have three dmd panels here , am going to try them now... Cheers Dennis. Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
trippyben Regular Member Joined: 26/06/2011 Location: AustraliaPosts: 91 |
I got me one of these DMS's too. Runing mine on the Duniomite mini, programming it using MPLAB C32. Is it just me, or is the pixel mapping on the DMD kinda daft. Each 32bits of SPI data seems to represent 4 lines in an 8 LED wide block, with the Most Significant Byte being in the lower left, the next byte 4 lines above etc, moving across to the right after 4 bytes. |
||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
@ trippyben Yeah , I think it must be because of the use of the 74HC595's (8 bit shift registers). You work with what you get I suppose, they must have designed it that way for a reason ?? You also have to invert the bits to display properly, 1 =off 0=on ,from mmbasic anyway... The SpiDMD() command takes on average 860 Nano seconds to complete one of the four line loops, so update the whole panel in just under 4 ms.. Tried multiple panels, and it displayed the text on the next panels, but 1 line lower on each subsequent panel, as the pin_a, pin_b loop had incremented by the time the data got to those chips.. will have a crack again later... cheers Dennis Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
trippyben Regular Member Joined: 26/06/2011 Location: AustraliaPosts: 91 |
Processing power is not in short supply anymore, so a bit of a short cut on the hardware is eaisly made up in the software I guess. I noticed the inverted bits thing. Also the documentation indicates that the OE line is active low, but you have to drive it high to turn on the leds! I haven't measured the display refresh time yet, but I'm currently running the SPI module with a 1MHz clock. Based on the generic data book I have for 74HC stuff, even the slowest '595 should be able to handle about 12MHz. |
||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
An update to the time spent in the command spidmd(). In a previous post I quoted a time of ~860 us. I used the coretimer to measure it properly, and returned the result through the junk1 variable. It calculated to between 970 & 950 us. So just a little slower than I quoted before, but still pretty fast...Still 4 ms to update the whole panel is good.. Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
Just got it working on 2 DMD panels in both configurations.. Side / side and above / below.. 2 dmds bouncing ball The code in the program, changes the panels status from side/side to above/below by pressing the 'S'witch key. The border helps to display the two modes.. will clean up the code and post here if needed... Geoff Graham gave me permission to distribute the 3.2C hex file with the SPIDMD(videomemhi,videomemlo+display,rx,tx,clk) and MM.Video commands added.... Cheers Dennis.. Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
Gizmo Admin Group Joined: 05/06/2004 Location: AustraliaPosts: 5078 |
Very cool The best time to plant a tree was twenty years ago, the second best time is right now. JAQ |
||||
MM_Wombat Senior Member Joined: 12/12/2011 Location: AustraliaPosts: 139 |
Ok, Joy to the world.... I found that if I set the number of panels to more than 6, the displays started to flicker, again. Woe is me.. So I re-wrote the code to write to all the panels for each line-group sweep.. The new command is.... SPIDMD( Videomemhi , Videomemlo , Displayrow , Displayswide , Displaysdown , rx , tx , clk ) The command takes 0.614 ms to complete it's loop for 1 x 1 0.663 ms to complete it's loop for 2 x 1 0.753 ms to complete it's loop for 2 x 2 0.852 ms to complete it's loop for 3 x 2 1.139 ms to complete it's loop for 3 x 4 1.716 ms to complete it's loop for 6 x 4 WriteCoreTimer(0) at beginning of command return ReadCoreTimer() in Junk1 variable Multiply Junk1 x 0.05 to get us(nano sec) I set the number of panels to 24 (6 x 4) and there was a little flicker with the text scrolling 1 pixel every 25 ms ..slowed it to every 85 ms and flicker was minimal.. Doin' the Snoopy Dance.. Have 3 DMD's at the moment. Will have to buy more [wonder if Jaycar or Freetronics would loan me some] and see what they look like, in a bigger configuration..... Dennis Keep plugging away, it is fun learning But can be expensive (if you keep blowing things up). Maximite, ColourMaximite, MM+ |
||||
Print this page |