Shop OBEX P1 Docs P2 Docs Learn Events
Just Yacking outload about an algorithm... — Parallax Forums

Just Yacking outload about an algorithm...

TinkersALotTinkersALot Posts: 535
edited 2013-09-26 17:53 in Propeller 1
Okay, So lets say I have "n" 165's as inputs that I want to sample at some frequency.

Next, let's say I have "n" 595's as some outputs that should "follow" the inputs with some "decay";

where the decay is represented by a decreasing duty cycle for the output bit at that "shift position."

Each "output follower" would have its decay related to only its input "bit position".

So, in rough terms, I want to read in 'n' bits. For each bit that is found to be 'on' I want to start an output pulse on the output bit. The output bit would at first have a very long duty cycle. Then for each sample of the input pins, if a bit position (that was previously on was now off), the duty cycle for the signal on its corresponding output pin would be reduced (toward zero).

In rough terms I am trying to describe a "slow fade" of a number of output pins related to a high signal on a a set of input pins.
Does that make sense?
Let's see if I can "draw some signals" to illustrate the idea

in 1  ___----________________---___

in 2  _______---_____________________________---___

ot 1  __-------___-----_____---___-------___-----_____---__________

ot 2  _______-------___-----_____---______________-------___




Seems simple enough, but the devil will be in the details. Has anyone ever seen anything like this, or will be discovering this from the scratch point?

Comments

  • kwinnkwinn Posts: 8,697
    edited 2013-09-23 19:48
    Never seen anything like that but it looks like it should be simple enough to program. The devilish part would be deciding on the initial output pulse width, output pulse width delta, and output pulse width frequency. Whats the relationship between input and output?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2013-09-23 20:01
    Trying to dim LEDs with a '595 in Spin is may be a problem. I'm not sure how many '595s and at what resolution you'd be able to control in Spin.

    When I first started playing with some
    8x8 RGB LED arrays, I initially tried it Spin. Updating the '595s was so slow the LEDs would flash rather than dim.

    The code I posted in the above mentioned thread PWM the LEDs at up to 8-bits of resolution. It may be chore to trim away all the unneeded stuff from the code so you may be better off using code from the OBEX with can drive up to four '595 chips with PWM.

    I'd have one section of code continually modifying (dimming) values in a buffer representing the desired brightness of the LED. Another section (cog) would read these values and drive the '595 appropriately.

    Edit: After rereading your original post, now I'm not so sure. It kind of looks like you want to stretch the incoming pulses and send them to the outgoing pulses? What's the relationship between the sampling frequency and PWM frequency?

    I'm still inclined to think you'd be better off controlling the output from a separate cog based on the values in a buffer. The values in the buffer would be set by a different cog reading the inputs.

    Any guess on the value of "n"? There's a definite trade off between the number of '595 being driven and the brightness resolution of the LEDs.


    Edit again: Reading the OP again, I think I may have projected my own projects onto what you want to do. Now I'm not sure what you mean by "slow fade". I had assumed you meant you wanted to dim the the output (which I now realize my have nothing to do with LEDs).
  • YanomaniYanomani Posts: 1,524
    edited 2013-09-23 20:33
    I'd figured at least one way to do what you aparently intended to, but its based in my own thoughts, then perhaps they doesn't reflect your actual needs.
    In my view, the solution is just implementing a 32 bit register to control each output at the '595.
    You can load them all at startup, with a value of your choice, perhaps a 50/50 duty cycle signal, with 16off and 16on bits.
    Then you can read each corresponding controlling bit position at the '165 and decide if you must left or right shift its controled register, adding a leading one or trailing zero.
    Provided your application can be tolerant to an output scan rate that is 32 times the input scan rate frequency, I am certain you can 'see' at an osciloscope screen, exactly what you meant.
    If it's not your intent to do something like this, then your comments can lead us to a better understanding of your actual needs.

    Yanomani

    edited: Looking again at your original post, I believe I'd missing something. Lets see...
  • YanomaniYanomani Posts: 1,524
    edited 2013-09-23 20:43
    Lets try again...

    It's your intent doing something like a 'snapshot driven' control or, perhaps, a 'history driven' control?

    Or are my thoughts a bunch of misleading ones?

    Yanomani
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-09-23 20:53
    I'd say forget the '165 and the '595 at first--Just prototype it in your head or in reality using parallel pins. Logically, there is no difference between that and using the shifters, which would be encapsulated as methods that mimic input from parallel pins and output to parallel pins. Of course, there could be issues with speed of the shifters in relation to parallel pins, but that is a separate deal.

    I can imagine that a rising edge that sets a counter to 255. At each time tick after that, the counter decrements until it again reaches zero. A rule for output at each tick is: If the value of the lower nibble is less than value of the upper nibble, then the output is made high, otherwise low. That would be a linear fade.

    I may be completely misunderstanding too. Is there a going to be a microcontroller in between these shifters? We need more context and detail. (That's what you get for yacking!)
  • prof_brainoprof_braino Posts: 4,313
    edited 2013-09-23 20:54
    Okay, So lets say I have "n" 165's as inputs that I want to sample at some frequency.
    ok
    Next, let's say I have "n" 595's as some outputs that should "follow" the inputs with some "decay";
    ok
    where the decay is represented by a decreasing duty cycle for the output bit at that "shift position."
    Lost me here
    Each "output follower" would have its decay related to only its input "bit position".

    So, in rough terms, I want to read in 'n' bits. For each bit that is found to be 'on' I want to start an output pulse on the output bit. The output bit would at first have a very long duty cycle. Then for each sample of the input pins, if a bit position (that was previously on was now off), the duty cycle for the signal on its corresponding output pin would be reduced (toward zero).

    Do you want to sample for say 1 second, and them output for say 10 seconds (at 1/10 the frequency)?
    In rough terms I am trying to describe a "slow fade" of a number of output pins related to a high signal on a a set of input pins.
    Does that make sense?

    Not getting the slow fade idea.
  • kwinnkwinn Posts: 8,697
    edited 2013-09-23 22:44
    My interpretation was that an input high would trigger a string of output pulses at a fixed frequency where each pulse was of shorter duration than the one before by some amount. The sequence of output pulses would start over for each input trigger pulse, or the output would end up as a low once the output pulse width became zero. Like PWM control of a motor to decelerate it to a stop.
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-24 09:17
    I'd say forget the '165 and the '595 at first--Just prototype it in your head or in reality using parallel pins. Logically, there is no difference between that and using the shifters, which would be encapsulated as methods that mimic input from parallel pins and output to parallel pins. Of course, there could be issues with speed of the shifters in relation to parallel pins, but that is a separate deal.

    I can imagine that a rising edge that sets a counter to 255. At each time tick after that, the counter decrements until it again reaches zero. A rule for output at each tick is: If the value of the lower nibble is less than value of the upper nibble, then the output is made high, otherwise low. That would be a linear fade.

    I may be completely misunderstanding too. Is there a going to be a microcontroller in between these shifters? We need more context and detail. (That's what you get for yacking!)

    I think you are on to it -- and have provided a technique that I can use as a starting point. I was going to drop a prop in the middle of the 165s and the 595s. One cog would be sampling the 165s, and drop a long into a shared buffer, another cog would read that buffer for deltas and would apply the "fader" routine and those results would be dropped into its output buffer, the output cog would shift the result from the "fader cog" to the 595s. Another challenge would be to to determine the sample rates at the 'cog boundaries'. For instance, the "fader" and the "out shifter" would have to run at a higher speed than the input sampler and it would have to be responsive to the input scan so that the device would not miss edge events.
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-24 09:18
    kwinn wrote: »
    My interpretation was that an input high would trigger a string of output pulses at a fixed frequency where each pulse was of shorter duration than the one before by some amount. The sequence of output pulses would start over for each input trigger pulse, or the output would end up as a low once the output pulse width became zero. Like PWM control of a motor to decelerate it to a stop.

    Now why couldn't I say it like that. This is spot on.
  • kwinnkwinn Posts: 8,697
    edited 2013-09-24 18:09
    I'm also guessing that the trigger pulse will be very short duration, or at least shorter than the first pulse of the sequence it triggers. Is that the case?

    If the output pulse frequency is to be constant then any time subtracted from the high time will be added to the low time. Since you were thinking of using '165's and '595's I'm guessing the frequency will be low enough to use PASM or possibly even Spin.

    What sort of frequencies and number of channels did you have in mind?
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-24 18:53
    kwinn wrote: »
    I'm also guessing that the trigger pulse will be very short duration, or at least shorter than the first pulse of the sequence it triggers. Is that the case?

    If the output pulse frequency is to be constant then any time subtracted from the high time will be added to the low time. Since you were thinking of using '165's and '595's I'm guessing the frequency will be low enough to use PASM or possibly even Spin.

    What sort of frequencies and number of channels did you have in mind?

    Nice bits of analysis here, kwinn.

    To start, I am thinking of 16 inputs (two 165's lashed in "series" ) with an equal amount of outputs (though I could see some value in 32 outputs, with a pulse-train and a inverted-levels pulse train for each input channel (this could be done with 4 595s -- or with 2 595s and an inverter off each output (likely much easier)).

    Sample frequency of the input channels would be *very low*. I think I could easily get away with a 10 Hz sample rate, but may sample at 100 Hz (10x oversample). Even with the "shift-in overhead" involved, I think this would be plenty fast for the application I have in mind. And I think this would still be fast enough for me to detect "signal level changes" on the inputs (I don't think I need to necessarily detect edges with this project).

    In thinking about how I may decompose this, I think a "shift in" cog would just shift in the bits, and then write a message to the "mixer cog" for processing.

    The mixer cog would first try to detect each bit location where the signal has gone high. (the mixer could mask out that bit location from that point until it had seen the same bit position go to a low state (that would clear the masking of that bit).

    The "mixer cog" would would initialize the pulse train for each bit position that had had toggled to a high state. It would "launch" a pulse train for that bit position with the first pulse having a width 100 milSecs. The "mixer cog" would also loop over all "active pulse trains" reducing them by 5 milSecs on each successive pulse. The "mixer cog" would manage all the timing for all the bit positions and would then just write the resulting bit mix to an output buffer to be read by an output-cog.

    The "output cog" would simply shift out whatever mix of bits it was sent.
  • kwinnkwinn Posts: 8,697
    edited 2013-09-24 22:49
    ...
    To start, I am thinking of 16 inputs (two 165's lashed in "series" ) with an equal amount of outputs (though I could see some value in 32 outputs, with a pulse-train and a inverted-levels pulse train for each input channel (this could be done with 4 595s -- or with 2 595s and an inverter off each output (likely much easier)).

    Since you need the same number of chips either way I would go with the inverters. It makes the software simpler and faster.
    Sample frequency of the input channels would be *very low*. I think I could easily get away with a 10 Hz sample rate, but may sample at 100 Hz (10x oversample). Even with the "shift-in overhead" involved, I think this would be plenty fast for the application I have in mind. And I think this would still be fast enough for me to detect "signal level changes" on the inputs (I don't think I need to necessarily detect edges with this project).

    In thinking about how I may decompose this, I think a "shift in" cog would just shift in the bits, and then write a message to the "mixer cog" for processing.

    If you have cogs to spare:

    Cog 1 (Input) could read the input from the '165's and save it in variable1.

    Cog 2 (Mixer) could could read variable1, produce, and store the output bit pattern in variable2.

    Cog 3 could read variable2 and output it to the '595's

    Since cog 2 would have the most time consuming task and limits the speed of data I/O you can connect the '165's and '595's so they share some signals and have a single cog read the input and write the output simultaneously.
    The mixer cog would first try to detect each bit location where the signal has gone high. (the mixer could mask out that bit location from that point until it had seen the same bit position go to a low state (that would clear the masking of that bit).

    The "mixer cog" would would initialize the pulse train for each bit position that had had toggled to a high state. It would "launch" a pulse train for that bit position with the first pulse having a width 100 milSecs. The "mixer cog" would also loop over all "active pulse trains" reducing them by 5 milSecs on each successive pulse. The "mixer cog" would manage all the timing for all the bit positions and would then just write the resulting bit mix to an output buffer to be read by an output-cog.

    The mixer cog is going to be one very busy little cog so perhaps multiple cogs (say 4) could be made mixer cogs and each one works on 4 of the 16 bits.

    BTW, since the pulse width has to be reduced by 5mS on each successive pulse the mixer loop has to be pretty fast to get it all done so PASM may be required. Maybe try spin first and if it is not fast enough switch to pasm.
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2013-09-25 09:06
    Cog 1 in that scheme could handle the detection of the rising edge. The shared variable to pass to cog 2 need only have ones in bits where the rising edge has been detected.

    All three cogs could be synced to the 5ms cycle. For cog 2, the rising edge on a pin could set the corresponding counter to a value of 400. Each subsequent sample period tests the counter and sets the corresponding output bit based on a comparison of counter/20//20 to counter//20 and decrements the whole counter by 1. The cycle of counter//20 takes 100 milliseconds. The proportion of time the output bit is high in each successive 100ms period decreases as the high bits decrease.
    if counter[.] // 20 =< counter[.] / 20 // 20 then result<<1 + 1 else result<<1
    (The math can be simpler if the cycle count is a power of 2, also it can be condensed with computed intermediate results.)
    I think that could work as a pretty tight state machine. I don't know if spin could do it in 5ms for 32 channels, but pasm certainly could.
  • kwinnkwinn Posts: 8,697
    edited 2013-09-25 18:13
    Having cog 1 take some of the load off cog 2 by doing the edge detection is a good idea. Using counters as suggested would also work well if all the outputs are at the same frequency and synchronized. Not sure how well it would work with the triggers coming at random times unless you mean to use separate counters for each output bit.
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-25 19:32
    @Tracy Allen -- good idea about moving the edge/level detection into the input cog.
    @Kwinn -- good idea about dividing up the bits across more than one "mixer cog" to divide the load of the pulse train manipulations

    Thank you both so much for these inspired ideas
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-25 19:36
    kwinn wrote: »
    Not sure how well it would work with the triggers coming at random times unless you mean to use separate counters for each output bit.

    I was thinking along these same lines -- the inputs/trigger signals are completely unrelated to all other of the others. The outputs are not related to another either. Each of their pulse trains is only related to the event that started the train. But looks like I will get to learn alot about timers with this project :)
  • kwinnkwinn Posts: 8,697
    edited 2013-09-25 22:16
    You're more than welcome for any help my suggestions may have provided. Just to clarify what I said in post 15, when I said counters I was thinking of software counters in hub ram or cog registers that would be incremented/decremented, not the two hardware counters in each cog. No reason you couldn't use the two counters in each of the mixer cogs to good advantage though. Using PASM and dividing the task between 6 cogs should make it easy to meet or exceed the timing you proposed. My suggestion would be to write an object that takes the parameters needed to generate the four output signal trains and use it to start 4 cogs.

    Can you elaborate on the relationship between the input trigger and output signal? Since you are only interested in triggering the output with the leading edge of the input I'm guessing the input on channel x always triggers the same output signal on output y. I am very curious as to what the application for this would be. Care to provide a hint?
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-26 01:08
    kwinn wrote: »
    I am very curious as to what the application for this would be. Care to provide a hint?

    I am working on an interactive sculpture installation where the observer would trigger one or more inputs and the sculpture would respond in a way that fades over time but will "reinvigorate" with each new trigger. Admittedly a wild eyed notion, but that's what's on the bench.
  • kwinnkwinn Posts: 8,697
    edited 2013-09-26 10:19
    Ah, none of my guesses were even close to that area. That explains a lot and puts the requirements into perspective. What sort of actuators will the pulse trains be driving?
  • TinkersALotTinkersALot Posts: 535
    edited 2013-09-26 12:03
    kwinn wrote: »
    Ah, none of my guesses were even close to that area. That explains a lot and puts the requirements into perspective. What sort of actuators will the pulse trains be driving?

    curious in return: what were some of the guesses that you thought this would have been applied toward?
  • kwinnkwinn Posts: 8,697
    edited 2013-09-26 17:53
    I thought it might have been for some sort of Halloween lighting, sound, or movement effects, or possibly a combination of them.
Sign In or Register to comment.