Map function causes servo jitter?

I am making an Airsoft turret I’m using this code that i found online along with some code in Processing,

/*

ATTACHMENT INSTRUCTIONS:
attach x-axis standard servo to digital I/O pin 5
attach y-axis standard servo to digital I/O pin 6
attach firing transistor / relay to digital I/O pin 7 (or servo that pulls trigger… see directions regarding this below)

*/

#include <Servo.h>

Servo pan; // x axis servo
Servo tilt; // y axis servo
//Servo trigger; // trigger servo - if you have a servo pulling the trigger, uncomment this line
int xPosition = 75; // ‘home’ position
int yPosition = 80; // ‘home’ position
int fire = 0; // if 1, fire; else, don’t fire
char buff= “00000000000”; // store incoming serial bytes
int serialCounter = 0; // how many frames scince last serial byte was available
int serialTimeout = 10000; // max number of frames without incoming serial before going back to idle mode

void setup(){
pan.attach(5);
tilt.attach(6);
//trigger.attach(7); // if you have a servo firing your gun, uncomment this line, and delete the next line
pinMode(7, OUTPUT); // firing transistor / relay
Serial.begin(9600);
}

void loop() {
if (Serial.available()>0) {
serialCounter = 0;
for (int i=0; i<10; i++) {
buff*=buff[i+1]; // move each serial buffer byte down one space*

  • }*

  • buff[10]=Serial.read(); // add new serial byte to end of buffer*

  • if (buff[10]==‘X’ && buff[6] == ‘F’) { // check for indicators*
    _ xPosition = (100*(int(buff[7])-48)) + (10*(int(buff[8])-48)) + (int(buff[9])-48); // previous values are coords_

  • }*

  • if (buff[10]==‘Y’ && buff[6] == ‘X’) {*
    _ yPosition = (100*(int(buff[7])-48)) + (10*(int(buff[8])-48)) + (int(buff[9])-48);_

  • }*

  • if (buff[10]==‘F’ && buff[8] == ‘Y’) {*

  • fire = int(buff[9]) - 48;*

  • }*

  • pan.write(xPosition); // send instructions to servos*

  • tilt.write(yPosition);*

  • if(fire == 1) { // firing - if your gun needs special triggering, such as semi-auto, define that behavior here.*

  • digitalWrite(7, HIGH);*

  • //trigger.write(90); // uncomment for firing servo, and delete previous line*

  • }*

  • else{*

  • digitalWrite(7, LOW);*

  • //trigger.write(110); // same as above*

  • }*

  • }*

  • else{*

  • serialCounter++; // timeout check (safety feature)*

  • if(serialCounter > serialTimeout) { // go into idle mode after serial counter timeout*

  • pan.write(75);*

  • tilt.write(150);*

  • //trigger.write(140); // see above directions regarding servos for firing*

  • digitalWrite(7, LOW);*

  • serialCounter = serialTimeout+1;*

  • }*

  • else{ // if just a momentary pause:*

  • pan.write(xPosition); // continue with previous actions*

  • tilt.write(yPosition);*

  • if(fire == 1) {*

  • //trigger.write(90); // see above directions regarding servos for firing*

  • digitalWrite(7, HIGH); // firing relay*

  • }*

  • else{*

  • //trigger.write(110); // see above directions regarding servos for firing*

  • digitalWrite(7, LOW); // firing relay*

  • }*

  • }*

  • }*
    }
    But when i used it, I found that the x axis (pan) servo was moving inverse of the direction i wanted it to go. to fix that i added this line of code:
    xPosition = map(xPosition, 0, 180, 180, 0);
    and the new code was this:
    /*
    ----------------TURRET VERSION 4 CODE V09---------------
    ========================================================
    Bob Rudolph

For upload onto arduino board

ATTACHMENT INSTRUCTIONS:
attach x-axis standard servo to digital I/O pin 5
attach y-axis standard servo to digital I/O pin 6
attach firing transistor / relay to digital I/O pin 7 (or servo that pulls trigger… see directions regarding this below)

*/
#include <Servo.h>
Servo pan; // x axis servo
Servo tilt; // y axis servo
//Servo trigger; // trigger servo - if you have a servo pulling the trigger, uncomment this line
int xPosition = 75; // ‘home’ position
int yPosition = 80; // ‘home’ position
int fire = 0; // if 1, fire; else, don’t fire
char buff[]= “00000000000”; // store incoming serial bytes
int serialCounter = 0; // how many frames scince last serial byte was available
int serialTimeout = 10000; // max number of frames without incoming serial before going back to idle modeca
void setup(){

  • pan.attach(5);*
  • tilt.attach(6);*
  • //trigger.attach(7); // if you have a servo firing your gun, uncomment this line, and delete the next line*
  • pinMode(7, OUTPUT); // firing transistor / relay*
  • Serial.begin(9600);*
    }
    *void loop() { *
  • if (Serial.available()>0) {*
  • serialCounter = 0;*
  • for (int i=0; i<10; i++) { *
    _ buff*=buff[i+1]; // move each serial buffer byte down one space*_
    * }*
    * buff[10]=Serial.read(); // add new serial byte to end of buffer*
    * if (buff[10]==‘X’ && buff[6] == ‘F’) { // check for indicators*
    _ xPosition = (100*(int(buff[7])-48)) + (10*(int(buff[8])-48)) + (int(buff[9])-48); // previous values are coords_
    * }*
    * if (buff[10]==‘Y’ && buff[6] == ‘X’) {*
    _ yPosition = (100*(int(buff[7])-48)) + (10*(int(buff[8])-48)) + (int(buff[9])-48);
    * }*
    * if (buff[10]==‘F’ && buff[8] == ‘Y’) {*
    * fire = int(buff[9]) - 48;*
    * }*
    xPosition = map(xPosition, 0, 180, 180, 0); _

    * pan.write(xPosition); // send instructions to servos*
    * tilt.write(yPosition);*
    * if(fire == 1) { // firing - if your gun needs special triggering, such as semi-auto, define that behavior here.*
    * digitalWrite(7, HIGH);*
    * //trigger.write(90); // uncomment for firing servo, and delete previous line*
    * }*
    * else{*
    * digitalWrite(7, LOW);*
    * //trigger.write(110); // same as above*
    * }*
    * }*
    * else{*
    * serialCounter++; // timeout check (safety feature)*
    * if(serialCounter > serialTimeout) { // go into idle mode after serial counter timeout*
    * pan.write(75);*
    * tilt.write(150);*
    * //trigger.write(140); // see above directions regarding servos for firing*
    * digitalWrite(7, LOW);*
    * serialCounter = serialTimeout+1;*
    * }*
    * else{ // if just a momentary pause:*
    * pan.write(xPosition); // continue with previous actions*
    * tilt.write(yPosition);*
    * if(fire == 1) {*
    * //trigger.write(90); // see above directions regarding servos for firing*
    * digitalWrite(7, HIGH); // firing relay*
    * }*
    * else{*
    * //trigger.write(110); // see above directions regarding servos for firing*
    * digitalWrite(7, LOW); // firing relay*
    * }*
    * }*
    * }*
    }
    Although the new code worked, it also added jitter to my x axis.
    How can I fix that? Also, is there another way to invert my x axis servo in this code? I’m sorry if this is a very stupid question, but i am very new to the Arduino.

I think this would be easier:

xPosition = 180 - xPosition;

The map function does 32-bit arithmetic, including division, so it is relatively "slow". Perhaps that is causing the jitter.

http://www.ruggedcircuits.com

I agree that 32 bit division is slow, but in the context of a servo update time frame of 20ms on a 16MHz processor, this doesn't seem that likely

So, i tried your code and it still gave me jitter.. I would put it in the same place of the map function, correct? I think i need to make a new integer and make that equal to 180 - xPosition

for example

xAxis = 180 - x Position

My bad, i tried adding the code in a different location and now it works perfectly! You guys are Awesome!!

question: What do i do, now that my question is answered? Do I delete the post?

No, don't delete, please - others may find it useful.

As AWOL said, leave it to others to find, and maybe post the final working code, so others can see what you did :)

Heres the end product of the code:

/*
----------------TURRET VERSION 4 CODE V09---------------

Bob Rudolph

For upload onto arduino board

ATTACHMENT INSTRUCTIONS:
attach x-axis standard servo to digital I/O pin 5
attach y-axis standard servo to digital I/O pin 6
attach firing transistor / relay to digital I/O pin 7 (or servo that pulls trigger… see directions regarding this below)

*/

#include <Servo.h>

Servo pan; // x axis servo
Servo tilt; // y axis servo
//Servo trigger; // trigger servo - if you have a servo pulling the trigger, uncomment this line
int xPosition = 75; // ‘home’ position
int yPosition = 80; // ‘home’ position
int fire = 0; // if 1, fire; else, don’t fire
char buff= “00000000000”; // store incoming serial bytes
int serialCounter = 0; // how many frames scince last serial byte was available
int serialTimeout = 10000; // max number of frames without incoming serial before going back to idle modeca

void setup(){
pan.attach(5);
tilt.attach(6);
//trigger.attach(7); // if you have a servo firing your gun, uncomment this line, and delete the next line
pinMode(7, OUTPUT); // firing transistor / relay
Serial.begin(9600);
}

void loop() {
if (Serial.available()>0) {
serialCounter = 0;
for (int i=0; i<10; i++) {
buff*=buff[i+1]; // move each serial buffer byte down one space*

  • }*
  • buff[10]=Serial.read(); // add new serial byte to end of buffer*
  • if (buff[10]==‘X’ && buff[6] == ‘F’) { // check for indicators*
    _ xPosition = (100*(int(buff[7])-48)) + (10*(int(buff[8])-48)) + (int(buff[9])-48); // previous values are coords_
  • xPosition = 180 - xPosition;*
  • }*
  • if (buff[10]==‘Y’ && buff[6] == ‘X’) {*
    _ yPosition = (100*(int(buff[7])-48)) + (10*(int(buff[8])-48)) + (int(buff[9])-48);_
  • }*
  • if (buff[10]==‘F’ && buff[8] == ‘Y’) {*
  • fire = int(buff[9]) - 48;*
  • } *
  • pan.write(xPosition); // send instructions to servos*
  • tilt.write(yPosition);*
  • if(fire == 1) { // firing - if your gun needs special triggering, such as semi-auto, define that behavior here.*
  • digitalWrite(7, HIGH);*
  • //trigger.write(90); // uncomment for firing servo, and delete previous line*
  • }*
  • else{*
  • digitalWrite(7, LOW);*
  • //trigger.write(110); // same as above*
  • }*
  • }*
  • else{*
  • serialCounter++; // timeout check (safety feature)*
  • if(serialCounter > serialTimeout) { // go into idle mode after serial counter timeout*
  • pan.write(75);*
  • tilt.write(150);*
  • //trigger.write(140); // see above directions regarding servos for firing*
  • digitalWrite(7, LOW);*
  • serialCounter = serialTimeout+1;*
  • }*
  • else{ // if just a momentary pause:*
  • pan.write(xPosition); // continue with previous actions*
  • tilt.write(yPosition);*
  • if(fire == 1) {*
  • //trigger.write(90); // see above directions regarding servos for firing*
  • digitalWrite(7, HIGH); // firing relay*
  • }*
  • else{*
  • //trigger.write(110); // see above directions regarding servos for firing*
  • digitalWrite(7, LOW); // firing relay*
  • }*
  • }*
  • }*
    }
    Go to http://code.google.com/p/airsoft-sentry-gun/ for more information on building the airsoft sentry turret