0

Currently, my project is to get a x coordination , cX value, from a webcam connected to raspberry pi 3B+, and send it to Arduino Uno. I successfully do the action when the integer is in range 0 to 255. Can I modify my code and send a larger integer, say up to 1920 to Arduino?

Here is part of my python code on raspi side:

import serial
import struct

while True:
        ...
        cX = 248  //I want to send a larger number
        print (cX)
        ser.write(struct.pack('>H', cX))
        ...

Here is part of my c code on Arduino:

int cX = 0;

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

void loop()
{
 if (Serial.available()) 
 {
   cX = Serial.read();
   if (cX == 248)
    {
     //do something 
    }
 }
}

Any help would be greatly appreciated

Vincent Yu
  • 11
  • 4
  • You are reading only 1 byte at a time in the Arduino code. This means that you won't be able to read a value greater than 255. See `Serial.readBytes()` to be able to receive more that 1 byte, in this case, 2 bytes will allow you to send values up to 65535. – Hugo Cunha Aug 03 '20 at 16:49
  • Thank you for your prompt reply, Hugo. – Vincent Yu Aug 03 '20 at 16:57
  • So for 2 bytes, I need to write Serial.readBytes(buffer, 2). I have few questions: What should I declare for the variable buffer? I checked the example and it said byte or char, so it should be bytes[2]? Can I simply convert the value to int cX = Serial.readBytes(bytes[2],2)? Another question is for python side that does ser.write(struct.pack('>H', cX)) already sending integer more than 1 byte? – Vincent Yu Aug 03 '20 at 17:14
  • See my answer below. – Hugo Cunha Aug 03 '20 at 17:48

1 Answers1

0

Try this on the Arduino side:

unsigned int cX = 0;
byte buffer[2] = {0};
size_t len = 0;

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

void loop()
{
    if (Serial.available())
    {
        len = Serial.readBytes(buffer, 2);
        if (len == 2)
        {
            cX = (((int)buffer[0]) << 8) | buffer[1];
            if (cX == 1920)
            {
                //do something
            }
        }
    }
}

On the Python side, I don't know in detail, but from what I could see on the documentation, with the argument >H you should be sending an unsigned short (2 bytes size), big-endian, so it should work.

Hugo Cunha
  • 86
  • 4
  • Program has no mechanism (e.g. a message protocol) to ensure that sender and receiver are synchronized. For example, stop and restart the Arduino. Does it always receive the correct data after the restart? – sawdust Aug 04 '20 at 05:42
  • I understand your point and agree. But the point here is not to write a full-featured code but to guide the OP on how to solve that specific problem - send values greater than 255 by the serial interface. – Hugo Cunha Aug 04 '20 at 16:40
  • I have tried Hugo’s code and it works as long as the number greater than 32767 and it returns to -32768 when 32768 is sent. So i think change the int to long type in arduino would be more appropriate. Further to sawdust response, What should i do to synchronise the data when arduino is down and reconnected? – Vincent Yu Aug 04 '20 at 17:04
  • When using this transfer method, is that mean the data transfer speed would decrease to half. I.e 9600 braud rate, 9600 bits per second, originally i can send 9600/8= 1200 numbers per second, and now i can only send 600 numbers per second ? – Vincent Yu Aug 04 '20 at 17:13
  • Change `int cX` definition to `unsigned int cX` and you will be able to represent values from 0 to 65535, without increasing the payload size. Check the edited answer. – Hugo Cunha Aug 04 '20 at 19:28