I implement a simply CmdMessenger example to permits Arduino communicate with PC via serial port.
The program intent to listen to serial waiting for the command '0;'. When this command is typed, Arduino reads a temperature sensor and write temperature result to serial.
It work's fine from serial monitor, but I cannot use it with PYthon using pySerial. I think I'm doing something wrong in python implementation, below is the code snippet: EDiTED: the code below runs as expected if I run in debug mode (on PyCharm). I put a breakpoint at beggining on this line:
if (not self.serialConnection.isOpen()): ...
and run with 'Resume Program' from there and it works. I don't know why it don't run in 'Normal Mode'.
import serial
import time
class Temperature:
def __init__(self, comPath='/dev/ttyACM0', bauds=115200):
self.serialConnection = serial.Serial(comPath, bauds, parity=serial.PARITY_ODD, stopbits=serial.STOPBITS_TWO,
bytesize=serial.SEVENBITS)
def queryTemperature(self):
if (not self.serialConnection.isOpen()):
self.serialConnection.open()
# prints True:
print self.serialConnection.isOpen()
self.serialConnection.write("0;\n")
time.sleep(2)
while self.serialConnection.inWaiting() == 0:
pass
# don't reach this point. It stops on loop above
time.sleep(2)
iw = self.serialConnection.inWaiting()
temp = (self.serialConnection.read(iw))
self.serialConnection.close()
return temp
and the call of the method queryTemperature:
from temp_read import *
dObject = Temperature('COM3')
print dObject.queryTemperature();
the program doesn't finish. It seems that it stops on the loop:
while self.serialConnection.inWaiting() == 0:
pass
bellow is the arduino sketch:
#include <CmdMessenger.h>
#include <OneWire.h>
#include <DallasTemperature.h>
int pinTemp = 13;
CmdMessenger cmdMessenger = CmdMessenger (Serial);
OneWire oneWire (pinTemp);
DallasTemperature sensors (&oneWire);
enum {
kReadTemperature,
kStatus,
};
void attachCommandCallbacks (){
cmdMessenger.attach (onUnknownCommand);
cmdMessenger.attach (kReadTemperature, onReadTemperature);
}
void onStatus (){
Serial.println ("status");
}
void onUnknownCommand (){
Serial.println ("unknow");
}
void onReadTemperature (){
Serial.println ("readTemp");
sensors.requestTemperatures();
delay (1500);
float temp = sensors.getTempCByIndex(0);
cmdMessenger.sendCmd(kStatus, (float) temp);
}
void setup() {
Serial.begin(115200);
sensors.begin ();
cmdMessenger.printLfCr();
attachCommandCallbacks();
}
void loop() {
cmdMessenger.feedinSerialData();
}
It's not using your code, but to achieve the same functionality, I have written a robust python interface to CmdMessenger ( https://github.com/harmsm/PyCmdMessenger ). You could use it to do this task by:
import PyCmdMessenger
# set up serial connection at proper baud rate
a = PyCmdMessenger.ArduinoBoard('/dev/ttyACM0',baud_rate=115200)
# list of commands at top of sketch, with argument formats
commands = [["kReadTemperature","f"],
["kSendTemperature","f"],
["kStatus","s"]]
cmd = PyCmdMessenger.CmdMessenger(a,commands)
cmd.send("kReadTemperature")
print(cmd.receive())
The changes to your arduino sketch would be adding kSendTemperature
to your initial command enumeration:
enum {
kReadTemperature,
kSendTemperature,
kStatus,
};
replacing your send command so it sends the float as a binary string:
//cmdMessenger.sendCmd(kStatus, (float) temp);
cmdMessenger.sendBinCmd(kSendTemperature, (float) temp);
and removing the extra Serial.Println(XXX)
commands.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.