Shop OBEX P1 Docs P2 Docs Learn Events
Advice on program architecture - free falling body emulation in LEDs — Parallax Forums

Advice on program architecture - free falling body emulation in LEDs

John KauffmanJohn Kauffman Posts: 653
edited 2014-01-08 19:56 in Robotics
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.

Comments

  • ErlendErlend Posts: 612
    edited 2014-01-07 06:12
    If I were to do this, I would calculate the timepoints at every cm, each being used as togglepoints - switch on / switch off, the toggle being routed to the relevant LED - controlled by means of the count *1. The togglepoint times can be pre-calculated, or live-calculated. I would do the live version because it is more open to expansion/adaption, e.g. two photodiodes measure the marble speed at entry and use this speed as input into the calculation.
    *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
  • John KauffmanJohn Kauffman Posts: 653
    edited 2014-01-07 06:33
    I agree the live calc would be more flexible, but am concerned about speed of the uCon to keep up. (Calc is also a little longer if there is an initial velocity coming into the function as opposed to table entries that each start from the top at 0 velocity).

    Multi-color would be interesting. That would then be calc of RGB values in addition to LED ON/OFF timing.
  • Mark_TMark_T Posts: 1,981
    edited 2014-01-07 07:12
    DDA technique may be a winner here - it means "digital differential analyser", which really means using a coherence algorithm
    (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++):
      for (int x = 0 ; x <= 10 ; x++)
        process (x * 7) ;
    
    But that involves mutiplication. In a loop like this you can replace multiplication by repeated addition:
      int val = 0 ;
      for (int x = 0 ; x <= 10 ; x++)
      {
        process (val) ;
        val += 7 ;
      }
    

    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
      // assume using a fixed-point representation for g, t, position
      long position = fix_mul (dt, dt) >> 1 ;
      long g_times_dt = fix_mul (g, dt) ;
      long multiple = 0 ;
      long next_LED_pos = ONE_CM ;
      long t = 0 ;
      while (position < END_POSITION)
      {
        delay (DT_MILLIS) ; // synchronize with real time, 
        position += multiple ;       // position = 0.5 * g * t * t 
        multiple += g_times_dt ;   // multiple = g * t * dt
        if (position >= next_LED_pos)
        {
          step_led () ;
          next_LED_pos += ONE_CM;
        }
        t += dt ;
       }
      }
    
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-07 08:58
    I would go with real-time calculation. This would allow you simulate more than just a dropping marble. You could make it bounce, and add a damping factor so it loses energy at each bounce. You could also simulate gravity on different planets and moons.

    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.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-01-07 09:16
    You might want to crunch some numbers to find your extreme speeds. How quickly will the last two LEDs need to change states (on/off) at the bottom of the 10m drop? You might be getting into the extremes of how quickly you can drive shift registers.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-07 09:46
    It takes 1.4 seconds for something to fall 10 meters on earth. So the maximum speed is about 14 m/s, or 140 cm/s. So the minimum time between state changes is 1000/140 msec, which is about 7 msec. I think a Spin program could keep up with that. If not, the gravity simulator could be written in PASM.

    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.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2014-01-07 10:19
    Dave Hein wrote: »
    So the maximum speed is about 14 m/s, or 140 cm/s.

    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.
  • kwinnkwinn Posts: 8,697
    edited 2014-01-07 10:54
    Since you will need drivers for the LEDs I would suggest using them to simplify the software as much as possible. Connect the LEDs as an array of 32 x 32 LEDs, use 4 TPICS to drive the cathodes, and 4 to drive 32 anode circuits. A single data bit and a clock would be the only signals required to drive the display.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-01-07 11:51
    Duane, thanks for finding the factor-of-ten problem. I corrected my earlier post. So the driver would probably need to be written in PASM.
  • ErlendErlend Posts: 612
    edited 2014-01-07 12:24
    Have you considered utilizing the log-tables in Propeller ROM?

    Erlend
  • John KauffmanJohn Kauffman Posts: 653
    edited 2014-01-08 12:01
    Thanks for spending such much time to provide your expertise.
    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.
  • kwinnkwinn Posts: 8,697
    edited 2014-01-08 19:56
    Thanks for spending such much time to provide your expertise.
    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.
Sign In or Register to comment.