Reading two integers through serial

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

TX:

/*
  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:

/*
  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?

SoftwareSerial mySerial(19,18); // RX, TX

On which Arduino? Looks like a Mega, which does hardware serial on those pins.

  pinMode(19, INPUT);
  pinMode(18, OUTPUT);

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

  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?

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.

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.

@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:

/*
  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:

/*
  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?

Why would this be?

Switch to using hardware serial. If the problem persists, post the new code. Until then, you are wasting time.

Hello,

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

guix:
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?

PaulS:
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:

/*
  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:

/*
  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); }
    

}

Read this (especially reply #2) and this.

guix:
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?

mpgiii:
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

Serial.print('<');
Serial.print(firstVal);
Serial.print(',');
Serial.print(secondVal);
Serial.println('>');

...R

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.

//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
    }
  }
}

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.

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

...R