Проблема с отправкой команд на ардуину через Com порт

Тема в разделе "Arduino & Shields", создана пользователем flashDD, 17 мар 2014.

  1. flashDD

    flashDD Нуб

    Предисловие: Знакомство с ардуино только начинаю, буду благодарен за дельные советы.

    Задача: Имеется загородный дом, где в силу определенных обстоятельств интернет только 3G (очень любящий порою "подвисать"), и некоторые иные сетевые устройства, доступность которых после проблем с сетевым питанием хотелось бы проверять. Имеется неттоп, работающий под win 7 х64, выполняющий роль видеорегистратора и ряда смежных задач.

    Решение: На неттоп устанавливается и настраивается софтина, мониторящая доступность локальных ресурсов (где-то достаточно ping, где-то нужна проверка доступности по http). По результату мониторинга выполняются батники, отправляющие необходимые команды ардуинке в com порт (используя родное подключение через usb шнурок).

    Батник имеет следующий вид:

    Mode com5 baud=9600 parity=n data=8 stop=1
    ECHO H > COM5
    PING 127.0.0.1 > nul
    ECHO L > COM5

    Соответсвенно скетч на ардуинке (китайская nano v3) - простой пример PhysicalPixel :

    const int ledPin = 13; // the pin that the LED is attached to
    int incomingByte; // a variable to read incoming serial data into

    void setup() {
    // initialize serial communication:
    Serial.begin(9600);
    // initialize the LED pin as an output:
    pinMode(ledPin, OUTPUT);
    }

    void loop() {
    // see if there's incoming serial data:
    if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'H') {
    digitalWrite(ledPin, HIGH);
    }
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'L') {
    digitalWrite(ledPin, LOW);
    }
    }
    }

    Проблема: Подключаю ардуину, заливаю скетч, запускаю батник - все ок. Однако стоит перезагрузить неттоп (имитируя пропадание питания) или просто отключить ардуинку от порта и подключить назад, вместо включения/выключения светодиода получаю быстрое моргание моргание (4 раза) и так на любую команду, передаваемую через bat файл. При этом отправка команды из утилиты Монитор порта обрабатывается корректно. Где грабли, что почитать? (Нашел в сети упоминание про Autoreset enable в стандартном загрузчике ардуины, оно? Не оно? И как бороться?)
     
  2. flashDD

    flashDD Нуб

    Добавлю - отправка команд через тот же Putty тоже работает как ни в чем не бывало, судя по всему грабли именно в работе с com портом через батник...
     
  3. geher

    geher Гуру

    Смутно припоминается, что ардуина ресетится при установлении соединения по последовательному порту, который через USB.
    Отсюда некоторые выводы на уровне гипотез.
    Возможно, что при работе через батник при посылке каждой команды происходит установление соединения с соответствующими спецэффектами и потерей команды. При соединении через монитор или через putty соединение устанавливается один раз, при подключении (с ресетом). Последующая подача команд идет своим чередом.
    Сразу после компиляции, возможно, соединение удерживается средой разработки.
     
  4. flashDD

    flashDD Нуб

    Т.е. как вариант выхода из ситуации - применение USB-UART адаптера?
     
  5. flashDD

    flashDD Нуб

    Ниже лог работы по com порту, полученный с помощью сниффера, сперва подключение через putty и отправка команды, следом работа батника вида
    Mode com5 baud=9600 parity=n data=8 stop=1
    ECHO H > COM5



    Лог:

    <20140317231813.212 SYS>
    COM открыт
    <20140317231813.213 SYS>
    Скорость передачи 9600
    <20140317231813.214 SYS>
    RTS включен
    <20140317231813.214 SYS>
    DTR включен
    <20140317231813.214 SYS>
    Биты данных=8, Стоповые биты=1, Четность=None
    <20140317231813.214 SYS>
    Служ. символы: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
    <20140317231813.215 SYS>
    Контроль передачи: ControlHandShake=(DTR_CONTROL), Замена=(AUTO_TRANSMIT, AUTO_RECEIVE, TRANSMIT_TOGGLE, RTS_CONTROL), Лимит Xon=2048, Лимит Xoff=512
    <20140317231813.215 SYS>
    Таймауты: ReadInterval=1, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
    <20140317231815.425 TX>
    H
    <20140317231819.694 SYS>
    COM закрыт

    А теперь батник

    <20140317231839.766 SYS>
    COM открыт
    <20140317231839.880 SYS>
    COM закрыт
    <20140317231839.885 SYS>
    COM открыт
    <20140317231839.886 SYS>
    Скорость передачи 9600
    <20140317231839.886 SYS>
    RTS включен
    <20140317231839.887 SYS>
    DTR включен
    <20140317231839.887 SYS>
    Биты данных=8, Стоповые биты=1, Четность=None
    <20140317231839.887 SYS>
    Служ. символы: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
    <20140317231839.887 SYS>
    Контроль передачи: ControlHandShake=(DTR_CONTROL), Замена=(AUTO_TRANSMIT, AUTO_RECEIVE, TRANSMIT_TOGGLE, RTS_CONTROL), Лимит Xon=2048, Лимит Xoff=512
    <20140317231839.999 SYS>
    COM закрыт
    <20140317231840.004 SYS>
    COM открыт
    <20140317231840.118 SYS>
    COM закрыт
    <20140317231840.127 SYS>
    COM открыт
    <20140317231840.127 TX>
    H [len=2]
    <20140317231840.127 TX>
    <LF>
    <20140317231840.241 SYS>
    COM закрыт

    Что интересно, батник точно также отдает все в порт и в тот момент, когда скетч только что залит и ардуина "выполняет команды, отправленные через батник"

    P.S. А вот так работает Монитор порта:

    <20140317234132.811 SYS>
    COM открыт
    <20140317234132.925 SYS>
    COM закрыт
    <20140317234132.932 SYS>
    COM открыт
    <20140317234132.932 SYS>
    Размер вх./исх. очереди 2048/1024
    <20140317234132.933 SYS>
    Скорость передачи 9600
    <20140317234132.933 SYS>
    RTS выключен
    <20140317234132.933 SYS>
    DTR включен
    <20140317234132.934 SYS>
    Биты данных=8, Стоповые биты=1, Четность=None
    <20140317234132.934 SYS>
    Служ. символы: Eof=0x04, Error=0x00, Break=0x00, Event=0x0A, Xon=0x00, Xoff=0x00
    <20140317234132.934 SYS>
    Контроль передачи: ControlHandShake=(DTR_CONTROL), Замена=(), Лимит Xon=0, Лимит Xoff=0
    <20140317234132.934 SYS>
    Таймауты: ReadInterval=0, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
    <20140317234132.935 SYS>
    Скорость передачи 9600
    <20140317234132.936 SYS>
    RTS выключен
    <20140317234132.936 SYS>
    DTR включен
    <20140317234132.936 SYS>
    Биты данных=8, Стоповые биты=1, Четность=None
    <20140317234132.936 SYS>
    Служ. символы: Eof=0x04, Error=0x00, Break=0x00, Event=0x0A, Xon=0x00, Xoff=0x00
    <20140317234132.937 SYS>
    Контроль передачи: ControlHandShake=(DTR_CONTROL), Замена=(), Лимит Xon=0, Лимит Xoff=0
    <20140317234132.937 SYS>
    Таймауты: ReadInterval=-1, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
    <20140317234132.943 SYS>
    Скорость передачи 9600
    <20140317234132.943 SYS>
    RTS выключен
    <20140317234132.944 SYS>
    DTR включен
    <20140317234132.944 SYS>
    Биты данных=8, Стоповые биты=1, Четность=None
    <20140317234132.944 SYS>
    Служ. символы: Eof=0x04, Error=0x00, Break=0x00, Event=0x0A, Xon=0x00, Xoff=0x00
    <20140317234132.945 SYS>
    Контроль передачи: ControlHandShake=(DTR_CONTROL), Замена=(), Лимит Xon=0, Лимит Xoff=0
    <20140317234132.945 SYS>
    Таймауты: ReadInterval=-1, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
    <20140317234136.907 TX>
    H<LF>
    <20140317234140.607 SYS>
    DTR выключен
    <20140317234140.608 SYS>
    RTS выключен
    <20140317234140.608 SYS>
    DTR выключен
    <20140317234140.609 SYS>
    RTS выключен
    <20140317234140.726 SYS>
    COM закрыт
     
    Последнее редактирование: 18 мар 2014
  6. flashDD

    flashDD Нуб

    Забавно, с китайской arduino uno вышеописанное заработало как и планировалось... однако тема все еще актуально (хочется использовать именно nano)
     
  7. Alex19

    Alex19 Гуру

    Интересная тема которую Вы подняли.
    Держите, пожалуйста, в курс после обеда попробую проверить, как у меня. Сейчас вою с C# и Serial на скорости 115200.

    UPD. Появилось окно.
    Самой такой проблемы нет, если у меня соединение на C#, работает норм.
    Отключаю порт, вынимаю USB. Затем вставляю USB соединяюсь с ардуиной и работаю. Перегружать компьютер сейчас нет возможности.

    А вот Ваш батник у меня даже после заливки не заработал. Просто залейте и запустите батник, будет работать. У меня Mega 2560, Win7 x64.

    UPD. 2
    Кстати, после заливки, если не запускать монитор, то Ваш батник не работает. А вот если залить, запустить монитор он работает, закрыть и запустить батник, то ок.

    В батниках не понимаю, поэтому помочь не смогу. Но думаю у Вас проблема именно в батнике.
     
    Последнее редактирование: 18 мар 2014
  8. Megakoteyka

    Megakoteyka Оракул Модератор

    Какие-то проблемы?
     
  9. Alex19

    Alex19 Гуру

    Спасибо уже нет. Благодаря коллеги, вместе пишем у кого-то больше знаний, у кого-то меньше.:)

    Не хватало
    ArduinoSerialPort.RtsEnable = false;
    ArduinoSerialPort.DtrEnable = true;

    Без этого к первому запросу добавлялся мусор. При скорости 9600 таких проблем не замечал.

    Кроме того намудрил с потоками, ну там надо переписать. На такой скорости очень важно максимальное быстрое выполнение DataReceived.
     
  10. Megakoteyka

    Megakoteyka Оракул Модератор

    Так ведь DataReceived сам вызывается, куда уж быстрей. Либо в потоке постоянно смотреть на BytesToRead, тогда можно реагировать на каждый байт.
    Жаль, что в Ардуино C# не засунуть :)
     
  11. Alex19

    Alex19 Гуру

    Вопрос обработки и потока данных.

    Если у Вас длинные строки и за секунду 30-50 пакетов с подтверждением, нужно выносить обработку из DataReceived, там только получать. О чем я не подумал, вчера вечером:).

    Сейчас использую ArduinoSerialPort.ReadLine(), думаю перейти на Read, может BytesToRead. Если будет мало.

    Без C# :), как мне сказали, он очень медленный.

    UPD.
    Ну есть вроде другие платы, которые поддерживают .Net
    А так, да, но проблема в ресурсах, .Net тяжеловат. Чувствую, что цена таких на порядок выше.
     
    Последнее редактирование: 18 мар 2014
  12. Megakoteyka

    Megakoteyka Оракул Модератор

    Нагло наврали. Разница в производительности не так уж велика и сильно зависит от конкретных алгоритмов, на некоторых задачах C# шустрей. И если программа на C# жрет 100% времени проца, то и на С/С++ ситуация в общем случае сильно лучше не станет.
    Я без проблем принимаю и анализирую на лету поток 256 Кбит/с, попутно выдавая данные по другим интерфейсам и отображая информацию в графическом виде. Загрузка проца при этом несколько %.
    Обращайтесь если что, я шарпом очень плотно последние несколько лет занимаюсь, могу подсказать.
     
  13. Megakoteyka

    Megakoteyka Оракул Модератор

    flashDD, а физически поднять ногу RESET контроллера не пробовали?
     
  14. Alex19

    Alex19 Гуру

    Большое спасибо, а то мы, любители. Пока исправлю, что знаю, но если возникнут, с Вашего позволения буду мучить:).

    Залил скетч и сделал батник от flashDD. Так вот, он не запускается даже после заливки скетча.
    Он запускается только если после заливки, я открываю монитор порта адруины, затем закрываю и после этого батник работает.

    Может эта информация будет полезна

    UPD. Убегаю, через часок вернусь.

    UPD 2.
    Просьба к flashDD держите нас в курсе.
     
    Последнее редактирование: 18 мар 2014
  15. Jorell

    Jorell Нуб

    Здравствуйте. Я тоже столкнулся с проблемой авторесета.
    Долго мучался, не мог передавать данные через ком-порт.
    В конце концов воспользовался альтернативой (вообще без передачи через ком-порт).
    А тут набрёл на эту тему...
    Может поможет вот такой способ? http://autohome.org.ua/17-arduino/39-disable-auto-reset-arduino-uno-r3
    Сам проверить уже не смогу, а Вы ещё можете попробовать.
     
  16. Jorell

    Jorell Нуб

    В общем проверено и решено следующим образом:
    Arduino NANO v3.0
    Я припаял конденсатор 10мкФ "-" на GND, "+" на микропереключатель, а с микропереключателя на "reset".
    пока микропереключатель включен - сброса не происходит, и всё прекрасно передаётся.

    Пример bat-файла:
    mode com4 baud=9600 parity=n data=8 stop=1
    echo 1 >com4

    работает и на XP и на 7-ке.
    А если надо загрузить в Ардуинку новый скетч, то нужно просто выключить микропереключатель.