Using pyserial all messages are sent together instead of 1 by 1

Hi guys,

I'm using pyserial in order to send some values from Python PC to Arduino, the main problem is that I use serial.write(1) several times in Python and then read them with Serial.parseInt();
The Python program get stucks and then receive all the prints that I have between serial.write all together except the first one. Any suggestions??

Arduino code:

void setup() {
  /*
   * --- SERIAL COMMUNICATION DATA FROM RASPBERRY/PC
   */
  //Start serial communication
  Serial.begin(9600);
  //Set preescaler 
  int preescaler = 0;
  while(preescaler == 0){
    preescaler = Serial.parseInt();
  }
  //Set compare register
  int registerCheck = 0;
  while(registerCheck == 0){
    registerCheck = Serial.parseInt();
  }
  //Set key length
  while(keyLen == 0){
    keyLen = Serial.parseInt();
  }
  //Read as many keys as indicated and store them in a byte array
  byte laserArray[keyLen] = {0};
  for(int i = 0;i<keyLen;i++){
    int data = 0;
    while(data == 0){
      data = Serial.parseInt();
      laserArray[i] = data;
    }
 
  }

And Python:

ser = serial.Serial(ArduinoVars.PORT.value, ArduinoVars.BOUND.value)
        progress_callback.emit(1)
        #Write preescalar to arduino
        self.__writeDataToArduino(ser,self.__prescaler)
        print("WROTE")
        #Write register to arduino
        self.__writeDataToArduino(ser, self.__register)
        print("WROTE")
        #For each laser array send to arduino
        for register in self.__laserArray:
            print("WROTE")
            self.__writeDataToArduino(ser, register)
        print("WROTE END")
        #Wait until beacon signal to start sending all to 1

        while self.__waitFlag[0]:
            pass
        self.__waitFlag[0] = True
        print("DONE")
        progress_callback.emit(2)
        #Send signal of starting all to 1 beacon
        self.__writeDataToArduino(ser,1)
        #Wait until signal that beacon is ok FROM TCP
        while self.__waitFlag[0]:
            pass

        #Send signal to start sending beacon msg and then qubits
        self.__writeDataToArduino(ser,1)
        #Wait until arduino say it has finished
        print(self.__readDataFromArduino(ser))
        print("FINISH")

    def __writeDataToArduino(self,ser,msg):
        ser.write(msg)

I just only see the first WROTE and then after a few seconds all the WROTE come together. By the way, when I use the Serial Monitor it works well.

looks like your code expects to read a series of non-zero ascii digits. for example "1298764111" without any delimiter between them, not even a space, " ". and the string must be a non-zero value otherwise is it read again

a more conventional approach would be to send the numeric strings terminated by a linefeed or carriage return, read the entire line and extract the numeric value. the following is pretty basic

char buf [80];

void loop ()
{
    if (Serial.available ())  {
        int n = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
        buf [n] = '\0';

        Serial.println (atoi(buf));
    }
}

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

a more elaborate approach is naming the values. the following output results from an input string

prescaler 55 register 29 keylen 9 1 2 3 4 
      0  prescaler
     55  55
      0  register
     29  29
      0  keylen
      9  9
      1  1
      2  2
      3  3
      4  4
char s [80];

#define MaxTok  20
char *toks [MaxTok];
int   vals [MaxTok];

// -----------------------------------------------------------------------------
int
tokenize (
    char       *s,
    const char *sep )
{
    unsigned n = 0;
    toks [n] = strtok (s, sep);
    vals [n] = atoi (toks [n]);

    for (n = 1; (toks [n] = strtok (NULL, sep)); n++)
        vals [n] = atoi (toks [n]);

    return n;
}

// -----------------------------------------------------------------------------
void dispToks (
    char * toks [])
{
    char s [40];
    for (unsigned n = 0; toks [n]; n++)  {
        sprintf (s, " %6d  %s", vals [n], toks [n]);
        Serial.println (s);
    }
}

// -----------------------------------------------------------------------------
void loop ()
{
    if (Serial.available ())  {
        int n = Serial. readBytesUntil ('\n', s, sizeof(s)-1);
        s [n] = 0;      // terminate string

        tokenize (s, " ");
        dispToks (toks);
    }
}

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

this approach suggests sending name value pairs and looking up the received name and setting a variable to the integer value

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