HobbyKing.com New Products Flash Sale
Reply
Thread Tools
Old Dec 02, 2012, 08:54 AM
Registered User
Australia, QLD
Joined Aug 2012
18 Posts
Discussion
LeoStick Arduino + RC transmitter = goodness

Hey guys,

New to all this! I just got my LeoStick Arduino setup to read a spare channel on my receiver. It performs 8 different actions depending on the position of the transmitter knob.

Currently those 8 different actions are just changing colours on the built in RGB LED, but I soon hope to wire that out to a breadboard and start controlling some relays to switch on/off bigger lights/gizmos.

Here's a quick video showing the LED change color depending on the position on the transmitter.

LeoStick arduino and RC receiver controlling LED (0 min 40 sec)


I'm still rather newb with electronics, so I'm trying to learn how to convert the 6V coming from the BEC down to 5V so it can power this LeoStick onboard the helicopter. After I tackle that I'll be learning how to correctly wire up a relay so I can turn on/off a 12v light source from the arduino. All pretty basic stuff - but new and exciting for me!

Code:

Code:
#define CHANNEL 6 // which input pin on arduino to read from
#define CHANNELMIN 16900 // value of pulseIn() when tx is min
#define CHANNELMAX 17500 // value of pulseIn() when tx is max
#define MODECOUNT 6 // split input into this many different actions, plus a min/max (8 total)

#define LEDPINR 13 // RED LED
#define LEDPING 9 // GREEN LED
#define LEDPINB 10 // BLUE LED

int modewidth = (CHANNELMAX - CHANNELMIN) / MODECOUNT; // width of each action
int currentmode = 0; 

void setup() {
  Serial.begin(9600);
  pinMode(CHANNEL, INPUT);     
  digitalWrite(CHANNEL, HIGH); 
  pinMode(LEDPINR, OUTPUT); 
  pinMode(LEDPING, OUTPUT); 
  pinMode(LEDPINB, OUTPUT); 
  Serial.println("Starting");
}

void loop() {
  int i = pulseIn(CHANNEL, LOW);
  if(i<=CHANNELMIN){
    // off
    //Serial.println("Min");
    currentmode = 0;
  }else if(i>=CHANNELMAX){
    // all way on.
    //Serial.println("Max");
    currentmode = MODECOUNT+1;
  }else{
    // one of the "modes" in between.
    currentmode = ((i - CHANNELMIN) / modewidth)+1;
  }
  Serial.println(currentmode);
  switch(currentmode){
    case 0:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 1:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 2:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 3:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, HIGH); //
    break;
    case 4:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 5:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, HIGH); //
    break;
    case 6:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, HIGH); //
    break;
    case 7:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, HIGH); //
    break;
  }
  
}
Cheers,
Dave
dtbaker is offline Find More Posts by dtbaker
Last edited by dtbaker; Dec 02, 2012 at 09:13 AM.
Reply With Quote
Sign up now
to remove ads between posts
Old Dec 02, 2012, 10:52 AM
Registered User
United Kingdom, Bristol
Joined Aug 2008
1,774 Posts
Nice one, Thanks

Phil
SadSack is offline Find More Posts by SadSack
Reply With Quote
Old Dec 02, 2012, 12:51 PM
Stuart
srnet's Avatar
UK, Cardiff
Joined Dec 2008
3,342 Posts
Goodstuff ......

C in not my thing, so are you reading the pulse input several times before switching the output ?

For most RC control, motor or plane controls, it usually does not matter if there is a glitch pulse, it just does not affect the control.

For a switched output, it can matter a great deal, you dont want a single glitch pulse to cause an action.

I did something similar for a remote camera trigger. To prevent false triggering of the camera, the program needed 5 consecutive pulses of the correct width in order to trigger the camera. I never have had a false trigger with that setup.
srnet is offline Find More Posts by srnet
Reply With Quote
Old Dec 02, 2012, 04:12 PM
Registered User
Australia, QLD
Joined Aug 2012
18 Posts
Quote:
Originally Posted by srnet View Post
C in not my thing, so are you reading the pulse input several times before switching the output ?
I did notice some LED flickering back and forward at certain points. Reading the input several times before actioning should fix that. Thanks for the tip!
dtbaker is offline Find More Posts by dtbaker
Reply With Quote
Old Dec 03, 2012, 03:27 AM
Registered User
Australia, QLD
Joined Aug 2012
18 Posts
this updated code will automatically configure the input range of pulseIn(). When the arduino starts just turn the TX all the way off then all the way on so it knows the full range it can work with. It will also average out the past few reads and only proceed if the average is the same (ie: once you have stopped turning the knob on the transmitter).

might be useful for someone else:

Code:
#define CHANNEL 6
#define MODECOUNT 6 // how many actions to split our tx range into (Min-0,1,2,3,4,5,6,7-Max)

#define LEDPINR 13 // RED
#define LEDPING 9 // GREEN
#define LEDPINB 10 // BLUE

int modewidth = 0;//(CHANNELMAX - CHANNELMIN) / MODECOUNT;
int channelmin = 0;
int channelmax = 0;
int currentmode = 0;
int pulseend = 50; 

const int numReadings = 6;      // how many to work out the average
int readings[numReadings];      // the readings from the analog input
unsigned int index = 0;                  // the index of the current reading
long total = 0;                  // the running total
long average = 0;                // the average

const int jump_check_min = 3; // we have to read 3 averages the same before programming the device.
int jump_check_count = 0;
int jump_check_last_value = 0;

void setup() {
  Serial.begin(9600);
  pinMode(CHANNEL, INPUT);     //set the pin to input
  digitalWrite(CHANNEL, HIGH); //
  pinMode(LEDPINR, OUTPUT); 
  pinMode(LEDPING, OUTPUT); 
  pinMode(LEDPINB, OUTPUT); 
  Serial.println("Starting");
  // we grab some default values for this channel.
  for (int x = 0; x < numReadings; x++)
    readings[x] = 0;   
}

void loop() {
  int i = pulseIn(CHANNEL, LOW);
  Serial.print(i);
  if(i<12000){
    digitalWrite(LEDPING, HIGH); //
    return;
  }
  total = total - readings[index];
  readings[index] = i; 
  total = total + readings[index];
  index = index + 1;
  if (index >= numReadings) 
    index = 0;  
  average = total / numReadings;
  average = average/10; // round
  average = average*10;
  Serial.print(" Average: ");
  Serial.println(average);
  
  if(jump_check_last_value == average){
    // we are the same as last average check! yay! 
    jump_check_count++;
    if(jump_check_count<=jump_check_min)return;
  }else{
    jump_check_count = 0;
    jump_check_last_value = average;
    return;
  }
  i = average;

  
  if(i > channelmax)channelmax = i;
  if(i < channelmin || channelmin == 0)channelmin = i;
  //pulseend = (channelmax - channelmin) / (MODECOUNT+2);
  modewidth = ((channelmax-pulseend) - (channelmin+pulseend)) / MODECOUNT;
  
  if(i<channelmin+pulseend){
    // off
    Serial.print("Min ");
    currentmode = 0;
  }else if(i>channelmax-pulseend){
    // all way on.
    Serial.print("Max ");
    currentmode = MODECOUNT+1;
  }else{
    // one of the "modes" in between.
    currentmode = ((i - channelmin) / modewidth)+1;
  }
  Serial.println(currentmode);
  switch(currentmode){
    case 0:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 1:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 2:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 3:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, HIGH); //
    break;
    case 4:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, LOW); //
    break;
    case 5:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, LOW); //
      digitalWrite(LEDPINB, HIGH); //
    break;
    case 6:
      digitalWrite(LEDPINR, LOW); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, HIGH); //
    break;
    case 7:
      digitalWrite(LEDPINR, HIGH); //
      digitalWrite(LEDPING, HIGH); //
      digitalWrite(LEDPINB, HIGH); //
    break;
  }
  
}
dtbaker is offline Find More Posts by dtbaker
Reply With Quote
Reply


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Discussion Tiny Arduino perfect for RC TinyCircuits Product Announcements 1 Sep 26, 2012 04:07 PM
Discussion RC Segway with arduino wm+ nunchuk and multiwii code Widelec Multirotor Talk 0 Mar 07, 2012 08:43 AM
Discussion Spektrum / Arduino Joystick Transmitter sonicj DIY Electronics 19 Aug 16, 2010 03:13 PM
Question What RC Transmitter Has Good Range? RCOnboard FPV Talk 22 Sep 18, 2009 01:56 PM