0

I need to use my laptop talk with the Arduino(send a command to control state machine to make a simple vending machine) everything looks fine when I tried to put the command in the serial monitor but when I send the command via the python is not working. look like the state not change as I expect.

Here is the python code:

def query():
   cmd = "0"
   dev = serial.Serial("COM3", 9600,timeout=5)
   time.sleep(2)
   dev.write(cmd.encode("utf-8"))
   print("Pyhton: Query                  ",dev.readline())
   #time.sleep(1)
   #print(dev.readline())

def up():
   cmd = "1"
   dev = serial.Serial("COM3", 9600)
   time.sleep(2)
   dev.write(cmd.encode("utf-8"))
   print("Pyhton: up                     ",dev.readline())
   #time.sleep(1)
   #print(dev.readline())

def pickup():
   cmd = "2"
   dev = serial.Serial("COM3", 9600)
   time.sleep(2)
   dev.write(cmd.encode("utf-8"))
   print("Pyhton: pickup                  ",dev.readline())
   #time.sleep(1)
   #print(dev.readline())


def ship():
   cmd = "3"
   dev = serial.Serial("COM3", 9600)
   time.sleep(2)
   dev.write(cmd.encode("utf-8"))
   print("Pyhton: ship                 ",dev.readline())
   #time.sleep(1)
   #print(dev.readline())


def origin():
   cmd = "4"
   dev = serial.Serial("COM3", 9600)
   time.sleep(2)
   dev.write(cmd.encode("utf-8"))
   print("Pyhton: origin               ",dev.readline())
   #time.sleep(1)
   #print(dev.readline())


tokenDict = {
   "001":query,
   "002":up,
   "003":ship,
   "004":pickup,
   "005":origin
   }

lineList = [line.rstrip('\n') for line in open("cmd.txt")]

for line in lineList:
   time.sleep(1)
   functionToCall = tokenDict[line]
   functionToCall()

Here is the Arduino code:

int cmd = 0;
enum {IDLEx, UP, PICKUP, SHIP, ORIGIN};
uint8_t STATE = IDLEx;

void setup() {
  Serial.begin(9600);
  //Serial.flush();
  pinMode(LED_BUILTIN, OUTPUT);
}

void readSerialData() {
  if (Serial.available()>0) {
    delay(300);
    //cmd = Serial.readStringUntil('\n');
    cmd = Serial.read();
    process_serial(cmd, &STATE);
    //test(cmd);
  }
}

  void process_serial(int data, uint8_t *state)
  {
    switch (*state)

    {
      case IDLEx: {
          if (data == '0') {
            *state = IDLEx;
            Serial.println("Arduino: IDLE");

          } else if (data == '1' ) { //go to up state
            *state = UP;
            //Serial.println("Arduino: Up");
          } else if (data == '2') {
            *state = PICKUP;
            //Serial.println("Arduino: PICKUP");
          } else if (data == '3') {
            //Serial.println("Arduino: SHIP");
            *state = SHIP;
          } else if (data == '4') {
            //Serial.println("Arduino: ORIGIN");
            *state = ORIGIN;
          } 
          break;
        }
      case UP: {
          Serial.println("Arduino: UP");
          delay(1000);
          *state = PICKUP;
          break;
        }
      case PICKUP: {
          Serial.println("Arduino: PICKUP");
          delay(1000);
          *state = SHIP;
          break;
        }
      case SHIP: {
          Serial.println("Arduino: SHIP");
          delay(1000);
          *state = ORIGIN;
          break;
        }
      case ORIGIN: {
          Serial.println("Arduino: ORIGIN");
          delay(1000);
          *state = IDLEx;
        }
        break;
    }
  }
  void loop() {
    //Serial.println(STATE);
    readSerialData();
  }

I read the command from the text file something like

001
001
002
001
001
003
001
004
001
005

Here is the output I expect:

Pyhton: Query                   b'Arduino: IDLE\r\n'
Pyhton: Query                   b'Arduino: IDLE\r\n'
Pyhton: up                      b'Arduino: Up\r\n'
Pyhton: Query                   b'Arduino: Up\r\n'
Pyhton: Query                   b'Arduino: Up\r\n'
Pyhton: ship                  b'Arduino: SHIP\r\n'
Pyhton: Query                   b'Arduino: SHIP\r\n'
Pyhton: pickup                   b'Arduino: PICKUP\r\n'
Pyhton: Query                   b'Arduino: PICKUP\r\n'
Pyhton: origin                b'Arduino: ORIGIN\r\n'

My issue is when I send the data to Arduino seems like Arduino not change the State(Swith case as the code) please note that I use the Arduino nano 328 and python 3.x Can anyone suggest to me? How I can solve this issue?

4
  • Do you mean Serial.readStringUntil('\n'); in Arduino? if yes, it not in use Commented Jun 19, 2020 at 9:48
  • 1
    Why do you have this line: dev = serial.Serial("COM3", 9600) repeated over and over in each function. That should happen ONCE at the beginning and then just keep using that same serial port. Every time you open that port you reset the board. Put something in your setup function to print something so you can see if the board is being reset each time you send data. Commented Jun 19, 2020 at 13:14
  • Thank you very much that is working now. Commented Jun 19, 2020 at 13:41
  • I will make it an answer then. Please accept it. Commented Jun 19, 2020 at 13:41

1 Answer 1

1

In each one of your functions you have this line:

dev = serial.Serial("COM3", 9600)

That line opens the serial port which resets the Arduino board. To avoid this you should open that port once at the beginning of your program and then just keep using that same instance of the serial port each time instead of recreating it in each function.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. it very helpful for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.