Shop OBEX P1 Docs P2 Docs Learn Events
trying to tie an r/c receiver output to pwm motor control — Parallax Forums

trying to tie an r/c receiver output to pwm motor control

mikeamikea Posts: 283
edited 2012-04-10 20:26 in Propeller 1
ive done some digging and still dont understand how to write a code to proportionally relate the output of an r/c receiver to pwm motor. the goal is intercept signals and output them to the motor with the propeller.does anyone know of a tutorial, similar project, or thorough explanation they can point me to? -mike

Comments

  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-04-10 17:19
    Actually, I do just this with my Mecanum wheeled robot project.

    I'm not sure if I've posted code to do this or not. I'll check and make sure to post a version of code that controls the motors based on the RC signal.
  • RobotWorkshopRobotWorkshop Posts: 2,307
    edited 2012-04-10 17:22
    You should be able to build something quickly with the Propeller. Some of these object should get you started:

    http://obex.parallax.com/objects/482/

    http://obex.parallax.com/objects/331/

    http://obex.parallax.com/objects/88/

    Robert
  • mikeamikea Posts: 283
    edited 2012-04-10 18:12
    thanks guys...i would be interested to see your code if you don't mind duane.

    robotworkshop, i live just west of kalamazoo, and have looked for a club or some people to meet with to learn some of this stuff and work on projects. i see you live in michigan and wondered if it was around kzoo if you know of any clubs/people to rub elbows with.
  • W9GFOW9GFO Posts: 4,010
    edited 2012-04-10 19:03
    Here's the code I use for the Mecanum robot that I will have at UPEW. It has encoders but they are not being used right now. I use http://obex.parallax.com/objects/482/ to read the pulses from the receiver.
    {{
    *****************************************
    * Mecanum                               *
    * Author: Rich Harman                   *
    * Copyright (c) Rich Harman             *
    * See end of file for terms of use.     *
    *****************************************
    
    
    Begun Mar 15 2012
    
    
    }}
    
    CON
     
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
    
      BasePinEnc    = 0  'Pins 0 to 7 motors 1 to 4 quadrature input
      PWM1          = 8  'PWM input motor 1
      PWM2          = 9
      PWM3          = 10
      PWM4          = 11
      Motor1A       = 23
      Motor1B       = 22
      Motor2A       = 21
      Motor2B       = 20
      Motor3A       = 19
      Motor3B       = 18
      Motor4A       = 17
      Motor4B       = 16
      RC4           = 24
      RC3           = 25
      RC2           = 26
      RC1           = 27
    
    
      Kf            = 100
      Ks            = 115
      Ky            = 100
      Vscale        = 40
      null          = 5
      ramp          = 1
      MaxV          = 255
      Center        = 1520
      
    VAR
    
    
    
    
      long  pulsewidth[4]
    
    
      long  Strafe[2]
      long  FWD[2]
      long  Yaw[2]
    
    
      long  FrontL
      long  FrontR
      long  RearL
      long  RearR
    
    
      long  Pos[8]             'Address of position buffer
    
    
    
    
    
    
    OBJ
    
    
      Encoder : "Quadrature Encoder"  
      RX      : "RX"
      pwm     : "PWMx8"  
    
    
    PUB Init
      
      dira := 00_0000_1111_1111_1111_1111_0000_0000
      
      outa[Motor1A..Motor4B] := 11_1111
    
    
      RX.start(@pins,@pulseWidth)
      pwm.start(PWM1, 00_1111, 20_000)
      'Encoder.Start(BasePinEnc, 4, 4, @Pos)
    
    
      Main
      
    PUB Main
    
    
      repeat
        ReadRC
        'ReadENC
        Calc
        Motors 
    
    
    PUB ReadRC
    
    
      repeat until pulsewidth[0] =< 1920 or pulsewidth[0] >= 920
    
    
      Strafe[1]  := Strafe[0]
      FWD[1]     := FWD[0]
      Yaw[1]     := Yaw[0]
      
      Strafe[0]  := -100 #> (pulsewidth[3] - Center) / 4 <# 100
      FWD[0]     := -100 #> (pulsewidth[2] - Center) / 4 <# 100
      Yaw[0]     := -100 #> (pulsewidth[1] - Center) / 4 <# 100
    {
      if ||(Strafe[0] - Strafe[1]) > null
        Strafe[0] += ramp
      else
        Strafe[0] := Strafe[1]
    
    
      if ||(FWD[0] - FWD[1]) > null
        FWD[0] += ramp
      else
        FWD[0] := FWD[1]
    
    
      if ||(Yaw[0] - Yaw[1]) > null
        Yaw[0] += ramp
      else
        Yaw[0] := Yaw[1]  }  
    
    
    PUB ReadEnc 
    '  repeat
    '   <read Pos[0] or Pos[1] here>         'Read each encoder's absolute position
    '    <variable> := Encoder.ReadDelta(0)   'Read 1st encoder's delta position (value since last read)
    
    
    PUB Calc | Vmax
     
     FrontL  := ((Kf * FWD) + (Ks * Strafe) + (Ky * Yaw)) / Vscale
     Vmax := FrontL
         
     FrontR  := ((Kf * FWD) - (Ks * Strafe) - (Ky * Yaw)) / Vscale
      if ||FrontR => ||Vmax
        Vmax := FrontR
           
     RearL   := ((Kf * FWD) - (Ks * Strafe) + (Ky * Yaw)) / Vscale
      if ||RearL => ||Vmax
        Vmax := RearL
        
     RearR   := ((Kf * FWD) + (Ks * Strafe) - (Ky * Yaw)) / Vscale
      if ||RearR => ||Vmax
        Vmax := RearR
    
    
     ||Vmax     
    
    
     if Vmax => MaxV
      FrontR := (FrontR * 100) / ((Vmax * 100) / MaxV)
      FrontL := (FrontL * 100) / ((Vmax * 100) / MaxV)
      RearL  := (RearL * 100) / ((Vmax * 100) / MaxV)
      RearR  := (RearR * 100) / ((Vmax * 100) / MaxV)
    
    
    
    
    
    
    Pub Motors 
    '// Set motor direction and power
    
    
     if FrontL == 0
      outa[Motor1A .. Motor1B] := 
     if FrontL < 0
      outa[Motor1A..Motor1B] := 
     if FrontL > 0
      outa[Motor1A..Motor1B] := 
     pwm.duty(PWM1, ||FrontL)
     
     if FrontR == 0
      outa[Motor2A .. Motor2B] := 
     if FrontR < 0
      outa[Motor2A..Motor2B] := 
     if FrontR > 0
      outa[Motor2A..Motor2B] := 
     pwm.duty(PWM2, ||FrontR)
     
     if RearL == 0
      outa[Motor3A .. Motor3B] := 
     if RearL < 0
      outa[Motor3A..Motor3B] := 
     if RearL > 0
      outa[Motor3A..Motor3B] := 
     pwm.duty(PWM3, ||RearL)
    
    
     if RearR == 0
      outa[Motor4A .. Motor4B] := 
     if RearR < 0
      outa[Motor4A..Motor4B] := 
     if RearR > 0
      outa[Motor4A..Motor4B] := 
     pwm.duty(PWM4, ||RearR)
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-04-10 20:19
    Rich, I started out using your object to control my Mecanum robot but it uses three cogs and I had too much else going on to tie up three cogs to monitor the RC receiver.

    Jason Dorie has an object (I think modified from someone elses code) that monitors six channels with one cog. The down side to Jason's object is it needs to use the first six pins. This wasn't a problem with my breadboard version of the robot. My current plan is to use Nordic nRF24L01+ modules to control the robot so I wont be using RC gear at all with it.

    Your robot has the power to drive those Mecanum wheels with authority without using encoders. The Rover 5 chassis I'm using, has a really hard time without the assistance of the encoders.

    I hope you post more details about your robot some time. I'd really like to know what motors you're using. It looks amazing!

    I added the code to my Mecanum robot thread.
  • W9GFOW9GFO Posts: 4,010
    edited 2012-04-10 20:26
    I only use two cogs for this one since I only need three channels. Soon, I won't be using any RC gear either. Instead it will have an XBee. The motors are Pololu 50:1 37mm gear motors.
Sign In or Register to comment.