Trossen Accelerometer Gyro Top Banner
Results 1 to 8 of 8

Thread: Arduino- xbee -xbee-arduino - stepper motors

  1. #1

    Arduino- xbee -xbee-arduino - stepper motors

    Hi folks.

    I am trying to control a stepper motor (5 eventually) over xbee pro 900's. I have a motion controller that outputs step and direction signals. I am trying to read these into an arduino mega (because eventualy i'll need to reed inputs for 5 steppers) connected to an xbee pro 900 then send a character for each input pin depending whether it is high or low. These characters are received by the other xbee connected to a second arduino mega which reads the characters then sets the step and direction output pins connected to the stepper motor controller either high or low accordingly.

    I have it kind of working but the motor responds very erratically when controlled through the arduino wireless link but works ine f the main controller is connected direct to the stepper driver without the rduino xbee combo.

    I'll post my code when I can get on my computer but it is vey simple ie:
    read input pins high or low
    Assign character a if high, b if low.
    Serial print characters

    Serial read characters
    Set output pins high or low depending on character read.

    Arduino and xbees set to matching high baud rate of 11200bps

    Has any had any success with this kind of set up and have any sample code I can play with. Any thoughts or input old be appreciated.

  2. #2
    Join Date
    May 2008
    Posts
    2,227
    Images
    155
    Rep Power
    109

    Re: Arduino- xbee -xbee-arduino - stepper motors

    Reliable data transmission is not guarunteed over wireless radios, even XBEEs. If properly paired the XBEEs will attempt to resend data up to three times -- however this depends on there being extra time available to resend, I don't know how much data you are sending at 115200bps (I assume, 112k sounds kinda weird), but if you are basically saturating the channel, there won't be much overhead left for the hardware to try resending in.

    Regardless of hardware resend, it is a good idea to come up with a packet structure that allows some way of determining if a packet is corrupt. The simplest approach is to simply add a packet header and then a checksum. The checksum ensures that a packet is at least correct, or very specially corrupted. The packet header will help you restart if a packet is corrupted due to dropped byte(s). For instance, bioloid and many of the ArbotiX/Commander protocols use a double '0xff 0xff' at the start of each packet, as that is value rarely seen within a 'good' packet, and then have a simple checksum byte at the end.

    -Fergs

  3. #3

    Re: Arduino- xbee -xbee-arduino - stepper motors

    Thanks for the feedback. I am not a programmer so am learning step by step with this.

    here is my Transmitter code. It is assembled from other code snippets hence many of the commented out sections. As it is it communicates but the results aren't right at the RX end in terms of the stepper motor response. I'll post the Receiver code next.


    Code:
     // This program sends information from a MaxStream XBee radio.
    
    // serial out is on port 1
    // serial in is on port 0
    
    
    // a digital input is on ports 2 to 13
    
    
    int switchPin2 = 2;
    int switchPin3 = 3;
    int switchPin4 = 4;
    int switchPin5 = 5;
    int switchPin6 = 6;
    int switchPin7 = 7;
    int switchPin8 = 8;
    int switchPin9 = 9;
    int switchPin10 = 10;
    int switchPin11 = 11;
    int switchPin12 = 12;
    int switchPin13 = 13;
    int ledPin = 39;
    
    
    
    
    // a byte to send out data:
    char thisByte2 = 0;
    char thisByte3 = 0;
    char thisByte4 = 0;
    char thisByte5 = 0;
    char thisByte6 = 0;
    char thisByte7 = 0;
    char thisByte8 = 0;
    char thisByte9 = 0;
    char thisByte10 = 0;
    char thisByte11 = 0;
    char thisByte12 = 0;
    char thisByte13 = 0;
    void setup () {
    // set pins to input and output appropriately
    pinMode(switchPin2, INPUT);
    digitalWrite(switchPin2, HIGH);
    pinMode(switchPin3, INPUT);
    digitalWrite(switchPin3, HIGH);
    pinMode(switchPin4, INPUT);
    digitalWrite(switchPin4, HIGH);
    pinMode(switchPin5, INPUT);
    digitalWrite(switchPin5, HIGH);
    pinMode(switchPin6, INPUT);
    digitalWrite(switchPin6, HIGH);
    pinMode(switchPin7, INPUT);
    digitalWrite(switchPin7, HIGH);
    pinMode(switchPin8, INPUT);
    digitalWrite(switchPin8, HIGH);
    pinMode(switchPin9, INPUT);
    digitalWrite(switchPin9, HIGH);
    pinMode(switchPin10, INPUT);
    digitalWrite(switchPin10, HIGH);
    pinMode(switchPin11, INPUT);
    digitalWrite(switchPin11, HIGH);
    pinMode(switchPin12, INPUT);
    digitalWrite(switchPin12, HIGH);
    pinMode(switchPin13, INPUT);
    digitalWrite(switchPin13, HIGH);
    pinMode(ledPin, OUTPUT);
    // start up the serial connection with 19200-8-n-1-true (non-inverted):
    Serial.begin(230400);
    
    
    /*
    
    
    // for some reason it seems to help to send an arbitrary character first
    //then pause for the guard time before requesting command mode
    Serial.print("X");
    delay(1100);
    // put the XBee in command mode
    Serial.print("+++");
    delay(1100);
    // wait for a response from the XBee for 2000 ms, or start
    // over with setup if no valid response comes
    
    
    
    
    if (returnedOK() == 'T') {
    // if an OK was received then continue
    }
    else {
    setup(); // otherwise go back and try setup again
    }
    
    
    
    
    
    
    // set the PAN (personal area network) ID number
    // this example uses 0x3330, but you'll want to choose your own
    // unique hexadecimal number between 0x0 and 0xFFFE
    // (note the comma at the end of the command which indicates that another command will follow)
    Serial.print("ATID1111,");
    // set the Destination High to 0x0
    // to select 16 bit addressing mode. These addresses can
    // be assigned and changed by sending commands from a microcontroller
    Serial.print("DH13A200,");
    // set the Destination Low (16 bit address)
    // this example uses 0x0 for send and 0x1 for receive but you'll
    // want to choose your own hexadecimal numbers between 0x0 and 0xFFFE
    
    
    Serial.print("DL405319E8,");
    // exit command mode (note that we use Serial.printLN here to issue a linefeed that completes the command sequence)
    Serial.println("CN");
    
    
    // the preceeding commands can also be sent on a single line like this, using a single AT command with commas:
    // Serial.println("ATID3330,DH0,DL1,CN");
    
    
    // the preceeding command line could also be sent as separate commands, by reissuing the AT command:
    // Serial.println("ATID3330");
    // Serial.println("ATDH0");
    // Serial.println("ATDL1");
    // Serial.println("ATCN");
    
    
    // wait for a response from the XBee for 2000 ms, or start
    // over with setup if no valid response comes
    
    
    if (returnedOK() == 'T') {
    // if an OK was received then continue
    }
    else {
    setup(); // otherwise go back and try setup again
    }*/
    
    
    }
    
    
    
    
    void loop () {
    // read the switch:
    thisByte2 = digitalRead(switchPin2);
    // convert it to a readable ASCII value, send it out the serial port:
    //delay(1);
    if (thisByte2 == 0) {
    thisByte2 = 'a'; 
    digitalWrite (ledPin, HIGH);}
    else{
    digitalWrite (ledPin, LOW);}
    if (thisByte2 == 1) {
    thisByte2 = 'b';
    digitalWrite (ledPin, LOW);}
    else{
      
    digitalWrite (ledPin, HIGH);}
    Serial.print(thisByte2);
    
    
    
    
    thisByte3 = digitalRead(switchPin3);
    //delay(1);
    if (thisByte3 == 0) {
    thisByte3 = 'c'; 
    }
    if (thisByte3 == 1) {
    thisByte3 = 'd';
    }
    Serial.print(thisByte3);
    
    
    thisByte4 = digitalRead(switchPin4);
    //delay(1);
    if (thisByte4 == 0) {
    thisByte4 = 'e'; }
    if (thisByte4 == 1) {
    thisByte4 = 'f';}
    Serial.print(thisByte4);
    
    
    delay(5);
    /*
    thisByte5 = digitalRead(switchPin5);
    // delay(20);
    if (thisByte5 == 0) {
    thisByte5 = 'g'; }
    if (thisByte5 == 1) {
    thisByte5 = 'h';}
    Serial.print(thisByte5);
    
    
    thisByte6 = digitalRead(switchPin6);
    // delay(20);
    if (thisByte6 == 0) {
    thisByte6 = 'i'; }
    if (thisByte6 == 1) {
    thisByte6 = 'j';}
    Serial.print(thisByte6);
    
    
    thisByte7 = digitalRead(switchPin7);
    // delay(20);
    if (thisByte7 == 0) {
    thisByte7 = 'k'; }
    if (thisByte7 == 1) {
    thisByte7 = 'l';}
    Serial.print(thisByte7);
    
    
    thisByte8 = digitalRead(switchPin8);
    // delay(20);
    if (thisByte8 == 0) {
    thisByte8 = 'm'; }
    if (thisByte8 == 1) {
    thisByte8 = 'n';}
    Serial.print(thisByte8);
    
    
    thisByte9 = digitalRead(switchPin9);
    // delay(20);
    if (thisByte9 == 0) {
    thisByte9 = 'o'; }
    if (thisByte9 == 1) {
    thisByte9 = 'p';}
    Serial.print(thisByte9);
    
    
    thisByte10 = digitalRead(switchPin10);
    // delay(20);
    if (thisByte10 == 0) {
    thisByte10 = 'q'; }
    if (thisByte10 == 1) {
    thisByte10 = 'r';}
    Serial.print(thisByte10);
    
    
    thisByte11 = digitalRead(switchPin11);
    // delay(20);
    if (thisByte11 == 0) {
    thisByte11 = 's'; }
    if (thisByte11 == 1) {
    thisByte11 = 't';}
    Serial.print(thisByte11);
    
    
    thisByte12 = digitalRead(switchPin12);
    // delay(20);
    if (thisByte12 == 0) {
    thisByte12 = 'u'; }
    if (thisByte12 == 1) {
    thisByte12 = 'v';}
    Serial.print(thisByte12);
    
    
    thisByte13 = digitalRead(switchPin13);
    // delay(20);
    if (thisByte13 == 0) {
    thisByte13 = 'w'; }
    if (thisByte13 == 1) {
    thisByte13 = 'x';}
    Serial.print(thisByte13);
    */
    }
    
    
    
    
    /*
    char returnedOK () {
    // this function checks the response on the serial port to see if it was an "OK" or not
    char incomingChar[3];
    char okString[] = "OK";
    char result = 'n';
    int startTime = millis();
    while (millis() - startTime < 2000 && result == 'n') { // use a timeout of 10 seconds
    if (Serial.available() > 1) {
    // read three incoming bytes which should be "O", "K", and a linefeed:
    for (int i=0; i<3; i++) {
    incomingChar[i] = Serial.read();
    }
    if ( strstr(incomingChar, okString) != NULL ) { // check to see if the respose is "OK"
     if (incomingChar[0] == 'O' && incomingChar[1] == 'K') //{ // check to see if the first two characters are "OK"
    result = 'T'; // return T if "OK" was the response
    }
    else {
    result = 'F'; // otherwise return F
    }
    }
    }
    return result;
    }
    */

  4. Trossen Hexapod  Thread Banner
  5. #4

    Re: Arduino- xbee -xbee-arduino - stepper motors

    here is the receiver code. baud rate is set at highest rate listed in xbee config in x-ctu however I am sure I was using 19200 and 115200, on separate tests, in the sketch uploaded to the arduinos. I am hoping some simple coding fix will help the comms process as I am sure that it should be quite possible to control steppers via xbee like this as I already have a set up which uses them for wireless control of dc motors. If the code looks alright then maybe I need to review my connections, etc.


    Code:
    // This program receives information from a MaxStream XBee radio.
    
    
    // serial out is on port 1
    // serial in is on port 0
    
    
    
    
    int outputPin2 = 2;
    int outputPin3 = 3;
    int outputPin4 = 4;
    int outputPin5 = 5;
    int outputPin6 = 6;
    int outputPin7 = 7;
    int outputPin8 = 8;
    int outputPin9 = 9;
    int outputPin10 = 10;
    int outputPin11 = 11;
    int outputPin12 = 12;
    int outputPin13 = 13;
    
    
    
    
    
    
    // a byte to receive data:
    
    
    
    
    char inByte = 0;
    char inByte2 = 0;
    char inByte3 = 0;
    char inByte4 = 0;
    char inByte5 = 0;
    char inByte6 = 0;
    char inByte7 = 0;
    char inByte8 = 0;
    char inByte9 = 0;
    char inByte10 = 0;
    char inByte11 = 0;
    char inByte12 = 0;
    char inByte13 = 0;
    
    
    
    
    
    
    void setup () {
    // set pins to input and output appropriately
    
    
    
    
    pinMode(outputPin2, OUTPUT);
    pinMode(outputPin3, OUTPUT);
    pinMode(outputPin4, OUTPUT);
    pinMode(outputPin5, OUTPUT);
    pinMode(outputPin6, OUTPUT);
    pinMode(outputPin7, OUTPUT);
    pinMode(outputPin8, OUTPUT);
    pinMode(outputPin9, OUTPUT);
    pinMode(outputPin10, OUTPUT);
    pinMode(outputPin11, OUTPUT);
    pinMode(outputPin12, OUTPUT);
    pinMode(outputPin13, OUTPUT);
    
    
    
    
    // start up the serial connection with 19200-8-n-1-true (non-inverted):
    Serial.begin(230400);
    
    
    /*
    // for some reason it seems to help to send an arbitrary character first
    //then pause for the guard time before requesting command mode
    Serial.print("X");
    delay(1100);
    // put the XBee in command mode
    Serial.print("+++");
    delay(1100);
    // wait for a response from the XBee for 2000 ms, or start
    // over with setup if no valid response comes
    
    
    
    
    if (returnedOK() == 'T') {
    // if an OK was received then continue
    }
    else {
    setup(); // otherwise go back and try setup again
    }
    
    
    
    
    
    
    // set the PAN (personal area network) ID number
    // this example uses 0x3330, but you'll want to choose your own
    // unique hexadecimal number between 0x0 and 0xFFFE
    // (note the comma at the end of the command which indicates that another command will follow)
    Serial.print("ATID3330,");
    // set the MY (16 bit address)
    // this example uses 0x0 for send and 0x1 for receive but you'll
    // want to choose your own hexadecimal numbers between 0x0 and 0xFFFE
    Serial.print("DH13A200,");
    
    
    Serial.print("DL405319E8,");
    // exit command mode (note that we use Serial.printLN here to issue a linefeed that completes the command sequence)
    Serial.println("CN");
    
    
    // the preceeding commands can also be sent on a single line like this, using a single AT command with commas:
    // Serial.println("ATID3330,MY1,CN");
    
    
    // the preceeding command line could also be sent as separate commands, by reissuing the AT command:
    // Serial.println("ATID3330");
    // Serial.println("ATMY1");
    // Serial.println("ATCN");
    
    
    // wait for a response from the XBee for 2000 ms, or start
    // over with setup if no valid response comes
    
    
    if (returnedOK() == 'T') {
    // if an OK was received then continue
    }
    else {
    setup(); // otherwise go back and try setup again
    }
    */
    }
    
    
    
    
    void loop () {
    // get any incoming data:
    if (Serial.available() > 1) {
    // read a byte
    inByte = Serial.read();
    Serial.print(inByte);
    // light the LED if a 1 has been received
    if (inByte == 'a') {
    digitalWrite(outputPin2, HIGH);
    }
    if (inByte == 'b') {
    digitalWrite(outputPin2, LOW);
    }
    
    
    
    
    if (inByte == 'c') {
    digitalWrite(outputPin3, HIGH);
    }
    if (inByte == 'd'){
    digitalWrite(outputPin3, LOW);
    }
    
    
    
    
    if (inByte == 'e') {
    digitalWrite(outputPin4, HIGH);
    }
    if (inByte == 'f'){
    digitalWrite(outputPin4, LOW);
    }
    
    
    /*
    if (inByte == 'g') {
    digitalWrite(outputPin5, LOW);
    }
    if (inByte == 'h'){
    digitalWrite(outputPin5, HIGH);
    }
    
    
    
    
    if (inByte == 'i') {
    digitalWrite(outputPin6, LOW);
    }
    if (inByte == 'j'){
    digitalWrite(outputPin6, HIGH);
    }
    
    
    
    
    if (inByte == 'k') {
    digitalWrite(outputPin7, LOW);
    }
    if (inByte == 'l'){
    digitalWrite(outputPin7, HIGH);
    }
    
    
    
    
    if (inByte == 'm') {
    digitalWrite(outputPin8, LOW);
    }
    if (inByte == 'n'){
    digitalWrite(outputPin8, HIGH);
    }
    
    
    
    
    if (inByte == 'o') {
    digitalWrite(outputPin9, LOW);
    }
    if (inByte == 'p'){
    digitalWrite(outputPin9, HIGH);
    }
    
    
    
    
    if (inByte == 'q') {
    digitalWrite(outputPin10, LOW);
    }
    if (inByte == 'r'){
    digitalWrite(outputPin10, HIGH);
    }
    
    
    
    
    if (inByte == 's') {
    digitalWrite(outputPin11, LOW);
    }
    if (inByte == 't'){
    digitalWrite(outputPin11, HIGH);
    }
    
    
    
    
    if (inByte == 'u') {
    digitalWrite(outputPin12, LOW);
    }
    if (inByte == 'v'){
    digitalWrite(outputPin12, HIGH);
    }
    
    
    
    
    if (inByte == 'w') {
    digitalWrite(outputPin13, LOW);
    }
    if (inByte == 'x'){
    digitalWrite(outputPin13, HIGH);
    }
    
    
    }*/
    }
    
    
    /*
    
    
    void blinkLED(int targetPin, int numBlinks) {
    // this function blinks the status LED light as many times as requested
    for (int i=0; i;){
    digitalWrite(targetPin, HIGH); // sets the LED on
    delay(250); // waits for a second
    digitalWrite(targetPin, LOW); // sets the LED off
    delay(250);
    }*/
    }
    
    
    /*
    char returnedOK () {
    // this function checks the response on the serial port to see if it was an "OK" or not
    char incomingChar[3];
    char okString[] = "OK";
    char result = 'n';
    int startTime = millis();
    while (millis() - startTime < 2000 && result == 'n') { // use a timeout of 10 seconds
    if (Serial.available() > 1) {
    // read three incoming bytes which should be "O", "K", and a linefeed:
    for (int i=0; i<3; i++) {
    incomingChar[i] = Serial.read();
    }
    if ( strstr(incomingChar, okString) != NULL ) { // check to see if the respose is "OK"
    // if (incomingChar[0] == 'O' && incomingChar[1] == 'K') { // check to see if the first two characters are "OK"
    result = 'T'; // return T if "OK" was the response
    }
    else {
    result = 'F'; // otherwise return F
    }
    }
    }
    return result; 
    }*/

  6. #5

    Re: Arduino- xbee -xbee-arduino - stepper motors

    Any further suggestions fom anyone? I understand the notion of sending data packets and allowing verification of data sent/received however I am not a programmer, just finding my way, so any code samples or snippets I can add to my odes above or modify to suit my needs would be really appreciated.

  7. #6
    Join Date
    Apr 2012
    Posts
    1,787
    Images
    25
    Rep Power
    57

    Re: Arduino- xbee -xbee-arduino - stepper motors

    I think you want to work at a much higher level of abstraction. For example, you can have a "current position." Make "current position" simply be incremented by one when stepping "forward" and decremented by one when stepping "backward."

    Now, the sending Xbee can keep sending what you want the current position to be at a reasonable rate (20 times a second?) and the receiver can send back what it thinks the current position is, for read/back or control.

    The code becomes very simple. Below is some example code I typed into the forum -- it may not exactly compile, but should be illustrative:

    Code:
    unsigned int curPos = 0;
    unsigned int targetPos = 0;
    int every_n = 0;
    void loop() {
      unsigned int recvPos = 0;
      if (receive_packet(&recvPos)) {
        targetPos = recvPos;
      }
      if (++every_n == 20) {
        send_packet(curPos);
        every_n = 0;
      }
      if (curPos != targetPos) {
        if (targetPos - curPos < curPos - targetPos) {
          step_forward();
          ++curPos;
        }
        else {
          step_backward();
          --curPos;
        }
      }
      sleep(3); // or whatever your limited step rate is
    }
    The code makes use of the fact that unsigned integers wrap between max-value and 0 when you increment/decrement.

    The business of curPos-targetPos and vice versa uses a property of unsigned math to figure out which direction is the "close" direction to move in.

    receive_packet() will have to buffer (remember) incoming data until it has a full packet, and only return the packet at that time. Easiest is to use a packet delimiter -- say, every packet ends with the character 13 (CR.)

  8. #7

    Re: Arduino- xbee -xbee-arduino - stepper motors

    Ah that makes a lot of sense. I assume that code snippet should be deployed in the RX arduino and that each motor would need its own targetPos and currentPos variables and associated code.

    As I say I am not a software person so learning as I go. Appreciate all the help.

  9. #8
    Join Date
    Apr 2012
    Posts
    1,787
    Images
    25
    Rep Power
    57

    Re: Arduino- xbee -xbee-arduino - stepper motors

    Quote Originally Posted by Icemonkey View Post
    I assume that code snippet should be deployed in the RX arduino and that each motor would need its own targetPos and currentPos variables and associated code.
    You assume correctly :-)

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Question(s) Xbee and its PWM out
    By rnpnick in forum Robotics General Discussion
    Replies: 1
    Last Post: 01-01-2011, 09:19 PM
  2. Xbee socket
    By Resilient in forum Robotics General Discussion
    Replies: 5
    Last Post: 05-25-2009, 12:19 PM
  3. Question(s) Replacing stepper motors with servos on ptz
    By broadband155 in forum Arbotix, Microcontrollers, Arduino
    Replies: 4
    Last Post: 04-09-2009, 08:37 PM
  4. Xbee woes
    By Rift in forum Arbotix, Microcontrollers, Arduino
    Replies: 16
    Last Post: 03-05-2009, 03:54 PM
  5. PVision library for Arduino (Pixart/Wiimote to Arduino)
    By shobley in forum Robot Computers
    Replies: 1
    Last Post: 03-01-2009, 05:07 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •