Behavior when receiving data over serial port (PC to Arduino)

Hi,

I have a Python script that sends data over the serial port to the Arduino. When the Arduino receives data from the serial port it seems to 'reset' and run through the setup routine again. Is this normal behavior?

Basically I am monitoring a gmail account and then sending information to my uno and displaying messages on an LCD.

This code was thrown together quickly from examples...just trying to see if I can get everything to flow correctly.

Thanks!

Matt

Arduino code

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup(){
  // initialize the serial communications:
  Serial.begin(9600);
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  lcd.print("XXXXXXXX Environment Status");
  delay(1000);
  for (int i = 1; i < 12; i++) {
    lcd.scrollDisplayLeft();
    delay(300);
  }
  delay(500);
   for (int i = 1; i < 12; i++) {
    lcd.scrollDisplayRight();
    delay(300);
  }
  delay(3000);
  lcd.clear();
  lcd.print("Monitoring...");
}

void loop()
{
  // when characters arrive over the serial port...
  if (Serial.available()) {
    // wait a bit for the entire message to arrive
    delay(100);
    // clear the screen
    lcd.clear();
    // read all the available characters
    while (Serial.available() > 0) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }
  }
}

Python Script

import imaplib
import serial
import time
 
def serialSend(serMsg):
    # Open a connection to the serial port.
    ser = serial.Serial('COM7')   
    time.sleep(1.5)  
    # Send data over serial port
    written = ser.write(serMsg)
    ser.close()
    return

mlSubSrch1 = "build"
mlSubSrch2 = "online"
mlSubSrch3 = "reboot"
mlSubSrch4 = "ready"
mlSubSrch5 = "Build"

server = imaplib.IMAP4_SSL('imap.gmail.com','993')
server.login('xxx@gmail.com','xxxxxx')

count = 0

while (count < 10000):
    server.select('inbox')

    for i in server.search(None,'all')[1][0].split():
        mlSubject ="\n"+server.fetch(i,'(BODY[HEADER.FIELDS (Subject)])')[1][0][1]

        found1 = mlSubject.find(mlSubSrch1)
        found2 = mlSubject.find(mlSubSrch2)
        found3 = mlSubject.find(mlSubSrch3)
        found4 = mlSubject.find(mlSubSrch4)
        found5 = mlSubject.find(mlSubSrch5)

        dsEnv = mlSubject.split("is")[0]
        dsEnv = dsEnv[10:]
        dsEnv = dsEnv.strip()
        
        if found1 != -1:
           print dsEnv + "- Build"
           serialSend(dsEnv + "-Build")
        elif found2 != -1:
           print dsEnv + "- Online"
           serialSend(dsEnv + "-Online")
        elif found3 != -1:
           print dsEnv + "- Reboot"
           serialSend(dsEnv + "-Reboot")
        elif found4 != -1:
           print dsEnv + "- Online"
           serialSend(dsEnv + "-Online")
        elif found5 != -1:
           print dsEnv + "- Build"
           serialSend(dsEnv + "-Build")

        server.store(i, '+FLAGS', '\\Seen')
        server.store(i, '+FLAGS', '\\Deleted')

    server.expunge()
    count = count + 1
    print count
    time.sleep(2)

When the Arduino receives data from the serial port it seems to 'reset' and run through the setup routine again. Is this normal behavior?

No it implies that the script is disconnecting the port at the end and so causing the arduino to reset.
It is a problem with your script or drivers on your PC.

To use code on the pc that opens/closes the serial port on each data transmission, you will need to defeat the arduino auto reset with a resistor or capacitor.

you will need to defeat the arduino auto reset with a resistor or capacitor.

No you do this by cutting the reset enable link. But if you do that you will have to manually reset it at the right moment when you upload a new sketch.

No you do this by cutting the reset enable link. But if you do that you will have to manually reset it at the right moment when you upload a new sketch.

Adding a 150 ohm resistor between +5vdc and the reset pin will also defeat the auto-reset pulse, as well as a capacitor, but I forget the value needed. Cutting the trace as you say also does the job, just in a more permanent manner. :wink:

Lefty

look at your serial software for a no reset command on exit i.e. the DTR line

for example picocom uses the -r

picocom -r -b 9600 /dev/ttyUSB0

Your suggestions were very helpful! I was opening and closing the serial connection in the Python script each time I sent data to the Arduino. I took these statements out of my function and put them at the beginning and end of the script respectively. It is working fine now!

Thanks!

Matt

def serialSend(serMsg):
    # Open a connection to the serial port.
    #ser = serial.Serial('COM7')         # OPEN SERIAL CONNECTION
    time.sleep(1.5)  
    # Send data over serial port
    written = ser.write(serMsg)
    #ser.close()                               # CLOSE SERIAL CONNECTION
    return