[Solved] Serial port - reading on select characters

I have python code sending to arduino two numbers 0, and 9...but because i have to encode it with python it will show up in the serial port in the following format:

b'0'
b'9'

The following arduino code will receive from serial mouse movement from 0-180 degrees...for now i am only sending two numbers from python 0 degrees and 9 degrees..... what change can i make to the arduino code so it is able to read the 0 and 9 without the other characters: b'0', b'9'

Arduino code:

#include <Servo.h>

Servo yservo;  Servo xservo; // servos for x and y
//set initial values for x and y
int ypos = 0;
int xpos= 0;

void setup(){
  xservo.attach(7); //(analog pin 0) for the x servo
  yservo.attach(15);  //(analog pin 1) for the y server

  Serial.begin(9600); // 19200 is the rate of communication
  Serial.println("Rolling"); // some output for debug purposes.

}

void loop() {
  static int v = 0; // value to be sent to the servo (0-180)
  if ( Serial.available()) {
    char ch = Serial.read(); // read in a character from the serial port and assign to ch
    switch(ch) { // switch based on the value of ch
      case '0'...'9': // if it's numeric
        v = v * 10 + ch - '0';
        /*
           so if the chars sent are 45x (turn x servo to 45 degs)..
           v is the value we want to send to the servo and it is currently 0
           The first char (ch) is 4 so
           0*10 = 0 + 4 - 0 = 4;
           Second char is 4;
           4*10 = 40 + 5 = 45 - 0 = 45;
           Third char is not a number(0-9) so we  drop through...
        */
        break;
      case 'x': // if it's x
      /*
       ....and land here
       where we send the value of v which is now 45 to the x servo
       and then reset v to 0
      */
        xservo.write(v);
        v = 0;
        break;
      case 'y':
        yservo.write(v);
        v = 0;
        break;
    }
  }
}

Please show the Python script that sends the data.

Maybe this might be helpful.
parseData() section
Getting the data you want and omit the rest.

https://gist.github.com/dwblair/97edd6b8bef565437f332d37db60f664

import serial
from time import sleep
ser7 = serial.Serial('COM8',9600)

while True:
	ser7.write(str.encode('9'))
	sleep(1)
	ser7.write(str.encode('0'))
	sleep(1)
#include <Servo.h>

Servo yservo;  Servo xservo; // servos for x and y
//set initial values for x and y
int ypos = 0;
int xpos= 0;

void setup(){
  xservo.attach(7); //(analog pin 0) for the x servo
  yservo.attach(15);  //(analog pin 1) for the y server

  Serial.begin(9600); // 19200 is the rate of communication
  Serial.println("Rolling"); // some output for debug purposes.

}

void loop() {
  static int v = 0; // value to be sent to the servo (0-180)
  if ( Serial.available()) {
    byte ch = Serial.parseInt(); // read in a character from the serial port and assign to ch
    switch(ch) { // switch based on the value of ch
      case 0:
      case 9: 
        v = v * 10 + ch;
        break;
    /*  case 'x': // if it's x
      
       ....and land here
       where we send the value of v which is now 45 to the x servo
       and then reset v to 0
        xservo.write(v);
        v = 0;
        break;
      case 'y':
        yservo.write(v);
        v = 0;
        break;      */
    }
  }
}

I'm not a python programmer but maybe one of the links in how to get rid of the b in python string - Google Search will help you to get rid of it.

The serial port transmits information in byte size packets and each byte has a value between 0 and 255. The bytes appearance when it reaches its destination depends on the way it is formatted.

If we want to transmit a value greater 255 we have a few options, perhaps the easiest is to transmit the values as a string and this is how arduino's print and println work. Your values b'9' and b'0' are strings but they are not in the format that you want

So here is an example along the lines of what I understand you wanting. The python code has two variables for the serial data, one variable is an integer and the second is a string variable. Both variables are converted to a string before transmission, the transmission string is called a "f" string in python and allows you to use variables in your strings, check it out.

The sample arduino code simply echoes the string back to the python script after a small math subtraction.

PY

import serial
from time import sleep

flush_system="<>".encode()

ser7 = serial.Serial('COM8',9600)
ser7.timeout=1
ser7.read_until(flush_system)

my_int=900
my_string='10'

while True:
	
	sleep(0.1)
	ser7.write(f"{my_int}\n".encode())
	input_string=ser7.readline().strip().decode("utf-8")
	print(input_string)

	sleep(0.1)
	ser7.write(f"{my_string}\n".encode())
	input_string=ser7.readline().strip().decode("utf-8")
	print(input_string)

ARDUINO

int my_integer;

void setup() {

  Serial.begin(9600);
  Serial.print("<>");
}

void loop() {
  
 if (Serial.available()) {
  
    my_integer = Serial.readStringUntil('\n').toInt(); 
    my_integer -= 6;
    Serial.println(my_integer);
    
 }

}

thank you :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.