Ошибка типа данных Bluetooth Arduino

В моем коде я хочу отправить несколько значений с плавающей запятой с моего телефона на Bluetooth Arduino, которые я затем разделю с помощью функции подстроки. затем он напечатает это разделенное значение на последовательном мониторе.

Я даже не знаю, что не так, но ошибки нет, и он просто выдает код ascii этих чисел (не разделенный). Пожалуйста, помогите, если кто-нибудь имеет какие-либо идеи. Вот мой код:

#include <Wire.h>
#include<SoftwareSerial.h>
#define TxD 3 
#define RxD 2 
SoftwareSerial bluetoothSerial(TxD,RxD);

String Sstring;
String arrayOne;

void setup() 
{
  bluetoothSerial.begin(9600);  
  Serial.begin(9600);
}

void loop() 
{
 
 if(bluetoothSerial.available()>0)
 {
  
  arrayOne=bluetoothSerial.read();
  
  Sstring=arrayOne.substring(0);
  Serial.println(Sstring);
 } 
}

, 👍0


2 ответа


0

Я предполагаю, что это строка arrayOne=bluetoothSerial.read(); преобразует полученное значение в строку (символьный массив символов ASCII, оканчивающийся символом '\0'). Затем вы копируете эту строку в другую строковую переменную. Если вы хотите разделить строку, вы должны:

  • определить начальный символ > 0
  • и/или: определите конечный символ < общий размер строки.

Для получения дополнительной информации см. эту ссылку.

Вы можете попробовать следующее. Я уверен, что он далек от совершенства, но может помочь вам в этом.

void setup()
{
    bluetoothSerial.begin(9600);
    Serial.begin(9600);
}

void loop()
{
    if (bluetoothSerial.available)
    {
        delay(100); // немного подождем, пока последовательный буфер не заполнится. Это значение должно быть как можно короче.

        // Сохраняем байты буфера как число с плавающей запятой (Big Endian!)
        double received_float = (bluetoothSerial.read() << 24) | (bluetoothSerial.read() << 16) | (bluetoothSerial.read() << 8) | (bluetoothSerial.read());
        Serial.println(received_float);
    }
}

Некоторые соображения:

  • Количество байтов, которое занимает число с плавающей запятой, может отличаться на вашем телефоне и на вашей плате Arduino. В приведенном выше примере используется 32-битное число с плавающей запятой.
  • Если возможно, вы хотите начать передачу с последовательности начальных символов. Таким образом, вы можете быть уверены, что прочитали правильное значение.
,

Есть несколько проблем с этим способом построения числа с плавающей запятой из отдельных байтов: 1. Порядок байтов не определен: это будет любой порядок, который эта версия компилятора решит использовать в этот день. 2. Сдвиг на 16 или 24 бита приведет к переполнению на Uno. 3. Это не может работать для числа с плавающей запятой: вы получите биты исходного числа с плавающей запятой, интерпретированные как целое число, и это целое число будет представлено как (совершенно другое) число с плавающей запятой., @Edgar Bonet

Эй, я пытался использовать код, но само сообщение не печаталось., @CodeStuff


1

Во-первых, необходимо решить, какой формат данных будет использоваться в телефонном приложении. будет использовать для отправки данных в Arduino: определите «язык» сорта. Затем вам нужно запрограммировать и телефон, и Arduino, чтобы они говорили. на том же языке.

Если скорость передачи данных не является критической, я настоятельно рекомендую вам использовать текстовом формате, где каждое «сообщение» сопровождается выделенным символ, обозначающий конец сообщения. Популярный выбор для терминатором сообщения являются '\n' (перевод строки ASCII, числовое значение 0x0a = 10), '\r' (возврат каретки = 0x0d = 13) и ';' (точка с запятой = 0x3b = 59). Точка с запятой часто используется как разделитель второго уровня, чтобы разделить сообщение в поля меньшего размера.

Вот простой пример чтения однострочных сообщений с использованием перевода строки. в качестве разделителя:

void loop() {
    if (bluetoothSerial.available() > 0) {
        String message = bluetoothSerial.readStringUntil('\n');
        Serial.println(message);
    }
}

Если вы хотите отправить данные в виде двоичных файлов, то кадрирование сообщения становится каверзная проблема. Так как любое возможное значение байта может быть допустимо внутри сообщения (любой байт может появиться внутри числа с плавающей запятой), вы не можете просто зарезервируйте один байт для использования в качестве терминатора. Вот почему, если только вы продвинутый программист, я настоятельно рекомендую вам отправить любые данные, которые вы хотите отправить в виде текста. Текст также значительно упрощает отладку. проще.

Наконец, я должен предупредить вас, что класс String не подходит для память вашего Arduino и может привести к нестабильности при использовании экстенсивно. Если у вас есть время, я рекомендую вам изучить надежный способ для чтения текста из последовательного порта: см. статью Чтение серийного номера на Arduino от Маженко.

,

Эй, спасибо за ваш ответ. Я попробовал ваш код, и он, похоже, не показал ошибок (что хорошо), но когда я попытался отправить сообщение со своего телефона, а затем использовал терминатор \n, IDE было все равно, он просто напечатал все сообщение. Я видел несколько журналов, касающихся substring и readstringuntil, но не нашел ответа. Я, вероятно, думаю, что это все еще ошибка типа данных. Спасибо!, @CodeStuff

@CodeStuff: Что вы подразумеваете под «_IDE было все равно_»? IDE не имеет к этому никакого отношения. Если Arduino не нашла терминатор перевода строки, это потому, что вы не отправили его с телефона. Вы вместо этого отправили два символа '\' и 'n'? Я не знаю, какую среду программирования вы используете на стороне телефона, и действительно ли вы знаете, как правильно ее использовать, но важно, чтобы _вы знали, что отправляете_. Если перевод строки слишком сложен для этой среды, попробуйте ';'., @Edgar Bonet