Home Forums EasyTransfer Library Support Forum little problem with timing

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #2162
    Anonymous
    Inactive

    I love the library so far, but I had a few questions. Can you use booleans, because I have tried setting my two unos up as master slave and having the master send boolean commands to the slave. The problem is that the slave only receives the first command in the list. ex.

    struct SEND_DATA_STRUCTURE { //Send commands

    boolean SCAN;

    boolean FORWARD;

    boolean STOP;

    boolean REVERSE;

    boolean LEFT;

    boolean RIGHT;

    };

    The slave only will pick up SCAN, even if I have the master send SCAN = LOW; and FORWARD = HIGH; the slave still just executes SCAN. Any ideas?

    #2163
    Bill
    Member

    I don’t know what could be wrong without looking at the rest of your code, but I do suggest a more efficient way to do what you are trying to do.

    You are trying to send 6 boolean (yes/no) values, however the smallest unit of data in an AVR is a byte of 8 bits. So each boolean uses up a whole byte of data space. So to send 6 yes/no values you are using up 6 whole bytes or 48 bits of data. Instead, you could encode all of your boolean values into a single byte. Here’s an example:

    //first create a naming to position address convention, this is just to make it easier for us
    #define SCAN 0
    #define FORWARD 1
    #define STOP 2
    #define REVERSE 3
    #define LEFT 4
    #define RIGHT 5

    //create a variable that will hold all the values.
    byte commands;

    //When we want to set a value to 1 (true) we do this
    bitSet(commands, FORWARD);
    bitSet(commands, LEFT);

    //When we want to clear a value (set to 0, false) we do this
    bitClear(commands, RIGHT);
    bitClear(commands, SCAN);

    //When we want to act on the different values
    if(bitRead(commands, FORWARD) == true)
    Do Something;

    if(bitRead(commands, SCAN) == false)
    Stop Something;

    So it looks a bit different but it is a much more efficient way to encode binary (on or off) information. Give it a try and see if it works out for you.

    You could also set a value directly from a digital input pin like this:

    bitWrite(commands, FORWARD, digitalRead(13));

    That will set the FORWARD bit TRUE if pin 13 is HIGH or FALSE if the pin is LOW.

    #2164
    Bill
    Member

    Oops, forgot to show you how to send that. It’s simple:

    struct SEND_DATA_STRUCTURE { //Send commands

    byte commands;

    };

    And That’s it. 6 of the 8 bits in commands hold all your boolean values as 1s or 0s.

    #2165
    Anonymous
    Inactive

    Thanks Bill, I’ve started changing the code to your suggestion. I will test in a few. If it doesn’t work, I’ll copy all the code and hopefully Iv’e just made a stupid mistake.

    #2166
    Anonymous
    Inactive

    I have gotten the code you suggested working the same as the old (had to change bitWrite(commands, FORWARD, digitalRead(13)); 

    to

    bitWrite(commDataOut.commands, FORWARD, digitalRead(13));    etc.

    however, I’m still only getting the slave to execute the first command (scan). code follows. I’m sure its in the slave code, but i’m unsure how to write it. I cant use interupts(I dont think) because of timing. Should i use case statements? I’m unsure how to get it working. BTW the slave is actually a pololu 3pi base (ATMEGA328)

     

    //MASTER

    #include <SoftwareSerial.h>

    #include <SoftEasyTransfer.h>

     

    unsigned long start, finished, elapsed;

    boolean working;

    int baseElapsed;

     

     

    //ULTRASONIC

    int distance;

    int shortestDistance = 999;

    int lowerDeadZone = 4;

    int upperDeadZone = 500;

    int sensorAngle = 15;

    int pulseTime;

    int initPin = 19;

    int echoPin = 18;

    int averageAmount = 10;

    int currentNumber = 0;

    int totalRaw;

     

     

    //COMMUNICATION

    SoftwareSerial BrainS(10, 11);

    SoftEasyTransfer CommunicationsOut, CommunicationsIn; //Objects set up

    #define Scan 0

    #define Forward 1

    #define Stop 2

    #define Reverse 3

    #define Left 4

    #define Right 5

    #define Complete 6

    #define TimeElapsed 7

    //byte COMMANDS;

    //byte FEEDBACK;

     

    struct SEND_DATA_STRUCTURE { //Send commands

    byte COMMANDS;

    };

    struct RECEIVE_DATA_STRUCTURE{ //Receive commands

    byte FEEDBACK;

    };

    SEND_DATA_STRUCTURE commDataOut; //name command groups

    RECEIVE_DATA_STRUCTURE commDataIn;

     

     

    //MAPPING

    //int MAP [100] [100];

     

     

    void setup() {

    pinMode (initPin, OUTPUT);

    pinMode (echoPin, INPUT);

    Serial.begin(9600);

    BrainS.begin(9600);

    CommunicationsIn.begin(details(commDataIn), &BrainS);

    CommunicationsOut.begin(details(commDataOut), &BrainS);

    delay (2000);

    findClosestWall();

    }

     

    void loop() {

    if (CommunicationsIn.receiveData()) {

    if (bitRead(commDataIn.FEEDBACK, Complete) == true) {

    Serial.println (“Complete!”);

    bitClear(commDataIn.FEEDBACK, Complete);

    }

    //    if (bitRead(FEEDBACK, TimeElapsed) == true) {

    //      Serial.print (“time elapsed: “);

    //      Serial.println (commDataIn.timeElapsed);

    //      baseElapsed = commDataIn.timeElapsed;

    //      commDataIn.TIMEELAPSED = LOW;

    //    }

    }

    }

     

    void findClosestWall () {

    findDistance();

    if (working == false) {

    Serial.println(commDataOut.COMMANDS, Scan);

    bitSet(commDataOut.COMMANDS, Scan);

    Serial.println(commDataOut.COMMANDS, Scan);

    CommunicationsOut.sendData();

    start = millis();

    Serial.println(“scan”);

    working = true;

    }

    while (working == true) { //while waiting for base to finish

    findDistance();

    if (distance < shortestDistance) { //update shortest distance and find time since start

    shortestDistance = distance;

    finished = millis();

    }

    if (CommunicationsIn.receiveData()) {

    if (bitRead(commDataIn.FEEDBACK, Complete) == HIGH) {

    bitClear(commDataIn.FEEDBACK, Complete);

    working = false;

    elapsed = finished – start; //calculate time to turn

    Serial.println(“scan 1 complete”);

    Serial.print(“Closest: “);

    Serial.println(shortestDistance);

    delay (500);

    Serial.print(“Time to wall: “);

    Serial.println(elapsed);

    delay (1000);

    Serial.println(“turning towards wall”);

    bitSet(commDataOut.COMMANDS, Scan); //turn

    CommunicationsOut.sendData();

    start = millis();

    delay (elapsed);

    bitSet(commDataOut.COMMANDS, Stop); //stop after turning towards wall

    CommunicationsOut.sendData();

    finished = millis();

    elapsed = finished – start;

    Serial.print(“Stopped after: “);

    Serial.println(elapsed);

    delay (1000);

    findDistance();

    while (distance >= lowerDeadZone) {

    findDistance();

    bitSet(commDataOut.COMMANDS, Forward); //forward

    CommunicationsOut.sendData();

    Serial.print(“Distance to 0:”);

    Serial.println(distance – lowerDeadZone);

    }

    if (distance <= lowerDeadZone) {

    bitSet(commDataOut.COMMANDS, Stop); //stop

    CommunicationsOut.sendData();

    Serial.println(“found wall”);

    delay (200);

    }

    Serial.println(“turn 180”);

    bitSet(commDataOut.COMMANDS, Scan); //turn

    CommunicationsOut.sendData();

    delay(baseElapsed / 2);

    bitSet(commDataOut.COMMANDS, Stop); //stop after turning away from wall

    CommunicationsOut.sendData();

    }

    }

    }

    }

     

     

    void findDistance () {

    for (int x = 0; x < averageAmount; x++) {

    digitalWrite (initPin, HIGH);

    delayMicroseconds (10);

    digitalWrite (initPin, LOW);

    pulseTime = pulseIn (echoPin, HIGH);

    distance = pulseTime/58;

    while (distance <= -1 || distance > upperDeadZone) {

    digitalWrite (initPin, HIGH);

    delayMicroseconds (10);

    digitalWrite (initPin, LOW);

    pulseTime = pulseIn (echoPin, HIGH);

    distance = pulseTime/58;

    }

    totalRaw += distance;

    currentNumber ++;

    delay (5);

    if (currentNumber == 10) {

    distance = totalRaw / averageAmount;

    totalRaw = 0;

    currentNumber = 0;

    }

    }

    }

     

     

     

    //SLAVE

    #include <pololu/orangutan.h>

    #include <OrangutanMotors.h>

    #include <OrangutanLCD.h>

    #include <SoftwareSerial.h>

    #include <SoftEasyTransfer.h>

     

    unsigned long start, finished, elapsed;

    int scanTime = 840;

    int turnTime = 200;

     

    SoftwareSerial BaseS(0, 1);

    SoftEasyTransfer CommunicationsIn, CommunicationsOut; //Objects set up

    #define Scan 0

    #define Forward 1

    #define Stop 2

    #define Reverse 3

    #define Left 4

    #define Right 5

    #define Complete 6

    #define TimeElapsed 7

    //byte COMMANDS;

    //byte FEEDBACK;

     

    struct RECEIVE_DATA_STRUCTURE{ //Receive commands

    byte COMMANDS;

    };

    struct SEND_DATA_STRUCTURE{ //Send commands

    byte FEEDBACK;

    };

     

    RECEIVE_DATA_STRUCTURE commDataIn; //name command groups

    SEND_DATA_STRUCTURE commDataOut;

     

    void setup() {

    BaseS.begin(9600);

    CommunicationsIn.begin(details(commDataIn), &BaseS);

    CommunicationsOut.begin(details(commDataOut), &BaseS);

    }

     

    void loop() {

    // Recieve and process recieved command

    if (CommunicationsIn.receiveData()) {

    update:

    if (bitRead(commDataIn.COMMANDS, Scan) == true) { //SCAN

    OrangutanLCD::clear();

    OrangutanLCD::print(“SCAN”);

    start = millis();

    OrangutanMotors::setSpeeds(80, -80);

    while (millis() < start + scanTime) {

    if (CommunicationsIn.receiveData()) {

    goto update;

    }

    }

    OrangutanMotors::setSpeeds(0, 0);

    finished = millis();

    elapsed = finished – start;

    //commDataOut.TIMEELAPSED = HIGH;

    //commDataOut.timeElapsed = elapsed;

    bitSet(commDataOut.FEEDBACK, Complete);

    CommunicationsOut.sendData();

    OrangutanLCD::clear();

    bitClear(commDataIn.COMMANDS, Scan);

    }

    else if (bitRead(commDataIn.COMMANDS, Forward) == true) { //FORWARD

    OrangutanLCD::clear();

    OrangutanLCD::print(“FORWARD”);

    OrangutanMotors::setSpeeds(80, 80);

    bitClear(commDataIn.COMMANDS, Forward);

    }

    else if (bitRead(commDataIn.COMMANDS, Stop) == true) { //STOP

    OrangutanLCD::clear();

    OrangutanLCD::print(“STOP”);

    OrangutanMotors::setSpeeds(0, 0); //stop movement

    bitClear(commDataIn.COMMANDS, Scan);

    bitClear(commDataIn.COMMANDS, Forward);

    bitClear(commDataIn.COMMANDS, Reverse);

    bitClear(commDataIn.COMMANDS, Left);

    bitClear(commDataIn.COMMANDS, Right);

    bitSet(commDataOut.FEEDBACK, Complete);

    CommunicationsOut.sendData();

    bitClear(commDataIn.COMMANDS, Stop);

    }

    else if (bitRead(commDataIn.COMMANDS, Reverse) == true) { //REVERSE

    OrangutanLCD::clear();

    OrangutanLCD::print(“REVERSE”);

    OrangutanMotors::setSpeeds(-80, -80);

    }

    else if (bitRead(commDataIn.COMMANDS, Left) == true) { //LEFT

    OrangutanLCD::clear();

    OrangutanLCD::print(“LEFT”);

    start = millis();

    OrangutanMotors::setSpeeds(-80, 80);

    while (millis() < start + turnTime) {

    if (CommunicationsIn.receiveData()) {

    goto update;

    }

    }

    OrangutanMotors::setSpeeds(0, 0);

    bitSet(commDataOut.FEEDBACK, Complete);

    CommunicationsOut.sendData();

    OrangutanLCD::clear();

    bitClear(commDataIn.COMMANDS, Left);

    }

    else if (bitRead(commDataIn.COMMANDS, Right) == true) { //RIGHT

    OrangutanLCD::clear();

    OrangutanLCD::print(“RIGHT”);

    start = millis();

    OrangutanMotors::setSpeeds(80, -80);

    while (millis() < start + turnTime) {

    if (CommunicationsIn.receiveData()) {

    goto update;

    }

    }

    OrangutanMotors::setSpeeds(0, 0);

    bitSet(commDataOut.FEEDBACK, Complete);

    CommunicationsOut.sendData();

    OrangutanLCD::clear();

    bitClear(commDataIn.COMMANDS, Right);

    }

    }

    }

    #2167
    Anonymous
    Inactive

    I’ve solved my issue by converting the byte into an integer after the slave receives it, then sending it through a switch case. I have now gotten the base to do all the commands it is supposed to. This library is a lifesaver. I would have hated (and had started when I found SoftEasy) to write my own protocol. Thanks Bill

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.