Raspberry Pi和Arduino不与Python串行通信

2024-09-30 12:15:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图让树莓Pi向Arduino发送一个串行命令,然后Arduino解释该命令并相应地打开或关闭pin。我编写了一个python脚本,它只接受命令(是一个整数)并将其转换为字符串,然后对其进行编码并通过串行方式发送给Arduino。当我在命令行上尝试每个命令时,我会得到预期的结果,并且Arduino会打开,但是当我尝试使用该命令作为参数运行脚本时,它不起作用。在发送命令之前,我没有收到任何错误,并且所有打印都与预期的一样。我大致遵循本教程:

https://roboticsbackend.com/raspberry-pi-arduino-serial-communication/

Python代码:

import serial
import sys
import time

command = sys.argv[1]

if __name__ == '__main__':
    print(command)
    ser=serial.Serial('/dev/ttyACM0',9600, timeout=1)
    print((str(command)+"\n").encode('ascii'))
    ser.write((str(command)+"\n").encode('ascii'))
    time.sleep(0.2)
    response = ser.readline().decode('ascii').rstrip()
    f=open('/home/pi/responselog.txt', 'w')
    f.write(response)
    f.close()
    ser.close()

尝试通过脚本执行命令118时返回:

118
b'118\n'

通过Python shell执行write命令时返回:

4

Arduino代码:

#define F_CPU 16000000L //defines clock frequency

#include <avr/io.h> // Call in the AVR/IO library
#include <avr/delay.h> //Call in the AVR/delay library
#include <Arduino.h> //Call in the Arduino library

int incomingByte = 0;
int incoming[3];

int command = 0;
int ActivePump = 1;
int error = 0;

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

  // Set data direction registers for digital pins: each bit is set to 1 for output, 0 for input
  DDRA = 0xFF;
  DDRB = 0b00001111;
  DDRC = 0xFF;
  DDRD = 0x8F;
  DDRE = 0x38;
  DDRG = 0x27;
  DDRH = 0x08;
  DDRJ = 0x00;
  DDRL = 0xFF;


  //Set inital port values for digital pins
  PORTA = 0;
  PORTB = 0xF0;
  PORTC = 0;
  PORTD = 0;
  PORTE = 0;
  PORTG = 0;
  PORTH = 0x73;
  PORTJ = 0x03;
  PORTL = 0;
}

/*int ReadFlowRate(SensorNum) {
  SIGNAL(TIMER0_COMPA_vect){
    
  }

}*/

int ActivatePump(){
  if((PINB4 && ActivePump == 1) || (PINB5 && ActivePump == 2)){

    error = 1;
    return 1;
  }

  if(ActivePump == 1){
    PORTE += 0x10;
    return 0;
  } else {
    PORTE += 0x20;
    return 0;
  }
}

void StopPump(){
  if(ActivePump == 1){
    PORTE -= 0x10;
  } else {
    PORTE -= 0x20;
  }
}

void OpenMains(){
  PORTG += 0x20;
  PORTE += 0x08;
  PORTH += 0x08;
}

void CloseMains(){
  PORTG -= 0x20;
  PORTE -= 0x08;
  PORTH -= 0x08;
}

void loop() {
  if(Serial.available()){

    char First = Serial.read();
    // Serial.println(First); Debugging for serial communication
    if(First >= '0' && First <= '9'){
        command = (command*10)+(First-48); 
      } /*code for debugging the serial communication

      else if(First == 10){ 

        Serial.print("Command received: ");
        Serial.println(command);      
        }

    Serial.print("Command received: ");
    Serial.println(command);*/
    }

    int commandClass = command/100;
    int SubCommand = command-(commandClass*100);

    if(commandClass == 1){

      //1xx commands turn on digital pins

      switch(SubCommand){
        case 02:
          PORTE += 0x10;
          command = 0;
          break;
        case 03:
          PORTE += 0x20;
          command = 0;
          break;
        case 04:
          PORTG += 0x20;
          command = 0;
          break;
        case 05:
          PORTE += 0x08;
          command = 0;
          break;
        case 06:
          PORTH += 0x08;
          command = 0;
          Serial.println("Received");
          break;
        //Skipping 107-117 because those are input pins
        case 18:
          PORTD += 0x08;
          command = 0;
          break;
        case 19:
          PORTD += 0x04;
          command = 0;
          break;
        case 20:
          PORTD +=0x02;
          command = 0;
          break;
        case 21:
          PORTD += 0x01;
          command = 0;
          break;
        case 22:
          PORTA += 0x01;
          command = 0;
          break;
        case 23:
          PORTA +=0x02;
          command = 0;
          break;
        case 24:
          PORTA += 0x04;
          command = 0;
          break;
        case 25:
          PORTA += 0x08;
          command = 0;
          break;
        case 26:
          PORTA += 0x10;
          command = 0;
          break;
        case 27:
          PORTA += 0x20;
          command = 0;
          break;
        case 28:
          PORTA += 0x40;
          command = 0;
          break;
        case 29:
          PORTA += 0x80;
          command = 0;
          break;
        case 30:
          PORTC += 0x80;
          command = 0;
          break;
        case 31:
          PORTC += 0x40;
          command = 0;
          break;
        case 32:
          PORTC += 0x20;
          command = 0;
          break;
        case 33:
          PORTC += 0x10;
          command = 0;
          break;
        case 34:
          PORTC += 0x08;
          command = 0;
          break;
        case 35:
          PORTC += 0x04;
          command = 0;
          break;
        case 36:
          PORTC +=0x02;
          command = 0;
          break;
        case 37:
          PORTC += 0x01;
          command = 0;
          break;
        case 38:
          PORTD += 0x80;
          command = 0;
          break;
        case 39:
          PORTG += 0x04;
          command = 0;
          break;
        case 40:
          PORTG +=0x02;
          command = 0;
          break;
        case 41:
          PORTG += 0x01;
          command = 0;
          break;
        case 42:
          PORTL += 0x80;
          command = 0;
          break;
        case 43:
          PORTL += 0x40;
          command = 0;
          break;
        case 44:
          PORTL += 0x20;
          command = 0;
          break;
        case 45:
          PORTL += 0x10;
          command = 0;
          break;
        case 46:
          PORTL += 0x08;
          command = 0;
          break;
        case 47:
          PORTL += 0x04;
          command = 0;
          break;
        case 48:
          PORTL +=0x02;
          command = 0;
          break;
        case 49:
          PORTL += 0x01;
          command = 0;
          break;
        case 50:
          PORTB += 0x08;
          command = 0;
          break;
        case 51:
          PORTB += 0x04;
          command = 0;
          break;
        case 52:
          PORTB +=0x02;
          command = 0;
          break;
        case 53:
          PORTB += 0x01;
          command = 0;
          break;
      }
    } else if(commandClass==2){

      //2xx commands turn off digital pins

      switch(SubCommand){
        case 02:
          PORTE -= 0x10;
          command = 0;
          break;
        case 03:
          PORTE -= 0x20;
          command = 0;
          break;
        case 04:
          PORTG -= 0x20;
          command = 0;
          break;
        case 05:
          PORTE -= 0x08;
          command = 0;
          break;
        case 06:
          PORTH -= 0x08;
          command = 0;
          break;
        //Skipping 207-217 because those are input pins
        case 18:
          PORTD -= 0x08;
          command = 0;
          break;
        case 19:
          PORTD -= 0x04;
          command = 0;
          break;
        case 20:
          PORTD -=0x02;
          command = 0;
          break;
        case 21:
          PORTD -= 0x01;
          command = 0;
          break;
        case 22:
          PORTA -= 0x01;
          command = 0;
          break;
        case 23:
          PORTA -=0x02;
          command = 0;
          break;
        case 24:
          PORTA -= 0x04;
          command = 0;
          break;
        case 25:
          PORTA -= 0x08;
          command = 0;
          break;
        case 26:
          PORTA -= 0x10;
          command = 0;
          break;
        case 27:
          PORTA -= 0x20;
          command = 0;
          break;
        case 28:
          PORTA -= 0x40;
          command = 0;
          break;
        case 29:
          PORTA -= 0x80;
          command = 0;
          break;
        case 30:
          PORTC -= 0x80;
          command = 0;
          break;
        case 31:
          PORTC -= 0x40;
          command = 0;
          break;
        case 32:
          PORTC -= 0x20;
          command = 0;
          break;
        case 33:
          PORTC -= 0x10;
          command = 0;
          break;
        case 34:
          PORTC -= 0x08;
          command = 0;
          break;
        case 35:
          PORTC -= 0x04;
          command = 0;
          break;
        case 36:
          PORTC -=0x02;
          command = 0;
          break;
        case 37:
          PORTC -= 0x01;
          command = 0;
          break;
        case 38:
          PORTD -= 0x80;
          command = 0;
          break;
        case 39:
          PORTG -= 0x04;
          command = 0;
          break;
        case 40:
          PORTG -=0x02;
          command = 0;
          break;
        case 41:
          PORTG -= 0x01;
          command = 0;
          break;
        case 42:
          PORTL -= 0x80;
          command = 0;
          break;
        case 43:
          PORTL -= 0x40;
          command = 0;
          break;
        case 44:
          PORTL -= 0x20;
          command = 0;
          break;
        case 45:
          PORTL -= 0x10;
          command = 0;
          break;
        case 46:
          PORTL -= 0x08;
          command = 0;
          break;
        case 47:
          PORTL -= 0x04;
          command = 0;
          break;
        case 48:
          PORTL -=0x02;
          command = 0;
          break;
        case 49:
          PORTL -= 0x01;
          command = 0;
          break;
        case 50:
          PORTB -= 0x08;
          command = 0;
          break;
        case 51:
          PORTB -= 0x04;
          command = 0;
          break;
        case 52:
          PORTB -=0x02;
          command = 0;
          break;
        case 53:
          PORTB -= 0x01;
          command = 0;
          break;
      }
    } else if(commandClass==3){

      //3xx commands control pumps (302 & 303) and activate and deactivate water change (318-389)
      switch(SubCommand){
        case 02:
          ActivePump = 1;
          command = 0;
          break;
        case 03:
          ActivePump = 2;
          break;
        case 18:
          int errorCheck = ActivatePump();
          if(errorCheck == 0){
            OpenMains();
            PORTD += 0x08;
            command = 0;
            break;
          } else {
            command = 0;
            break;
          }
        case 54:
          PORTD -= 0x08;
          CloseMains();
          StopPump();
          break;

      }
    } else if(commandClass == 4){

      //4xx commands read analog inputs
      switch(SubCommand){

      }
    } else if(commandClass == 5){

      //5xx commands read digital inputs
      switch(SubCommand){

      }
    }/*case 400:
        int initalRead; 
        initialRead = analogRead(A0);
        Serial.println(initialRead);
        command = 0;
        break;*/    

}

编辑:我猜出来了。显然,ser.readline()命令抛出了一个异常,由于某种原因,该异常没有打印出来,直到我将一个监控程序连接到串行端口,然后它抛出了异常。我把那句话注释掉了,现在效果很好

编辑2:嗯,我说得太快了。如果未连接串行监视器程序,脚本仍无法工作


Tags: ifserialelsecommandarduinointcasebreak

热门问题