title: Raspberry PI and Arduino Serial communication with Python
body: <p>I have some problems with serial communication between Raspberry Pi (Python Script) and Arduino nano/uno. I have both devices connected by USB port and when I send command directly from arduino IDE serial monitor, the arduino sketch always response correctly:</p>
  
  <pre><code>&lt;Arduino is ready&gt;
  &lt;MSG:GDI,RESPONSE:EMD-1707-1993,Time:7&gt;
  &lt;MSG:GDI,RESPONSE:EMD-1707-1993,Time:23&gt;
  &lt;MSG:GDI,RESPONSE:EMD-1707-1993,Time:26&gt;
  &lt;MSG:GDI,RESPONSE:EMD-1707-1993,Time:30&gt;
  &lt;MSG:GDI,RESPONSE:EMD-1707-1993,Time:34&gt;
  &lt;MSG:GDI,RESPONSE:EMD-1707-1993,Time:38&gt;
  </code></pre>
  
  <p>But, when I run the python script, and he send same command, the sketch response in a random way. </p>
  
  <p>Raspberry terminal:</p>
  
  <pre><code>pi@raspberrypi:~/test/raspberry $ python test.py 
  Sending GDI command to device...
  &lt;GDI&gt;
  Traceback (most recent call last):
    File "test.py", line 47, in &lt;module&gt;
      response = read_from_device(serial_connection)
    File "test.py", line 15, in read_from_device
      while ord(current_char) != MSG_START_CHAR: 
  TypeError: ord() expected a character, but string of length 0 found
  </code></pre>
  
  <p>Arduino serial monitor:</p>
  
  <pre><code>&lt;Arduino is ready&gt;
  MGIRSPi35
  </code></pre>
  
  <p>Mi code is:</p>
  
  <p>Arduino sketch: </p>
  
  <pre><code>#include &lt;EEPROM.h&gt;
  
  #define DEVICE_BAUD_RATE        9600
  
  #define EEPROM_SIZE             1024
  
  #define ID_PREFIX               "EMD-"
  
  #define MSG_START_CHAR          '&lt;'
  #define MSG_END_CHAR            '&gt;'
  
  #define MSG_GET_DEVICE_ID       "GDI"
  
  const byte buffSize = 40;
  char inputBuffer[buffSize];
  byte bytesRecvd = 0;
  boolean readInProgress = false;
  boolean newMsg = false;
  
  char cmd[buffSize] = {0};
  int pin = 0;
  int value = 0;
  
  unsigned long curMillis;
  
  void setup() {
    if(getDeviceId() == "") {
      setDeviceId();
    }
  
    Serial.begin(DEVICE_BAUD_RATE);
  
    while(!Serial) {
      ;
    }
  
    Serial.println("&lt;Arduino is ready&gt;");
  }
  
  void loop() {
    curMillis = millis();
    readMsg();
    processCommand();
  }
  
  void readMsg() {
    if(Serial.available() &gt; 0) {
      char x = Serial.read();
  
      if(x == MSG_END_CHAR) {
        readInProgress = false;
        newMsg = true;
        inputBuffer[bytesRecvd] = 0;
        strcpy(cmd, inputBuffer);
      }
  
      if(readInProgress) {
        inputBuffer[bytesRecvd] = x;
        bytesRecvd++;
  
        if(bytesRecvd == buffSize) {
          bytesRecvd = buffSize - 1;
        }
      }
  
      if(x == MSG_START_CHAR) { 
        bytesRecvd = 0; 
        readInProgress = true;
      }
    }
  }
  
  void processCommand() {
    if(strcmp(cmd, MSG_GET_DEVICE_ID) == 0) {
      sendMsg(getDeviceId());
    } else {
      sendMsg("Command Not Found");
    }
  }
  
  void sendMsg(String response) {
    if(newMsg) {
      newMsg = false;
      Serial.print("&lt;MSG:");
      Serial.print(cmd);
      Serial.print(",RESPONSE:");
      Serial.print(response);
      Serial.print(",Time:");
      Serial.print(curMillis &gt;&gt; 9);
      Serial.println("&gt;");
    }
  }
  
  String getDeviceId() {
    String id = "";
  
    for(int i=0; i&lt;EEPROM_SIZE; i++) {
      int value = EEPROM.read(i);
  
      if(value == 0xFF) {
        return id;
      }
  
      id += char(value);
    }
  
    return id;
  }
  
  void setDeviceId() {
    randomSeed(analogRead(0));
  
    String id = ID_PREFIX + String(random(1000, 10000)) + "-" + String(random(1000, 10000));
  
    for(int i=0; i&lt;EEPROM_SIZE; i++) {
      EEPROM.write(i, i&lt;id.length() ? id.charAt(i) : 0xFF);
    }
  }
  </code></pre>
  
  <p>Python script:</p>
  
  <pre><code>#!/usr/bin/python
  import os
  import serial
  
  MSG_START_CHAR              = '&lt;'
  MSG_END_CHAR                = '&gt;'
  
  MSG_GET_DEVICE_ID           = 'GDI'
  
  
  def read_from_device(serial_connection):  
      response = ""
      current_char = "z"
  
      while ord(current_char) != MSG_START_CHAR: 
          current_char = serial_connection.read()
  
      while ord(current_char) != MSG_START_CHAR:
          if ord(current_char) != MSG_START_CHAR:
              response = response + current_char 
  
          current_char = serial_connection.read()
  
      return(response)
  
  def write_to_device(serial_connection, msg):
      cmd = MSG_START_CHAR + msg + MSG_END_CHAR
  
      print(cmd)
  
      serial_connection.write(cmd)
  
  with serial.Serial('/dev/ttyACM0', 9600, timeout=10) as serial_connection:
      waiting_for_reply = False
  
      if waiting_for_reply == False:
          print('Sending {0} command to device...'.format(MSG_GET_DEVICE_ID))
  
          write_to_device(serial_connection, MSG_GET_DEVICE_ID)
  
          waiting_for_reply = True
  
      if waiting_for_reply == True:
          while serial_connection.inWaiting() == 0:
              pass
  
          response = read_from_device(serial_connection)
  
          print('Reply Received: {0}'.format(response))
  
          waiting_for_reply = False
  
      serial_connection.close()
  </code></pre>