Re: Spoke-POV-like application
by flounder on Thu Dec 31, 2015 3:12 am
If you do a symmetric X you can reduce the rotation by a factor of 4 over a semi-strip size of 1. If you use a 1m strip across the entire X, you reduce the resolution by a factor of 2, but then your whole assembly area shrinks by a factor of 4; instead of a 2m circle, you have a 1m circle, pi*r^2. You could also do two strips, 180 degrees apart, making it easier to make a balanced system. You could consider then making one strip be offset 1/2 pixel from the other, in which case you have increased resolution by using "interlacing". If you keep the same spacing, you could cut the speed in half.
One of the problems I face is getting the system "balanced"; a single arm coming out from the center will be grossly unbalanced. My current idea is to use a bicycle wheel and a 2m mounting, and mount the computer, battery, etc. in a solid box near the center, so a similar box with the same mass, mounted the same way on the opposite side of the axle (I'm thinking of BBs or similar small quantized weights that can be put in the counterweight). If I mount the axle or the motor with a flexible rubber (it doestn't need to very flexible, as long as it has a little bit of give) mount, I can then place a strain gauge between the shaft mount and something bolted to the supporting frame, to check the balance. If the shaft is parallel to the Z axis, then any eccentricity measured along the X or Y plane indicates a balance problem. Note that I only need to measure along one vector, because any imbalance will be detectable; note that eccentric force will always stress it differently across every point around the circle, so if is off-balance at angle theta, it is off-balance at ever other angle != theta, so we only need to examine one vector. Ideally, we make that measurement when the Hall sensor activates, so we know which side weighs too much relative to the other, and can add or remove mass quanta (e.g., BBs) to achieve balance. Sort of like balancing a car tire.
You could reduce the frame time to 27 (old analog tv frame time) or 24 (standard theatre movie projector) or even 18 (the frame speed of old silent films, which is why everyone seems to move fast in them; there are no 18fps projectors available in theaters), but some people can react badly to that flicker rate, which is just a wee bit off from the alpha wave trap of 7-15Hz). But 30 is good for lots of reasons, particularly in the US. For example, the line frquency is 60Hz. You can generate a 60Hz interrupt rather easily. Take a 6.3vac signal. Run one end through a diode. You now have a positive-only semi-sine wave running at 60Hz. Don't use a full-wave bridge or you get 120Hz, which only adds overhead. Now, run that through a resistor that allows only a few ma draw, connect a 5V Zener diode to clip the peak (remember that AC voltage measurements are RMS, and the zero-to-peak voltage is actuall sqrt(2)*rms, and your chips will see that peak)[note: I learned this the hard way when I was 13; I had cascaded in series three 450V electrolytics to get a capacitor with 1/3 the capacitance but 3x the dielectric voltage as one; this meant a capacitor that could handle 1350 volts. I hooked it to a 1200-volt transformer via a rectifier tube (no solid-state rectifier in those days could handle that voltage). I narrowly missed serious, perhaps fatal, injury when one of the metal-can electrolytics punched a hole in the ceiling. The capacitors saw the peak-to-peak of nearly 1700 volts. Oops.] So clamp it with a Zener. A .1uF capacitor would probably reduce line noise. Now feed this into a Schmitt trigger, whose role in life is to convert sloppy slow-rising analog waveforms into clean dgital waveforms. Hook the output pin of the Schmitt trigger to the interrupt pin of the processor. Throw away every second interrupt, and you now have a 30Hz reference signal, that is, an interrupt every frame-start time. In this fashion, you only need the Hall event during startup, if you believe the rotation is actually 1800rpm. Or, as I mentioned earlier, you can use this to see what the rotation speed really is, and adjust accordingly.
Note that the area swept by an LED at the outer edge is much larger than that of an inner LED. This leads to the decision about CAV vs CLV. CAV is Constant Angular Velocity, which means if you slice the image radially you may find that your new image loses resolution at the outside edges, and may even have all-dark "slices" radiating from the center. Or, to get better resolution, you slice the image so the outer edge is one pixel from the previous slice. This may result in an angle so small that the update frequency exceeds either the DotStar's maximum update rate, or perhaps the processor's ability to keep up with the updates. Constant Linear Velocity means that you update the string at a rate based on constant linear displacement, which means you don't have to update the inner LEDs as fast as the outer LEDs. Alas, DotStar, like NeoPixel, is a giant shift register and to update the 144th pixel means you have to write the previous 143, so nominally we still have all the problems of data rate and data size to deal with. But we could do a simple run-length compression by noting, at slicing time, "pattern N+1 is exactly the same as pattern N, except for...". Now we only need to keep one full vector in memory ready to write out, and then modify it by applying deltas to it. At T0, say when the strip is vertical, we start by writing the first vector from the sliced file, then apply deltas to it until we have done all the updates (one key frame, and a set of deltas, like MPEG). The frequency of the updates has to increase, however, so the CLV is maintained for the outermost LED. Which leads to the same problem as before: DotStar and processor bandwidth become the limit. But wait! There's more! Suppose that, instead of a single 144 LED DotStar, we cut the signal lead between two of them and now have two 72-pixel DotStar strips. We run another lead out to the second half. Since under CLV, most of the LEDs in the inner strip will remain unchanged, we don't have to rewrite those. So now, most of our updates will be only half as many LEDs. Lather, rinse, repeat. Using 8 equal partitions means only 18 DotStars in a segment. Faster update, lower processor overhead. But then ask, "Why do they have to be 8 equal segments? Is there a partitioning that gives better behavior by "front-loading" the CLV partitioning, making the most-frequently-changing segments as long as they need to be, but no longer, and the steadier segments long? Would a partitioning of 1/2;1/4;1/8;1/8 work better? Would 80;20;20;12;12 work better? Note that this can be computed statically at the time of slicing, and after slicing some sample images, a partitioning can be chosen that, if not optimal in all cases, is not pessimal for every case.
For a 1m arm, the circumference is 6.28m. This means that at 30fps, the velocity of the outer edge is 188.5m/sec. In one hour, the outermost LED would have traveled 678,584m, or expressed as a velocity, 678km/hr, or 420mi/hr. Hmmm...maybe this idea needs more work...
Maybe two 1/2m strips, interlaced, can do better. Same resolution, smaller space, half the rim linear velocity at 1800rpm. Or a single half-meter strip, 1/4 the rim linear velocity (105mph); run interlaced, it would give 72dpi. So to simplify the coding of the skicer, let your favorite image tool reduce your image to 72x72 pixels, and the slicer only works on 72x72 images, period.
Have to think about this more. Note that if I have 1/2m, that's only 72 DotStars to update two "scan lines" at the same time, one for the even-numbered scan lines and one for the odd-numbered scan lines which are 180 degrees away.
I'm an engineer. Wind me up and I design.