[Solved] Serial communication with an arduino

Following these threads: Spark (3.3v) to Arduino (5v) Serial Communication ,Arduino serial communication to Spark Core, I tried to send data from an analog sensor from an Arduino to a Spark via Logic Level Converter. Without any success.

My Arduino code is

const int analogPin = A0;

void setup() {
  
Serial.begin(9600);
pinMode(analogPin, INPUT); 
int sensor =0 ;
  
}


void loop(){
  int   sensor = analogRead(analogPin) ;
   Serial.println(sensor);
   delay (1000);
}

My Spark code is

int sensor = 0; 
void setup() {

  Serial1.begin(9600);
    Spark.variable("sensor", &sensor, INT);
}

void loop() {

if (Serial1.available() > 0) {
    sensor = Serial1.read();
    delay(100);
}
}

Any ideas?

You are doing a Serial.println(int); which does output the value as a character string followed by a CR LF, but on the Core side you are reading the individual characters into a number, so you will never get the original value read into sensor.

Try Serial.write(int) on the Arduino side and read the incoming value byte by byte into the correct bytes of your sensor var, but be aware, that a Arduino int might be shorter than a Core int. You might be better using int16_t on both sides, to make sure the two are alike.

Thank you ScurffR.
I tried to modify the spark to read each character with an Arduino example but still hadn’t gotten it to work.

The modified Arduino code

const int analogPin = A0;

void setup() {
  
Serial.begin(9600);
pinMode(analogPin, INPUT); 
int sensor =0 ;
  
}


void loop(){
 int16_t  sensor = analogRead(analogPin) ;
   Serial.write(sensor);
   delay (1000);
}

The modified Spark code

char inString[6];
int inByte=0;
int stringPos = 0; 
int16_t  sensor = 0; 
void setup() {

  Serial1.begin(9600);
    Spark.variable("sensor", &sensor, INT);
}

void loop() {

if((inByte >= '0') && (inByte <= '9')){
    inString[stringPos] = inByte;
    stringPos ++;
  }

  if(inByte == '\r'){ // if there is a line end character, this string is done
     sensor = atoi(inString); //convert string to int
}
}

Now we have the opposite problem.
With Serial.write(int) you are sending the binary value of the integer, so you will receive a binary value and not a character string, which you are now trying to read.

Before you sent out a character string and were trying to receive a binary value.

You have tp be type consistant :wink:

:smile:
Missed it. That’s what happens with copy/paste. Sorry, I am still a beginner.
So if I change the Arduino code back to Serial.println it should work?
Thanks for helping.

No it won’t - sorry :wink:
You seem not to read any data from Serial1 in the last example.
And since you are not resetting stringPos you’ll run out of inString[] corrupting other memory.
And since you are not terminating your string with '\0' once you drop out of your digit acquisitioning if-statement, your atoi will probably fail or give you wrong results.

But if I were you, I’d not go down the string route anyway, unless you want to present the data transmitted data in human readable form.
Since you are using the transmitted value as a number anyway, I’d stick with write() and receive the bytes directly into the int variable. And I’d read both bytes in one iteration of loop(). You are pushing out both bytes in one iteration of the Arduino loop(), too.

@coconut, give this a go for binary value transmission.

int16_t sensor = 0;

void setup() {
  pinMode(D7, OUTPUT);

  Serial.begin(115200);       // setup USB-Serial
  Serial1.begin(9600);        // setup RX/TX 
  while(!Serial.available())  // wait for anything to arrive via USB-Serial
      Particle.process();
}

void loop() {
  digitalWrite(D7, !digitalRead(D7));                 // toggle blue LED
  while(Serial1.available() >= sizeof(sensor))        // we are expecting at least 
                                                      // two byte to compose a int16_t
    sensor = Serial1.read() | (Serial1.read() << 8);  // read first byte, then 
                                                      // combine with second byte 
                                                      // which gets left shifted 
                                                      // by 8 bits
    
  Serial.println(sensor, HEX);   // print result to USB-Serial#

  if (digitalRead(D7)) {         // one way to transmit an int16_
    Serial1.write(0x1234);       // first send LSB (least significant byte)
    Serial1.write(0x1234 >> 8);  // then right shift 8 bit to send MSB 
  }
  else {
    sensor <<= 1;                // multiply by two - the nerdy (binary) way ;-)
    Serial1.write((const uint8_t*)&sensor, sizeof(sensor));  // another way to do 
                                                             // the same thing
  }
    
  delay(500);
}

Flash this to your Core, connect RX to TX of your Core to let it talk to itself and watch the USB output :wink:

Hello
In case anyone is interested, I found 2 ways of reading an integer with unknown length from arduino via serial communication.

  1. With a loop:
int inByte = -1;
char inString[6];
int stringPos = 0; 
int sensor =0;
    
void setup()  { 
  Serial1.begin(9600); 
  Particle.variable("sensor", sensor);   
} 
    
void loop() { 
  inByte = Serial1.read();
  if((inByte >= '0') && (inByte <= '9')){
    inString[stringPos] = inByte;
    stringPos ++;
  }
    
  //if there is a line end character, this string is done.
  //clear the string when done
  if(inByte == '\r'){
    sensor = atoi(inString); //convert string to int
    
    //clear the values from inString
    for (int c = 0; c < stringPos; c++){
      inString[c] = 0;
    }
    stringPos = 0;
  }
}
  1. With parseInt command:
int sensor=0;

void setup() {
  Serial1.begin(9600);
  Particle.variable("sensor", sensor);
}

void loop() {
  sensor = Serial1.parseInt() ;
}

both working…

1 Like