I am finally ready to start my first POV project but just wanted to cconfirm the basic math to see if all my components fit the bill. I would like to try a rotating cylindrical shaped device as opposed to a sphere.
Atmega328 at 16MHz
Motor rotation speed, lets say 1800 rpm which gives 30 turns per second or 30Hz.
Further lets say the resolution must be 60 points on the circumference of the cylinder which makes it 180Hz.
I would then add say 64 LEDS along the length of the cylinder driven by 8 x 595 shift registers or similar.
I have seen that the SPI library can be used which apparently gives a byte output at 3uS (source http://arduino.cc/forum/index.php/topic,59369.0.html) I assume SPI here is running at 4MHz since the clock divider was not set in the author's code.
Since I have 8 registers that is a total of 24uS to refresh all registers which translates to 1/ 0.0024 = 416Hz. This is more than double the 180Hz requirement calculated above at point 2 and thus workable.
Data would have to be read from somewhere and passed to the SPI library as well as a method of determining precise rotational speed which will add extra overhead but I can set the SPI library to 8MHz also ..
Is all this correct as a basis for my rotation speed, resolution calculations?
Also if anyone has any information they wish to share on optimum speeds, brightness for LED's etc for POVs please post that as well?
Sure, if you think of a single LED moving around a set circular path at 30 revolutions per second I would like to be able to switch that LED off or on at 60 set intervals along that path per rotation. That got me to 180Hz .. then again math has never been a strong point of mine .. :~
Mm .. now that you mention it 30 x 60 is closer to 1800 isn't it ..
Whoops .. (or whatever is grammatically correct) .. found another mistake.
uS from the quoted post is microseconds but I treated it as miliseconds.
Revised arithmetic:
Atmega328 at 16MHz
Motor rotation speed, lets say 1800 rpm which gives 30 turns per second or 30Hz.
Further lets say the resolution must be 60 points on the circumference of the cylinder which makes it 1800Hz. (thanks to PaulS)
I would then add 64 LEDS along the length of the cylinder driven by 8 x 595 shift registers or similar.
A single shift register refreshes at 3uS on SPI (4Mhz?) as per quote in first post which is 0.000003 seconds which totals 0.000024 seconds or 41666 Hz (1 divided by 0.000024) for all 8 registers
This still seems well within reach or am I going from bad to worse?
So with a 64 dot horisontal resolution and with 1920 rpm it works out to:
Required Refresh Rate = (1920 / 60) * 64
Required Refresh Rate = 2048 Hz or 2 KHz
Keep in mind that this only provides for 1 LED though.
How fast can Arduino update 64 LEDS at 16 MHz?
I did some testing with a 74HC595 and came up with the following code to test with. It uses SPI at 8Mhz and bitSet bitClear for fast latching. Anyone who knows of a faster way let me know, I'd love to 'clock' it on the o'scope.
I then attached old trusty to the ouput pin 0 of the 595 and it came up with this:
So at max myArduino can refresh 64 LEDs at 56KHz vs a required 2KHz.
Note that this was tested on a breadboard with one 595...
Next I'll try loading 512 bytes from memory into an array and clock that.
In case you're wondering .. 512 bytes = 4096 bits which is the amount of 'pixels' my theoretical POV display has (64 horizontal * 64 vertical resolution)
30rev/s is a bit too fast to me. Mine spins at 4.5rev/s max, well because the motor can't spin any faster. But I'd stay within 10rev/s. I'd need a much wider magnet to trigger it if I spin it too fast.
Have you thought about what to use to trigger the display? You can't just expect your motor to spin at a constant rate. Once you realize that, you will hope to spin slower so your trigger sensor can pick up the magnet or IR that triggers the display. Spinning too fast results in missed triggers.
Note too sure if I understand you correctly but 30Hz is rather slow .. sensor wise. I looked around and the first one I came across (IR interruptor type) was rated 1KHz? Omron EE-SX670OMC
Of course building a stable balanced frame is something else entirely...
JBMetal:
Note too sure if I understand you correctly but 30Hz is rather slow .. sensor wise. I looked around and the first one I came across (IR interruptor type) was rated 1KHz? Omron EE-SX670OMC
Of course building a stable balanced frame is something else entirely...
Exactly it is too fast and your sensor is too slow. I imagine you make a tab to trigger the interrupter on the rotation stage, how large will the tab be? Maybe 10 degree of angle so it is not too big. Then the tab is only under the interrupter for 1/36 of the full period so 1/1080 second, which makes your sensor too slow. I am asking because I had to switch to larger magnet for my setup due to my magnetic sensor limitation. BTW 10 degree is pretty wide so you do th math for me.
Just wanted to offer up, this combination may actually slow things down. IIRC, this gets compiled by default with -Os, which optimizes for size. That means its extremely unlikely those functions will be inlined*. I didn't check if the bitSet/bitClear functions were actually macros or not. If they too are functions, you likely added yet another function call. If performance were really critical here, you should likely call bitSet and bitClear directly in the code or create defines and use those rather than the latchOn/latchOff functions.
Obviously review of the resulting asm can verify, but its just something to consider if/when performance headroom ever becomes critical for your project.
Please note, inlining, in of itself, can also be detrimental to performance as well as lose out on the size equation.
@Gerg: Thanks for the heads up, you have brought something to my attention that was previously unknown to me. I'll try the defines route and post the results.
@liudr: I think I understand now. You measure the time the reed switch is on which since the magnet is a known length lets you then calculate the speed. I was thinking of just catching the rising edge of the sensor on the interrupt and then measure time elapsed between two 'trigger' events of the sensor. This gives me the time taken to do a full rotation needed to calculate the current speed .. or am I missing something?
Wow. 8Khz gain. Pretty impressive for such a small change.
For those of you who don't know, as I previously hinted at, inlining can (not always) also hurt performance in larger application. I don't know enough about the CPU architecture of the AVR's to know if that's a noteworthy concern. Usually its cache thrashing which ultimately hurts performance from inlining. Just keep in mind, inlining via the macro trick can make your code larger. This is why, when compiling with -Os, the compiler is extremely picky about what it inlines. Which is to say, using -Os is the antithesis of inlining for speed optimization.
I used Hall Effect digital switch in my setup. I had smaller magnets before and my switch starts to skip around 4.5 rev/s due to the size of the magnet (not its field strength). I then replaced the smaller magnet with a larger one and solved the problem. If you run an interrupter on stage and a stationary block, you will see the same effect until you make your block large enough in size to allow at least 1ms blocking time to trigger the interrupter. That will translate to (0.03rev/ms)(1ms)=0.03 rev or 0.03360=11Deg or angle of coverage. Just make sure that happens ie you don't use a tiny slip of paper as a blocker. The paper won't spend 1ms blocking the beam.