Как решить проблему отправки текста в Arduino через последовательный порт Bluetooth из C # - PullRequest
1 голос
/ 15 декабря 2011

У меня есть Arduino Uno с подключенным модулем Bluesmirf Silver. У моего Arduino есть датчик температуры, который регулярно записывает температуру. Arduino прослушивает любую строку, отправляемую ему через Bluetooth, и отвечает последними данными.

Я написал приложение на C # для получения этих данных, но я вижу странное поведение. Я использую следующий код для подключения, отправки строки и получения возвращенных данных.

mPort = new SerialPort(mPortName, 115200, Parity.None, 8, StopBits.One);
mPort.Open();
mPort.Write("download");
Thread.Sleep(1000);
while (mPort.BytesToRead > 0)
{
  String data = mPort.ReadExisting();
  this.BeginInvoke(new Action<String>(AddMessage), data);
}

Данные, которые я получаю, выглядят так:

Строка, добавленная локально в приложении C #:

Send: download

Строки добавлены на основе данных, полученных от Arduino:

Read: d???+?
GotData
------
Total Readings, 1069
Num Readings, 360
Lost Readings, 709
Reading Interval, 240000
------
350,19.34
351,19.34
352,19.34
353,20.31
....

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

К вашему сведению - таблица данных для модуля bluetooth находится здесь: http://www.sparkfun.com/datasheets/Wireless/Bluetooth/rn-bluetooth-um.pdf

@ Jeff - это код, который я использую на своем Arduino для получения данных: https://github.com/mchr3k/arduino/blob/master/tempsensor/StringReader.cpp

@ Jeff - stringDataLen определяет длину, и я вызываю полную функцию из этого файла: https://github.com/mchr3k/arduino/blob/master/tempsensor/tempsensor.ino

РЕДАКТИРОВАТЬ: Вот полный исходный код

Код C # по какой-то причине определенно неправильно управляет потоком. Я перешел на использование следующего кода в C #, и это позволяет получить строку без повреждения.

private void write(SerialPort mPort, string str)
{
    foreach (char c in str)
    {
        mPort.Write(new char[] {c}, 0, 1);
        Thread.Sleep(10);
    }
}

Ответы [ 3 ]

1 голос
/ 15 декабря 2011

Возможно, неправильная кодировка?

mPort = new SerialPort(mPortName, 115200, Parity.None, 8, StopBits.One);
mPort.Encoding = System.Text.Encoding.ASCII;   // Or System.Text.Encoding.UTF8
mPort.Open();
mPort.Write("download");

Чтение за байтом и проверка каждого байта один за другим для устранения проблем нижнего уровня. ReadExisting() преобразует байты в String на основе свойства Encoding.

0 голосов
/ 20 декабря 2011

Моя проблема была вызвана тем, что я использовал класс SoftwareSerial для связи с моим модулем Bluetooth на контактах 2 и 3. Я использовал скорость передачи 115200, которая, как утверждается, поддерживается на этой странице: http://arduino.cc/en/Reference/SoftwareSerial

Однако на этой странице (http://arduino.cc/en/Reference/SoftwareSerialBegin) указано, что максимальная поддерживаемая скорость передачи данных составляет 9600. Я не уверен, что это точно, но снижение скорости передачи до 9600 исправило мою проблему.

0 голосов
/ 15 декабря 2011

Я предлагаю вам уменьшить скорость связи, потому что нет никакой причины использовать 115200 бит / с (только если ваш модуль требует эту скорость, тогда все в порядке).Также вы отправляете строку «download», которая не подходит, лучше используйте маркеры типа «#D», которые для вашего устройства Arduino внутренне означают отправку данных на компьютер.Таким образом, вы отправляете только два байта вместо восьми, и вы уменьшите вероятность ошибки, и код Arduino будет лучше.

Теперь давайте попробуем решить проблему.Сначала попробуйте использовать что-то вроде этого, когда вы читаете данные с устройства Arduino:

ArayList dataReceaved=new ArrayList():
while(serialPort.BytesToRead>0 && serialPort.IsOpen){
                dataReceaved.Add(serialPort.ReadByte());
            }

Так что я предлагаю вам читать побайтно, таким же образом или аналогичным образом.Также будьте осторожны, если отправляете номера с устройства Arduino.Если да, то используйте что-то вроде этого:

Serial.print(temperatureValue,BYTE);

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

...