|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools |
Rating:
|
Display Modes |
|
|
|
#1
|
|||
|
|||
|
Arduino Mecanum drive using PWM?
I have been trying to program an Arduino Uno to take PWM signals from a spectrum RC receiver and mix those signals to control 4 motors on a mecanum drive bot. Although I don't have the bot built/designed yet I have been trying to get some of the code working. My issue is that when ever I try to use more than one pulseIn command it adds about 1 second of lag per pulseIn command. I am controlling a servo through this setup.
The code: Code:
#include <Servo.h>
Servo FLS; //front left servo
Servo FRS; //front right servo...
Servo RLS;
Servo RRS;
int Forward = 1; //Inputs from RC receiver
int Strafe = 2;
int Rotate = 3;
unsigned long ForwardDuration; //To store the duration of the pulses
unsigned long StrafeDuration; //coming from the receiver
unsigned long RotateDuration;
unsigned long FL; //Front Left Value
unsigned long FR; //Front Right Value...
unsigned long RL;
unsigned long RR;
void setup()
{
FLS.attach(10);
FRS.attach(11);
RLS.attach(12);
RRS.attach(13);
pinMode(Forward, INPUT);
pinMode(Strafe, INPUT);
pinMode(Rotate, INPUT);
}
void loop()
{
ForwardDuration = pulseIn(Forward, HIGH); //read receiver inputs
StrafeDuration = pulseIn(Strafe, HIGH);
RotateDuration = pulseIn(Rotate, HIGH);
FL = ForwardDuration + StrafeDuration + RotateDuration;
FR = ForwardDuration - StrafeDuration - RotateDuration;
RL = ForwardDuration - StrafeDuration + RotateDuration;
RR = ForwardDuration + StrafeDuration - RotateDuration;
FLS.writeMicroseconds(FL);
FRS.writeMicroseconds(FR);
RLS.writeMicroseconds(RL);
RRS.writeMicroseconds(RR);
}
My attempt at using Interrupts: Code:
#include <Servo.h>
Servo FLS; //front left servo
Servo FRS; //front right servo...
Servo RLS;
Servo RRS;
int Forward = 1; //Inputs from RC receiver
int Strafe = 2;
int Rotate = 3;
volatile unsigned long ForwardDuration; //To store the duration of the pulses
volatile unsigned long StrafeDuration; //coming from the receiver
volatile unsigned long RotateDuration;
volatile unsigned long FL; //Front Left Value
volatile unsigned long FR; //Front Right Value...
volatile unsigned long RL;
volatile unsigned long RR;
void setup()
{
attachInterrupt(0, reciever, CHANGE);
FLS.attach(10);
FRS.attach(11);
RLS.attach(12);
RRS.attach(13);
pinMode(Forward, INPUT);
pinMode(Strafe, INPUT);
pinMode(Rotate, INPUT);
}
void loop()
{
FLS.write(FL);
FRS.writeMicroseconds(FR);
RLS.writeMicroseconds(RL);
RRS.writeMicroseconds(RR);
}
void reciever()
{
ForwardDuration = pulseIn(Forward, HIGH); //read receiver inputs
StrafeDuration = pulseIn(Strafe, HIGH);
RotateDuration = pulseIn(Rotate, HIGH);
FL == ForwardDuration + StrafeDuration + RotateDuration;
FR == ForwardDuration - StrafeDuration - RotateDuration;
RL == ForwardDuration - StrafeDuration + RotateDuration;
RR == ForwardDuration + StrafeDuration - RotateDuration;
}
|
|
#2
|
||||
|
||||
|
Re: Arduino Mecanum drive using PWM?
http://forum.arduino.cc/index.php?PH...p ic=42462.60
Should Help, looks like there is an interrupt library developed for servo. |
|
#3
|
||||
|
||||
|
Re: Arduino Mecanum drive using PWM?
I don't think that you'll be needing interrupts. The arduino is fast enough to control 4 PWM's. Also, don't use the unsigned longs. If forwardDuration is 10, strafeDuration is 100, and rotateDuration is 100, you will have a negative value for FR, which is unsigned. I don't know what happens on the arduino, but it may wrap around to some massive number.
EDIT: Depending on what you're using to control your motors, you may have better sucsess with analogWrite. Also, how are you testing to see the lag? Last edited by magnets : 12-07-2013 at 15:16. |
|
#4
|
|||
|
|||
|
Re: Arduino Mecanum drive using PWM?
Thanks for the help. I finally was able to load the arduino forums and now have my servos responding virtually instantly. I just needed to increase the timeout in the pulseIn function (the amount of time the arduino searched for a pulse coming in before moving on in the code).
|
|
#5
|
|||
|
|||
|
Re: Arduino Mecanum drive using PWM?
Care to share your implementation? It may help other expri-mentors. Thanks.
|
|
#6
|
|||
|
|||
|
Re: Arduino Mecanum drive using PWM?
I am planning on taking the pwm signals from my spectrum ar6210 and mixing them with the arduino using the following code to create a robot with a mecanum drive. For the motors I plan on using some continuous rotation servos and I am planning on buying some small mecanum wheels such as the 4in vex wheels.
Code:
#include <Servo.h>
Servo FLS; //front left servo
Servo FRS; //front right servo...
Servo RLS;
Servo RRS;
int Forward = 1; //Inputs from RC receiver
int Strafe = 2;
int Rotate = 3;
unsigned long ForwardDuration; //To store the duration of the pulses
unsigned long StrafeDuration; //coming from the receiver
unsigned long RotateDuration;
unsigned long FL; //Front Left Value
unsigned long FR; //Front Right Value...
unsigned long RL;
unsigned long RR;
unsigned long timeout = 20000;
void setup()
{
FLS.attach(10);
FRS.attach(11);
RLS.attach(12);
RRS.attach(13);
pinMode(Forward, INPUT);
pinMode(Strafe, INPUT);
pinMode(Rotate, INPUT);
}
void loop()
{
ForwardDuration = pulseIn(Forward, HIGH, timeout); //read receiver inputs
StrafeDuration = pulseIn(Strafe, HIGH, timeout);
RotateDuration = pulseIn(Rotate, HIGH, timeout);
FL = ForwardDuration + StrafeDuration + RotateDuration;
FR = ForwardDuration - StrafeDuration - RotateDuration;
RL = ForwardDuration - StrafeDuration + RotateDuration;
RR = ForwardDuration + StrafeDuration - RotateDuration;
if(FL < 1000){
FL = 1000;
}else if(FL > 2000){
FL = 2000;
}if(FR < 1000){
FR = 1000;
}else if(FR > 2000){
FR = 2000;
}if(RL < 1000){
RL = 1000;
}else if(RL > 2000){
RL = 2000;
}if(RR < 1000){
RR = 1000;
}else if(RR > 2000){
RR = 2000;
}
FLS.writeMicroseconds(FL);
FRS.writeMicroseconds(FR);
RLS.writeMicroseconds(RL);
RRS.writeMicroseconds(RR);
}
|
|
#7
|
|||
|
|||
|
Re: Arduino Mecanum drive using PWM?
cad321,
A couple of observations regarding the I/O. The pulseIn code (source) looks like it will return a zero (0) when it does not find the pulse within the timeout period. You may want to put in some code to check for this, otherwise your outputs may not be what you would like. Also, be aware that your "loop" execution time will be variable depending on how long it takes to obtain the three pulse values and output to your four servos. Assuming a standard 20 millisecond interval for the incoming servo PWM value, you will probably have a range between 8 to 65 milliseconds. This may not be a problem. My knowledge of the hardware you are using is limited, but You may also want to review your mixing algorithm as well. Again, assuming a standard servo input (1-2 ms pulse), the pulseIn should return values between 1000 and 2000 (usec). Adding all three together for FL (for example) would yield 3000 to 6000, or basically your maximum all the time. This could be correct if the inputs are not what I assumed, but it doesn't look right for a standard servo input/output signal. My guess, based on your original post of the 1 second delays, indicate that you are probably not reading at least two of the signals (Strafe & Rotate perhaps?), so you are adding zero (0) to your forward value and the calculations are doing what you expect. The 1 second delay is approximately the timeout for the default pulseIn when it doesn't see a pulse and no explicit timeout is passed. Mike |
|
#8
|
|||
|
|||
|
Re: Arduino Mecanum drive using PWM?
Quote:
Quote:
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|