Saturday, November 19, 2011

an Arduino sketch for transmitter tuning


One heachachy thing of dealing with quad is the need to plug the quad into the computer and run the quad tuning software in order to fiddle with your radio settings.  That wouldn't be so bad, except that I fanatically remove the props whenever I do this, which of course means you  then have to turn around and put them right back on.





So, I put together this quick Arduino project to read and display the PWM values from the receiver.  This has allowed me to spend a lot more time fiddling with the often inscrutable menus of the Turnigy 9x and making sense of them.






I made these connection wires to reduce the clutter of having six full three-wire servo connectors.  One end has a male connector and connects to the Arduino; the other end has a female pin and connects to the signal pin of the receiver.  The standard connector goes to an ESC and battery and provides power to the ESC.  I think the Arduino has enough power that it could be used instead.




From the Arduino environment, click the Terminal button and you'll see this output. Nothing fancy, but it allows accurate fiddling with transmitter controls.








This version of the code uses pulseIn(), which nicely does the right thing but suckily does it very slowly.  It's fine if you're just printing out the values, but if you were wanting to do some real control work in between reading the signals, it wouldn't work very well.

#include "WProgram.h"

#define NCHAN (sizeof(chan)/sizeof(chan[0]))
int chan[]={2,3,4,5,6};
int val[NCHAN];

void setup()
{
  int i;
  for (i = 0; i < NCHAN; ++i)
    pinMode(chan[i], INPUT);
  Serial.begin(115200);
}

void loop()
{
  int i;
  for (i = 0; i < NCHAN; ++i)
    val[i] = pulseIn(chan[i], HIGH);
 
  Serial.println();
  for (i = 0; i < NCHAN; ++i) {
    Serial.print(i+1);
    Serial.print(": ");
    Serial.print(val[i]);
    Serial.print("    ");
  }
  //delay(20);
}


Here's some code that uses interrupts to get the timings.  This would be useful on an Arduino Mega, which supports interrupts on six pins.  If you don't have a Mega, you've only got two pins so you're better off with the code above.  There are two other problems with  this code:
  • micros() returns a value which is rounded to a multiple of 4 microseconds, totally unacceptable for tuning radio PWM signals.
  • digitalRead() is very slow and can be made much faster.
I'm going to keep working on this approach, and I'll update later when I've got something to show.  I'm also thinking of making a GUI using Processing.

// reading a PWM signal using interrupts

int pin = 2;       // arduino pin number
int intrnum = 0;   // interrupt number, 0-5 for mega, 0-1 for others

volatile int width;  // width of most recent signal
volatile unsigned long start;  // start time of rising signal

// myisr -- interrupt handler
void myisr()  
{
  unsigned long now = micros();
  int val = digitalRead(2);     // are we high (meaning pulse just started)
                                // or low (meaning pulse just finished) ?
  
  if(val == HIGH) // ascending edge, just save off start time
    start = now;
  else // val == LOW, descending edge, compute pulse width 
   width= now - start;
}  

void setup()  
{  
  Serial.begin(115200);  
  pinMode(pin,INPUT);  
  attachInterrupt(intrnum, myisr, CHANGE); 
}  

void loop()  
{  
  Serial.println(width);
  delay(10);  
}

No comments:

Post a Comment