Python 串行到 Arduino
Python serial to Arduino
我目前正在尝试将 1024 字节的数据发送到带有外部 EEPROM 的 Arduino。
但是运行这些代码的时候,传输经常在到达EOF之前就停止了,整个过程很奇怪。
我的代码如下:
import binascii
import os
import serial
import time
ser = serial.Serial('/dev/ttyUSB0',9600)
recv = -1
counter = 0
totalcount = 0
with open('TestCard.txt', 'rb') as f:
hexdata = binascii.hexlify(f.read())
hexlist = map(''.join, zip(*[iter(hexdata)]*2))
f.close
while(1):
#Wait for arduino to ask for address
if(ser.readline()=="address\n"):
ser.write("0")
print "written 0 \n" #Give arduino address I wanted to write
break
for a in hexlist:
ser.write("srq\n")
#Check if arduino is good to revcieve data
while(ser.readline() != "OK\n"):
if(ser.readline() == "write\n"):
print "write\n"
ser.write("srq\n")
print "srq\n"
while(ser.readline() != "read\n"):
if(ser.readline() == "read\n"):
print "sok\n"
ser.write("SOK\n")
break
print "sok\n"
ser.write("SOK\n")
#Send data
ser.write(a.encode())
print "written " + a.encode()
counter = counter + 1
totalcount = totalcount + 1
#else:
#while(ser.readline()!="Next Block\n" and ser.readline()!="Done\n"):
#continue
if(counter == 16 ):
print "\n\n16 bytes\n\n"
counter = 0
ser.write("EOF\n")
print "\nEOF\n"
ser.close()
还有我的arduino草图:
#include <Wire.h>
#include <SoftwareSerial.h>
byte buff[16];
int addr=-1;
int count=0;
char readed[5];
char srq[4] = "srq\n";
char eof[4] = "EOF\n";
char sok[4] = "SOK\n";
byte recv;
bool ended = false;
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.write(data[c]);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.read();
}
void LOL(char* arr)
{
strcpy(arr, "LOL\n");
}
bool checksrq(){
bool same = false;
for(int i=0 ; i<4; i++){
readed[i] == srq[i] ? same = true : same = false;
}
return same;
}
bool checkEOF(){
bool same = false;
for(int i=0 ; i<4; i++){
readed[i] == eof[i] ? same = true : same = false;
}
return same;
}
bool checkSOK(){
bool same = false;
for(int i=0 ; i<4; i++){
readed[i] == sok[i] ? same = true : same = false;
}
return same;
}
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if(ended == true){
delay(1000000);
}
while(addr==-1&& ended != true){
Serial.print("address\n");
addr = Serial.read();
delay(500);
}
while(1){
for(int i=0 ; i<4; i++){
readed[i] = Serial.read();
}
if(checksrq()){
delay(5);
Serial.write("OK\n");
LOL(readed);
break;
}else if(checkEOF()){
ended = true;
}
LOL(readed);
delay(1);
}
Serial.write("read\n");
while(checkSOK == false){
delay(1);
Serial.write("read\n");
}
for(int i=0; i<16 ; i++){
buff[i] = Serial.read();
count++;
}
LOL(readed);
if(count == 16 && ended != true){
for(int i=0 ; i<16 ; i++){
addr += i;
//i2c_eeprom_read_byte(0x50,addr)!= buff[i] ? i2c_eeprom_write_byte(0x50,addr,buff[i]) : delay(1);
delay(5);
Serial.write("write\n");
}
//i2c_eeprom_write_page(0x50, addr, buff, sizeof(buff));
//delay(10);
count = 0;
Serial.write("Next Block\n");
}
}
整个数据流应该是这样的:
- Arduino 继续发送
address
直到它从串口接收到一个地址。
- Python 向串口发送发送请求
srq\n
。
- Arduino 不断读取串行输入并检查它是
srq\n
还是 EOF\n
。
- 如果是
srq\n
,Arduino发送OK\n
。
- Arduino 发送
read\n
建议它已准备好读取。
- Python 如果接收到
read\n
将发送 "send OK" SOK\n
给 Arduino
- Python开始发送数据
- 循环步骤 1-6,直到发送完所有 1024 个字节。
- Python 发送
EOF\n
告诉 Arduino 数据发送完成。
我认为我的代码编写正确,但不知何故它不起作用。我整天都在尝试解决这个问题,但我真的卡住了。
我的 Python 调试消息一直在打印 write srq
并且数据传输经常在 EOF 之前停止(我知道是因为 RX/TX Arduino 板上的 LED 将停止闪烁。)
我对串口完全不熟悉,所以我不确定这是我的代码问题还是我对串口数据传输知识不足。
希望有人能帮我解决这个问题。
如果您不介意,可以从 https://drive.google.com/open?id=1HLhxZfIcAf1iDZqIiWdlcYnRWB35MLqN 下载 1024 字节的测试文件。
抱歉直言不讳,但您确实需要检查您的代码。您的代码中有不少错误。
关于您的查询,
python 打印 write srq 并等待的原因是因为以下部分代码
while(checkSOK == false){
checkSOK 是一个函数指针,其中 checkSOK() 是一个函数。
现在 checkSOK 的值永远不会为假,所以你的代码永远不会处理 "SOK\n" 并且 "SOK\n" 中的 4 个字符成为 16 个 hexfile 字节的一部分,你的整个通信序列失控。
我无法真正理解你试图用这段代码实现什么,但你应该知道,Arduino 对警告非常宽容,因此在你的代码中发现问题可能非常困难。
我建议转到 Arduino 首选项,并启用详细的错误和警告数据。
希望对您有所帮助,祝您好运。
我目前正在尝试将 1024 字节的数据发送到带有外部 EEPROM 的 Arduino。
但是运行这些代码的时候,传输经常在到达EOF之前就停止了,整个过程很奇怪。
我的代码如下:
import binascii
import os
import serial
import time
ser = serial.Serial('/dev/ttyUSB0',9600)
recv = -1
counter = 0
totalcount = 0
with open('TestCard.txt', 'rb') as f:
hexdata = binascii.hexlify(f.read())
hexlist = map(''.join, zip(*[iter(hexdata)]*2))
f.close
while(1):
#Wait for arduino to ask for address
if(ser.readline()=="address\n"):
ser.write("0")
print "written 0 \n" #Give arduino address I wanted to write
break
for a in hexlist:
ser.write("srq\n")
#Check if arduino is good to revcieve data
while(ser.readline() != "OK\n"):
if(ser.readline() == "write\n"):
print "write\n"
ser.write("srq\n")
print "srq\n"
while(ser.readline() != "read\n"):
if(ser.readline() == "read\n"):
print "sok\n"
ser.write("SOK\n")
break
print "sok\n"
ser.write("SOK\n")
#Send data
ser.write(a.encode())
print "written " + a.encode()
counter = counter + 1
totalcount = totalcount + 1
#else:
#while(ser.readline()!="Next Block\n" and ser.readline()!="Done\n"):
#continue
if(counter == 16 ):
print "\n\n16 bytes\n\n"
counter = 0
ser.write("EOF\n")
print "\nEOF\n"
ser.close()
还有我的arduino草图:
#include <Wire.h>
#include <SoftwareSerial.h>
byte buff[16];
int addr=-1;
int count=0;
char readed[5];
char srq[4] = "srq\n";
char eof[4] = "EOF\n";
char sok[4] = "SOK\n";
byte recv;
bool ended = false;
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}
// WARNING: address is a page address, 6-bit end will wrap around
// also, data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes
void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddresspage >> 8)); // MSB
Wire.write((int)(eeaddresspage & 0xFF)); // LSB
byte c;
for ( c = 0; c < length; c++)
Wire.write(data[c]);
Wire.endTransmission();
}
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}
// maybe let's not read more than 30 or 32 bytes at a time!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length ) {
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,length);
int c = 0;
for ( c = 0; c < length; c++ )
if (Wire.available()) buffer[c] = Wire.read();
}
void LOL(char* arr)
{
strcpy(arr, "LOL\n");
}
bool checksrq(){
bool same = false;
for(int i=0 ; i<4; i++){
readed[i] == srq[i] ? same = true : same = false;
}
return same;
}
bool checkEOF(){
bool same = false;
for(int i=0 ; i<4; i++){
readed[i] == eof[i] ? same = true : same = false;
}
return same;
}
bool checkSOK(){
bool same = false;
for(int i=0 ; i<4; i++){
readed[i] == sok[i] ? same = true : same = false;
}
return same;
}
void setup() {
Wire.begin();
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
if(ended == true){
delay(1000000);
}
while(addr==-1&& ended != true){
Serial.print("address\n");
addr = Serial.read();
delay(500);
}
while(1){
for(int i=0 ; i<4; i++){
readed[i] = Serial.read();
}
if(checksrq()){
delay(5);
Serial.write("OK\n");
LOL(readed);
break;
}else if(checkEOF()){
ended = true;
}
LOL(readed);
delay(1);
}
Serial.write("read\n");
while(checkSOK == false){
delay(1);
Serial.write("read\n");
}
for(int i=0; i<16 ; i++){
buff[i] = Serial.read();
count++;
}
LOL(readed);
if(count == 16 && ended != true){
for(int i=0 ; i<16 ; i++){
addr += i;
//i2c_eeprom_read_byte(0x50,addr)!= buff[i] ? i2c_eeprom_write_byte(0x50,addr,buff[i]) : delay(1);
delay(5);
Serial.write("write\n");
}
//i2c_eeprom_write_page(0x50, addr, buff, sizeof(buff));
//delay(10);
count = 0;
Serial.write("Next Block\n");
}
}
整个数据流应该是这样的:
- Arduino 继续发送
address
直到它从串口接收到一个地址。 - Python 向串口发送发送请求
srq\n
。 - Arduino 不断读取串行输入并检查它是
srq\n
还是EOF\n
。 - 如果是
srq\n
,Arduino发送OK\n
。 - Arduino 发送
read\n
建议它已准备好读取。 - Python 如果接收到
read\n
将发送 "send OK" - Python开始发送数据
- 循环步骤 1-6,直到发送完所有 1024 个字节。
- Python 发送
EOF\n
告诉 Arduino 数据发送完成。
SOK\n
给 Arduino
我认为我的代码编写正确,但不知何故它不起作用。我整天都在尝试解决这个问题,但我真的卡住了。
我的 Python 调试消息一直在打印 write srq
并且数据传输经常在 EOF 之前停止(我知道是因为 RX/TX Arduino 板上的 LED 将停止闪烁。)
我对串口完全不熟悉,所以我不确定这是我的代码问题还是我对串口数据传输知识不足。
希望有人能帮我解决这个问题。
如果您不介意,可以从 https://drive.google.com/open?id=1HLhxZfIcAf1iDZqIiWdlcYnRWB35MLqN 下载 1024 字节的测试文件。
抱歉直言不讳,但您确实需要检查您的代码。您的代码中有不少错误。
关于您的查询, python 打印 write srq 并等待的原因是因为以下部分代码
while(checkSOK == false){
checkSOK 是一个函数指针,其中 checkSOK() 是一个函数。
现在 checkSOK 的值永远不会为假,所以你的代码永远不会处理 "SOK\n" 并且 "SOK\n" 中的 4 个字符成为 16 个 hexfile 字节的一部分,你的整个通信序列失控。
我无法真正理解你试图用这段代码实现什么,但你应该知道,Arduino 对警告非常宽容,因此在你的代码中发现问题可能非常困难。
我建议转到 Arduino 首选项,并启用详细的错误和警告数据。
希望对您有所帮助,祝您好运。