MicroTrac Controller v17.10/Code

From Open Source Ecology
Jump to: navigation, search

Goals

  • Establish serial communication over xbee radio
  • Transmit commands from the "remote controller" box to "onboard controller" box.
  • Attempt to run identical arduino control software on both boxes.
    • Will run in onboard mode if jumper set between defined pins.
  • When in onboard mode, transmit GPS location.
  • Boxes will ping each other and will shut down if connection lost.
  • Store radio information in EEPROM. Update on startup.
    • Create a program to define the EEPROM
  • Operate relay switches when "HAND" switch is on
  • Test different turning methods.
    • stop and turn
    • fether on/off to turn on a curve
      • is this too jerky
    • determine turn radius at specified duty cycles

Usage Notes

when uploading new arduino sketches while the xbee radio is attached to the mega board, make sure that the switch on the xbee shield is in the "USB" position.

Terms, Pins and Variables

Each Solenoid and corresponding relay switch will be defined by a single alphabet letter.

A - Left Track Forward
B - Left Track Backward
C - Right Track Forward
D - Right Track Backward
E - Arms Up
F - Arms Down
G - Bucket Up
H - Bucket Down

AT Commands

xbee AT Command PDF

ATIDXXXX - set radio network ID
ATWR - save settings to long term memory

Code Theory

When a switch is thrown, its letter followed by a 1 or 0 will be transmitted over serial.

example: "E1" will engage the solenoid to raise the arms. "E0" will turn off the solenoid and will stop raising the arms.
While "F1" will lower the arms and "F0" will stop lowering the arms.

If vehicle is stopped, gather and transmit position and orientation data. otherwise briefly stop vehicle every X minutes.

  • might try sending commands all together like "abCdefgh". then after read, flush all serial available to get a fresh serial data set

Code

Controller Box


//name pins for easy use thoughout code
//"read" pins for switches
int pLF = 39; //left track forward
int pLB = 41; //left track backward
int pRF = 43; //right track forward
int pRB = 45; //right track backward
int pAU = 47; //arms up
int pAD = 49; //arms down
int pBU = 51; //bucket up
int pBD = 53; //bucket down

//"write" pins to control relay module
int rLF = 38; //left track forward
int rLB = 40; //left track backward
int rRF = 42; //right track forward
int rRB = 44; //right track backward
int rAU = 46; //arms up
int rAD = 48; //arms down
int rBU = 50; //bucket up
int rBD = 52; //bucket down

//to handle data of current state of a switch
int sLF = digitalRead(39); //left track forward
int sLB = digitalRead(41); //left track backward
int sRF = digitalRead(43); //right track forward
int sRB = digitalRead(45); //right track backward
int sAU = digitalRead(47); //arms up
int sAD = digitalRead(49); //arms down
int sBU = digitalRead(51); //bucket up
int sBD = digitalRead(53); //bucket down

//to temporarily remember the last broadcast data for each switch
int bLF; //left track forward
int bLB; //left track backward
int bRF; //right track forward
int bRB; //right track backward
int bAU; //arms up
int bAD; //arms down
int bBU; //bucket up
int bBD; //bucket down

boolean freshb = false; //keep track of weather a new broadcast has been send each loop
int freshc = 0; //keep track of last fresh broadcast
int freshf = 1; // flip bit to send different message each time
int fresho = 30; // number of loops to run before sending signal. might change code later to be based on watchdog timer

void setup() {

//SET PINS AS INPUT FROM TOGGLE SWITCHES
pinMode(pLF,INPUT_PULLUP); //LF
pinMode(pLB,INPUT_PULLUP); //LB
pinMode(pRF,INPUT_PULLUP); //RF
pinMode(pRB,INPUT_PULLUP); //RB
pinMode(pAU,INPUT_PULLUP); //AU
pinMode(pAD,INPUT_PULLUP); //AD
pinMode(pBU,INPUT_PULLUP); //BU
pinMode(pBD,INPUT_PULLUP); //BD

//SET PINS AS OUTPUT TO RELAY MODULE

pinMode(rLF, OUTPUT);
pinMode(rLB, OUTPUT);
pinMode(rRF, OUTPUT);
pinMode(rRB, OUTPUT);
pinMode(rAU, OUTPUT);
pinMode(rAD, OUTPUT);
pinMode(rBU, OUTPUT);
pinMode(rBD, OUTPUT);

//START COMMUNICATING WITH XBEE
Serial.begin(9600);
}

void loop() {

freshb = false;

sLF = digitalRead(pLF);
if (sLF != bLF) {
if (sLF == LOW) {
    Serial.print('A');
    bLF = LOW;
  } else {
    Serial.print('a');
    bLF = HIGH;
  }
  freshb = true;
}

sLB = digitalRead(pLB);
if (sLB != bLB) {
if (sLB == LOW) {
    Serial.print('B');
    bLB = LOW;
  } else {
    Serial.print('b');
    bLB = HIGH;
  }
  freshb = true;
}

sRF = digitalRead(pRF);
if (sRF != bRF) {
if (sRF == LOW) {
    Serial.print('C');
    bRF = LOW;
  } else {
    Serial.print('c');
    bRF = HIGH;
  }
  freshb = true;
}

sRB = digitalRead(pRB);
if (sRB != bRB) {
if (sRB == LOW) {
    Serial.print('D');
    bRB = LOW;
  } else {
    Serial.print('d');
    bRB = HIGH;
  }
  freshb = true;
}

sAU = digitalRead(pAU);
if (sAU != bAU) {
if (sAU == LOW) {
    Serial.print('E');
    bAU = LOW;
  } else {
    Serial.print('e');
    bAU = HIGH;
  }
  freshb = true;
}

sAD = digitalRead(pAD);
if (sAD != bAD) {
if (sAD == LOW) {
    Serial.print('F');
    bAD = LOW;
  } else {
    Serial.print('f');
    bAD = HIGH;
  }
  freshb = true;
}

sBU = digitalRead(pBU);
if (sBU != bBU) {
if (sBU == LOW) {
    Serial.print('G');
    bBU = LOW;
  } else {
    Serial.print('g');
    bBU = HIGH;
  }
  freshb = true;
}

sBD = digitalRead(pBD);
if (sBD != bBD) {
if (sBD == LOW) {
    Serial.print('H');
    bBD = LOW;
  } else {
    Serial.print('h');
    bBD = HIGH;
  }
  freshb = true;
}


//send message if nothing has been sent recently
if (freshb == false) {
  freshc ++; //add one to fresh count
  if(freshc >= fresho) {
    if (freshf == 1) {
      Serial.print('Z');
      freshf = 0;
    }
    else {
      Serial.print('z');
      freshf = 1;
    }
  }
}

} //end main loop

 

Onboard Box

#include <avr/wdt.h>
#include <avr/interrupt.h>

//name pins for easy use thoughout code
//"read" pins for switches
int pLF = 39; //left track forward
int pLB = 41; //left track backward
int pRF = 43; //right track forward
int pRB = 45; //right track backward
int pAU = 47; //arms up
int pAD = 49; //arms down
int pBU = 51; //bucket up
int pBD = 53; //bucket down

//"write" pins to control relay module
int rLF = 38; //left track forward
int rLB = 40; //left track backward
int rRF = 42; //right track forward
int rRB = 44; //right track backward
int rAU = 46; //arms up
int rAD = 48; //arms down
int rBU = 50; //bucket up
int rBD = 52; //bucket down

//to handle data of current state of a switch
int sLF = digitalRead(39); //left track forward
int sLB = digitalRead(41); //left track backward
int sRF = digitalRead(43); //right track forward
int sRB = digitalRead(45); //right track backward
int sAU = digitalRead(47); //arms up
int sAD = digitalRead(49); //arms down
int sBU = digitalRead(51); //bucket up
int sBD = digitalRead(53); //bucket down

//to temporarily remember the last broadcast data for each switch
int bLF; //left track forward
int bLB; //left track backward
int bRF; //right track forward
int bRB; //right track backward
int bAU; //arms up
int bAD; //arms down
int bBU; //bucket up
int bBD; //bucket down

void setup() {

wdt_disable(); //turn off timer to prevent errors on setup

//SET PINS AS OUTPUT TO RELAY MODULE

pinMode(rLF, OUTPUT);
pinMode(rLB, OUTPUT);
pinMode(rRF, OUTPUT);
pinMode(rRB, OUTPUT);
pinMode(rAU, OUTPUT);
pinMode(rAD, OUTPUT);
pinMode(rBU, OUTPUT);
pinMode(rBD, OUTPUT);

//SET AND START WATCHDOG TIMER
wdt_reset();   //reset watchdog
WDTCSR |= 0b00011000; 
WDTCSR = 0b00100001;
WDTCSR = WDTCSR | 0b01000000;  //put watchdog in interupt mode (interupt will happen every 8 seconds)
wdt_reset(); //reset watchdog - START COUNTING FROM ZERO
sei(); //enable interrupts

//START COMMUNICATING WITH XBEE
Serial.begin(9600);
}

void loop() {

while (Serial.available()>0){

char RXbyte = char(Serial.read());

if (RXbyte == 'A') {
    digitalWrite(rLF, HIGH);
    wdt_reset();
  }
if (RXbyte == 'a') {
    digitalWrite(rLF, LOW);
    wdt_reset();
  }
if (RXbyte == 'B') {
    digitalWrite(rLB, HIGH);
    wdt_reset();
  }
if (RXbyte == 'b') {
    digitalWrite(rLB, LOW);
    wdt_reset();
  }
if (RXbyte == 'C') {
    digitalWrite(rRF, HIGH);
    wdt_reset();
  }
if (RXbyte == 'c') {
    digitalWrite(rRF, LOW);
    wdt_reset();
  }
if (RXbyte == 'D') {
    digitalWrite(rRB, HIGH);
    wdt_reset();
  }
if (RXbyte == 'd') {
    digitalWrite(rRB, LOW);
    wdt_reset();
  }
if (RXbyte == 'E') {
    digitalWrite(rAU, HIGH);
    wdt_reset();
  }
if (RXbyte == 'e') {
    digitalWrite(rAU, LOW);
    wdt_reset();
  }
if (RXbyte == 'F') {
    digitalWrite(rAD, HIGH);
    wdt_reset();
  }
if (RXbyte == 'f') {
    digitalWrite(rAD, LOW);
    wdt_reset();
  }
if (RXbyte == 'G') {
    digitalWrite(rBU, HIGH);
    wdt_reset();
  }
if (RXbyte == 'g') {
    digitalWrite(rBU, LOW);
    wdt_reset();
  }
if (RXbyte == 'H') {
    digitalWrite(rBD, HIGH);
    wdt_reset();
  }
if (RXbyte == 'h') {
    digitalWrite(rBD, LOW);
    wdt_reset();
  }

if (RXbyte == 'Z') {
    wdt_reset();
  }
if (RXbyte == 'z') {
    wdt_reset();
  }

} //end while
} //end main loop

//IF NO NEW SIGNALS RECIEVED WITHIN 8 SECONDS LOOP IS INTERRUPTED - TURNS OFF ALL RELAYS 
ISR(WDT_vect)
{
    digitalWrite(rLF, LOW);
    digitalWrite(rLB, LOW);
    digitalWrite(rRF, LOW);
    digitalWrite(rRB, LOW);
    digitalWrite(rAU, LOW);
    digitalWrite(rAD, LOW);
    digitalWrite(rBU, LOW);
    digitalWrite(rBD, LOW);
}