Постоянная передача данных через Bluetooth на мониторинг

arduino-nano python hc-05 data stream

Я использую модуль Bluetooth HC-05 для потоковой передачи данных с Arduino на свой компьютер. На их компьютере я использую скрипт Python для получения

Они технические характеристики: Скорость передачи: 9600

Но я получаю сообщение об ошибке. Правильные данные, полученные в компьютере, должны быть:

b'123,098x726,8393x123x\r\n'

Что я почти всегда получаю, но иногда я получаю следующее:

b'123,098x726,8393x123x123,098x726,8393x123\r\n'. неверно

Поэтому я не знаю, бывает, в python я использую метод reset_input_buffer() и reset_output_buffer(), а в Arduino ide использую Serial.flush()

Ошибка сохраняется, может быть, это скорость передачи данных? Я увеличиваю это будет решение?

Заранее спасибо

String str;
String strs[8];

int pwm=9;

int tech;
String sync_fromApp = "?";
String sync_ok = "okx";

int cyc_num;
int PWM_0;
int PWM_i;
int PWM_f;

float volt;
float cur;
int t;

void setup() {
  // поместите сюда код установки для однократного запуска:
  TCCR1B = TCCR1B & B11111000 | B00000001;
  Serial.begin(9600);
  Serial.setTimeout(5);
  pinMode(A0, INPUT);
  pinMode(pwm, OUTPUT);
  analogWrite(pwm, 130);
  delay(1000);
}

void loop() {
  // поместите сюда ваш основной код для многократного запуска:
  int strCount = 0;
  if (Serial.available() > 0) {
    
    str = Serial.readString();
    str.trim();
    
    if (str == sync_fromApp) {
      Serial.println(sync_ok);
      //Serial.flush();
    }

    while (str.length() > 0) {
      int index = str.indexOf('x');
      if (index == -1) {
        strs[strCount++] = str;
        break;
      }
      else {
        strs[strCount++] = str.substring(0, index);
        str = str.substring(index + 1);
      }
    }

    tech = strs[0].toInt();
    float E0 = strs[1].toInt() / 1000.0;
    float Ei = strs[2].toInt() / 1000.0;
    float Ef = strs[3].toInt() / 1000.0;
    cyc_num = strs[4].toInt();
    int scan_rate = strs[5].toInt();
    int t_chro = strs[6].toInt();
    int t_step_chro = strs[7].toInt();
    float e00 = ((995.0 / 1986.0) * 5.06 + (995.0 / 1004.0) * E0);
    PWM_0 = e00 * (255 / 4.99); //Начальное напряжение
    float eii = ((995.0 / 1986.0) * 5.06 + (995.0 / 1004.0) * Ei);
    PWM_i = eii * (255 / 4.99)-1; //Минимальное напряжение
    float eff = ((995.0 / 1986.0) * 5.06 + (995.0 / 1004.0) * Ef);
    PWM_f = eff * (255 / 4.99)+1; // Максимальное напряжение
    long t = (4990000L) / (256L * scan_rate); // скорость сканирования задержки
    //По умолчанию:
    analogWrite(pwm, PWM_0);
    switch (tech) {
      //---Циклическая вольтамперометрия---
      case 1:
        delay(3000);
        for (int n = 1; n <= cyc_num; n++) {
          for (int val = PWM_0; val < PWM_f; val++) {
            analogWrite(pwm, val);

            volt = 0.01974563 * val - 2.558; //0,01974563
            cur = 0.51469 * (analogRead(A0)) - 255.226; //254.226

            Serial.print(volt, 3);
            Serial.print('x');
            Serial.print(cur, 3);
            Serial.print('x');
            Serial.print(val);
            Serial.println('x');
            Serial.flush();
            delay(t);
          }

          for (int val = PWM_f; val > PWM_i; val--) {
            analogWrite(pwm, val);

            volt = 0.01974563 * val - 2.558;
            cur = 0.50669 * (analogRead(A0)) - 255.226;
            //cur_ave = AnalogRead(A0);
            Serial.print(volt, 3);
            Serial.print('x');
            Serial.print(cur, 3);
            Serial.print('x');
            Serial.print(val);
            Serial.println('x');
            Serial.flush();
            delay(t);
          }
          PWM_0 = PWM_i;
          //Серийный.println(n);
        }
        Serial.println("Nx");
        Serial.flush();
        analogWrite(pwm, 130);
        tech = 0;
        break;
      default:
        break;
    }
  }
  else {
    digitalWrite(13, HIGH);
    delay(200);
    digitalWrite(13, LOW);
    delay(200);
  }
}

Вверху слева скетч Arduino.

Ниже приведен код Python

            self.ser.write(self.parametersToArduino.encode()) #command to start stream
            pass
        
        self.ser.reset_input_buffer()   #flush input buffer
        self.ser.reset_output_buffer()   #flush output buffer    
        COM.stop_button["state"] = "active"

        while self.threading:
            try:
                data.RowMsg = self.ser.readline()  # read data from arduino
                data.DecodeMsg()                   #decode data from arduino
                if len(data.RowMsg)>0:
                    if b'N' in data.RowMsg:
                        #print("It's over")

                        self.threading = False
                        break
                    data.upXData()  #update a list to plot
                    data.upYData()  #update a list to plot
                    self.ser.reset_input_buffer()
                    self.ser.reset_output_buffer()
                    pass
                pass
            except Exception as e:
                print(e)
                pass

DecodeMsg — код ниже

    def DecodeMsg(self):
        temporal = self.RowMsg.decode('utf8')
        if len(temporal)>0:
            if "x" in temporal:
                self.msg = temporal.split("x")
                del self.msg[-1]
                pass
            print(self.msg) #debugg
            pass
        pass

, 👍-1

Обсуждение

Проблема может быть на стороне Python. У вас есть другие средства мониторинга этого последовательного потока? Последовательный монитор Arduino, PuTTY, picocom или даже cat?, @Edgar Bonet

Спасибо за ответ. Да, я также использую последовательный монитор Arduino IDE, но ошибка все равно возникает. Это похоже на то, как если бы следующие данные потока были отправлены в то же время, что и предыдущие данные, @Elí Flores

У вас все еще есть та же ошибка, если вы удалите модуль Bluetooth и запустите последовательный поток через USB? Если это так, это может быть ошибка в скетче Arduino, и мы можем помочь найти ее, если вы поделитесь кодом., @Edgar Bonet

Я еще не тестировал с USB. Я мог бы протестировать, но позвольте мне загрузить скетч My Arduino., @Elí Flores

Готово, скетч уже загружен, спасибо., @Elí Flores

уменьшите свой код до постоянной отправки b'123.098x726.8393x123x\r\n, @jsotola

Извините, я не понимаю, что Вы имеете в виду? Вы предлагаете мне удалить другие операции? И мой код только со строками Serial.print()?, @Elí Flores

Я не совсем понимаю, что ты делаешь. В частности, какой ввод вы вводите в этот код. Что я заметил, так это то, что, кажется, не так уж много удерживает strCount от переполнения strs, @timemage

Поведение ввода работает нормально, проблема в выводе., @Elí Flores

Опубликуйте код Python., @Fahad

Конечно, выложу, @Elí Flores

Обновление: я загрузил код Python., @Elí Flores


1 ответ


0

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

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

Чтобы проверить это, я бы вставил счетчик в начало "packet" послан. Я подозреваю, что когда вы видите ошибку, вы сможете увидеть, что один пакет искажается, когда он переполняется. Итак, вы можете получить что-то вроде этого (где первые 3 цифры — это номер пакета):

b'001123,098x726,8393x123x\r\n' b'001123,098x726,8393x123x123,098x726,8393x123\r\n б'003123,098x726,8393x123x\r\n'

Возможно, это не является окончательным, но поможет лучше понять, что происходит.

Прежде чем сделать это, я бы, наверное, закомментировал: TCCR1B = TCCR1B & B11111000 | Б00000001; который увеличивает частоту ШИМ на 9. Это просто для того, чтобы посмотреть, изменит ли это поведение, поскольку это так легко проверить.

Надеюсь, это поможет, но я признаю, что это всего лишь предложение.

Кстати: интересная проблема, и я надеюсь, что вы расскажете нам, что происходит.

,