【问题标题】:Python + Arduino controlling DC MotorPython + Arduino 控制直流电机
【发布时间】:2016-12-30 15:50:45
【问题描述】:

嗨,这是我的 Arduino 代码,因为我只想要循环一次,所以我在 void loop() 中使用了 while(1) {} 构造

int motorPin = 3;
int motorDir = 12;
int motorBr = 9;

void setup() {
 //pinMode(motorPin, OUTPUT);
 pinMode(motorBr, OUTPUT);  
 pinMode(motorDir, OUTPUT);
 
 if (Serial.available() > 0) {

  if(Serial.read() == '1') {    
    digitalWrite(motorBr, LOW);
    digitalWrite(motorDir, HIGH);
    digitalWrite(motorPin, HIGH);
    delay(500); 
    digitalWrite(motorBr, HIGH);


  } else if(Serial.read() == '0') {
    digitalWrite(motorBr, LOW);
    digitalWrite(motorDir, LOW);
    digitalWrite(motorPin, HIGH);
    delay(500); 
    digitalWrite(motorBr, HIGH);
  }
 }
 
}

void loop() { while(1) {}
  }

这是我的 Python 代码:

import serial
import time

ser = serial.Serial('COM3', 9600, timeout=1)
time.sleep(2)


#I am forcing the script to write 1 to Arduino to make the motor turn

ser.write(b'1')

ser.flush()

time.sleep(2)

ser.close()

但是,通信没有发生。任何见解都应该有所帮助。我正在使用带有更新驱动程序的 Python 3.5 和 Arduino Uno。

编辑:

你好 Julien,是的,下面的代码完成了它的工作:

int motorPin = 3;
int motorDir = 12;
int motorBr = 9;

void setup() {
 // put your setup code here, to run once:
 //pinMode(motorPin, OUTPUT);
 pinMode(motorBr, OUTPUT);  
 pinMode(motorDir, OUTPUT);
 
 digitalWrite(motorBr, LOW);
 digitalWrite(motorDir, HIGH);
 digitalWrite(motorPin, HIGH);
 delay(500); 
 digitalWrite(motorBr, HIGH);

 delay(2000);
 
 digitalWrite(motorBr, LOW);
 digitalWrite(motorDir, LOW);
 digitalWrite(motorPin, HIGH);
 delay(500); 
 digitalWrite(motorBr, HIGH);
}

void loop() {
  // put your main code here, to run repeatedly:
}

我还做了以下改动:

ser.write('1') --> ser.write(b'1')

Serial.read() == 1 --> Serial.read() == '1' 

Serial.read() == 1 --> Serial.read() == 0x31 

似乎没有任何作用。

我实现这一点的方法是首先将 Arduino 程序上传到内存,然后运行 ​​Python 脚本。也没有出现错误。

通过 Python 中的 Subprocess 调用执行 Arduino 代码:

import subprocess

actionLine = "upload"
projectFile = "C:/Users/Tomography/Desktop/DCM2/DCM2.ino"
portname = "COM3"
boardname = "arduino:avr:uno"

#I added the ardiono.exe to path, the command automatically sources the 
Command = "arduino" + " --" + actionLine +" --board " + boardname + " --port " + portname + " " + projectFile

print(Command)

result = subprocess.call(Command)

if result != 0:
 print("\n Failed - result code = %s --" %(result))
else:
 print("\n-- Success --")

【问题讨论】:

  • 我想 arduino 代码已经过测试并可以与终端通信一起使用?尝试在写入之后进行刷新,尽管我认为还有另一个问题。这将强制硬件写入
  • 我已经更新了 Arduino 代码,我认为它应该可以解决您的问题。无论如何:在这种情况下,要知道问题是来自 Arduino 还是 Python,应该始终进行独立测试。您可以使用 Arduino IDE 工具-> 串行监视器(我们确定这可以正常工作,但不确定您的代码)将 1 和 0 写入串行。如果这行得通,那么 Python 是错误的,否则就是 Arduino 代码(那么它不能证明 Python 可以工作......)。这将帮助您进行调试。您也可以将 println 放入您的代码 Arduino 代码中,它会出现在串行监视器中并帮助您调试
  • 感谢您的指点,独立代码适用于 Arduino。我正在尝试查看是否可以将某些内容从 Arduino 发送到 Python,以查看通信是否正常。仅供参考,我决定使用 subprocess 模块并像在命令行上一样执行 arduino 程序:Command = arduino + " --" + "--upload" + " --port " + portLine + projectFile print("\n\n -- Arduino 命令 --") print(Command) result = subprocess.call(Command) 效果很好。我会将代码 sn-p 添加到我之前的帖子中

标签: python arduino serial-port


【解决方案1】:

旧帖子,但我想我会用这个发布我的发现,以防其他人在未来看到这个。

在 void setup() 下的 arduino 文件中确保包含

Serial.begin(9600);

否则无法建立连接。

这是我用来在 python 中使用 1 或 0 打开和关闭电机的完整工作代码:

Arduino 代码:


void setup() {
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600);
}

void loop() //This will be executed over and over
{ 
    if (Serial.available() > 0) {
        if(Serial.read() == '1') {
          analogWrite(motorPin, 50);
        } 
        else if(Serial.read() == '0') {
          analogWrite(motorPin, 0);
        }
    }
}

Python 代码:

import serial
import time

ser = serial.Serial('COM3', 9600) //established connection

time.sleep(2)

ser.write(b'1') ##sends '1' to serial 

time.sleep(5) ##motor runs for this period

ser.write(b'0') ##sends '0' to serial on arduino to turn motor off

ser.close()

【讨论】:

    【解决方案2】:

    试试这个:

    import serial
    import time
    
    ser = serial.Serial('COM3', 9600, timeout=1) #here you may add write_timeout=1 to avoid indefinite blocking on failing flush
    
    time.sleep(2)
    
    ser.write('1')
    ser.flush() #force the physical write
    
    #time.sleep(2) #no need to sleep as flush was blocking
    
    ser.close()
    

    对于 Arduino 代码,通信测试只发生一次,因为它位于 setup 函数中。 loop() 相当于主循环中的 while(1),您可能从“普通”C 代码中知道。

    Reference manual for setup

    Reference manual for loop

    这意味着一旦您执行 Python,您的 arduino 代码就已经在 loop() 中的 while(1) 中,并且永远不会被允许分析串行数据。

    正确的 Arduino 代码是:

    int motorPin = 3;
    int motorDir = 12;
    int motorBr = 9;
    
    void setup() //this is executed only once at init
    {
     //pinMode(motorPin, OUTPUT);
     pinMode(motorBr, OUTPUT);  
     pinMode(motorDir, OUTPUT);
    }
    
    void loop() //This will be executed over and over
    { 
        if (Serial.available() > 0) {
    
            // here '1' (the character) is important as 1 is the number
            // and '1' equals 0x31 (ASCII)
            if(Serial.read() == '1') {   
                digitalWrite(motorBr, LOW);
                digitalWrite(motorDir, HIGH);
                digitalWrite(motorPin, HIGH);
                delay(500); 
                digitalWrite(motorBr, HIGH);
            } else if(Serial.read() == '0') {
                digitalWrite(motorBr, LOW);
                digitalWrite(motorDir, LOW);
                digitalWrite(motorPin, HIGH);
                delay(500); 
                digitalWrite(motorBr, HIGH);
            }
        }
    }
    

    【讨论】:

    • 我尝试了 ser.flush() 方法,至少现在还不行。也许还有其他事情发生。
    【解决方案3】:

    您的 Python 代码正在发送字符串“1”,但您的 arduino 代码正在寻找数字 1。尝试将 arduino 代码更改为此

    Serial.read() == 0x31
    

    Serial.read() == 0x30
    

    这些分别是 '1' 和 '0' 的 ASCII 码

    在您从 python 脚本发送字符时,您的 setup() 函数中的代码很可能已经运行。

    将代码放在 loop() 函数中,然后在 loop 函数中放置一些逻辑,使其只运行一次。

    【讨论】:

    • 大家好,感谢 cmets,我对原始帖子进行了一些更改以接听您的电话。感谢您的时间。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多