简体   繁体   English

python + arduino控制直流电动机

[英]python + arduino controlling DC Motor

Hi This is my Arduino code, since I want the loop only once, I used the while(1) {} construct in the void loop() 嗨,这是我的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) {}
  }

This is my python code 这是我的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()

The communication isn't happening. 通讯没有发生。 Any insight should help. 任何见识都应该有所帮助。 I am using Python 3.5 and Arduino Uno with the updated drivers. 我正在将Python 3.5和Arduino Uno与更新的驱动程序配合使用。

Edit: 编辑:

Hi Julien, yes the following code does its job: 嗨,朱利安,是的,以下代码可以完成工作:

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:
}

I have also made the following changes 我还做了以下更改

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

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

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

doesn't seem to have any effect. 似乎没有任何作用。

The way I am accomplishing this is first uploading the Arduino program to memory, then running the Python script. 我完成此操作的方法是先将Arduino程序上传到内存,然后运行Python脚本。 No errors show up either.. 也没有错误显示。

Execution of the Ardiono code via Subprocess call in Python: 通过Python中的Subprocess调用执行Ardiono代码:

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 --")

Old post but I figured I'd post my findings with this incase anybody else sees this in the future. 旧帖子,但我认为我会把我的发现发布在这里,以防将来有人看到。

In the arduino file under the void setup() make sure to include 在void setup()下的arduino文件中,确保包括

Serial.begin(9600);

Otherwise the connection won't be established. 否则将无法建立连接。

Here is the completed working code I used to turn the motor on and off using 1 or 0 in python: 这是我用来在python中使用1或0打开和关闭电机的完整工作代码:

Arduino Code: 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 Code: 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()

try this : 尝试这个 :

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()

for the Arduino code, the test on Communication happens only once as it is located in setup function. 对于Arduino代码,对通讯的测试仅在设置功能中进行一次。 The loop() is the equivalent of the while(1) in the main loop that you may know from "normal" C codes. loop()与主循环中的while(1)等价,您可以从“正常” C代码中知道。

Reference manual for setup 设置参考手册

Reference manual for loop 循环参考手册

This means your arduino code is already in the while(1) in loop() once you execute the Python and it will never be alowed to analyse the serial data. 这意味着一旦执行Python,您的arduino代码就已经在loop()中的while(1)中,并且绝不会允许它分析串行数据。

The correct Arduino code would be : 正确的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);
        }
    }
}

Your Python code is sending the string '1', but your arduino code is looking for the number 1. Try changing the arduino code to this 您的Python代码正在发送字符串'1',但是您的arduino代码正在寻找数字1。尝试将arduino代码更改为此

Serial.read() == 0x31

and

Serial.read() == 0x30

Those are the ASCII codes for the '1' and '0' respectively 这些分别是“ 1”和“ 0”的ASCII码

The code in your setup() function has most likely already ran by the time you send the character from your python script. 在您从python脚本发送字符时,setup()函数中的代码很可能已经运行。

Place the code in the loop() function and then place some logic in the loop function so it only runs once. 将代码放在loop()函数中,然后在循环函数中放置一些逻辑,使其仅运行一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM