Go Down

Topic: Reading two integers through serial (Read 178 times) previous topic - next topic

mpgiii

So I have one integer reading just fine with these two codes:

TX:
Code: [Select]
/*
  AnalogToSerial
  Reads an analog input on pin 0, outputs to TX.
*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(19,18); // RX, TX
int data [2];
int data1 [4];
int potPin = 0;  // analog pin used to connect the potentiometer
int pot0;    // variable to read the pot0ue from the analog pin
 
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(19, INPUT);
  pinMode(18, OUTPUT);
 
}
 
void loop() {
 
  pot0 = analogRead(potPin);   // reads the pot0ue of the potentiometer (pot0ue between 0 and 1023)
  data[0] = pot0 & 0xFF; //least significant 8 bit byte
  data[1] = (pot0 >> 8); //most significant 2 bits

//  Serial.print(data[1], HEX);
//  Serial.print(" ");
//  Serial.print(data[0], HEX);
//  Serial.print(" ");
//  Serial.println(data[1]<<8 | data[0]);
 
  mySerial.write(data[0]);
  mySerial.write(data[1]); //bytes sent
 delay(50);        // delay in between reads for stability

 
}

RX:
Code: [Select]
/*
  Analog Receive
  Reads a 10 bit serial stream in two bytes
  reassembles and converts to binary display using 8 LEDs
*/

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,18); // RX, TX
int val[4];    // variable to read the value from the analog pin
int serialBytes[2];
int motorVal;
int coolVal; // 0-1024 from serial
int directionPin = 8;
int PWM_out_pin = 9; // works on pins 2 - 13 and 44 - 46

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
//  mySerial.begin(9600);
  pinMode(10, INPUT);
  pinMode(18, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

void loop() {

  if (mySerial.available()>1) {
    val[0]=mySerial.read();         // least significant 8 bits
    val[1]=mySerial.read();         // most significant 2 bits

    val[2] = val[1]<<8 | val[0];    // reassebled 10 bit value, sore in val[2]
    delay(10);
  }

    Serial.print(val[1],HEX); Serial.print(" ");
    Serial.print(val[0],HEX); Serial.print(" ");
    Serial.print(val[2], HEX); Serial.print (" ");
    coolVal = val[2];
    Serial.println(coolVal);

  if (coolVal > 550) {
    digitalWrite (directionPin, HIGH);
    motorVal = map(coolVal, 550, 1023, 0, 1023);
    analogWrite (PWM_out_pin, motorVal / 4); }

  if ((coolVal < 550) && (coolVal > 500)) {
    analogWrite (directionPin, HIGH);
    analogWrite (PWM_out_pin, 0); }
 
  if (coolVal < 500) {
    digitalWrite (directionPin, LOW);
    motorVal = map(coolVal, 0, 500, 1023, 0);
    analogWrite (PWM_out_pin, motorVal / 4); }


}


I tried adding another integer to send over serial the same way, by inserting a data1[0] and data1[1] to the TX and a val1[0] and val1[1] to receive it and it jumbled both of my values. How am I supposed to achieve this?

PaulS

Code: [Select]
SoftwareSerial mySerial(19,18); // RX, TX
On which Arduino? Looks like a Mega, which does hardware serial on those pins.

Code: [Select]
  pinMode(19, INPUT);
  pinMode(18, OUTPUT);

Don't you suppose that SoftwareSerial knows that is necessary?

Code: [Select]
  pot0 = analogRead(potPin);   // reads the pot0ue of the potentiometer (pot0ue between 0 and 1023)
  data[0] = pot0 & 0xFF; //least significant 8 bit byte
  data[1] = (pot0 >> 8); //most significant 2 bits

Why are you storing the bytes in an int array?

Quote
How am I supposed to achieve this?
You would start by showing the code. Now you see why sending binary data is so difficult. Sending ASCII data is far more robust.

LarryD

Quote
I tried adding another integer to send over serial the same way, by inserting a data1[0] and data1[1] to the TX and a val1[0] and val1[1] to receive it and it jumbled both of my values. How am I supposed to achieve this?

Show us the sketches that don't work.
Always blame yourself.

mpgiii

@PaulS -
I don't need to be using SoftwareSerial, you are right. But that is not what it is important I would think.

I have this code which is sending them both relatively well but has a lot of glitches when viewing through the Serial monitor and am wondering how to remove these.


@LarryD -
The code I'm using now is:

TX:
Code: [Select]
/*
  AnalogToSerial
  Reads an analog input on pin 0, outputs to TX.
*/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(19,18); // RX, TX
int data [2];
int potPin = 0;  // analog pin used to connect the potentiometer
int pot0;    // variable to read the pot0ue from the analog pin
int pot1Pin = 1;
int pot1;
 
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(19, INPUT);
  pinMode(18, OUTPUT);
 
}
 
void loop() {
 
  pot0 = analogRead(potPin);   // reads the pot0ue of the potentiometer (pot0ue between 0 and 1023)
  data[0] = pot0 & 0xFF; //least significant 8 bit byte
  data[1] = (pot0 >> 8); //most significant 2 bits
  pot1 = analogRead(pot1Pin);
  data[2] = pot1 & 0xFF;
  data[3] = (pot1 >> 8);

//  Serial.print(data[1], HEX);
//  Serial.print(" ");
//  Serial.print(data[0], HEX);
//  Serial.print(" ");
//  Serial.println(data[1]<<8 | data[0]);
 
  mySerial.write(data[0]);
  mySerial.write(data[1]); //bytes sent
  mySerial.write(data[2]);
  mySerial.write(data[3]);
 delay(50);        // delay in between reads for stability

 
}


RX:
Code: [Select]
/*
  Analog Receive
  Reads a 10 bit serial stream in two bytes
  reassembles and converts to binary display using 8 LEDs
*/

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10,18); // for UNO RX, TX
int val[4];    // variable to read the value from the analog pin
int serialBytes[2];
int motorVal;
int coolVal; // 0-1024 from serial
int coolVal1;
int directionPin = 8;
int PWM_out_pin = 9; // works on pins 2 - 13 and 44 - 46

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
//  mySerial.begin(9600);
  pinMode(10, INPUT); // for UNO
  pinMode(18, OUTPUT); // for UNO
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

void loop() {

  if (mySerial.available()>1) {
    val[0]=mySerial.read();         // least significant 8 bits
    val[1]=mySerial.read();         // most significant 2 bits
    val[2]=mySerial.read();
    val[3]=mySerial.read();
    coolVal = val[1]<<8 | val[0];    // reassebled 10 bit value, sore in val[2]
    coolVal1 = val[3]<<8 | val[2];
    delay(10);
  }

//    Serial.print(val[1],HEX); Serial.print(" ");
//    Serial.print(val[0],HEX); Serial.print(" ");
//    Serial.print(val[2], HEX); Serial.print (" ");

//    coolVal = val[2];
    Serial.print("pot0: ");
    Serial.print(coolVal);
    Serial.print("   pot1: ");
    Serial.println(coolVal1);
    
  if (coolVal > 550) {
    digitalWrite (directionPin, HIGH);
    motorVal = map(coolVal, 550, 1023, 0, 1023);
    analogWrite (PWM_out_pin, motorVal / 4); }

  if ((coolVal < 550) && (coolVal > 500)) {
    digitalWrite (directionPin, HIGH);
    analogWrite (PWM_out_pin, 0); }
 
  if (coolVal < 500) {
    digitalWrite (directionPin, LOW);
    motorVal = map(coolVal, 0, 500, 1023, 0);
    analogWrite (PWM_out_pin, motorVal / 4); }
    

}


It reads it correctly around 70% of the time, or the number becomes either way too big or negative. Why would this be?

PaulS

Quote
Why would this be?
Switch to using hardware serial. If the problem persists, post the new code. Until then, you are wasting time.

guix

#5
Jan 08, 2016, 02:37 am Last Edit: Jan 08, 2016, 02:38 am by guix
Hello,

In the RX code, you read 4 characters even if they are not all received yet. Also remove the useless delay.

mpgiii

In the RX code, you read 4 characters even if they are not all received yet
How exactly would I make it not read if they have not yet been received?

mpgiii

Switch to using hardware serial. If the problem persists, post the new code. Until then, you are wasting time.
Still getting the same problem, here's my new codes

TX:
Code: [Select]
/*
  AnalogToSerial
  Reads an analog input on pin 0, outputs to TX.
*/
int data [2];
int potPin = A0;  // analog pin used to connect the potentiometer
int pot0;    // variable to read the pot0ue from the analog pin
int pot1Pin = A1;
int pot1;
 
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  pinMode(19, INPUT);
  pinMode(18, OUTPUT);
}
 
void loop() {
 
  pot0 = analogRead(potPin);   // reads the value of the potentiometer (pot0ue between 0 and 1023)
  data[0] = pot0 & 0xFF; //least significant 8 bit byte
  data[1] = (pot0 >> 8); //most significant 2 bits

  pot1 = analogRead(pot1Pin);
  data[2] = pot1 & 0xFF;
  data[3] = (pot1 >> 8);

//  Serial.print(data[1]<<8 | data[0]);
//  Serial.print(" ");
//  Serial.println(data[3]<<8 | data[2]);

Serial.println(pot0);
 
  Serial1.write(data[0]);
  Serial1.write(data[1]); //bytes sent
  Serial1.write(data[2]);
  Serial1.write(data[3]);
 delay(100);        // delay in between reads for stability

 
}


RX:
Code: [Select]
/*
  Analog Receive
  Reads a 10 bit serial stream in two bytes
  reassembles and converts to binary display using 8 LEDs
*/
int val[4];    // variable to read the value from the analog pin
int serialBytes[2];
int motorVal;
int coolVal; // 0-1024 from serial
int coolVal1;
int directionPin = 8;
int PWM_out_pin = 9; // works on pins 2 - 13 and 44 - 46

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
//  Serial1.begin(9600);
  pinMode(10, INPUT);
  pinMode(18, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
}

void loop() {

  if (Serial1.available()>1) {
    val[0]=Serial1.read();         // least significant 8 bits
    val[1]=Serial1.read();         // most significant 2 bits
    val[2]=Serial1.read();
    val[3]=Serial1.read();
    coolVal = val[1]<<8 | val[0];    // reassebled 10 bit value, sore in val[2]
    coolVal1 = val[3]<<8 | val[2];
    delay(10);
  }

//    Serial.print(val[1],HEX); Serial.print(" ");
//    Serial.print(val[0],HEX); Serial.print(" ");
//    Serial.print(val[2], HEX); Serial.print (" ");

//    coolVal = val[2];
//    Serial.print("pot0: ");
    Serial.print(coolVal);
    Serial.print(" ");
    Serial.println(coolVal1);
   
  if (coolVal > 550) {
    digitalWrite (directionPin, HIGH);
    motorVal = map(coolVal, 550, 1023, 0, 1023);
    analogWrite (PWM_out_pin, motorVal / 4); }

  if ((coolVal < 550) && (coolVal > 500)) {
    digitalWrite (directionPin, HIGH);
    analogWrite (PWM_out_pin, 0); }
 
  if (coolVal < 500) {
    digitalWrite (directionPin, LOW);
    motorVal = map(coolVal, 0, 500, 1023, 0);
    analogWrite (PWM_out_pin, motorVal / 4); }
   

}

guix

#8
Jan 08, 2016, 03:09 am Last Edit: Jan 08, 2016, 03:10 am by guix
Read this (especially reply #2) and this.

mpgiii

Read this (especially reply #2) and this.
So what I'm seeing is send a starting and ending character. Is there a way to send a start byte and end byte and do it that way?

Robin2

Is there a way to send a start byte and end byte and do it that way?
If you are looking at the 3rd example in Serial Input Basics (which is linked to by @guix) then you can send the data in the correct format with simple code like this
Code: [Select]
Serial.print('<');
Serial.print(firstVal);
Serial.print(',');
Serial.print(secondVal);
Serial.println('>');


...R
Two or three hours spent thinking and reading documentation solves most programming problems.

zoomkat

Quote
So what I'm seeing is send a starting and ending character. Is there a way to send a start byte and end byte and do it that way?
The below code is for servos, but might fit what you are trying to do. As to the start character, I really haven't seen a decent reason to use one. The end character generally indicates the next input will be the start of the next data packet.

Code: [Select]

//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added
// Powering a servo from the arduino usually *DOES NOT WORK*.

String readString;
#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500); //set initial servo position if desired

  myservoa.attach(6);  //the pin for the servoa control
  myservob.attach(7);  //the pin for the servob control
  myservoc.attach(8);  //the pin for the servoc control
  myservod.attach(9);  //the pin for the servod control
  Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}

void loop() {

  //expect single strings like 700a, or 1500c, or 2000d,
  //or like 30c, or 90a, or 180d,
  //or combined like 30c,180b,70a,120d,

  if (Serial.available())  {
    char c = Serial.read();  //gets one byte from serial buffer
    if (c == ',') {
      if (readString.length() >1) {
        Serial.println(readString); //prints string to serial port out

        int n = readString.toInt();  //convert readString into a number

        // auto select appropriate value, copied from someone elses code.
        if(n >= 500)
        {
          Serial.print("writing Microseconds: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
          if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
          if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
        }
        else
        {   
          Serial.print("writing Angle: ");
          Serial.println(n);
          if(readString.indexOf('a') >0) myservoa.write(n);
          if(readString.indexOf('b') >0) myservob.write(n);
          if(readString.indexOf('c') >0) myservoc.write(n);
          if(readString.indexOf('d') >0) myservod.write(n);
        }
         readString=""; //clears variable for new input
      }
    } 
    else {     
      readString += c; //makes the string readString
    }
  }
}

Google forum search: Use Google Search box in upper right side of this page.
Why I like my 2005 Rio Yellow Honda S2000  https://www.youtube.com/watch?v=pWjMvrkUqX0

jrdoner

Look up the C++ structure called a union,  with it, you can store data as one type, then interpret it as another.  So you store your integers as integers, ship them out the serial port as bytes, receive 'em as bytes, and read them out as integers.   No fancy bit operations needed.   I've done this to ship integers and floats across serial links.

Robin2

The code in this Python Binary Data demo illustrates what @jrdoner mentioned in Reply #12.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy