5

I'm trying to read orientation sensor values from android and send them to an Arduino. The android will send valueX, valueY and valueZ in bytes.

Each value will end with x,y and z character at end of value (from.java).

String valueX = xPosition + "x";
btSocket.getOutputStream().write(valueX.toString().getBytes());

When I rotate the phone the value will read only one value at the time, which is valueZ.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(6, 5);
// Pin 13 - LED
int ledG = 13;
int ledR = 12;
int ledW = 11;
int state;
String value,value1,valueZ,valueY,valueX;

void setup() {                
  // initialize the digital pin as an output.
  pinMode(ledG, OUTPUT);  
  pinMode(ledR, OUTPUT);
  pinMode(ledW, OUTPUT);   
  // initialize serial communication at 9600 bits per second:
  mySerial.begin(9600);
}

void loop() {
  if(mySerial.available() > 0){     
     state = ((byte)mySerial.read());}




  if (state == 'z') {
      int state = valueZ.toInt();
      //state = state + valueZ;
      digitalWrite(ledG, HIGH);}   // turn the LED on (HIGH is the voltage level)
  else if (state != 'z' && state!=0) {
      digitalWrite(ledG, LOW);}    // turn the LED off by making the voltage LOW

  else if ( state == 'y') {
    int casted2 = valueY.toInt();
      digitalWrite(ledR, HIGH);}
  else if (state != 'y') {
      digitalWrite(ledR, LOW);}

  else if (state == 'x') {
    int casted = valueX.toInt();
      digitalWrite(ledW, HIGH);}
  else if (state != 'x') {
      digitalWrite(ledW, LOW);}

  delay(1);               // wait for 100ms

  //For debugging purpose
  //Serial.println(state);
}
6
  • 1
    You might get better help at android.stackexchange.com
    – Mawg
    Commented May 9, 2017 at 7:42
  • Nope, look code is pure arduino.
    – mico
    Commented May 9, 2017 at 16:18
  • Problem is, that all if statements are if elses, so that only the first is run if first one matches. Also there is no row to show how those values are read, so if you happen to have some z I cannot say whether it is the correct one. For my eye it seems not.
    – mico
    Commented May 9, 2017 at 16:36
  • 1
    You should add minimum runnable code containing all necessary lines of the functionality where you have the issue. At least this code shown cannot be all you have because so much essential parts are missing.
    – mico
    Commented May 9, 2017 at 16:59
  • @Mawg it may be Arduino stack exchange Commented May 11, 2017 at 5:46

2 Answers 2

6

I'm not sure why you're checking for z's and so on but your first else if clause ensures that none of the clauses in the rest of the block is ever executed.

else if (state != 'z' && state!=0) {
  digitalWrite(ledG, LOW);}    // turn the LED off by making the voltage LOW

When state is any value that's neither z nor 0 (x, y, etc) then this block is executed and the rest are skipped. It seems state is seldom 0, so all you get is an LED that's off for any x or y values. What you should probably do instead is something like:

int orientx;
int orienty;
int orientz;

switch (state) {
  case 'z':
    orientz = valueZ.toInt();
    digitalWrite(ledG, HIGH);
    digitalWrite(ledR, LOW);
    digitalWrite(ledW, LOW);
    break;
 case 'y':
    orienty = valueY.toInt();
    digitalWrite(ledG, LOW);
    digitalWrite(ledR, HIGH);
    digitalWrite(ledW, LOW);
    break;
case 'x':
    orientx = valueX.toInt();
    digitalWrite(ledG, LOW);
    digitalWrite(ledR, LOW);
    digitalWrite(ledW, HIGH);
    break;
}
delay(1);

You can also use if-else statements if you want, though I find this more concise if you'll only be testing the value of the one variable state.

An even more elegant solution would be:

int orientx;
int orienty;
int orientz;

switch (state) {
  case 'z':
    orientz = valueZ.toInt();
    break;
  case 'y':
    orienty = valueY.toInt();
    break;
  case 'x':
    orientx = valueX.toInt();
    break;
}
digitalWrite(ledG, (state == 'z'));
digitalWrite(ledR, (state == 'y'));
digitalWrite(ledW, (state == 'x'));
2

To improve on TisteAndii's answer, your program could lose context which might be part of your problem on the serial line because it has no start/stop markers. For example, say a byte gets dropped, and then the next byte (a value byte) is a 'y' then next state would be read as a value. I would recommend framing your packets, especially with software serial. This will help prevent data corruption. A very simple version of this would be as follows.

 ____________
|Start byte  | Byte 0
|_ _ _ _ _ _ |
|Msg ID      | Byte 1 optional if using only one message type
|_ _ _ _ _ _ |
|Msg Length  | Byte 2 (defined as total length of message including header)
|_ _ _ _ _ _ |
|Data        | Bytes 3-254
|_ _ _ _ _ _ |
|Checksum    | Byte 3 + Len(Data) (Max 255)
|____________|

This structure would allow you to cast things such as structs or protobufs into the message, and right back again without much work. This is essentially a stripped down version of how ANT and XBee radios talk to external microcontrollers. Here is an example implementation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.