简体   繁体   中英

Python serial to Arduino

I'm currently trying to send 1024 bytes of data to an Arduino with external EEPROM.

But when running these code, the transmission often stopped before EOF is reached, and the whole process was just weird.

My code is as below:

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

And my arduino sketch:

#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");
      }
}

The whole data flow should be like this:

  1. Arduino continue to send address until it received an address from serial.
  2. Python sends send request srq\\n to serial.
  3. Arduino keeps reading serial input and check if it is srq\\n or EOF\\n .
  4. If it's srq\\n , Arduino sends OK\\n .
  5. Arduino sends read\\n suggesting it's ready to read.
  6. Python will send "send OK" SOK\\n to Arduino if it received read\\n
  7. Python starts sending data
  8. Loop step 1-6 until all 1024 bytes are sent.
  9. Python sends EOF\\n telling Arduino the data send is complete.

I thought my code was written correctly, but somehow it just doesn't work. I was trying to fix this all day long, but I'm really stuck.

My Python debug message just kept printing write srq and often the data transmit stops before EOF (I know it because RX/TX LEDs on Arduino board will stop flashing.)

I'm not familiar with serial at all, so I'm not sure if this is problem of my code or my lack of knowledge in serial data transmit.
Hope some one could help me with this.

You could download a 1024 byte test file from https://drive.google.com/open?id=1HLhxZfIcAf1iDZqIiWdlcYnRWB35MLqN if you don't mind.

Apologies for being blunt, but you really need to check your code. There are quite a few mistakes in your code.

As for your query, The reason python prints write srq and waits is because of the following part of the code

  while(checkSOK == false){

checkSOK is a function pointer, where as checkSOK() is a function.

Now the value of checkSOK will never be false, so your code never processes the "SOK\\n" and the 4 characters from the "SOK\\n" become a part of the 16 hexfile bytes, and your whole communication sequence goes haywire.

I couldn't really understand what you are trying to achieve with this code, but you should know, Arduino is very lenient with warnings, and hence finding problems in your code can be pretty difficult.

I would suggest going to Arduino preferences, and enabling detailed error and warning data.

I hope this helps, and good luck.

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.

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