Серийный Python для Arduino - PullRequest
0 голосов
/ 11 мая 2018

В настоящее время я пытаюсь отправить 1024 байта данных в Arduino с внешней EEPROM.

Но при запуске этого кода передача часто прекращалась до достижения 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");
      }
}

Весь поток данных должен быть таким:

  1. Arduino продолжает отправлять address, пока не получит адрес от серийного номера.
  2. Python отправляет запрос на отправку srq\n на серийный номер.
  3. Arduino продолжает читать последовательный ввод и проверяет, является ли он srq\n или EOF\n.
  4. Если это srq\n, Arduino отправляет OK\n.
  5. Arduino отправляет read\n, предполагая, что он готов к чтению.
  6. Python отправит «отправить OK» SOK\n в Arduino, если он получил read\n
  7. Python начинает отправку данных
  8. Повторять шаги 1-6, пока не будут отправлены все 1024 байта.
  9. Python отправляет EOF\n, сообщая Arduino, что отправка данных завершена.

Я думал, что мой код написан правильно, но почему-то он просто не работает. Я пытался исправить это весь день, но я действительно застрял.

Мое отладочное сообщение Python только продолжало печататься write srq, и часто передача данных прекращается до EOF (я знаю это, потому что светодиоды RX / TX на плате Arduino перестанут мигать.)

Я совсем не знаком с последовательным интерфейсом, поэтому я не уверен, является ли это проблемой моего кода или моего недостатка знаний в передаче последовательных данных.
Надеюсь, кто-нибудь сможет мне помочь с этим.

Вы можете загрузить 1024-байтовый тестовый файл с https://drive.google.com/open?id=1HLhxZfIcAf1iDZqIiWdlcYnRWB35MLqN, если не возражаете.

1 Ответ

0 голосов
/ 14 мая 2018

Извините за грубость, но вам действительно нужно проверить свой код. В вашем коде немало ошибок.

Что касается вашего запроса, Причина, по которой python печатает write и ждет, заключается в следующей части кода

  while(checkSOK == false){

checkSOK - это указатель на функцию, где checkSOK () - это функция.

Теперь значение checkSOK никогда не будет ложным, поэтому ваш код никогда не обрабатывает «SOK \ n», и 4 символа из «SOK \ n» становятся частью 16 байтов шестнадцатеричного файла, и вся ваша коммуникационная последовательность идет непрочное.

Я не мог понять, чего вы пытаетесь достичь с помощью этого кода, но вы должны знать, что Arduino очень снисходительно относится к предупреждениям, и, следовательно, поиск проблем в вашем коде может быть довольно трудным.

Я бы предложил перейти в настройки Arduino и включить подробные данные об ошибках и предупреждениях.

Надеюсь, это поможет, и удачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...