Shop OBEX P1 Docs P2 Docs Learn Events
BS2.PULSIN_uS watchdog??? — Parallax Forums

BS2.PULSIN_uS watchdog???

W9GFOW9GFO Posts: 4,010
edited 2009-06-18 18:55 in Propeller 1
I want to read RC servo inputs on up to six pins but not necessarily all of them. The BS2.PULSIN_uS method cautions about locking up a cog if there is no input and says to "see distributed example".

PUB PULSIN_uS (Pin, State) : Duration | ClkStart, clkStop, timeout
{{
  Reads duration of Pulse on pin defined for state, returns duration in 1uS resolution
  Note: Absence of pulse can cause cog lockup if watchdog is not used - See distributed example
    x := BS2.Pulsin_uS(5,1)
    BS2.Debug_Dec(x)
}}
 
   Duration := PULSIN_Clk(Pin, State) / us + 1             ' Use PulsinClk and calc for 1uS increments



What do I need to do to make sure I can't lock up a cog? What is this "distributed example"?

Rich H

Comments

  • StefanL38StefanL38 Posts: 2,292
    edited 2009-06-17 11:44
    Hello Rich,

    in the obex is an object Servo Pulse Input

    This object works similar to a driver. It reads all the servopulses in the background all the time in it's own cog.
    It stores and updates the measured values at a HUB-RAM-adress which you can specifiy in the start-method

    So whenever you read the corresponding variable (where the values are stored in) you can read out the most actual value

    if you have questions about this object feel free to ask again in this forum.

    best regards

    Stefan
  • W9GFOW9GFO Posts: 4,010
    edited 2009-06-18 03:00
    I tried that very object and was not having success with it. It says it only works if the pulses occur on each pin sequentially which doesn't fit fit well with my application.

    Rich H
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-06-18 05:28
    Hello Rich,

    A RC-receiver has to send pulses every 20 milliseconds to every channel
    otherwise the servos wouldn't work properly

    So how can it be that not all of the PINs get signals?

    If it is that way that not always all six pins are connected to the receiver
    you could modify the servo-object that it uses an array of bytes to get the pin numbers


    right now it works like this

      repeat each from 0 to (numPins-1)
    
    
    






    
    PUB
    ...
        repeat each from 0 to 5
          ctra[noparse][[/noparse]5..0] := LONG[noparse][[/noparse]pinsIn][noparse][[/noparse]each]                           ' Set APIN = to each pin in turn
    
          if LONG[noparse][[/noparse]pinsIn][noparse][[/noparse]each] <> 0   'for unused Pins value is 0    
            waitpeq(|< LONG[noparse][[/noparse]pinsIn][noparse][[/noparse]each], |< LONG[noparse][[/noparse]pinsIn][noparse][[/noparse]each], 0)   ' Wait for pulse to start
            waitpne(|< LONG[noparse][[/noparse]pinsIn][noparse][[/noparse]each], |< LONG[noparse][[/noparse]pinsIn][noparse][[/noparse]each], 0)   ' Wait for pulse to stop             
            LONG[noparse][[/noparse]pulsesOut][noparse][[/noparse]each] := phsa /(clkfreq/1_000_000)         ' Calculate Width, in microseconds
          phsa := 0                                                  ' Reset the counter
    
    
    



    with the if condition the wait-commands are only executed if the value of the pin is set to something <> zero
    otherwise it just goes on with the next pin

    If it is that way that the signals are coming in discontinously you can't use the wait-command in that way
    the wait-command stops the cog until the condition is matching


    then you would have to poll for the change of the pin-state with a timeout
    to get a resolutionof microseconds you have to to this in assembler

    I have several other ideas but without more details of what you want to do in the end
    it makes no sense to describe these ideas

    best regards

    Stefan
  • W9GFOW9GFO Posts: 4,010
    edited 2009-06-18 06:14
    Hi Stefan,

    I've made a little servo tester that I want to be able to use with a variety of airplanes, helis and other stuff. I would like to be able to hook up from one to six RC RX outputs in any order and read out the pulse-width in microseconds. Some RC RXs output the pulses non sequentially, I don't remember the sequence but they do that to "improve response". So you can't hook up channel 1 to pin1 channel 2 to pin2 etc.. if the pulses need to be in order for it to work. It may be that the TX rearranges the channels - requiring servos to be plugged in to different spots on the RX so that they are still sequential on the RX side. On at least a couple of my flying things I don't have direct access to the RX, it would be troublesome to figure out which lead goes to which channel - additionally, some have more than six channels so to swap leads AND keep them sequential I would have to shift all the leads. Then what would I do if I wanted to read both channels 1 and 8 at the same time?

    I also want to simultaneously output those same pulses on pins [noparse][[/noparse]7..12].

    Currently I have four cogs launched , two must keep running but the other two could be stopped so I have up to five cogs available. If I had six available then I suppose I could just launch six cogs, one for each pin.

    Rich H
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-06-18 12:54
    Hello Rich,

    OK so one idea is

    there is one cog doing the measuring of the pulse-length

    I assume that the pulses come not sequentually but around every 20 milliseconds. Maybe a little bit longer but not with pauses of more than 100 milliseconds in between

    now one cog could try to measure a pulselength on PIN 1 with the wait-commands. Right before eecuting the wait-command a flag (a variable) "measuring is started" is set high
    a second cog starts measuring how long this flag is high.
    If no pulse comes in from the RC-receiver the cog stays locked waiting for the transistion

    Now the second watch-dog-cog measures the time that has gone since the measuring-cog started waiting.
    If this time is greater than 10 milliseconds (5 times longer than a servopulse 1-2 milliseconds)
    the watch-dog-cog creates a 4 millisecond-pulse on let's say PIN 10 which is directed to PIN 1
    Now this 4 ms-pulse makes the measuring-cog execute the wait-commands for the pulse-transitions
    that the program can go on executing commands

    If it has measured a pulselength bigger than 2 milliseconds you know the measuring was not valid

    This is done for every of the six channels.

    This will work if you connect another IO-PIN 10 with PIN 1(the pulselength measuring-pin) with a current-limiting resistor of 1 kOhm between the two IO-Pins.
    I assume that your pulselength-measuring pins have a pull-down-resistor then connect a 4k7-resistor from the PIN 10 to ground

    PIN 10 is configured as output ONLY for creating the 4msec-pulse all the other time it is configured as input to have a high-impedance that does not influence
    the RC-signals.

    Or you are using OR-gates of an extra chip one input connected to the rc-signal on connected to PIN 10

    By this solution you can not measure every single pulselength. You will loose some pulses through the timeout-waiting but as long as the pulses do not change
    quickly and you want to watch all this changing in realtime you can use this.

    By the way: if you want to spent money take a look at ViewPort from Hanno Sander. With viewPort it is possible to watch the logic state of all 32 io-pins at a very high time-resolution
    and show its changing over time on a PC

    another idea would be to write an assembler-program that polls one io-pin for the transistion low-high with a timeout
    as soon as this transistion is detected it stores the counter-value and jumps over to another loop polling for the high-low transition with a timeout and again stores the countervalue
    then doing the same with the next pin

    The difference between the countervalues is the pulselength
    a pulselength with 2x timeoutlength means no pulse did come in

    best regards

    Stefan
  • W9GFOW9GFO Posts: 4,010
    edited 2009-06-18 14:12
    Thanks for the ideas Stefan, I'm on my way out the door now...

    I think the first idea would be ok but I have no pins left! The project is completely built and working nicely, this feature wasn't essential from the beginning but now highly desired.

    The second idea sounds like the way to go except I know next to nothing about PASM. Can you learn PASM in a day like you can SPIN???

    Rich H
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-06-18 18:55
    Hello Rich,

    hm -if you have learned SPIN within a day a guess the basics of PASM needed here maybe 2-3 days
    and I think the PASM-specialists here in the forum can help too.

    A good start would be the assembler-tutorial showing how values of variables
    can be transferred between SPIN(=HUB-RAM) and PASM(=COG-RAM)

    in PASM the basic set of commands is on a lower level
    but in your case most of it is
    load a value
    compare it with another value
    jump to two different adresses depending on the compare-result equal or not equal

    pseudo-code
    store actual countervalue in a long called START

    enter a loop wait for pulse-start
    wait for transition low high
    load INA
    bitwise and to filter a certain bit
    compare value with a constant representing the bit is set
    if the result of the comparing is equal jump to second part

    calculate difference of actual counter with START
    compare result with constant timeoutlength
    if the difference is bigger than the timeoutlength
    no signal received jump to polling the next IO-pin

    wait for pulse-end
    wait for transition high-low

    same commands as for wait for pulse-start
    calculate difference END START and store the result in HUB-RAM

    jump to next wait for next pin

    If you post concrete questions about how the PASM-code has to be modified to make it work
    the forum-members will surely answer

    One possability for debugging is to add a little code that switches on a LED when the program
    jumps to a certain place as a feedback that it did jump there and nowhere else
    or even better whenever the program executes a certain part store different values to HUB-RAM and read out and display the values from another cog to have a feedback what the PASM-program is doing (or better WAS doing before it crashed
    caused by bugs)

    best regards

    Stefan
Sign In or Register to comment.