Sending integers between arduinos using serial communication

Hi everyone.
I've been trying to read data from a joystick and send it to another arduino using serial communication. The range is supposed to be from 0 to 255 but for some reason I only get 1. Please help!

sender code:

uint8_t val[1];
int xpin = A0;
void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  val[1] = map(analogRead(xpin), 0, 1023, 0, 255);
  Serial.write(val, sizeof(val)); //Write the serial data
  delay(100);
}

receiver code:

uint8_t val[1];

void setup() {
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
}

void loop() {
  int readval = Serial.readBytes(val, sizeof(val));
  Serial.println(readval);
  delay(100);
}

Welcome to the forum

Why is val an array ?

What happens when you run this?
https://docs.arduino.cc/built-in-examples/analog/AnalogInOutSerial

What does this have to do with Networking, Protocols, and Devices?

1. You have connected the Arduinos using hardware UART Port (UART Port) which is not recommended as the UART Ports are engaged with PC/IDE/SM.

2. Connect the Arduinos using software UART Port (SUART Port) as per Fig-1.
uartUnoUno-1
Figure-1:

3. Connect wiper pint of Pot with A1 instead of A0 as my diagram shows A1.
4. Upload the following sketch in UNO-1 (Sender). (Your one with slight modification.)

#include<SoftwareSerial.h>
SoftwareSerial SUART(5, 6);////SRX = 5, STX = 6

uint16_t val;
int xpin = A1;

void setup() 
{
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
  SUART.begin(9600);   
}

void loop() 
{
  val = analogRead(xpin);    //val =0 to 0x03FF in hex base = 0 to 1023 in decimal base
  SUART.write(highByte(val));   //sending upper byte of the hex value of val
  SUART.write(lowByte(val));    //sending lower byte of the hex value of val
  delay(1000);   //test interval
}

5. Upload the following sketch in UNO-2.

#include<SoftwareSerial.h>
SoftwareSerial SUART(5, 6);////SRX = 5, STX = 6

uint16_t val;

void setup() 
{
  // Begin the Serial at 9600 Baud
  Serial.begin(9600);
  SUART.begin(9600);   
}

void loop() 
{
  byte n = SUART.available(); //check that at least1 1 char/byte in buffer
  if(n == 2)  //buffer contains 2-byte data that has come from Sender
  {
    byte yH = SUART.read();    //getting upper byte from buffer
    byte yL = SUART.read();  //getting lower byte from buffer
    val = yH << 8 | yL  //forming 16-bit val     ; yH00000000 + 00000000yL =  yHyL
    Serial.println(val, DEC);  // shows 0 to 1023 as Pot is rotated at Sender side
  }
}

6. Open SM for Receiver at Bd = 9600.
7. Slowly vary Pot at the Sender side.
8. Check that the SM2 shows decimal values from 0 to 1023.

1 Like

Oops

It's worthwhile checking the documentation for this function to see what it returns

Wow! Thank you so much it worked!
I'm trying to get it to work wirelessly on a xbee module. Would this code work with that?
Also, since I'm probably the world's biggest noob when it comes to this, I'd appreciate it if you could give me a code explanation for this.
Thanks so much!

Another question. I need to send both the x-axis value and the y-axis value of the joystick. How would I do that?

If x-axis and y-axis values of your joystick are analog, then you can easily connect them with Ch-0 and Ch-1 of the ADC.

I'm sorry. What I meant was, would I send the data received through the analog pins to the other uno using serial communication? In the last example we only sent data from one pin. I need to send two pieces of data, each from different analog pins separately.

You can send the 2 values but will need some way to know which is which when received. This implies structuring the data sent in some way

See Serial input basics - updated

The following tutorial may be helpful for the OP (@fdsfdsfdsfds) to send two 16-bit data items from Sender to Receiver.

1. Connection diagram (Fig-1) among Pot1, Pot2, UNO-1, UNO-2, SM1, and SM2.
uartUnoUno-1
Figure-1:

You can send the 2 values but will need some way to know which is which when received. This implies structuring the data sent in some way

2. Test sketch for UNO-1 (Sender)

#include<SoftwareSerial.h>
SoftwareSerial SUART(5, 6);

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

void loop()
{
  int y0 = analogRead(A0);
  SUART.write(highByte(y0));
  SUART.write(lowByte(y0));
  //-----------------------
  int y1 = analogRead(A1);
  SUART.write(highByte(y1));
  SUART.write(lowByte(y1));
  delay(1000);  //test inteval
}

3. Test Sketch for UNO-2

#include<SoftwareSerial.h>
SoftwareSerial SUART(5, 6);// SRX = DPin-5, STX = DPin-6

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

void loop()
{
  byte n = SUART.available();
  if (n != 4)
  {
    Serial.print("Received from Pot1: ");
    int y0 = SUART.read() << 8 | SUART.read();
    float y0F = (5.0 / 1023) * y0;
    Serial.print(y0F, 2);
    Serial.println('V');
    //-----------------------------------
    Serial.print("Received from Pot2: ");
    int y1 = SUART.read() << 8 | SUART.read();
    float y1F = (5.0 / 1023) * y1;
    Serial.print(y1F, 2);
    Serial.println('V');
    Serial.println("================================");
  }
}

4. Output on SM2

================================
Received from Pot1: 3.26V     
Received from Pot2: 5.00V
================================

Your question suggests you should have helped us earlier by answering the question in reply #2, "why is val[] an array?". Because, only now are you answering it. Thus you waited much longer for advice.

That is true.
Sorry.

How could I increase the number of data sent?

Have you practiced the sketch of of post #12 to see how two data items (each 16-bit) were sent from Sender to Receiver using SUART Port? Follow that post #12 to send any number of data items. Besides this approach, there are many approaches to find which do a google search.

No, this is a wrong way. As @UKHeliBob said, we need some packet structure for sending data, else OP will very quickly runs into the inability to distinguish between the first and second value.

and the result will be a complete mess in the receiver

The wrong way ultimately takes to the right point. Let the OP begin with something that works when he has no idea about data transmission.

Let the OP encounter the situation and then will be discovering that --
1. To send known number of binary coded data, he needs to send first 2/3-byte preamble bytes (the sync pattern).
2. Send the data items.
3. Send the checksum.
4. At the receiver, detect the sync pattern and then begin to collect data from buffer until known number of bytes are received + checksum byte.
5. Check the validity check of the the received frame.
6. Extract individual data item by combining successive two bytes of the received frame.

Ok, let's wait

1 Like

Yes I did. I need to be able to distinguish if a push button has been pressed or not, so I wrote the following code:

Sender:

#include<SoftwareSerial.h>
SoftwareSerial SUART(5, 6);
int buttonval = 0;

void setup()
{
  pinMode(4, INPUT);
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  int y0 = analogRead(A0);
  Serial.write(highByte(y0));
  Serial.write(lowByte(y0));
  //-----------------------
  int y1 = analogRead(A1);
  Serial.write(highByte(y1));
  Serial.write(lowByte(y1));
  //-----------------------
int y2 = digitalRead(4);
if(y2 == HIGH)
{
   buttonval = 1;
}
else
{
    buttonval = 0;
}  Serial.write(highByte(buttonval));
Serial.write(lowByte(buttonval));
  delay(100);  //test inteval
}

Receiver:

#include<SoftwareSerial.h>
SoftwareSerial SUART(5, 6);// SRX = DPin-5, STX = DPin-6

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

void loop()
{
  byte n = Serial.available();
  if (n == 4)
  {
    Serial.print("Received from Pot1: ");
    int y0 = Serial.read() << 8 | Serial.read();
    float y0F = (5.0 / 1023) * y0;
    Serial.print(y0);
    Serial.print('V');
    //-----------------------------------
    Serial.print("Received from Pot2: ");
    int y1 = Serial.read() << 8 | Serial.read();
    float y1F = (5.0 / 1023) * y1;
    int buttonval = Serial.read(); 
    Serial.print("Received from Pot1: ");
    Serial.print(y0);
    Serial.print('V');
    Serial.print("Received from Pot2: ");
    Serial.print(y1);
    Serial.print('V');
   Serial.print("   ");
    Serial.print(-buttonval);
    Serial.println('V');
    Serial.println("================================");
  }
}

When I ran the program, the values from the x and y axis of the joystick showed up fine on the SM, but the value from the push button was constantly 1.