Shop OBEX P1 Docs P2 Docs Learn Events
RC Input to Propeller — Parallax Forums

RC Input to Propeller

Greg NortonGreg Norton Posts: 70
edited 2009-01-19 11:01 in Propeller 1
I have an application where I'd like to receive 3 channels of RC input to the Propeller. My goal is to have 2 channels of directional input (from the right stick of the transmitter), and one on/off type input from one of the switches on the transmitter (normally used for landing gear on an RC plane). These are designated a channels 1,2, and 6 on the RC receiver.

The problem I'm having is with the InputServosRC object from the exchange. I can get the first two channel inputs to the propeller to work fine and show inputs from the right stick on the transmitter. However, I cannot get the 3rd input to the propeller working unless I connect it to the 3rd channel of the RC receiver.

Here's a diagram to try and clarify the situation. The following DOES work. My example program (see attached) shows expected values. I slightly modified InputServosRC to try and figure out where the problem lies.

RC Receiver Channel => Prop Input Pin
Channel 1 => Pin 8
Channel 2 => Pin 9
Channel 3 => Pin 10

The following DOES NOT work.

RC Receiver Channel => Prop Input Pin
Channel 1 => Pin 8
Channel 2 => Pin 9
Channel 6 => Pin 10

When I try the failing case, my program shows all 0 values, including the status value. I'm not even sure how this is possible. I have examined the output of the RC receiver channel 6 and it shows what I expect. The pulse width is 1.0 - 2.0 ms depending on the position of the switch. My examination of InputServosRC does not lead me to believe there is any requirement to use sequential channels from the RC receiver, but this seems to be the case so far.

Anyone have a suggestion on this?

Thanks.
Greg

Comments

  • hover1hover1 Posts: 1,929
    edited 2009-01-06 03:45
    Greg,

    What transmitter and receiver are you using? Probably does not make a difference but would be nice to know. I can try to set up same senario on my Hitec Optic 6 Xmiter and Hitec Micro 05S receiver and let you know what happens.

    Jim
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-06 09:58
    Hello Greg,

    the doc of the InputServosRC_v1.0.spin-files says

    ....
    In order for a series
    of pulses to be considered valid, every channel starting at 'FirstPin' and
    ending at 'FirstPin' + 'Total' must receive a valid pulse, and be in sequential
    order. If any channels from the radio receiver to the Propeller are
    disconnected, or connected out of order, no pulse sequences will be considered
    valid.....

    So I think this is what's happening.

    if there is a time-gap between the pulse for channel 2 and channel 6
    (because inbetween the pulses for channel 3-5 are sended) the calculation of the pulse-length is out of range

    To handle this you have to modify the object that every channel has it's own variables for the snapshot of cnt
    for the rising edge. The falling edge is the actual value of cnt itself

    The driver as it is uses the ONE variable "LastCnt" for the snapshot of the rising edge.

    best regards

    Stefan
  • Joel RosenzweigJoel Rosenzweig Posts: 52
    edited 2009-01-06 19:05
    An elegant solution, if you can afford the cogs, is to dedicate a single cog to each of the input signals. This offers a completely bullet proof, no compromises, signal aquisition system. The ability to dedicate a cog to an input signal is the reason I switched over to the Prop in the first place. I was building a device to control servos on a model helicopter, and the parallel architecture of the Prop is exactly the right tool for the job in this case.

    Joel-
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-01-06 20:57
    Actually, there are 2 counters for each cog so you only need half as many. Except in cases where more than 1 pulse occurs at the same time ( usually· 8+ channel systems), you should be able to do it with 1 cog and 2 counters but you would have to sequence the input pins. Different systems output the channels in different sequences so you would need to know the order. I will be doing this for my Futaba 9C later.

    Donald
  • Joel RosenzweigJoel Rosenzweig Posts: 52
    edited 2009-01-06 22:35
    Actually, there are 2 counters for each cog so you only need half as many.· Except in cases where more than 1 pulse occurs at the same time
    That's the reason why you would need to dedicate a cog to the each input.· If you want a no compromises robust solution, then it doesn't help if you have two counters per cog, because the receiver may be of the type that outputs two signals at the same time.

    There's another glitch.· In my case, I was using gyroscopes in line with the RX outputs, and the output from the gyroscopes were not perfectly periodic even if the receiver was.· Therefore, at any given instant, the signals could have one timing relationship where the signals do not overlap and another cycle at some future time the signals could overlap.
    Different systems output the channels in different sequences so you would need to know the order.
    If you already know exactly what the input will look like, then you can optimize for that.· If you're trying to make a product that works with everything available,·then you have to design it to be more robust.· In my case, I was making a product that was meant to interface to everyone's receiver, not just the one I had on my shelf.

    I don't know if Greg needs anything this robust or not.· I decided to mention it to help others who might pursue building a device that needs a bullet proof front end such as this.· It all depends on what you're doing.· Some people might choose to simply filter the glitches out with software.· I'd prefer to eliminate the glitch at the source.

    Joel-


    ·
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-01-06 22:40
    One cog (2 counters) can operate at the same time. They are completely independant.
  • Greg NortonGreg Norton Posts: 70
    edited 2009-01-06 23:21
    Thanks to all who responded.

    I found out through experimentation what StefanL38 pointed out from the comments (should have read them more closelynono.gif ).· Looking at waveforms on the outputs of the receiver showed that the sequential channels share a falling/rising edge.· That is, the falling edge of the channel 1 pulse is the same as the rising of the channel 2 pulse.· The code was designed for this and was only looking for falling edges of pulses after the initial rising edge from channel 1.· I modified the code to look for a rising edge on each of the additional channels and then do the measurement based on that.· This could be causing me to miss the rising edge of channel 2, but then channel 2·will be·measured·on the next set of pulses from the receiver.· I'll have to check this out when I get home.· My application is a fairly slow moving robot so I can afford the degraded refresh rate that results.

    Greg
  • JasonDorieJasonDorie Posts: 1,930
    edited 2009-01-06 23:50
    Greg - it's possible to sample 8 channels with arbitrary order (even simultaneous) and get decent precision.· J.A.B. posted code to do it quite a while ago here:

    http://forums.parallax.com/showthread.php?p=690465

    His comments imply that it gets 1uS resolution, but it's actually 1/4 that (he's assuming 1 instruction per clock, but it's every 4 clocks), so you get about 250 steps over the 1ms range for all 8 inputs.

    That said, if you modify the code to handle only 4 inputs, you can double the precision, and run two cogs to sample 4 pins each.· My quad-rotor is using this code modified to handle 6 inputs (gets me a little more precision) and it's great.
    ·
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-01-19 11:01
    I have finally gotten around to do some testing with my Futaba T9CHP 9 channel PCM system. I have done a demo in spin to test the accuracy and viability of using a single cog with the 2 counters. It works and gives 12.5 ns accuracy but I am just using the integer microseconds at this time. It does work in spin but really need to be done in assembly as there are only about 200us between pulse pairs. Also, using the wait peq, there is the possibily of system hang but that can be dealt with in the main routine later. Lots more to do but its a beginning. The terminal screen shot is attached.
    {
    * PCM Receiver Test
    * The receiver outputs (up to 10) are connected to P0..P9 through ~4.7k resistors.
    * Donald Nash 1/19/2009
    *
    *
    }
    CON
       
      _clkmode = xtal1 + pll16x                  ' System clock → 80 MHz
      _xinfreq = 5_000_000
    OBJ
       
      text      : "PC_Interface"
    VAR
      long  tmr1, tmr2
      long  prr, mode
      long  chan
    PUB Main   
      text.start(31,30)
      text.out(0)                 ' clear screen
      'WAITPEQ (State, Mask, Port ) for my own reference
      waitpeq(0,1,0)              'wait for all pulses off
      waitcnt(cnt + clkfreq)      'delay for display
      text.str(string("Receiver test .. Waiting for input",13))
      waitpeq(1,1,0)              'wait for chan 1 on
      tmr1 := cnt                 'start counter
      waitpeq(0,1,0)              'wait for chan 1 off
      tmr2 := cnt
      text.str(string("Received chan. 1  "))
      text.dec((tmr2 - tmr1)/80)  ' time in us
      text.str(string(" us",13))
      waitpeq(1,1,0)              'wait for chan 1 on
      prr := cnt - tmr1
      text.str(string("Receiver period = "))
      text.dec(prr/80)
      text.str(string(" us",13))
      text.str(string("Mode is "))
      waitpeq(0,1,0)              'wait for all pulses off
      waitpeq(1,1,0)              'wait for chan 1 on
      mode := ina & $3FF          'test number of simultaneous pulses
      if mode >1
        text.str(string("PCM",13))
        text.bin(mode,10)           'show binary mask
        text.out(" ")
        text.dec(mode)              'show decimal mask
        text.out(13)
        waitpeq(0,$3FF,0)           'wait for all off
        waitpne(0,$3FF,0)           'wait for next set
        chan := ina & $3FF          'save it
        text.bin(chan,10)           'show binary mask  
        text.out(" ")                                  
        text.dec(chan)              'show decimal mask 
        text.out(13)
        waitpeq(0,$3FF,0)           'wait for all off  
        waitpne(0,$3FF,0)           'wait for next set 
        chan := ina & $3FF          'save it           
        text.bin(chan,10)           'show binary mask  
        text.out(" ")                                  
        text.dec(chan)              'show decimal mask 
        text.out(13)
        waitpeq(0,$3FF,0)           'wait for all off  
        waitpne(0,$3FF,0)           'wait for next set 
        chan := ina & $3FF          'save it           
        text.bin(chan,10)           'show binary mask  
        text.out(" ")                                  
        text.dec(chan)              'show decimal mask 
        text.out(13)
        waitpeq(0,$3FF,0)           'wait for all off  
        waitpne(0,$3FF,0)           'wait for next set 
        chan := ina & $3FF          'save it           
        text.bin(chan,10)           'show binary mask  
        text.out(" ")                                  
        text.dec(chan)              'show decimal mask 
        text.out(13)
        frqa := frqb := 1
        ctra[noparse][[/noparse]30..26] := %01000                     ' Set ctra to POS mode
        ctrb[noparse][[/noparse]30..26] := %01000                     ' Set ctrb to POS mode
        ' This is main routine for PCM
        ' there is only about 300us from end of first pair to
        ' start of next pair.  Need to stash phsa &phsb to channel
        ' values and then change counter input pins and zero counters
        repeat
          'chan 1&2
          ctra[noparse][[/noparse]5..0] := 0                      ' Set ctra's APIN
          ctrb[noparse][[/noparse]5..0] := 1                      ' Set ctra's APIN
          'waitpeq(%0000000011,%0000000011,0)
          waitpeq(%0000000000,%0000000011,0)
          phsa := phsb := 0                    ' zero counters
          waitpeq(%0000000011,%0000000011,0)   ' wait for pulse
          waitpeq(%0000000000,%0000000011,0)   ' wait for pulse end
          setpos(0,9)
          text.dec(phsa /80 )
          setpos(0,10)
          text.dec(phsb /80 )
          
          'chan 7$8
          ctra[noparse][[/noparse]5..0] := 6                      ' Set ctra's APIN
          ctrb[noparse][[/noparse]5..0] := 7                      ' Set ctra's APIN
          'waitpeq(%0011000000,%0011000000,0)
          waitpeq(%0000000000,%0011000000,0)
          phsa := phsb := 0                    ' zero counters 
          waitpeq(%0011000000,%0011000000,0)
          waitpeq(%0000000000,%0011000000,0)
          setpos(10,11)
          text.dec(phsa /80 )
          setpos(10,12)
          text.dec(phsb /80 )
          
          'chan 3&4
          ctra[noparse][[/noparse]5..0] := 2                      ' Set ctra's APIN
          ctrb[noparse][[/noparse]5..0] := 3                      ' Set ctra's APIN
          'waitpeq(%0000001100,%0000001100,0)
          waitpeq(%0000000000,%0000001100,0)
          phsa := phsb := 0                    ' zero counters 
          waitpeq(%0000001100,%0000001100,0)
          waitpeq(%0000000000,%0000001100,0)
          setpos(0,11)
          text.dec(phsa /80 )
          setpos(0,12)
          text.dec(phsb /80 )
          
          'chan 9
          ctra[noparse][[/noparse]5..0] := 8                      ' Set ctra's APIN
          'waitpeq(%0100000000,%0100000000,0)
          waitpeq(%0000000000,%0100000000,0)
          phsa := phsb := 0                    ' zero counters 
          waitpeq(%0100000000,%0100000000,0)
          waitpeq(%0000000000,%0100000000,0)
          setpos(20,9)
          text.dec(phsa /80 )
          
          'chan 5&6
          ctra[noparse][[/noparse]5..0] := 4                      ' Set ctra's APIN
          ctrb[noparse][[/noparse]5..0] := 5                      ' Set ctra's APIN
          'waitpeq(%0000110000,%0000110000,0)
          waitpeq(%0000000000,%0000110000,0)
          phsa := phsb := 0                    ' zero counters 
          waitpeq(%0000110000,%0000110000,0)
          waitpeq(%0000000000,%0000110000,0)
          setpos(10,9)
          text.dec(phsa /80 )
          setpos(10,10)
          text.dec(phsb /80 )
        
          ' code for PPM receivers   
      else
        text.str(string("PPM",13))
        repeat       'stub
        
    PRI setpos(px, py)
      text.out(10)
      text.out(px)
      text.out(11)
      text.out(py)
        
    

    Donald
    326 x 274 - 33K
Sign In or Register to comment.