PDA

View Full Version : trying to tie an r/c receiver output to pwm motor control



mikea
04-11-2012, 12:15 AM
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

Duane Degn
04-11-2012, 12:19 AM
Actually, I do just this with my Mecanum wheeled robot (http://forums.parallax.com/showthread.php?130797-Mecanum-Wheeled-Robot-with-Machine-Vision)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.

RobotWorkshop
04-11-2012, 12:22 AM
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

mikea
04-11-2012, 01:12 AM
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.

W9GFO
04-11-2012, 02:03 AM
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 Degn
04-11-2012, 03:19 AM
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 (http://forums.parallax.com/showthread.php?130797-Mecanum-Wheeled-Robot-with-Machine-Vision&p=1089938&viewfull=1#post1089938).

W9GFO
04-11-2012, 03:26 AM
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.