You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Thijs Elenbaas, toasted-circu...@googlegroups.com
Hi Thijs,
Interesting... I did not see bleeding in my matrix so to save a pin I made "enable" always on by default.
However, if you feel you need it, it can be redirected. If you look at the bottom of the board, just to the right of the tiny ATMEGA 328 chip, you will see a solder blob short under the name "enable". If you heat up this solder blob with a soldering iron, you'll see that it actually consists of a pad (like the one just above it) and a through hole. Clean the solder so it the pad is no longer connected to the hole, and then you can put a jumper wire in the hole and redirect it to any pin.
BUT... before you do that make sure you are using the "finish" API in the LightuinoSink. See LightuinoMatrix.cpp for details but in sum: set "sink.finishReq=true;" in the constructor, and then sink.set() will do 99% of the work, but you call sink.finish() to do the final latch in to change the sinks. This let me put the control of the source driver and sink driver so close in time that no bleeding was apparent. But maybe it is more visible for you. If so, you'll need to redirect the pin as described above.
Finally, note that if you can see the bleeding, you'll notice using enable/disable. You will see dimmer LEDs because what is currently the bleed time will be changed to "off" time. So you may want to optimize LightuinoSourceDriver to: 1. use direct register writes instead of digitalWrite. digitalWrite is actually extremely inefficient so this will dramatically decrease the time required to reprogram the source driver chips (your "off" time) 2. Combine the code of the sink.finish() and the the final "strobe" of the source driver chips into a single 2 instruction routine -- this technique essentially sets up both chips in advance and then "latches" the changes into both chips essentially simultaneously.
Some follow-up, I overlooked that enaPin is set, by default, to
Lightuino5_SRC_ENABLE_PIN, which is 0xff
Does this mean that the Output-Enable pin of the MIC5891 is not settable?
Thijs
Op 20 okt. 2012 om 22:37 heeft Thijs Elenbaas <th...@contemplated.nl> het volgende geschreven:
Hi Andrew,
I am playing with my Lightuino with much pleasure, and I have gotten my 11 x 10 matrix up and running, which will soon illuminate my word-clock ( http://www.instructables.com/id/A-Word-Clock/ ).
I am using 55 sinks and 2 sources to drive the array, to minimize multiplexing. However, I noticed there was a lot of bleeding in each led pair that shares a sink. After some investigation i traced the cause to the function source.off() in lightuinoSourceDriver. This should disable the sources when switching scan-line in lightuinoMatrix. However, this function doesnt work because enaPin is always 0xFF and the conditional statement gets skipped.
if (enaPin != 0xFF) digitalWrite(enaPin,HIGH);
what does this check do? Is this a bug in the library? I wanted to post this in the Google group, but it seems my invitation had expired.
cheers, Thijs
Thijs Elenbaas
unread,
Oct 23, 2012, 4:32:41 PM10/23/12
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Andrew Stone, toasted-circu...@googlegroups.com
Hi Andrew,
Thanks for your very helpful remarks. I must admit I did not feel
confident enough to solder on the Lightuino board, so I have been
looking for a software solution, where you can repair everything
you break :-)
I tried 2 things. First, instead of using the source latch, I
quickly flush the registers. This works quite well and reduced the
"bleeding" to almost nill. Next I turned things around: I first
set all sinks to 0, shift the source to the next line, and set the
sinks. This gives approximately the same result.
The loop function was only mildly changed void LightuinoMatrix::loop(unsigned char amt) { unsigned char cnt = amt; while(cnt>0) { cnt--; curRow++; if (curRow >= startRow+numRows) { curRow=startRow; } sink.set(0,0,0); if (curRow ==startRow) src.shift(1); else src.shift(0); sink.set(videoRam +
(curRow*NUMOUTSDIV8ADD1)); } }
Out of curiosity, why did you replace src.shift(1); by
src.set(1)? Is it in order to make sure the unused
sources are set to 0? On the other hand, the shift command seems a
lot more efficient.
I did a quick check on speed of setting sources and sinks, and it
doesn't differ much: 23us vs 18us. Still, I replaced the digitalWrite
with a more efficient implementation. This worked without issues
for the source driver, but for the sinks, the 2nd chip started
functioning intermittently. I guess from the commented out delays
in your code, that this may have something to do with timing.
Still, things seem fast enough for now, I may revisit this, if I
get around to PWM the matrix (transitions from one matrix to next)
With respect to led brightness, I had expected that I would need
to add a delay after each loop() call. I gathered that
this would make the ratio of turned-on/turned-off better, and give
a brighter led. In practice I hardly notice any difference,
though.
Cheers!
Thijs
Hi Thijs,
Thijs Elenbaas
unread,
Dec 25, 2012, 4:21:22 PM12/25/12
Reply to author
Sign in to reply to author
Forward
Sign in to forward
Delete
You do not have permission to delete messages in this group
Copy link
Report message
Show original message
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Andrew Stone, toasted-circu...@googlegroups.com
Hi Andrew and Lightuino group
First of all a Merry Christmas and a happy new year! In the seasons
spirit, I come with a little gift: I made some additions to the
Lightuino library which I hope you will like. However I am also in need
of some help, more about that later.
For my wordclock project I want to have an animated matrix that blends
from one image to the next. The idea is pretty simple. I'm alternating
between 2 video buffers in a PWM like fashion. First 100% of the cycles
are image 1, halfway 50% image 1 and 50% image 2, and ending up at 100%
image 2.
In order to do this I made a few modifications to the Lightuino library:
- I wanted to run the matrix using the timer2 interrupt, but because the
timer function is also used for the software PWM of the sinks, I moved
the timer2 code to the class LightuinoTimer2. I added that the
pre-multiplier is chosen based on the requested run frequency. This
results in a broader range of frequencies, while using maximal resolution.
- I updated the LightuinoPwm class to use the LightuinoTimer2. I must
admit I haven't tested this, but it compiles, and the setup is very
similar to that in the LightuinoAnimatedMatrix class. What could
possibly go wrong? :-)
- I modified the LightuinoSourceDriver to use the DigitalPin library by
by William Greiman, which implements much faster digital in and out
functions. For the LightuinoAnimatedMatrix class I only use the
src.shift function, so I think this cannot be further optimized for speed.
- I added the LightuinoAnimatedMatrix class, which holds 2 image
buffers. While one is being shown, the other can be edited. After
editing, you can directly switch to the next image, or blend the next
image in. Compared to the LightuinoMatrix class, it exposes the
following new functions
- startAutoLoop() - Start automatic looping
- startAutoLoop(rate) - Start automatic looping with custom
frequency
- stopAutoLoop() - Stop automatic looping
- void update() - Make next image current image and show it
- void animate() - Animate from current image to next image.
Finally, make next image the current image
- clearCurrent(val) - clears the current image
- clearNext(val) - clears the next image
While in steady state (not animating), the autoLoop function loops
through the sources at low speed, 100*numberOfSources, to reduce CPU
load. When animating, the refresh rate needs to be cranked up to reduce
flickering. If during a Pwm loop of N values, the led is turned only
once, the refresh frequency should be at least 100*numberOfSources*N.
For my clock matrix I use 2 sources, and a PWM loop of 10 steps, which
would need a refresh rate of more than 2 kHz.
This is where I have troubles. I cannot reach a high enough refresh
rate. I suspect the bottle neck is the unoptimized LightuinoSink class.
I have tried using the DigitalPin library there as well, but it seems to
throw of the timing of pushing bits. I had a look at the optimized code
you wrote for the LightuinoPWM class, but I must admit I don't really
understand it. I suspect that you crafted it to deliver the most optimal
ASM code, but there I'm out of my depth.
So my question is: would it be possible for you to optimize the
LightuinoSink class similar to the LightuinoPwm class? That would really
help me out!