Go Down

Topic: Android, Arduino, and Bluetooth (Read 1 time) previous topic - next topic

TeslaIaint

#15
Aug 22, 2017, 02:59 pm Last Edit: Aug 22, 2017, 03:03 pm by TeslaIaint
I'm stuck on how to do that correctly. I'm thinking of a for loop, but I don't know how to populate the data unless every function is duplicated. I started this sketch, but it's not done, and it isn't finished because I know it's wrong.

Code: [Select]

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing
char receivedChars1[numChars];
char tempChars1[numChars];        // temporary array for use when parsing
unsigned long previousMillis = 0;
const long interval = 10;

// variables to hold the parsed data
int xAxis = 0;
int yAxis = 0;
int xAxis1 = 0;
int yAxis1 = 0;
int i = 0;

boolean newData = false;




void setup() {



  Serial.begin(230400);  //230400  460800   921600

}

void loop() {
  for (i = 0; i < 2; i++) {
    if (i == 0) {
      recvWithStartEndMarkers();
      if (newData == true) {
        strcpy(tempChars, receivedChars);
        // this temporary copy is necessary to protect the original data
        //   because strtok() used in parseData() replaces the commas with \0
      }
    }
        if (i == 1) {
      recvWithStartEndMarkers1();
      if (newData == true) {
        strcpy(tempChars, receivedChars);
        // this temporary copy is necessary to protect the original data
        //   because strtok() used in parseData() replaces the commas with \0
      }
    }
  }
  processAndroidData();
  // if the first character is 'a' or 'b', control the led
  if (receivedChars[0] == 'a' || receivedChars[0] == 'b')    {
    ledControl();
  }
  // else control the motors
  else
  {
    makeTurns();
  }
  newData = false;
 
  if (i==1) {   //reset counter so it resets loop or else it would only repeat once
    i=0;
  }
}


void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }

      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;

      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void recvWithStartEndMarkers1() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars1[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }

      else {
        receivedChars1[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;

      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void processAndroidData() {      // split the data into its parts
  char * strtokIndx; // this is used by strtok() as an index
  strtokIndx = strtok(tempChars, ",");
  xAxis = atoi(strtokIndx);     // convert this part to an integer

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  yAxis = atoi(strtokIndx);     // convert this part to an integer
}

void makeTurns() {
}


void ledControl()
{
  if (receivedChars[0] == 'a')
  {
    // digitalWrite(ledR, LOW);
  }
  if (receivedChars[0] == 'b')
  {
    // digitalWrite(ledR, HIGH);
  }
}



void allStop () {
  //md.setBrakes(70, 70);
}

PaulS

Quote
I'm thinking of a for loop
To do what?

Code: [Select]
char receivedChars1[numChars];
char tempChars1[numChars];        // temporary array for use when parsing

Wrong.

Suppose that I hand you a post it note with two numbers written on it. You have a pencil and paper. Can you tell that the post it note has numbers on it that match what the last post it note had? How many post it notes do you need to have to determine that?

Hint: the answer to the last question is ONE.

The post it note corresponds to the receivedChars array. You read the data ONCE/get a post it note once.

When you get the first note, you have NO previous data (your paper is blank), so obviously the note contains numbers that don't match what you got last time.

So, you do something with the numbers AND YOU WRITE THEM DOWN. Throw the post it note away; you are done with it.

Now, you get another note. It either contains new data or it contains the same data as last time. How do you know? Well, either the numbers on the post it note match what you wrote down, or they don't.

Now, which variables correspond to the data on the post it note? Which variables correspond to the data on the paper?
The art of getting good answers lies in asking good questions.

TeslaIaint

Am I on the right track here?

Code: [Select]
  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        if (rc != receivedChars[ndx] {   //MAKE SURE THEY DON'T MATCH LAST LOOP DATA
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      }
...

PaulS

Quote
Am I on the right track here?
Code: [Select]
        if (rc != receivedChars[ndx] {   //MAKE SURE THEY DON'T MATCH LAST LOOP DATA
No.

You want to read and store all the data. You want to parse the data, when the end of the record arrives.

It is the parsed data that you want to compare to the previously parsed data.
The art of getting good answers lies in asking good questions.

TeslaIaint

#19
Aug 22, 2017, 05:49 pm Last Edit: Aug 22, 2017, 05:50 pm by TeslaIaint
Is this close?
Code: [Select]
void processAndroidData() {      // split the data into its parts
  xAxis1 = xAxis; //variable to compare data from last loop
  char * strtokIndx; // this is used by strtok() as an index
  strtokIndx = strtok(tempChars, ",");
  xAxis = atoi(strtokIndx);     // convert this part to an integer
  if (xAxis==xAxis1) {  //if variables match, then Android is "frozen" - stop motors
    allStop();
  }
  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  yAxis = atoi(strtokIndx);     // convert this part to an integer
  
}

PaulS

Quote
Is this close?
That snippet looks better, but I still don't think that it is right. I think that you want to get xAxis AND yAxis, and compare them to xAxis1 and yAxis1. If either value is different, use both values.

I could be wrong, though.
The art of getting good answers lies in asking good questions.

TeslaIaint

Is this how you would do it? (or close)
Code: [Select]
void processAndroidData() {      // split the data into its parts
  xAxis1 = xAxis; //variable to compare data from last loop
  yAxis1 = yAxis; //variable to compare data from last loop
  char * strtokIndx; // this is used by strtok() as an index
  strtokIndx = strtok(tempChars, ",");
  xAxis = atoi(strtokIndx);     // convert this part to an integer
  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  yAxis = atoi(strtokIndx);     // convert this part to an integer

  if ((yAxis == yAxis1) || (xAxis == xAxis1)){ //if variables match, then Android is "frozen" - stop motors
    allStop();
  }
}

PaulS

Quote
Is this how you would do it? (or close)
Yes.
The art of getting good answers lies in asking good questions.

TeslaIaint

It works just like I was intending. Thanks for your help. I appreciate it.

Go Up