Advice on program architecture - free falling body emulation in LEDs
John Kauffman
Posts: 653
I could use opinions on which route to take for functions in a project.
I'd like to emulate a free-falling marble by using a column of lights. Given a ten-meter high column of 1000 LEDs 1 cm apart, I'd like them to light, one at a time, starting at the top and lighting sequentially down at the same acceleration as a free-falling body. The progression would be slow at start and then accelerate at 9.8 m/ss. There will be scaling, for example another version with only 100 LEDs in a 1 m high column. If done right, a falling marble started at the same time would actually be alongside a given lit LED at each moment in its fall.
The overall need is to know when each LED must turn on and off. In my mind that means the LED is on during the whole duration the "marble" would be in the 1 cm space of that LED. That is actually a little different then a flash of fixed duration for when the marble is in the middle of a given LED's 1 cm space. LEDs at the top would stay on longer than LEDs at the bottom. Having said that, a fixed-duration flash would be a start on the problem.
A few points to make this simpler. The math is not hard using the free-fall equations, I can do that. Actual control of LEDs is not a problem using shift registers, I can do that. Ignore air resistance. I don't need code, I can do that once I select the design.
The distinctions in the approaches are two:
- pre-calc data prior to drop vs. calc real-time during the drop.
- Use duration of ON after getting hand-off from above LED vs. use a clock time point for ON and a clock time point for OFF.
option one - real time calc of duration of an LED
The function would be repeated in real time after last LED hands off its turn and current goes ON. The function takes the start velocity, calcs acceleration and returns how long until LED goes off. Then function starts for next LED. The function could be run for the LED a couple ahead of the current LED to allow for time of execution.
In this solution the function returns a duration in time, sets a timer and turns off the LED after that (short) duration.
option two - pre-calc array of time points
The function is run prior to start and puts into an array the real times (uSec from start) for on and off for each LED. Then the "drop" is run by starting a clock and watching clock for the next event to turn on/off an LED.
option three - pre-calc array of durations
Pre-calc duration for each light and put in an array. When each light starts then pull its duration from the array.
Much thanks for your opinions.
I'd like to emulate a free-falling marble by using a column of lights. Given a ten-meter high column of 1000 LEDs 1 cm apart, I'd like them to light, one at a time, starting at the top and lighting sequentially down at the same acceleration as a free-falling body. The progression would be slow at start and then accelerate at 9.8 m/ss. There will be scaling, for example another version with only 100 LEDs in a 1 m high column. If done right, a falling marble started at the same time would actually be alongside a given lit LED at each moment in its fall.
The overall need is to know when each LED must turn on and off. In my mind that means the LED is on during the whole duration the "marble" would be in the 1 cm space of that LED. That is actually a little different then a flash of fixed duration for when the marble is in the middle of a given LED's 1 cm space. LEDs at the top would stay on longer than LEDs at the bottom. Having said that, a fixed-duration flash would be a start on the problem.
A few points to make this simpler. The math is not hard using the free-fall equations, I can do that. Actual control of LEDs is not a problem using shift registers, I can do that. Ignore air resistance. I don't need code, I can do that once I select the design.
The distinctions in the approaches are two:
- pre-calc data prior to drop vs. calc real-time during the drop.
- Use duration of ON after getting hand-off from above LED vs. use a clock time point for ON and a clock time point for OFF.
option one - real time calc of duration of an LED
The function would be repeated in real time after last LED hands off its turn and current goes ON. The function takes the start velocity, calcs acceleration and returns how long until LED goes off. Then function starts for next LED. The function could be run for the LED a couple ahead of the current LED to allow for time of execution.
In this solution the function returns a duration in time, sets a timer and turns off the LED after that (short) duration.
option two - pre-calc array of time points
The function is run prior to start and puts into an array the real times (uSec from start) for on and off for each LED. Then the "drop" is run by starting a clock and watching clock for the next event to turn on/off an LED.
option three - pre-calc array of durations
Pre-calc duration for each light and put in an array. When each light starts then pull its duration from the array.
Much thanks for your opinions.
Comments
*1) Maybe have a cm->LED# table, it would allow the number of /spacing of LEDs along the axis to be configurable / nonlinear.
More fun?: use the speed calculated at each LED to control the colour of it (requires RGB LEDs).
Erlend
Multi-color would be interesting. That would then be calc of RGB values in addition to LED ON/OFF timing.
(that's what they call it in computer graphics).
Here's how coherence algorithms work: You want to calculate a formula repeatedly for step-wise increasing variable.
Lets say you want to calculate 7*x for x from 0 upto 10. You could do (in C++): But that involves mutiplication. In a loop like this you can replace multiplication by repeated addition:
But the same principal works for reducing a quadratic function to a repeated linear one (you reduce
the order of the equation by 1 by calculating differences and summing them, and then do the same for
the linear equation as above, so each order gets translated into an auxiliary variable and one addition:
For acceleration due to gravity x = 0.5 g t^2,
so successive values if t varies by dt differ by 0.5 g (2 t dt + dt^2) = g t dt + 0.5 dt^2
So if you choose a dt which is small enough you can track the position by simply summing a multiple of t
(g and dt are constant), so the code is
One way to construct this is to use a 10-bit shift register in each 1-meter section. Each LED just displays the state of a bit in the shift register. Or you could use a decade counter and a decoder. The hardware design depends on how flexible you one to make the display.
It takes 1.4 seconds for something to fall 10 meters on earth. So the maximum speed is about 14 m/s, or 1400 cm/s. So the minimum time between state changes is 1000/1400 msec, which is about 0.7 msec. I don't think a Spin program could keep up with that, but the gravity simulator portion could be written in PASM.
You left out a zero.
So you end up with 0.7ms which I'm not sure how Spin would handle. I agree that a PASM driver should be fast enough.
I think I'd precalculated a table of delays and then have the PASM driver shift out the bits as needed.
Erlend
I think I'll try the real-time function and then test with low height and low gravitational constant. Then increase until real-time calc can't keep up.
You could have a spin program calculate the delta time between each led and place it in an array each time the gravitational constant is changed so that the pasm program only has to read through the array and output a clock pulse to the shift register after the delta time has passed.