Некорректно работает программа

Vanilla_ratty
Offline
Зарегистрирован: 04.12.2011

 Приветствую и поздравляю с наступающим новым годом, дорогие форумчане! Начинающий и не понимающий в ардуино столкнулся с проблемой выполнения скетча:

enum { LED_PIN = 13 };
enum LedState { LED_ON, LED_OFF };

LedState led_state;

void setup()
{
  led_state = LED_OFF;
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(38400); // скорость работы bluetooth-модуля - 38400
}

void loop()
{  
  if (Serial.available())
    {
    char command = Serial.read();
    
    switch (command)
       {
         case '1': led_state = LED_ON; break;
         case '0': led_state = LED_OFF; break;
       }
    }
  
  switch (led_state)
    {
    
    case LED_ON: digitalWrite(LED_PIN, HIGH); break;
    case LED_OFF: digitalWrite(LED_PIN, LOW); break;
   
    }
}

Оригинал скетча взят отсюда: robocraft.ru/blog/electronics/587.html и малясик переделан

Программа написана для взаимодействия ардуино с другими устройствами (по bluetooth/проводам). При получении единички он должен зажечь диод на 13 пине, при получении нолика - потушить.  
Суть проблемы: не понятно, как воспринимается процедура switch (command). Пробовал писать единичку и нолик без кавычек (по идее так и надо), но контроллер их как таковые не воспринимает ни в каком случае. Проверял просто: при наличии ветки default выполняет именно её, case'ы игнорирует.  По идее число с кавычками - это номер символа в ASCII, а просто число - это число (или Кэп запутался?).

С железом полный порядок. Uno, USB-кабель и bluetooth-модуль новенькие и работают как положено. Софт (использовал Termite 2.7 и родные IDE 1.0 и 0023) тоже настроен правильно (номер порта, скорость и тп). Скетч на МК грузится без проблем. Короче, банальных ошибок нет.
Объясните, что тут неправильно и как это исправить?

 

 

step962
Offline
Зарегистрирован: 23.05.2011

Vanilla_ratty пишет:

 Объясните, что тут неправильно и как это исправить?

Данные в программу с компьютера через терминал отправляете? Попробуйте после
char command = Serial.read();
поставить
command = Serial.flush();

Почитайте о последовательной передаче данных хотя бы на этом сайте.

Цитата:

(по идее так и надо)

Вы имеете в виду - вам так надо? В таком случае объявите переменную command типа byte а не char, и если компилятор ругнется на недопустимость присвоения переменной типа byte значения char, добавьте явное преобразование типа:
byte command = (byte)Serial.read();

Vanilla_ratty
Offline
Зарегистрирован: 04.12.2011

Спасибо за совет, добавил очистку буфера, а 17 строку исправил по-иному: просто объявил переменную в самом начале. Переменную command оставлю как char, тк программа дополнится другими функциями, и переменная должна будет содержать литеру, но не число. 
Заработало через провод. Но через bluetooth он неправильно обрабатывает данные. В цикл switch (command) добавил ветку default, чтобы проверить работу терминала. Он явно что-то не то мутит, т.к. при отправке через терминал 1 или 0 вместо соответствующих case  программа выполняет default. Не понимаю, что делать.

step962
Offline
Зарегистрирован: 23.05.2011

 Если конфигурация вашей системы позволяет, попробуйте добавить вывод кода символа. Вполне возможно, что и через Bluetooth данные идут правильные, просто пересылаемая информация разбивается на два пакета - в первом собственно символ, во втором - символы конца посылки (как правило, 0x0d, 0x0a или оба вместе), а поскольку пакеты следуют очень быстро один за другим, то вы просто не успеваете отслеживать "правильную" реакцию.

У меня так бывало даже в случае проводного соединения (при отправке длинных строк): по Serial.available() начиналось считывание поступивших символов, вплоть до опустошения входного буфера. Вроде бы правильная логика. Но ведь МК обрабатывает информацию гораздо быстрее, чем она может поступать по UART. И вполне реалистична ситуация, когда после прихода первого символа телеграммы (в IT-смысле) ваша программа пробегает полный цикл обработки и вновь приходит в точку проверки приемного буфера, когда в него продолжает приходить пересылаемая от передатчика телеграмма.   

Поэтому стоит поробовать еще один трюк - в блоке после Serial.available() поставить небольшой delay, достаточный для прихода еще 2-3 символов при выбранной скорости передачи (2-3 мс для 9600 бит/с, 0,5-1 мс для 38400).

 

Цитата:

По идее число с кавычками - это номер символа в ASCII, а просто число - это число (или Кэп запутался?).

"По идее", число (точнее цифра) с кавычками - это код соответствующего символа: 48 для '0', 49 для '1' и так далее. (www.sciencelobby.com/ascii-table/images/ascii-table1.gif)

Vanilla_ratty
Offline
Зарегистрирован: 04.12.2011

 Добавил задержку и печать. Не знаю, как сделать печать не самого символа, а его кода, сделал просто печать символа. Но даже так получил любопытный результат: терминал при отправке 1 выдаёт ХФ, при отправке 0 выдаёт ФФ. Буквы - русские, большие. Полный аут...

step962
Offline
Зарегистрирован: 23.05.2011

 Это Bluetooth-канал?

Возможно, модуль работает не на дефолтовой частоте, а на какой-то иной.

Поиграйтесь частотами передачи, одновременно устанавливая в терминале и скетче Arduino все возможные варианты - 1200, ..., 115200.

Хотя... при сбитой дефолтовой частоте Bluetooth-модуля это не поможет. Тогда:

1. Проверьте, на какой частоте работает Bluetooth в компьютере.

2. Произведите настройку Bluetooth-модуля на эту же частоту.

3. Частоты передачи терминала и скетча настройте также на эту частоту.

4. Ну и, наконец, - в порядке бреда - проверьте еще раз: TX модуля подключен к RX ардуины? И все остальные проводочки соответствуют прописанному доктором рецепту?

Vanilla_ratty
Offline
Зарегистрирован: 04.12.2011

Да, канал bluetooth. Как узнать сокрость работы bluetooth на ПК, понятия не имею, возможно потому, что нет встроенного (в параметрах донгла нигде не указана). На донгле было написано 2,4-2,48 ГГц, но это и есть частота bluetooth по определению. Так что про частоту bluetooth на компьютере я не знаю.

Когда ставил в параметрах модуля скорость как в инструкции, в голову не пришло, что Windows для этого требуется аутентификация. В итоге покрутил частоты, выставляя в параметрах модуля, коде программы и терминале все возможные скорости, данные калечатся везде кроме 9600. Значит, оставлю такую скорость. Спасибо.

Сейчас буду пробовать связать ардуину с гаджетами на iOS, Simbyan и WMobile. Вопрос: если оставить скорость 9600, это никак не повлияет на связь с телефонами? С мобильной Windows всё предельно просто: скачаю на неё putty и буду счастлив. Но вот будет ли модуль правильно обрабатывать сигнал с iPhone 4 и Vivaz, которые понятия не имеют о терминалах и даже подробных настройках bluetooth (там кроме вкыл-выкл ничего нет)?

step962
Offline
Зарегистрирован: 23.05.2011

Vanilla_ratty пишет:

Да, канал bluetooth. Как узнать сокрость работы bluetooth на ПК, понятия не имею, возможно потому, что нет встроенного (в параметрах донгла нигде не указана). На донгле было написано 2,4-2,48 ГГц, но это и есть частота bluetooth по определению. Так что про частоту bluetooth на компьютере я не знаю.

Это несущая частота, а я имел в виду частоту последовательного порта, эмулируемого в Bluetooth-канале - бит/сек (300 ... 115200).  

step962
Offline
Зарегистрирован: 23.05.2011

Vanilla_ratty пишет:

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

А в самой Windows пробовали изменять скорость передачи соответствующего COM-порта (через диспетчер устройств)?

Vanilla_ratty
Offline
Зарегистрирован: 04.12.2011

Насчёт частоты после коммента сам погуглил и разобрался :) Да, разумеется, скорость менял, проверил все возможные варианты. Единственный корректно работающий - 9600.