Go Down

Topic: Convert Pulse Width Modulation into a char or a double? (Read 679 times) previous topic - next topic

CAD321

I would like to convert the ppm signals coming from my dx6i receiver into a char or double. This will be so I can attempt mecanum code in the near future hopefully. I am on a FIRST robotics team and have received support from the FIRST community on how to write mecanum code for the robots I work on in FIRST. The only problem I think I will have with porting this code over to the arduino is that I am dealing with pulse widths instead of chars or floats. For FIRST we use a library that converts the floats/chars into the pulse widths for us. Is there such a library I can use with the arduino. Any and all help is appreciated.

johnwasser

You should be able to use the pulseIn() function to get the pulse width in microseconds.  This should give you an unsigned long int between (roughly) 1000 and 2000.

http://arduino.cc/en/Reference/PulseIn
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

CAD321

I got the basics working where I can take a signal from my reciever and make it control my servo through the arduino. The issue I am now facing is that when I do more than one pulseIn command, there is considerable lag (about 1 second lag for every pulseIn command after the 1st). I am unsure how to correct this. My first instinct was to use interrupts but I have limited knowledge on the subject and can't seem to get it working.

Without Interrupts:
Code: [Select]
#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); 
}


With interrupts:
Code: [Select]
#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;
}

johnwasser

The default timeout for pulseIn() is one second. Could your other inputs not be pulsing?

You should set the timeout to a little greater then your expected pulse interval.  My guess would be 30 milliseconds (30,000 microseconds).
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

CAD321

Thanks for the help, It is responding virtually instantly (some tiny lag with the 30000 microsecond timeout so I reduced it to 20000 and now has great response time).

Go Up