Проблема с первыми двумя образцами последовательных данных, полученных RPi
Я пытаюсь получить строку от Arduino к Raspberry Pi через соединение с разъемом Bluetooth (RFCOMM). Я использую модуль Bluetooth HC-06, Arduino UNO R3 и RPi 4 модели B. По большей части все работает хорошо-за исключением первых двух образцов данных. Вот как обычно выглядит мой вывод, когда я просматриваю его с терминала RPi:
0.
06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
0.06,21,0.01,64
Есть ли какой-нибудь способ заставить первые две строки правильно отображать данные? Эти данные представляют собой единственную строку, и я выбрал свой буфер размером 32 бита, поэтому я не думаю, что проблема в размере буфера. Мне пришлось добавить время.delay(4) в моем сценарии Py, иначе каждый образец данных выглядел бы испорченным. Я пытался безжалостно регулировать временную задержку, но, похоже, не могу правильно отобразить первые два образца. Ниже приведен фрагмент моего кода на Python:
while 1:
try:
received_data = bluetoothSocket.recv(24)
formatted_data = received_data.decode("utf-8")
print("Received Data: ", formatted_data)
time.sleep(4)
except KeyboardInterrupt:
print("keyboard interrupt detected")
break
bluetoothSocket.close()
@phosphorescent, 👍1
Обсуждение2 ответа
Возможно, вы захотите попробовать отправить данные в пакете, разделенном уникальными символами, например {
и}
, аналогично формату JSON.
Стандарт GPS NMEA использует $
и '\n' для разделения сообщений.
Вот неблокирующий алгоритм Arduino на C++, который основан на примере readline()
Майенко для чтения пакета. Он возвращает значение true, когда входящие данные были собраны в допустимый пакет. Преобразовать его в Python должно быть довольно просто.
void setup()
{
Serial.begin(115200);
Serial.println(F("\n\nSerial Packet Test\n"));
pinMode(LED_BUILTIN, OUTPUT);
}
void loop()
{
const static unsigned int INTERVAL = 200;
static unsigned long previous_timestamp = millis();
unsigned long current_timestamp = millis();
static bool led_state = false;
if (current_timestamp - previous_timestamp >= INTERVAL)
{
led_state = !led_state;
digitalWrite(LED_BUILTIN, led_state);
previous_timestamp += INTERVAL;
}
static char packet[100];
if (ReadPacket(Serial, packet, sizeof(packet)))
{
Serial.print(F("Received packet >"));
Serial.print(packet);
Serial.println(F("<"));
}
}
bool ReadPacket(Stream& stream, char *const packet, const unsigned int SIZE)
{
const char FIRST = '{';
const char LAST = '}';
static bool read_until_last = false;
static unsigned int i = 0;
char ch;
if (stream.available())
{
ch = stream.read();
if (ch == FIRST)
{
Serial.println(F("Received FIRST."));
i = 0;
packet[0] = ch;
read_until_last = true;
return false;
}
if (read_until_last)
{
i++;
if (i > SIZE - 2)
{
Serial.println(F("Buffer overrun. Resetting to look for next packet."));
i = 0;
read_until_last = false;
return false;
}
if (ch == LAST)
{
Serial.println(F("Received LAST."));
packet[i++] = ch;
packet[i] = 0;
read_until_last = false;
return true;
}
else
{
Serial.print(F("Received char >"));
Serial.print(ch);
Serial.println("<");
packet[i] = ch;
return false;
}
}
}
return false;
}
Я не знаю, что исправляет оператор time.sleep(4)
, но вы можете попробовать переместить его в верхнюю часть цикла вместо нижней, чтобы он предшествовал первому чтению. В нижней части цикла первое выполнение происходит после первого чтения.
- Отправка/получение данных от/на Raspberry Pi к/от Arduino с помощью HM-10 (модуль Bluetooth LE)
- Связь Arduino с Raspberry Pi с помощью HC-05
- Можно ли измерить скорость акселерометром? Насколько точно?
- Модуль Bluetooth HC-05 мигает красным светом - Arduino Uno
- Модуль Bluetooth HC-05 возвращает закодированные данные
- Мой модуль Bluetooth HC-05 не работает
- Установите Arduino IDE в Raspberry Pi 3 модели B.
- Модуль AT-команд HM10 BLE — не работает
почему вы говорите, что это проблема с первыми двумя образцами? ... это похоже на проблему только с одной строкой, @jsotola
@jsotola, ты прав. Это всего лишь первый образец, разделенный на две строки., @phosphorescent
Это могут быть некоторые предыдущие данные, буферизованные HC-06, которые, наконец, поступают после открытия порта rfcomm. Вы ничего не можете с этим поделать, если только не создадите двунаправленный протокол для инициирования связи только после того, как порт открыт и принимающая программа готова к приему., @Majenko
@Majenko Есть ли какой-либо способ в получающем сценарии Py, чтобы сокет "удерживал" входящую строку до тех пор, пока не произойдет определенное событие? Я слышал, что может быть способ сделать это так, чтобы при достижении "\n" все было выпущено из сокета., @phosphorescent
@фосфоресцирующий Я не знаю - это Питон. Я не использую Python. Лично я бы попросил Arduino вообще ничего не делать, пока ваша программа на Python не запросит данные для отправки. Таким образом, не может быть никаких проблем с буферизацией. Кроме того, да, вы должны считывать данные с точностью до "\n " и использовать их в качестве разделяющего фактора при общении, вместо того, чтобы предполагать 24 байта., @Majenko
Простое исправление: сначала отправьте шаблон вместо того, чтобы сразу переходить к данным. Что-то вроде "--BEGIN--\n", которое вы можете легко удалить в python., @dandavis