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);
}
  • 1
    You might get better help at android.stackexchange.com – Mawg May 9 '17 at 7:42
  • Nope, look code is pure arduino. – mico May 9 '17 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 May 9 '17 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 May 9 '17 at 16:59
  • @Mawg it may be Arduino stack exchange – Prashanth Benny May 11 '17 at 5:46

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'));

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 acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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