Putting robotics at your service™

Free shipping on orders over $200

ArduinoFio/xbee +wii-chuck code > skid steering algorithm

Print view Share :
Previous topicNext topic

Page 2 of 2 [ 27 posts ]

1, 2
Rookie ( offline )
Posts: 17
Posted: 2011-11-19 03:27 
kurte wrote:
Some of the things I would still look at include:

Maybe make your input buffer a bit larger as to make sure that you don't overflow and reset it.

Also look at your LCD calls. I have not use the LCD library, but my quick look at it shows that several of the commands have some large delays in it, especially ones like: lcd.begin(16,2). My guess is you should move this call into the Setup function and not every time you try to output to the LCD...

Kurt


Messed with the buffer value, not sure why but it made things worse...
Commented out the lcd and that got rid of the "soft lock ups". I tried moving the lcd.begin call to void setup but that caused the lcd to glitch and become unusable...
But, I know the RX is getting the correct values for the most part I really its not needed IMO. Still getting jitter for servo output, and still not sure why. I don't really see anything in the code that should cause it.

~Wolf


User avatar
Guru ( offline )
Posts: 4906
Posted: 2011-11-19 11:53 
Not sure about LCD glitch. But maybe you are depending on some side effect of the init call, like the init cleared the screen or the like... Note sure about the LiquidCrystal library as my quick look through it, shows it has a base class of print, and the header file says the low level function: void LiquidCrystal::write(uint8_t value) is virtual, which makes sense as this would be the one function that would need to be implemented to direct the output to the right thing. But the implementation of write, shows that it is inline, which does not make sense to me...

If it were me, I would hook up my logic analyzer to several of the pins (2 servos, 1 for RX and maybe a few of the control lines of the LCD to get an idea of what was happening...), but... (My Analyzer from saleae.com has saved me many times)

Without that I would probably simplfiy the code to test out stuff. Like not use the servo values you are receiving, but maybe init both to 0, then maybe every 100ms increment them a bit until they hit some max... This way you can see if the servo outputs are working OK or is it getting corrupted...

Other things I would try is a little handshaking... That is have your RX program send back something when it processes a message and have the TX program only send something back when it receives this RESP, and or maybe some timeout to handle case where RX side did not properly receive the message. This keeps from having messages pile up and keeps from getting all of the interrupts for commands...

Kurt


Rookie ( offline )
Posts: 17
Posted: 2011-11-19 13:00 
ok, not sure why but commenting out the
Code:
 // if ((ulTimeLastMsg - ulTime) > MAX_DELAY) {
        // if we don't receive any valid message for a long time maybe we should set speeds to zero...
       // rthrust = 0;
     //   lthrust = 0;
   // }

got rid of the 0 position glitch/drive "jitter". Not sure why that piece of code isn't functioning the way it should, but I have noticed with another code attempt I was trying is that I couldn't get negative values to work correctly (mapping -255, 255 to the x/y). I really think its something w/ the arduino vs other avr(?) chips.
Now the problems with my poor attempt at channel mixing on my TX end are showing tho... :roll:


~Wolf


User avatar
Guru ( offline )
Posts: 4906
Posted: 2011-11-19 13:20 
Wolf99 wrote:
ok, not sure why but commenting out the
Code:
 if ((ulTimeLastMsg - ulTime) > MAX_DELAY) {

Note: the problem is because I screwed up :oops: ... Should be:
Code:
 if ((ulTime - ulTimeLastMsg ) > MAX_DELAY) {


Kurt


Rookie ( offline )
Posts: 17
Posted: 2011-11-19 17:10 
Well that explains why that wasn't working, I though it didn't look right but didn't do the math to see how it was suppose to work... oops
Now I have RX working fine, seems the next problem I need to look at is a better x/y to differential steering loop on the TX side.
I had a section of code that looked great but like I said before was not working due to the arduino not liking the negative values it seemed..
Any ideas?

Here it is in the rough (need to adjust a few values for the wii x/y) but I could not get it to work at all...
Code:
/*
 * WiiChuck-Servo Test with LCD output
 *v1.5 10/25/2011
 *
 *
 */

#include <Wire.h>
//#include <LiquidCrystal.h>
#include "nunchuck_funcs.h"
#define debounce 10 // ms debounce
#define holdTime 2000 // ms hold period: how long to wait for press+hold event
#define HALF_DEADBAND 3 //adjust till desired deadband is achieved
#define XRAW_CENTERED 126 // set to whatever "x joystick value is: " on the serial monitor
#define YRAW_CENTERED 129 // set to whatever "y joystick value is: " on the serial monitor
#define DEBUG false // set to false to stop serial messages


int loop_cnt=0;
int valx,valy,LEDstate;
int throttle, steering;
int xraw, yraw, leftSpd, rightSpd;
int ledPin0 = 9;
int ledPin1 = 10;
int ledPin2 = 11;
int ledPin3 = 13;
byte accx,accy,zbut,cbut,xjoy,yjoy;
//LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // LCD pins

int cbutVal = 0; // value read from button
int cbutLast = 0; // buffered value cbut previous state
int zbutVal = 0;
int zbutLast = 0;
long btnDnTime; // time the button was pressed down
long btnUpTime; // time the button was released
boolean ignoreUp = false; // whether to ignore the button release because the click+hold was triggered
boolean ledVal0 = false; // state of LED 0
boolean ledVal1 = false; // state of LED 1
boolean ledVal2 = false; // state of LED 2
boolean ledVal3 = false; // state of LED 3




void setup() {
 
    {
 
  /*pinMode(LEFT_PWM_PIN, OUTPUT);
  pinMode(RIGHT_PWM_PIN, OUTPUT); 
  pinMode(LEFT_DIRECTION_PIN, INPUT);// sets high impedance on pin, brake
  pinMode(RIGHT_DIRECTION_PIN, INPUT);// sets high impedance on pin, brake
  digitalWrite(LEFT_PWM_PIN, LOW); 
  digitalWrite(RIGHT_PWM_PIN, LOW);*/
 
    nunchuck_init(); // send the initilization handshake
    pinMode(ledPin0, OUTPUT);
    digitalWrite(ledPin0, ledVal0);
    pinMode(ledPin1, OUTPUT);
    digitalWrite(ledPin1, ledVal1);
    pinMode(ledPin2, OUTPUT);
    digitalWrite(ledPin2, ledVal2);
    pinMode(ledPin3, OUTPUT);
    digitalWrite(ledPin3, ledVal3);
   
    delay(1000);
  }
}

void loop(){
  {
    {
      if( loop_cnt > 100 ) { // every 100 msecs get new data
        loop_cnt = 0;

        nunchuck_get_data();

        accx  = nunchuck_accelx(); // ranges from approx 70 - 182
        accy  = nunchuck_accely(); // ranges from approx 65 - 173
        zbut = nunchuck_zbutton(); // 0 open 1 closed
        cbut = nunchuck_cbutton(); // 0 open 1 closed
        xjoy = nunchuck_joyx(); // ranges from aprox 29 - 224 c=127-129
        yjoy = nunchuck_joyy(); // ranges from aprox 29 - 226 c=129-132

        /*lcd.begin(16, 2);
        lcd.print("X:");lcd.print((byte)valx,DEC);lcd.write(0xdf);
        lcd.setCursor(6, 0);
        lcd.print("Y:");lcd.print((byte)valy,DEC);lcd.write(0xdf);
        lcd.setCursor(11, 0);if( cbut == HIGH){ lcd.print(" C");}
        lcd.setCursor(13,0); if( zbut == HIGH){ lcd.print(" Z");}
        lcd.setCursor(0, 1); if (ledVal1 == HIGH){lcd.print("Z Lights");}
        lcd.setCursor(9, 1); if (ledVal2 == HIGH){lcd.print("Z Armed!");
        }//End lcd out */
      }
      loop_cnt++;
      delay(1);
    }
 
  { 
    // capture joystick position
    yraw = yjoy;
    xraw = xjoy;
   
    // scale x and y axis so that both are zeroed at natural center of potentiometer, implement deadband
    if(yraw > YRAW_CENTERED + HALF_DEADBAND)//forward
    {
      throttle = map(yraw, YRAW_CENTERED + HALF_DEADBAND, 226, 0, 255);     
      if(xraw > XRAW_CENTERED + HALF_DEADBAND)//left
      {
        steering = map(xraw, XRAW_CENTERED + HALF_DEADBAND, 224, -0, -255);// reverse pot coordinates to agree with cartesian !verify wii X vals!       
      }
      else if(xraw < XRAW_CENTERED - HALF_DEADBAND)// right
      {
        steering = map(xraw, XRAW_CENTERED - HALF_DEADBAND, 0, 0, 255);// reverse pot coordinates to agree with cartesian  !verify wii X vals!       
      }
      else // in X deadband
      {
        steering = 0;
      }
    }
   
    else if(yraw < YRAW_CENTERED - HALF_DEADBAND)//reverse
    {
      throttle = map(yraw, YRAW_CENTERED - HALF_DEADBAND, 0, -0, -255);     
      if(xraw > XRAW_CENTERED + HALF_DEADBAND)//left
      {
        steering = map(xraw, XRAW_CENTERED + HALF_DEADBAND, 224, -0, -255);// reverse pot coordinates to agree with cartesian       
      }
      else if(xraw < XRAW_CENTERED - HALF_DEADBAND)// right
      {
        steering = map(xraw, XRAW_CENTERED - HALF_DEADBAND, 0, 0, 255);// reverse pot coordinates to agree with cartesian       
      }
      else// in X deadband
      {
        steering = 0;
      }
    }
    else //in Y deadband
    {
      throttle = 0;
      if(xraw > XRAW_CENTERED + HALF_DEADBAND)//left
      {
        steering = map(xraw, XRAW_CENTERED + HALF_DEADBAND, 224, -0, -255);// reverse pot coordinates to agree with cartesian       
      }
      else if(xraw < XRAW_CENTERED - HALF_DEADBAND)// right
      {
        steering = map(xraw, XRAW_CENTERED - HALF_DEADBAND, 0, 0, 255);// reverse pot coordinates to agree with cartesian       
      }
      else// in X deadband
      {
        steering = 0;
      }
    }
 
 
  rightSpd = throttle + steering; //transfer from x,y to l,r
  leftSpd = throttle - steering;
  //leftSpd and rightSpd will contain a number from -255 to 255 that gets updated each time the loop runs.
  //-255 equates to full reverse. 0 equates to anywhere within the deadband.  255 is full forward.
 
  // The next 2 sections can be replaced to use with servos, stepper motors, BLDCs or whatever drive you like.
 
/*  //write direction pin
  if (leftSpd < 0)
  digitalWrite(LEFT_DIRECTION_PIN, LOW);
  else if (leftSpd > 0)
  digitalWrite(LEFT_DIRECTION_PIN, HIGH);
   if (rightSpd < 0)
  digitalWrite(RIGHT_DIRECTION_PIN, LOW);

  else if (rightSpd > 0)
  digitalWrite(RIGHT_DIRECTION_PIN, HIGH);
 
 //write PWM pin
  analogWrite(LEFT_PWM_PIN, abs(leftSpd));
  analogWrite(RIGHT_PWM_PIN, abs(rightSpd));
 */
 
  if (DEBUG)
  {
  Serial.print("xjoy: "); Serial.print((byte)xraw,DEC);
  Serial.print("\tyjoy: "); Serial.print((byte)yraw,DEC);
  Serial.print("\tthrottle: "); Serial.print((byte)throttle,DEC);
  Serial.print("\tsteering: "); Serial.print((byte)steering,DEC);
  Serial.print("\tleftSpd: "); Serial.print((byte)leftSpd,DEC);
  Serial.print("\trightSpd: "); Serial.println((byte)rightSpd,DEC);
 
  delay(1);
  }
//End of steering loop///

//Button press&hold loop///
    {
    // Test for Cbut pressed and store the down time
    if (cbut == HIGH && cbutLast == LOW && (millis() - btnUpTime) > long(debounce)) {
      btnDnTime = millis();}
    cbutVal = cbut;// Read the state of the button
    // Test for button release and store the up time
    if (cbutVal == LOW && cbutLast == HIGH && (millis() - btnDnTime) > long(debounce)) {
      if (ignoreUp == false) eventc1();
      else ignoreUp = false;
      btnUpTime = millis();}
    // Test for button held down for longer than the hold time
    if (cbutVal == HIGH && (millis() - btnDnTime) > long(holdTime)) {
      eventc2();
      ignoreUp = true;
      btnDnTime = millis(); }
    cbutLast = cbutVal;//End of push hold C
   
    // Test for Zbut pressed and store the down time
    if (zbut == HIGH && zbutLast == LOW && (millis() - btnUpTime) > long(debounce)) {
      btnDnTime = millis();}
     zbutVal = zbut;// Read the state of the button
    // Test for button release and store the up time
    if (zbutVal == LOW && zbutLast == HIGH && (millis() - btnDnTime) > long(debounce)) {
      if (ignoreUp == false) eventz1();
      else ignoreUp = false;
      btnUpTime = millis();}
    // Test for button held down for longer than the hold time
    if (zbutVal == HIGH && (millis() - btnDnTime) > long(holdTime)) {
      eventz2();
      ignoreUp = true;
      btnDnTime = millis();}
    zbutLast = zbutVal;//End of push hold Z
  }
 }
 }
 }

// Events to trigger by click and press+hold Zbut

void eventz1(){ //Z press
  ledVal0 = !ledVal0;
  digitalWrite(ledPin0, ledVal0);
}
void eventz2(){ //Z hold
  ledVal1 = !ledVal1;
  digitalWrite(ledPin1, ledVal1);
}
void eventc1(){ //C press
  ledVal2 = !ledVal2;
  digitalWrite(ledPin2, ledVal2);
}
void eventc2(){ //C Hold
  ledVal3 = !ledVal3;
  digitalWrite(ledPin3, ledVal3);
}


User avatar
Guru ( offline )
Posts: 4906
Posted: 2011-11-19 20:22 
It would help to know what part of the code is not working. Note: signed versus unsigned math depends on types of variables... the type byte that is returned by several of the nunchuck functions returns byte values which are unsigned. But it looked like you already moved these to a signed int value...

Kurt


Rookie ( offline )
Posts: 17
Posted: 2011-11-19 23:01 
kurte wrote:
It would help to know what part of the code is not working. Note: signed versus unsigned math depends on types of variables... the type byte that is returned by several of the nunchuck functions returns byte values which are unsigned. But it looked like you already moved these to a signed int value...

Kurt


Mixing the x and y in to differential drive output (foward/ rev + left/right), the code in that last message I posted was taken from the following code, when I tried to modify it for the Wii chuck the drive output is all over the place, my best guess (is that I dont have a clue:cry:... ) it seems that the negative values are not working correctly or something... this was seen by viewing the output to serial.. If you need more detail, I'll reload the TX and log the transmission via serial...
Code:
/*
  Joystick controlled differential steer mobile robot.
  Author: Dustin Maki
  Date: Sept 1 2011
  GPL License.  Free to use, just give credit where due.
  This program scales the joystick reading to start at 1 just outside the deadband so you do not have a large jump in speed.
  It adjusts to the common case where the centered joystick does not rest at quite the center of the range.
  This was first used with
  Teensy++ v.1 http://www.pjrc.com/teensy/pinout.html
  Solarbotics LM298D H bridge http://www.solarbotics.com/products/k_cmd/
  with transistor on each side to switch the direction as in datasheet.
  Joystick http://www.sparkfun.com/products/9032 
     
*/
#define START_BUTTON 21 // not a momentary switch, a toggle switch will work
#define JOYSTICK_BUTTON_PIN 10 // hold joystick with 'tail' toward you.  side with holes on sparkfun breakout board
#define JOYSTICK_X_PIN A0 //full left is 1023, full right is 0
#define JOYSTICK_Y_PIN A1//full forward is 1023, full backward is 0
#define LEFT_PWM_PIN 14
#define LEFT_DIRECTION_PIN 13
#define RIGHT_PWM_PIN 24
#define RIGHT_DIRECTION_PIN 23
#define HALF_DEADBAND 3 //adjust till desired deadband is achieved
#define XRAW_CENTERED 525 // set to whatever "x joystick value is: " on the serial monitor
#define YRAW_CENTERED 493 // set to whatever "y joystick value is: " on the serial monitor
#define DEBUG true // set to false to stop serial messages

void setup()
{
  if (DEBUG)             
  Serial.begin(38400);
 
  pinMode(LEFT_PWM_PIN, OUTPUT);
  pinMode(RIGHT_PWM_PIN, OUTPUT); 
  pinMode(LEFT_DIRECTION_PIN, INPUT);// sets high impedance on pin, brake
  pinMode(RIGHT_DIRECTION_PIN, INPUT);// sets high impedance on pin, brake
  digitalWrite(LEFT_PWM_PIN, LOW); 
  digitalWrite(RIGHT_PWM_PIN, LOW);
}

int throttle, steering;
int xraw, yraw, leftSpd, rightSpd;

void loop()                     
{
  // start button is a push on, push off type. grounded when on
  // when start button is released, program just runs main loop
  while(digitalRead(START_BUTTON) == LOW)
  {
    if (digitalRead(JOYSTICK_BUTTON_PIN) == LOW)//brake requested
    {
      pinMode(LEFT_DIRECTION_PIN, INPUT);// sets high impedance on pin, brake
      pinMode(RIGHT_DIRECTION_PIN, INPUT);// sets high impedance on pin, brake
   
      if (DEBUG)
      {
        Serial.println("brake applied");
      }
      continue;// will not continue main loop, only while
    }
   
  else //start button pressed and not braked
  { 
    // capture joystick position
    yraw = analogRead(JOYSTICK_Y_PIN);
    xraw = analogRead(JOYSTICK_X_PIN);
   
    // scale x and y axis so that both are zeroed at natural center of potentiometer, implement deadband
    if(yraw > YRAW_CENTERED + HALF_DEADBAND)//forward
    {
      throttle = map(yraw, YRAW_CENTERED + HALF_DEADBAND, 1023, 0, 255);     
      if(xraw > XRAW_CENTERED + HALF_DEADBAND)//left
      {
        steering = map(xraw, XRAW_CENTERED + HALF_DEADBAND, 1023, -0, -255);// reverse pot coordinates to agree with cartesian       
      }
      else if(xraw < XRAW_CENTERED - HALF_DEADBAND)// right
      {
        steering = map(xraw, XRAW_CENTERED - HALF_DEADBAND, 0, 0, 255);// reverse pot coordinates to agree with cartesian       
      }
      else // in X deadband
      {
        steering = 0;
      }
    }
   
    else if(yraw < YRAW_CENTERED - HALF_DEADBAND)//reverse
    {
      throttle = map(yraw, YRAW_CENTERED - HALF_DEADBAND, 0, -0, -255);     
      if(xraw > XRAW_CENTERED + HALF_DEADBAND)//left
      {
        steering = map(xraw, XRAW_CENTERED + HALF_DEADBAND, 1023, -0, -255);// reverse pot coordinates to agree with cartesian       
      }
      else if(xraw < XRAW_CENTERED - HALF_DEADBAND)// right
      {
        steering = map(xraw, XRAW_CENTERED - HALF_DEADBAND, 0, 0, 255);// reverse pot coordinates to agree with cartesian       
      }
      else// in X deadband
      {
        steering = 0;
      }
    }
    else //in Y deadband
    {
      throttle = 0;
      if(xraw > XRAW_CENTERED + HALF_DEADBAND)//left
      {
        steering = map(xraw, XRAW_CENTERED + HALF_DEADBAND, 1023, -0, -255);// reverse pot coordinates to agree with cartesian       
      }
      else if(xraw < XRAW_CENTERED - HALF_DEADBAND)// right
      {
        steering = map(xraw, XRAW_CENTERED - HALF_DEADBAND, 0, 0, 255);// reverse pot coordinates to agree with cartesian       
      }
      else// in X deadband
      {
        steering = 0;
      }
    }
   
  //transfer from x,y to l,r
  leftSpd = throttle + steering;
  rightSpd = throttle - steering;
  //leftSpd and rightSpd will contain a number from -255 to 255 that gets updated each time the loop runs.
  //-255 equates to full reverse. 0 equates to anywhere within the deadband.  255 is full forward.
 
  // The next 2 sections can be replaced to use with servos, stepper motors, BLDCs or whatever drive you like.
 
  //write direction pin
  if (leftSpd < 0)
  digitalWrite(LEFT_DIRECTION_PIN, LOW);
  else if (leftSpd > 0)
  digitalWrite(LEFT_DIRECTION_PIN, HIGH); 
  if (rightSpd < 0)
  digitalWrite(RIGHT_DIRECTION_PIN, LOW);
  else if (rightSpd > 0)
  digitalWrite(RIGHT_DIRECTION_PIN, HIGH);
 
 //write PWM pin
  analogWrite(LEFT_PWM_PIN, abs(leftSpd));
  analogWrite(RIGHT_PWM_PIN, abs(rightSpd));
 
 
  if (DEBUG)
  {
  Serial.print("x joystick value is: ");
  Serial.println(xraw);
  Serial.print("y joystick value is: ");
  Serial.println(yraw);
  Serial.print("throttle is: ");
  Serial.println(throttle);
  Serial.print("steering is: ");
  Serial.println(steering);
  Serial.print("leftSpd is: ");
  Serial.println(leftSpd);
  Serial.print("rightSpd is: ");
  Serial.println(rightSpd);
 
  delay(250);
  }
 }
 }
}


User avatar
Guru ( offline )
Posts: 4906
Posted: 2011-11-21 12:53 
Since I happen to have an Arduino with a nunchuck hooked up (actually an Seeeduino Mega with prototype Botboarduino Mega shield and 2 nunchucks...), I decided to run your code to figure out what was going on.

Once I started running it, the problem became obvious...

If you look at some of your code like:
Code:
  Serial.print("xjoy: "); Serial.print((byte)xraw,DEC);
  Serial.print("\tyjoy: "); Serial.print((byte)yraw,DEC);
  Serial.print("\tthrottle: "); Serial.print((byte)throttle,DEC);
  Serial.print("\tsteering: "); Serial.print((byte)steering,DEC);
  Serial.print("\tleftSpd: "); Serial.print((byte)leftSpd,DEC);
  Serial.print("\trightSpd: "); Serial.println((byte)rightSpd,DEC);

You see that when you are outputting the values, such as Throttle, you are casting the value to a byte, which is an unsigned value with the range to 0-255. This more or less translates to: Serial.Print(throttle & 0xff, DEC);

So if you simply remove the casting of variables, you all of a sudden start to see both positive and negative values... On my machine I also kept the values of the previous xjoy, yjoy and only output the data when these change, that way it is easier to see how the values change without it all scrolling by real quick...

like:
Added defines:
Code:
byte xjoyPrev, yjoyPrev;


Code:
         if (DEBUG)
            {
                if ((xjoy != xjoyPrev) || (yjoy != yjoyPrev)) {
                    Serial.print("xjoy: ");
                    Serial.print(xraw,DEC);
                    Serial.print("\tyjoy: ");
                    Serial.print(yraw,DEC);
                    Serial.print("\tthrottle: ");
                    Serial.print(throttle,DEC);
                    Serial.print("\tsteering: ");
                    Serial.print(steering,DEC);
                    Serial.print("\tleftSpd: ");
                    Serial.print(leftSpd,DEC);
                    Serial.print("\trightSpd: ");
                    Serial.println(rightSpd,DEC);
                    xjoyPrev = xjoy;
                    yjoyPrev = yjoy;

                    delay(1);
                }
            }
 


Kurt


Rookie ( offline )
Posts: 17
Posted: 2011-11-21 15:59 
So, that means the code works as is, just my noob-ness outputting (byte) was stripping the negatives and trying to use variables mapped to a unsigned byte (when I first started playing with this). I see this the major drawback to trying to teach yourself how the coding work when you (I) have no idea what the basic stuff does, RTFM fail on my part... lol
Also now that I am starting to understand the processing restraints with the arduino platform have any of you thought about using the Leaf Maple micro controller?

Thanks for all the code help Kurte, I'll post back soon after I play with the code you posted and do some RTFM so I can attempt to avoid some more simple mistakes. :D


~Wolf


Rookie ( offline )
Posts: 17
Posted: 2012-05-07 01:51 
... Still trying to get this to work, Mostly still need help with the 2 axis joy input (x,y) to skid steer servo control. The code I have currently running works... sort of, steering control is next to nill, smooth radius turns do not exist. I can either get foward/back or pivot/zero space turns


Rookie ( offline )
Posts: 17
Posted: 2012-05-07 03:37 
Oh, and searching I found viewtopic.php?t=2860 , BUT... I don't understand any of the code in there :(


Rookie ( offline )
Posts: 17
Posted: 2012-06-21 01:58 
Really... The night after my new DX6I arrives because I finally decide to shelf the whole channel mixing idea I find on the web...
Code:
#include <Servo.h>

Servo servo1;
Servo servo2;
int gain1 = 2;
int gain2 = 2;
int s1= 0;
int s2= 0;

void setup()
{
// Serial.begin(115200);
servo1.attach(9); // attach Servo 1 to pin 9
servo2.attach(10); // attach Servo 2 to pin 10
pinMode(3, INPUT); // Signal 1 input at pin3 (Elevator)
pinMode(4, INPUT); // Signal 2 input at pin4 (Rudder)
}

void loop()
{
s1 = (pulseIn( 3,HIGH)-1500)/gain1;
s2 = (pulseIn( 4,HIGH) -1500)/gain2;
servo1.writeMicroseconds(s1+s2+1500);
servo2.writeMicroseconds(s1-s2+1500);
// Serial.println(s1);
}


Could it really be this simple? :roll: Seems the mixing term is Elevon wing/tail mixing which for seems to be the same mix rate/result as needed for the differential steer..


1, 2

All times are UTC - 5 hours [ DST ]. It is currently 2014-09-19 17:52
Feedback Form
Feedback Form