Последовательный порт ардуино: Serial | Аппаратная платформа Arduino

Содержание

Arduino. Работа с COM-портом | CUSTOMELECTRONICS.RU

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

Подготовка к работе

Большинство микроконтроллеров обладают множеством портов ввода-вывода. Для связи с ПК наиболее пригоден из них протокол UART. Это протокол последовательной асинхронной передачи данных. Для его преобразования в интерфейс USB на плате есть конвертор USB-RS232 – FT232RL.
Для выполнения примеров их этой статьи вам будет достаточно только Arduino-совместимая плата. Мы используем EduBoard. Убедитесь, что на вашей плате установлен светодиод, подключенный к 13му выводу и есть кнопка для перезагрузки.

Таблица ASCII

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

int symbol = 33;

void setup() {
  Serial.begin(9600);
  Serial.println("ASCII Table ~ Character Map");
}

void loop() {
  Serial.write(symbol);
  Serial.print(", dec: ");
  Serial.print(symbol);
  Serial.print(", hex: ");
  Serial.print(symbol, HEX);
  Serial.print(", oct: ");
  Serial.print(symbol, OCT);
  Serial.print(", bin: ");
  Serial.println(symbol, BIN);
  if(symbol == 126) {
    while(true) {
      continue;
    }
  }
  symbol++;  
}

Переменная symbol хранит код символа. Таблица начинается со значения 33 и заканчивается на 126, поэтому изначально переменной symbol присваивается значение 33.
Для запуска работа порта UART служит функция Serial.begin(). Единственный ее параметр – это скорость. О скорости необходимо договариваться на передающей и приемной стороне заранее, так как протокол передачи асинхронный. В рассматриваемом примере скорость 9600бит/с.
Для записи значения в порт используются три функции:

  1. Serial.write() – записывает в порт данные в двоичном виде.
  2. Serial.print() может иметь много значений, но все они служат для вывода информации в удобной для человека форме. Например, если информация, указанная как параметр для передачи, выделена кавычками – терминальная программа выведет ее без изменения. Если вы хотите вывести какое-либо значение в определенной системе исчисления, то необходимо добавить служебное слово: BIN-двоичная, OCT – восьмеричная, DEC – десятичная, HEX – шестнадцатеричная. Например, Serial.print(25,HEX).
  3. Serial.println() делает то же, что и Serial.print(), но еще переводит строку после вывода информации.

Для проверки работы программы необходимо, чтобы на компьютере была терминальная программа, принимающая данные из COM-порта. В Arduino IDE уже встроена такая. Для ее вызова выберите в меню Сервис->Монитор порта. Окно этой утилиты очень просто:

Монитор порта

Теперь нажмите кнопку перезагрузки. МК перезагрузится и выведет таблицу ASCII:

Таблица ASCII

Обратите внимание на вот эту часть кода:


if(symbol == 126) {
    while(true) {
      continue;
    }
  }

Она останавливает выполнение программы. Если вы ее исключите – таблица будет выводиться бесконечно.
Для закрепления полученных знаний попробуйте написать бесконечный цикл, который будет раз в секунду отправлять в последовательный порт ваше имя. В вывод добавьте номера шагов и не забудьте переводить строку после имени.

Отправка команд с ПК

Прежде чем этим заниматься, необходимо получить представление относительного того, как работает COM-порт.
В первую очередь весь обмен происходит через буфер памяти. То есть когда вы отправляете что-то с ПК устройству, данные помещаются в некоторый специальный раздел памяти. Как только устройство готово – оно вычитывает данные из буфера. Проверить состояние буфера позволяет функция

Serial.avaliable(). Эта функция возвращает количество байт в буфере. Чтобы вычитать эти байты необходимо воспользоваться функцией Serial.read(). Рассмотрим работу этих функций на примере:


int val = 0;

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

void loop() {
  if (Serial.available() > 0) {
    val = Serial.read();
    Serial.print("I received: ");
    Serial.write(val);
    Serial.println();
  }
}

После того, как код будет загружен в память микроконтроллера, откройте монитор COM-порта. Введите один символ и нажмите Enter. В поле полученных данных вы увидите: “I received: X”, где вместо X будет введенный вами символ.
Программа бесконечно крутится в основном цикле. В тот момент, когда в порт записывается байт функция Serial.available() принимает значение 1, то есть выполняется условие Serial.available() > 0. Далее функция

Serial.read() вычитывает этот байт, тем самым очищая буфер. После чего при помощи уже известных вам функций происходит вывод.
Использование встроенного в Arduino IDE монитора COM-порта имеет некоторые ограничения. При отправке данных из платы в COM-порт вывод можно организовать в произвольном формате. А при отправке из ПК к плате передача символов происходит в соответствии с таблицей ASCII. Это означает, что когда вы вводите, например символ “1”, через COM-порт отправляется в двоичном виде “00110001” (то есть “49” в десятичном виде).
Немного изменим код и проверим это утверждение:


int val = 0;

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

void loop() {
  if (Serial.available() > 0) {
    val = Serial.read();
    Serial.print("I received: ");
    Serial.println(val,BIN);
  }
}

После загрузки, в мониторе порта при отправке “1” вы увидите в ответ: “I received: 110001”. Можете изменить формат вывода и просмотреть, что принимает плата при других символах.

Управление устройством через COM-порт

Очевидно, что по командам с ПК можно управлять любыми функциями микроконтроллера. Загрузите программу, управляющую работой светодиода:


int val = 0;

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

void loop() {
  if (Serial.available() > 0) {
    val = Serial.read();
    if (val=='H') digitalWrite(13,HIGH);
    if (val=='L') digitalWrite(13,LOW);
  }
}

При отправке в COM-порт символа “H” происходит зажигание светодиода на 13ом выводе, а при отправке “L” светодиод будет гаснуть.
Если по результатам приема данных из COM-порта вы хотите, чтобы программа в основном цикле выполняла разные действия, можно выполнять проверку условий в основном цикле. Например:


int val = '0';

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

void loop() {
  if (Serial.available() > 0) {
    val = Serial.read();}
    if (val=='1') {
      digitalWrite(13,HIGH); delay (100);
      digitalWrite(13,LOW); delay (100);
    }
    if (val=='0') {
      digitalWrite(13,HIGH); delay (500);
      digitalWrite(13,LOW); delay (500);
    }
}

Если в мониторе порта отправить значение “1” светодиод будет мигать с частотой 5Гц. Если отправить “0” – частота изменится на 1Гц.

Индивидуальные задания

  1. Придумайте три светодиодных эффекта, переключение между которыми можно осуществлять при отправке различных символов с ПК.
  2. Напишите программу, мигающую светодиодом с частой, заданной пользователем с ПК.

Остальные статьи цикла можно найти здесь.

Мы будем очень рады, если вы поддержите наш ресурс и посетите магазин наших товаров shop.customelectronics.ru.

Советы по устранению ошибки последовательного порта в Arduino и ESP8266 (ESP-12E) — Мои статьи — Компьютер и интернет

Сначала проверьте последовательные порты. Загрузите Windows, но не подключайте плату Arduino или ESP8266. На рабочем столе щелкните правой кнопкой мыши (ПКМ) по ярлыку Этот компьютер (Компьютер). В меню выберите Свойства. В окне Система щелкните по ссылке Диспетчер устройств. В окне Диспетчер устройств откройте Порты (COM и LPT). Должен присутствовать последовательный порт COM1.

Теперь воткните в USB порт кабель от Arduino или ESP8266. В диспетчере устройств должен появиться дополнительный COM порт. Я подключил NodeMCU v3 и появился дополнительный порт COM3.

Если порт определился, но никаких сообщений в монитор порта не выводится, то проверьте скорость порта. В настройках Arduino IDE выставьте скорость порта ту, которая прописана в скетче. В окне монитора порта нажмите кнопку Очистить вывод. После этого монитор порта должен заработать.

Если ничего не изменилось и присутствует только порт COM1, то значит у вас проблемы с последовательным портом.
В этом случае при запуске скетча в окне выдается сообщение «Порт недоступен», «Ошибка подключения последовательного порта», «Порт не найден» и т.п. После этого начинаются пляски с бубном —  отключаются и снова подключаются кабели, перезагружается компьютер. Иногда это помогает, иногда — нет.

Вероятная причина ошибки порта — помехи при передаче данных по USB кабелю. Вначале проверьте кабели и USB разъёмы. Замените ненадёжные кабели и не используйте разбитые USB разъёмы.

Другая причина — недостаточно тока для питания Arduino или ESP8266. USB порт в компьютере может быть запитан от источника с малым выходным током. Попробуйте самое простое — подключить Arduino к другому порту в надежде на то, он запитан от более мощного источника. Такое возможно, если USB портов несколько. Кардинальное решение — подключить Arduino или ESP8266 через USB хаб (USB-разветвитель) с внешним блоком питания с выходным током не менее 2 — 3 А.
Ещё одно причина нехватки питания для портов USB — подключение к роутеру по Wi-Fi. Wi-Fi адаптер потребляет значительный ток и нагружает шину питания портов  USB. В связи с этим отключите  Wi-Fi адаптер и подключите компьютер к роутеру кабелем. Иногда это сразу может решить проблему.

Предпочтительно использовать компьютер с подключением клавиатуры и мыши к портам PS/2. Клавиатура и мышь с подключением по USB будут дополнительно нагружать шину +5В USB и питания для Arduino или Node MCU может не хватить. Отключите на время принтер, подключенный по USB, смартфон, подключенный по USB и другие устройства, подключенные к портам USB, без которых можно обойтись, так как они потребляют ток по шинам USB. Кроме того, они могут просто влиять на порты USB и вызывать сбои системы.
По возможности используйте десктоп с достаточно мощным блоком питания, который обеспечивает с запасом ток по шине +5В. Некоторые дешёвые материнские платы при подключении двух-трёх USB устройств уже начинают давать сбои.

Используйте короткий USB кабель, насколько это возможно. Это уменьшит помехи при передаче данных.
Не используйте USB удлинители, подключайте Arduino или ESP8266 непосредственно к USB портам компьютера на задней стенке системного блока. Не используйте USB разъёмы на передней панели системного блока или USB порты картридера. Они подключаются к материнской плате кабелями. Это увеличивает помехи при передаче данных.

Самый действенный способ снизить помехи это использовать USB кабель с ферритовыми фильтрами — цилиндрическими утолщениями из ферритовых колец на концах кабелей.

Фильтры бывают съемными, они надеваются на кабель и защелкиваются.

Можно изготовить фильтр самостоятельно. Возьмите ферритовое кольцо диаметром около 20 мм, притупите острые кромки наждачной бумагой, сделайте один виток кабеля вокруг сердечника и зафиксируйте кольцо на кабеле с помощью скотча или термоусадочной трубки.

Если использовать кольца небольшого диаметра, то никакой фиксации не понадобится. Например, я использовал два кольца, снятые с неисправной материнской платы. Только придется разрезать кабель и затем спаять его снова или припаять новый USB разъем.

Бывают ситуации, когда Arduino работает нормально, а при подключении ESP8266 появляются ошибки и скетч не работает. Такое может быть из-за того, что Wi-Fi передатчик модуля потребляет довольно значительный ток и для нормальной работы просто не хватает тока. Подключите ESP8266 через USB хаб с внешним блоком питания с выходным током 2-2.5-3 А. Также используйте для подключения короткие кабели с ферритовыми фильтрами на концах.
Желательно использовать Micro-USB или  Mini-USB кабель с двумя USB разъемами на конце. Отвод с USB разъемом служит для подачи дополнительного питания. Радиолюбители могут без труда подпаять дополнительный USB разъем сами.

Если USB порты на материнской плате слабы по токам питания, то можно попробовать дополнительно подключить в PCI разъем контроллер USB. Подключите к этому контроллеру USB-мышь и USB-клавиатуру. К USB портам на материнской плате подключайте только Arduino или NodeMCU v3. К PCI разъему подводится более мощное питание. Один из таких контроллеров показан на фото:

Пробуйте подключаться к разным USB разъёмам компьютера, если их несколько, или разным разъёмам USB хаба.
Если ваш компьютер имеет порты USB2.0 и USB3.0, то пробуйте подключаться к тем и другим. Скорее всего лучшие результаты получите при подключении к USB2.0. Драйвер USB3.0 может работать некорректно.
Windows иногда просто не может определить порт. Проверьте контакты блока питания USB хаба в розетке сети. Если блок питания болтается, то о надёжной работе USB портов не может быть и речи.

Подключайте плату Arduino или ESP8266 в USB разъём после полной загрузки Windows.
При переключениях в другие порты номер порта может измениться. Проверяйте номер порта. В верхнем меню Arduino IDE выберите Сервис (Tools) -> Последовательный порт (Serial Port). Рядом с портом COM1 должен быть дополнительный порт. Поставьте галку, чтобы активировать его. 

Работу COM порта и загрузку скетча визуально можно проверить по миганию светодиодов RX и TX на плате Arduino или по частому миганию светодиода рядом с Wi-Fi антенной на плате ESP8266 (NodeMCU v3).

Несмотря на все ухищрения, Windows 10 не открывает COM порт для Node MCU v3 (ESP-12E). Иногда подключает порт и тут же сбрасывает его и так без конца.
Подключил Node MCU v3 (ESP8266) через USB хаб с внешним блоком питания к компьютеру с Windows XP SP3. Установил драйвер ch441ser.exe и Arduino IDE 1.6.5. COM порт определяется и работает. В Windows XP COM порты определяются более надёжно. Проверил это на двух компьютерах с Windows XP с Intel и AMD процессорами.
Однако некоторые скетчи уже не используют приложения Win32 и при компиляции выдаётся ошибка. В этом случае потребуется как минимум 64-разрядная Windows 7.
COM порты виртуальные и, как в любой программе, возможен сбой при определении порта.

Семипортовые USB хабы (разветвители), как пишут в интернете, имеют две микросхемы по 4 порта. Последний порт первой микросхемы используется для подключения второй микросхемы.  В итоге получается 3+4 порта. Можно попробовать подключать Arduino или Node MCU в разные порты хаба.

В Windows откройте Диспетчер устройств, раскройте Порты (COM и LPT). Не закрывайте это окно. Начинайте пробовать разные кабели, разные порты и разные варианты подключения оборудования и, как только порт надёжно определится в Диспетчере устройств, запомните эту конфигурацию оборудования.

И последнее и, может быть, самое главное. Большинство бестрансформаторных блоков питания (зарядных устройств), выполненных в корпусе-вилке, не обеспечивают заявленных характеристик. Например, у зарядного устройства 5V 2.1А, показанного ниже, при токе 0,9 А напряжение на выходе падает до 3,8 В. Сомневаюсь в том, что такой блок питания вообще может отдать в нагрузку ток 2А.

При подозрениях на проблему с питанием используйте трансформаторный блок питания. По габаритам он будет намного больше, зато надежно обеспечит расчетные ток и напряжение.
Рекомендации по блоку питания (из книги «Неисправности вашего ZX SPECTRUM» С.-Петербург, 1991):
«Советуем Вам выбрать самую простую, но и самую надежную схему: трансформатор — диодный мост — конденсатор фильтра — микросхема КР142ЕН5А в стандартном включении — блокировочный конденсатор.
Не стремитесь к чрезмерной миниатюризации! Трансформатор должен иметь мощность не менее 15 Вт, провод вторичной обмотки диаметр не менее 0,7 мм и напряжение на вторичной обмотке под нагрузкой 7-8 Ом должно быть 9-10 В.
Диодный мост подойдет любой из серий КЦ402, КЦ405. Конденсатор фильтра должен быть не менее 4000 мкФ, а рабочее напряжение — не ниже 16 В. На выходе ЕН5А поставьте блокировочный конденсатор 100-200 мкФ на 10-16 В. После сборки БП проконтролируйте напряжение на входе ЕН5А при подключенной нагрузке 5 Ом — должно быть 10,5-11 В.
Если это не так — отмотайте или домотайте несколько витков вторичной обмотки трансформатора. Затем проконтролируйте под нагрузкой 5 Ом напряжение на выходном разъеме БП — должно быть 4,9 — 5,1 В. При низком напряжении придется взять более толстый провод для подсоединения разъема.
При окончательной проверке БП посмотрите на осциллографе переменную составляющую напряжения на пределе 10 мВ (под нагрузкой 5 Ом) — заметных отклонений от прямой линии не должно быть.
В случае неудачи емкость фильтрующего конденсатора нужно увеличить.
Наконец, позамыкайте выход БП накоротко и убедитесь, что ЕН5А не выходит из строя.»
Вместо диодного моста КЦ можно применть более компактный диодный мост DB157S.

Некоторые экземпляры ЕН5А имеют на выходе напряжение чуть меньше 5 В. Для регулировки выходного напряжения соберите блок питания по схеме: 

Номиналы резисторов R1 и R2 вы можете рассчитать сами. Например, после мостика на конденсаторе фильтра под нагрузкой у вас получилось напряжение 15 В. Напряжение на стабилитроне составит 3-3,3 В. Значит на резисторе R1 должно упасть 15 — 3 = 12 В. Ток стабилитрона КС133А 10 мА, т. е. 0,01 А. По закону Ома R = V/I. R = 12/0.01= 1200 Ом = 1,2 кОм. Также можно попробовать стабилитрон КС119А (напряжение стабилизации 1,9 В). Резистор R2 можно взять сопротивлением раза в три больше, чем R1, чтобы не так сильно шунтировал стабилитрон. R2 будет 3 — 3,6 кОм. Мощность рассеивания тоже рассчитывается по закону Ома. Резистор 0,25 Вт будет с большим запасом по мощности рассеивания. Для регулировки напряжения удобно использовать подстроечный многооборотный резистор СП5-3 или аналогичный.
Аккуратнее с регулировкой напряжения, а то выведите из строя само устройство. Вначале для проверки блока питания подключите нагрузку — резистор 5 Ом 5 Вт. Ток нагрузки будет 1 А. Резистором R2 установите напряжение на выходе + 5,0 ÷ 5,25 В.

Для повышения напряжения на выходе есть более простой вариант — включить в разрыв между выводом ЕН5А и общим проводом диод Д9Б. Так сделано в блоке питания для компьютера Специалист — М (ж. «Моделист-конструктор» № 4, 1991 г.)

Если вы хотите получить выходной ток 2 А, то вместо моста КЦ используйте четыре диода КД202. Также можно соединить «этажеркой» в параллель два мостика КЦ405, спаяв одноименные выводы между собой. Тогда вторичную обмотку выберите с проводом потолще. ЕН5А прикрепите к радиатору достаточных габаритов. О расчете трансформатора блока питания можно прочитать на странице Простейший расчет силового трансформатора. Сейчас проще подобрать трансформатор из готовых, например в ЧИП и ДИП. При этом учтите то, что входное напряжение КР142ЕН5А должно быть в диапазоне 7,5В < Vвх < 15В. 

Если описанные меры не помогают и виртуальный COM порт не появляется или в Диспетчере устройств  Windows строка виртуального порта все-таки появляется, помеченная желтым знаком вопроса (восклицательным знаком), то скорее всего проблема с драйвером Ch440. Щелкнув по строке правой кнопкой мыши и выбрав Свойства, можно увидеть сообщение о том, что драйвер не подписан цифровой подписью. Попробуйте скачать другие версии драйвера Ch440 (с разной длиной файла) и по очереди устанавливать их, удаляя старые версии.
Например, мне для Node MCU v.3 в Windows 7 максимальной подошел драйвер driver_ch440_341_arduino.exe (235 kb). Плата Node MCU v.3 подключена к контроллеру USB, который установлен в PCI разъем материнской платы.
На этом же ресурсе https://myrobot.ru/ можно скачать драйвер Ch440 (480 kb) для Windows, Mac OS и Linux.

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

Если все описанные меры не дали надежного результата, то скорее всего ваш системный блок имеет слаботочные порты USB и маломощный блок питания. Тут может помочь замена материнской платы и блока питания на более мощные, т.е по сути нужен новый системный блок.

Резюме
Чтобы устранить ошибки последовательного порта —
► используйте для питания Arduino или ESP8266 USB порты с достаточным выходным током или USB хаб с внешним блоком питания.
► используйте для подключения короткие USB кабели с ферритовыми фильтрами около разъемов.
► попробуйте разные версии драйвера Ch440, если не поможет — тогда другую версию Windows.
► используйте качественный кабель со всеми сигнальными жилами, а не кабель от зарядного устройства.

Последнее редактирование 14 февраля 2022 г.

Использованные ресурсы
https://wm-help.net/lib/b/book/1248084587/4
https://masterpaiki.ru/top-10-samyih-chastyih-neispravnostey-zhk-monitorov.html
https://www.dns-shop.ru/product/3a24983fdab4526f/usb-razvetvitel-ginzzu-gr-487ua/opinion/
https://kiloom.ru/spravochnik-radiodetalej/microsxema/k142en5a-k142en5b-k142en5v-k142en5g-kr142en5a-kr142en5b-kr142en5v-kr142en5g.html

Действия по чтению и записи последовательного порта

Web Serial API позволяет веб-сайтам обмениваться данными с устройствами с последовательным интерфейсом.

— Обновлено

Appears in: Устройства

Успех

Что такое Web Serial API? #

Последовательный порт — это двунаправленный интерфейс связи, который позволяет посылать и получать данные побайтно.

Web Serial API предоставляет веб-сайтам способ осуществлять действия по чтению/записи последовательного устройства с помощью JavaScript. Последовательные устройства подключаются либо через последовательный порт в системе пользователя, либо через съемные устройства USB и Bluetooth, которые имитируют последовательный порт.

Другими словами, Web Serial API соединяет сеть и физический мир, позволяя веб-сайтам обмениваться данными с устройствами с последовательным интерфейсом, такими как микроконтроллеры и 3D-принтеры.

Этот API также является отличным дополнением к WebUSB, поскольку операционные системы требуют, чтобы приложения взаимодействовали с некоторыми последовательными портами, используя свой высокоуровневый последовательный API, а не низкоуровневый USB API.

Предлагаемые варианты использования #

В образовательном, любительском и промышленном секторах пользователи подключают периферийные устройства к компьютерам. Эти устройства часто управляются микроконтроллерами через последовательное соединение, используемое специальным программным обеспечением. Некоторое программное обеспечение для управления этими устройствами создано с применением веб-технологий:

Веб-сайты могут связываться с устройством через приложение-агент, которое пользователи устанавливают вручную. Иногда устанавливается пакетное приложение через фреймворк, такой как Electron. В отдельных случаях от пользователя требуется выполнить дополнительные действия, например, скопировать скомпилированное приложение на устройство через USB-накопитель.

Во всех этих случаях пользовательский опыт будет улучшен за счет обеспечения прямой связи между веб-сайтом и устройством, которым он управляет.

Текущий статус #

Использование Web Serial API #

Обнаружение функции #

Чтобы проверить, поддерживается ли Web Serial API, используйте:

if ("serial" in navigator) {
// The Web Serial API is supported.
}

Откройте последовательный порт #

Web Serial API является асинхронным по своей природе. Это предотвращает блокировку пользовательского интерфейса веб-сайта при ожидании ввода. Это важно, поскольку последовательные данные могут быть получены в любое время, а для этого должен существовать способ их прослушивания.

Чтобы открыть последовательный порт, сначала получите доступ к объекту SerialPort. Первый способ: предложить пользователю выбрать один последовательный порт, вызвав navigator.serial.requestPort() в ответ на жест пользователя (прикосновение или щелчок мыши). Второй способ: выбрать порт с помощью функции navigator.serial.getPorts(), возвращающего список всех последовательных портов, к которым у сайта есть доступ.

document.querySelector('button').addEventListener('click', async () => {
// Prompt user to select any serial port.
const port = await navigator.serial.requestPort();
});
// Get all serial ports the user has previously granted the website access to.
const ports = await navigator.serial.getPorts();

Функция navigator.serial.requestPort() принимает необязательный объектный литерал, определяющий фильтры. Они используются для поиска любого последовательного устройства, подключенного по USB, с обязательным идентификатором поставщика (usbVendorId) и необязательным идентификатором продукта (usbProductId) для USB-устройства.

// Filter on devices with the Arduino Uno USB Vendor/Product IDs.
const filters = [
{ usbVendorId: 0x2341, usbProductId: 0x0043 },
{ usbVendorId: 0x2341, usbProductId: 0x0001 }
];

// Prompt user to select an Arduino Uno device.
const port = await navigator.serial.requestPort({ filters });

const { usbProductId, usbVendorId } = port.getInfo();

Указание пользователю выбрать BBC micro:bit

Вызов requestPort() предлагает пользователю выбрать устройство и возвращает объект SerialPort Если у вас есть SerialPort , вызов port.open() с желаемой скоростью передачи откроет последовательный порт. baudRate словаря baudRate указывает, насколько быстро данные передаются по последовательной линии. Он выражается в битах в секунду (бит / с). Проверьте правильность значения в документации вашего устройства, так как все данные, которые вы отправляете и получаете, будут бессмысленны, если они будут указаны неправильно. Для некоторых устройств USB и Bluetooth, которые имитируют последовательный порт, это значение может быть безопасно установлено на любое значение, поскольку оно игнорируется эмуляцией.

// Prompt user to select any serial port.
const port = await navigator.serial.requestPort();

// Wait for the serial port to open.
await port.open({ baudRate: 9600 });

Вы также можете указать любую из опций ниже при открытии последовательного порта. Эти параметры не являются обязательными и имеют удобные значения по умолчанию .

  • dataBits : количество бит данных в кадре (7 или 8).
  • stopBits : количество стоповых битов в конце кадра (1 или 2).
  • parity : режим четности ( "none" , "even" или "odd" ).
  • bufferSize : размер буферов чтения и записи, которые должны быть созданы (должен быть меньше 16 МБ).
  • flowControl : режим управления потоком ( "none" или "hardware" ).

Чтение из последовательного порта #

Потоки ввода и вывода в Web Serial API обрабатываются Streams API.

Если потоки для вас впервые, ознакомьтесь с концепциями Streams API . В этой статье даже поверхностно рассматриваются потоки и их обработка.

После установления соединения через последовательный порт свойства writable readable и записи из объекта SerialPort возвращают ReadableStream и WritableStream . Они будут использоваться для приема и отправки данных на последовательное устройство. Оба используют Uint8Array для передачи данных.

Когда новые данные поступают от последовательного устройства, port.readable.getReader().read() асинхронно возвращает два свойства: value и логическое done Если done имеет значение true, последовательный порт был закрыт или данные больше не поступают. Вызов port.readable.getReader() создает считыватель и блокирует readable к нему для чтения. Пока readable заблокировано , последовательный порт не может быть закрыт.

const reader = port.readable.getReader();

// Listen to data coming from the serial device.
while (true) {
const { value, done } = await reader.read();
if (done) {
// Allow the serial port to be closed later.
reader.releaseLock();
break;
}
// value is a Uint8Array.
console.log(value);
}

Некоторые нефатальные ошибки чтения последовательного порта могут возникать при определенных условиях, таких как переполнение буфера, ошибки кадрирования или ошибки четности. port.readable добавлением другого цикла поверх предыдущего, который проверяет port.readable. Это работает, потому что, пока ошибки не являются фатальными, автоматически создается новый ReadableStream. Если происходит фатальная ошибка, например, при удалении последовательного устройства, port.readable становится пустым.

while (port.readable) {
const reader = port.readable.getReader();

try {
while (true) {
const { value, done } = await reader.read();
if (done) {
// Allow the serial port to be closed later.
reader.releaseLock();
break;
}
if (value) {
console.log(value);
}
}
} catch (error) {
// TODO: Handle non-fatal read error.
}
}

Если последовательное устройство отправляет текст обратно, вы можете port.readable через TextDecoderStream как показано ниже. TextDecoderStream — это поток преобразования, который захватывает все Uint8Array и преобразует их в строки.

const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable.getReader();

// Listen to data coming from the serial device.
while (true) {
const { value, done } = await reader.read();
if (done) {
// Allow the serial port to be closed later.
reader.releaseLock();
break;
}
// value is a string.
console.log(value);
}

Запись в последовательный порт #

Чтобы отправить данные на последовательное устройство, передайте данные в port.writable.getWriter().write() . Вызов releaseLock() для port.writable.getWriter() требуется для закрытия последовательного порта позже.

const writer = port.writable.getWriter();

const data = new Uint8Array([104, 101, 108, 108, 111]); // hello
await writer.write(data);

// Allow the serial port to be closed later.
writer.releaseLock();

Отправьте текст на устройство через TextEncoderStream конвейеру port.writable как показано ниже.

const textEncoder = new TextEncoderStream();
const writableStreamClosed = textEncoder.readable.pipeTo(port.writable);

const writer = textEncoder.writable.getWriter();

await writer.write("hello");

Закройте последовательный порт #

port.close() закрывает последовательный порт, если его readable и writable члены разблокированы , что означает, что releaseLock() был вызван для их соответствующих читателей и писателей.

await port.close();

Однако при непрерывном чтении данных с последовательного устройства с использованием цикла port.readable всегда будет заблокирован до тех пор, пока не возникнет ошибка. В этом случае вызов reader.cancel() заставит reader.read() немедленно разрешиться с помощью { value: undefined, done: true } и, следовательно, позволит циклу вызвать reader.releaseLock() .

// Without transform streams.

let keepReading = true;
let reader;

async function readUntilClosed() {
while (port.readable && keepReading) {
reader = port.readable.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) {
// reader.cancel() has been called.
break;
}
// value is a Uint8Array.
console.log(value);
}
} catch (error) {
// Handle error...
} finally {
// Allow the serial port to be closed later.
reader.releaseLock();
}
}

await port.close();
}

const closedPromise = readUntilClosed();

document.querySelector('button').addEventListener('click', async () => {
// User clicked a button to close the serial port.
keepReading = false;
// Force reader.read() to resolve immediately and subsequently
// call reader.releaseLock() in the loop example above.
reader.cancel();
await closedPromise;
});

При использовании потоков преобразования (таких как TextDecoderStream и TextEncoderStream ) закрыть последовательный порт сложнее. Вызовите reader.cancel() как раньше. Затем вызовите writer.close() и port.close() . Это распространяет ошибки через потоки преобразования на базовый последовательный порт. Поскольку распространение ошибки не происходит сразу, вы должны использовать readableStreamClosed и writableStreamClosed обещания , созданный ранее для обнаружения , когда port.readable и port.writable разблокированы. Отмена reader приводит к прерыванию потока; вот почему вы должны поймать и проигнорировать возникшую ошибку.

// With transform streams.

const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable.getReader();

// Listen to data coming from the serial device.
while (true) {
const { value, done } = await reader.read();
if (done) {
reader.releaseLock();
break;
}
// value is a string.
console.log(value);
}

const textEncoder = new TextEncoderStream();
const writableStreamClosed = textEncoder.readable.pipeTo(port.writable);

reader.cancel();
await readableStreamClosed.catch(() => { /* Ignore the error */ });

writer.close();
await writableStreamClosed;

await port.close();

Прослушивание подключения и отключения #

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

navigator.serial.addEventListener("connect", (event) => {
// TODO: Automatically open event.target or warn user a port is available.
});

navigator.serial.addEventListener("disconnect", (event) => {
// TODO: Remove |event.target| from the UI.
// If the serial port was opened, a stream error would be observed as well.
});

До Chrome 89 события connect и disconnect SerialConnectionEvent настраиваемый объект SerialConnectionEvent с затронутым SerialPort доступным в качестве атрибута port Вы можете использовать event.port || event.target для обработки перехода.

Обработка сигналов #

После установления соединения через последовательный порт вы можете явно запросить и установить сигналы, предоставляемые последовательным портом, для обнаружения устройства и управления потоком. Эти сигналы определены как логические значения. Например, некоторые устройства, такие как Arduino, войдут в режим программирования, если включен сигнал готовности терминала данных (DTR).

Установка выходных сигналов и получение входных сигналов соответственно выполняется путем вызова port.setSignals() и port.getSignals() . См. Примеры использования ниже.

// Turn off Serial Break signal.
await port.setSignals({ break: false });

// Turn on Data Terminal Ready (DTR) signal.
await port.setSignals({ dataTerminalReady: true });

// Turn off Request To Send (RTS) signal.
await port.setSignals({ requestToSend: false });

const signals = await port.getSignals();
console.log(`Clear To Send: ${signals.clearToSend}`);
console.log(`Data Carrier Detect: ${signals.dataCarrierDetect}`);
console.log(`Data Set Ready: ${signals.dataSetReady}`);
console.log(`Ring Indicator: ${signals.ringIndicator}`);

Преобразование потоков #

Когда вы получаете данные с последовательного устройства, вам не обязательно получать все данные сразу. Он может быть произвольно разбит на части. Дополнительные сведения см. В разделе Концепции Streams API .

Чтобы справиться с этим, вы можете использовать некоторые встроенные потоки преобразования, такие как TextDecoderStream или создать свой собственный поток преобразования, который позволяет анализировать входящий поток и возвращать проанализированные данные. Поток преобразования находится между последовательным устройством и циклом чтения, который потребляет поток. Он может применить произвольное преобразование до того, как данные будут использованы. Думайте об этом как о сборочной линии: по мере того, как виджет спускается по конвейеру, каждый шаг в линии изменяет виджет, так что к тому времени, когда он доберется до своего конечного пункта назначения, это полностью функционирующий виджет.Самолетный завод в замке Бромвич времен Второй мировой войны

Например, рассмотрим, как создать класс потока преобразования, который потребляет поток и разбивает его на части на основе разрывов строк. Его transform() вызывается каждый раз, когда поток получает новые данные. Он может либо поставить данные в очередь, либо сохранить их на потом. Метод flush() вызывается при закрытии потока и обрабатывает все данные, которые еще не были обработаны.

Чтобы использовать класс потока преобразования, вам необходимо пропустить через него входящий поток. В третьем примере кода в разделе « Чтение из последовательного порта» исходный входной поток передавался только через TextDecoderStream , поэтому нам нужно вызвать pipeThrough() чтобы передать его через наш новый LineBreakTransformer .

class LineBreakTransformer {
constructor() {
// A container for holding stream data until a new line.
this.chunks = "";
}

transform(chunk, controller) {
// Append new chunks to existing chunks.
this.chunks += chunk;
// For each line breaks in chunks, send the parsed lines out.
const lines = this.chunks.split("\r\n");
this.chunks = lines.pop();
lines.forEach((line) => controller.enqueue(line));
}

flush(controller) {
// When the stream is closed, flush any remaining chunks out.
controller.enqueue(this.chunks);
}
}

const textDecoder = new TextDecoderStream();
const readableStreamClosed = port.readable.pipeTo(textDecoder.writable);
const reader = textDecoder.readable
.pipeThrough(new TransformStream(new LineBreakTransformer()))
.getReader();

Для отладки проблем связи с последовательным устройством используйте метод tee() для port.readable чтобы разделить потоки, идущие к последовательному устройству или от него. Два созданных потока можно использовать независимо друг от друга, что позволяет вывести один на консоль для проверки.

const [appReadable, devReadable] = port.readable.tee();

// You may want to update UI with incoming data from appReadable
// and log incoming data in JS console for inspection from devReadable.

Советы разработчиков #

Отладка Web Serial API в Chrome проста с помощью внутренней страницы about://device-log где вы можете увидеть все события, связанные с последовательным устройством, в одном месте.Внутренняя страница в Chrome для отладки Web Serial API.

Codelab #

В кодовой лаборатории Google Developer вы будете использовать Web Serial API для взаимодействия с доской BBC micro: bit для отображения изображений на ее светодиодной матрице 5×5.

Поддержка браузера #

Web Serial API доступен на всех настольных платформах (Chrome OS, Linux, macOS и Windows) в Chrome 89.

Полифилл #

В Android поддержка последовательных портов на базе USB возможна с помощью WebUSB API и полифилла Serial API . Этот полифил ограничен оборудованием и платформами, на которых устройство доступно через API WebUSB, поскольку оно не заявлено встроенным драйвером устройства.

Безопасность и конфиденциальность #

Авторы спецификации разработали и реализовали Web Serial API, используя основные принципы, определенные в разделе « Управление доступом к мощным функциям веб-платформы» , включая пользовательский контроль, прозрачность и эргономику. Возможность использования этого API в первую очередь обеспечивается моделью разрешений, которая предоставляет доступ только одному последовательному устройству за раз. В ответ на запрос пользователя пользователь должен предпринять активные действия для выбора конкретного последовательного устройства.

Чтобы понять компромиссы безопасности, ознакомьтесь с разделами о безопасности и конфиденциальности в объяснении Web Serial API Explainer.

Отзыв #

Команда Chrome хотела бы услышать о ваших мыслях и опыте работы с Web Serial API.

Расскажите о дизайне API #

Есть ли в API что-то, что не работает должным образом? Или отсутствуют методы или свойства, необходимые для реализации вашей идеи?

Отправьте вопрос спецификации в репозиторий GitHub Web Serial API или добавьте свои мысли к существующей проблеме.

Сообщить о проблеме с реализацией #

Вы нашли ошибку в реализации Chrome? Или реализация отличается от спецификации?

Сообщите об ошибке на https://new.crbug.com . Обязательно укажите как можно больше подробностей, предоставьте простые инструкции по воспроизведению ошибки и установите для Компонентов Blink>Serial . Glitch отлично подходит для быстрого и легкого обмена репродукциями.

Показать поддержку #

Планируете ли вы использовать Web Serial API? Ваша общедоступная поддержка помогает команде Chrome определять приоритеты функций и показывает другим поставщикам браузеров, насколько важна их поддержка.

Отправьте твит на @ChromiumDev, используя хэштег #WebShare, и сообщите нам, где и как вы его используете.

Полезные ссылки #

Демо #

Благодарности #

Спасибо Рейли Гранту и Джо Медли за рецензии на эту статью. Фотография завода самолетов Бирмингемского музейного фонда на Unsplash.

Последнее обновление: — Улучшить статью

Проекты с использованием последовательного порта

Радиочастотная идентификация (Radio Frequency Identification, RFID) получает все большее распространение в современном мире. Эта технология использует электромагнитные волны радиочастотного диапазона для передачи данных. Простейшая система радиочастотной идентификации (RFID) состоит из 2-х компонентов: сама метка и считывающее ее устройство. Считывающее устройство … Читать далее →

Наверняка многие из вас расплачивались где-нибудь картой или снимали с нее деньги в банкомате и после этого получали чек об произведенной операции. В большинстве случаев этот чек печатается с помощью термопринтера (Thermal Printer — термографический принтер, термопечатающее устройство (с матрицей, … Читать далее →

MATLAB представляет собой универсальное программное обеспечение, которое можно использовать для широкого множества разнообразных приложений. Ранее на нашем сайте мы уже рассматривали управление шаговым двигателем и двигателем постоянного тока с помощью MATLAB и Arduino, а также проект автоматизации дома на основе … Читать далее →

Наверняка многие из вас в отелях или где-нибудь в других местах уже встречались с электронными замками, которые можно открыть с помощью карты с радиочастотной идентификацией (RFID), без использования привычного механического ключа. Чтобы открыть такую дверь надо просто приложить карту к … Читать далее →

В этой статье мы будем проектировать систему на плате Arduino Uno для чтения идентификаторов (ID) карт с радиочастотной идентификацией (RFID, сокр. от Radio Frequency Identification). Каждая такая карта имеет уникальный идентификатор «зашитый» внутрь ее. Подобные системы широко распространены в современном … Читать далее →

В этой статье мы рассмотрим процесс взаимодействия микроконтроллера ATmega8 (семейство AVR) и платформой Arduino Uno через последовательный порт. Взаимодействие будет осуществляться через универсальный асинхронный приемопередатчик (UART — Universal Asynchronous Receiver Transmitter) – это последовательный порт связи. Подобное взаимодействие часто бывает … Читать далее →

В этой статье мы рассмотрим процесс взаимодействия двух микроконтроллеров ATmega8 (семейство AVR) через последовательный порт. Взаимодействие будет осуществляться с помощью универсальных асинхронных приемопередатчиков (UART — Universal Asynchronous Receiver Transmitter), имеющихся в микроконтроллерах. Подобное взаимодействие часто бывает востребовано в различных системах. … Читать далее →

Видеоурок 6. Serial и Processing

Видеоурок 6. Serial и Processing

сентября 23, 2014Arduino Андрей Антонов  Печать

Сегодняшний видеоурок от Джереми Блюма посвящен передачи данных с Arduino на компьютер и обратно. Для реализации этого взаимодействия здесь используется прием-передача данных через последовательный порт Arduino и обработка информации на компьютере, используя программу, написанную на языке программирования Processing.

Платы Arduino, в зависимости от модели, имеют на борту один или несколько последовательных портов. Выводы этих портов обозначены TX (от transmit, передача) и RX(от receive, прием). Через эти порты возможно осуществлять прием-передачу данных. Для индикации активности линий TX и RX на микроконтроллерных платах используются одноименные светодиоды. Через этот же порт, если он единственный, происходит и загрузка скомпилированных скетчей с компьютера в Arduino.

Преобразование уровней напряжения от уровней RS-232 до уровней TTL-логики, используемой на USB-порту компьютера, и обратно происходит в преобразователе уровней, находящимся на платах Arduino.

Перед тем как начать работать с портом, его необходимо инициализировать и установить скорость передачи данных по нему (измеряется в бодах — число бит в секунду).

Взаимодействие с пользователем можно осуществлять через (Меню → ). В процессе приема-передачи все символы передаются в виде их 8-битных ASCII-кодов. Для получения самих символов, а не их кодов нужно производить программное преобразование.

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

Часть 1

Часть 2

 

Еще по этой теме

Вы можете пропустить чтение записи и оставить комментарий. Размещение ссылок запрещено.

Основы последовательного терминала — Learn.sparkfun.com

Авторы: Джоэл_Е_Б, Джимблом, Маетту_Тис Избранное Любимый 39

Последовательный монитор Arduino (Windows, Mac, Linux)

Интегрированная среда разработки Arduino (IDE) — это программная часть платформы Arduino. И, поскольку использование терминала является такой важной частью работы с Arduino и другими микроконтроллерами, они решили включить последовательный терминал в программное обеспечение.В среде Arduino это называется последовательным монитором.

Установка соединения

Серийный монитор

поставляется с любой версией Arduino IDE. Чтобы открыть его, просто щелкните значок Serial Monitor.

Значок расположен справа от других значков в Arduino 0023 и ниже.

Значок расположен справа в Arduino 1.0 и более поздних версиях.

Выбор порта для открытия в Serial Monitor аналогичен выбору порта для загрузки кода Arduino.Перейдите в Инструменты -> Последовательный порт и выберите правильный порт.

После открытия вы должны увидеть что-то вроде этого:

Настройки

Serial Monitor имеет ограниченные настройки, но достаточные для удовлетворения большинства ваших потребностей в последовательной связи. Первая настройка, которую вы можете изменить, это скорость передачи данных. Щелкните раскрывающееся меню скорости передачи данных, чтобы выбрать правильную скорость передачи данных.

Вы также можете изменить эмуляцию клавиши ввода на возврат каретки, перевод строки, оба или ни то, ни другое.

Наконец, вы можете включить или отключить автоматическую прокрутку терминала, установив флажок в левом нижнем углу.

Плюсы

  • Serial Monitor — отличный быстрый и простой способ установить последовательное соединение с вашим Arduino. Если вы уже работаете в Arduino IDE, нет необходимости открывать отдельный терминал для отображения данных.

Минусы

  • Отсутствие настроек в Serial Monitor оставляет желать лучшего, и для продвинутых последовательных соединений это может не сработать.

← Предыдущая страница
Подключение к вашему устройству

Последовательная связь с Arduino Uno

название подразумевает, что последовательная связь означает отправку и получение данных побитно по одной линии.Плата Arduino uno имеет один последовательный порт на цифровых контактах 0 (RX) и 1 (TX) для связи с другими внешними последовательными устройствами или с компьютером через USB-кабель. Процесс отправки и получения данных можно наблюдать по миганию светодиодов TX и RX на плате Arduino.

Рядом с чипом Atmega 8U2 на плате Arduino Uno мы видим два светодиода, это светодиоды TX и RX.

В случае последовательной связи между Arduino и компьютером цифровые контакты 1 и 0 не должны использоваться в качестве контактов ввода/вывода.Чип Atmega 8U2 на плате Arduino действует как мост между компьютером и процессором Arduino.; Он работает на программном обеспечении, называемом прошивкой, которое можно обновлять через специальный протокол, называемый DFU (обновление прошивки устройства).

ПОСЛЕДОВАТЕЛЬНАЯ СВЯЗЬ МЕЖДУ ARDUINO UNO И КОМПЬЮТЕРОМ

  • Связь между arduino и компьютером устанавливается на определенной скорости передачи данных. Скорость передачи определяет, насколько быстро данные передаются по последовательной линии или, проще говоря, скорость последовательной связи.Некоторые распространенные скорости для UART: 9600 бод, 11520 бод и т. д. Для начала последовательной связи скорость передачи, установленная для Arduino и компьютера, должна быть одинаковой, если скорость передачи для обоих установлена ​​на 9600 бод, то для передачи 1 бита данных будет возьмите 1/9600 сек = 0,014 мсек! Удивительно, не так ли?
  • Сначала я попытаюсь написать простую программу для отправки символа с компьютера на arduino и получения его обратно компьютером. Во-первых, подключите Arduino и загрузите следующий скетч на свою плату.
  • Программа начинается с открытия последовательной связи между Arduino и компьютером с помощью последовательной функции «Serial.begin(9600)» со скоростью передачи данных 9600 бит/с. Другая полезная функция, используемая здесь, — это Serial.available(), которая возвращает количество байтов, которые в настоящее время присутствуют в последовательном буфере Arduino.
  • Цикл while в программе продолжает ожидать, пока с компьютера не будут получены какие-либо последовательные данные. Если какие-либо данные отправляются компьютером, данные будут доступны в последовательном буфере Arduino, и цикл while прерывается, поскольку функция Serial.available() возвращает значение больше нуля. Если серийные данные доступны, следующим шагом будет чтение данных с помощью Serial.read() и сохраните ее в символьной переменной с именем value.
  • После того, как данные, отправленные компьютером, были получены процессором arduino, мы хотим отправить эти данные обратно на компьютер. Функция, которая помогает нам в этом, называется Serial.println(). Эта функция выводит данные на последовательный порт, к которому подключена Arduino.
  • Нажмите Ctrl+Shift+M, чтобы запустить последовательный монитор в Arduino IDE. Последовательный монитор является частью Arduino IDE, который позволяет пользователю отправлять данные с компьютера на плату Arduino, а также получать данные с платы Arduino.
  • После загрузки программы введите символ 0 в поле редактирования последовательного монитора и нажмите кнопку отправки. Это означает, что мы отправляем символ 0 с компьютера на плату Arduino.
  • В соответствии с нашим кодом плата Arduino отправляет полученные данные обратно на компьютер, поэтому мы увидим ноль в последовательном мониторе под полем редактирования.
  • Повторите то же самое для 1, 2, 3, 4 и т. д. и верните их на свой экран, то есть на последовательный монитор.

Серийный номер — ссылка на Arduino

Описание

Используется для связи между платой Arduino и компьютером или другими устройствами.Все платы Arduino имеют как минимум один последовательный порт (также известный как UART или USART), а некоторые — несколько.

Доска Имя USB CDC Серийные контакты Последовательный 1 контакт Последовательный 2 контакта Последовательный 3 контакта

Уно, Нано, Мини

0 (прием), 1 (передача)

Мега

0 (прием), 1 (передача)

19 (прием), 18 (передача)

17 (прием), 16 (передача)

15 (прием), 14 (передача)

Леонардо, Микро, Юн

Серийный номер

0 (прием), 1 (передача)

Uno WiFi Rev.2

Подключен к USB

0 (прием), 1 (передача)

Подключен к NINA

Плиты MKR

Серийный номер

13 (прием), 14 (передача)

Ноль

SerialUSB (только собственный порт USB)

Подключен к порту программирования

0 (прием), 1 (передача)

Долг

SerialUSB (только собственный порт USB)

0 (прием), 1 (передача)

19 (прием), 18 (передача)

17 (прием), 16 (передача)

15 (прием), 14 (передача)

101

Серийный номер

0 (прием), 1 (передача)

На устройствах Uno, Nano, Mini и Mega контакты 0 и 1 используются для связи с компьютером.Подключение чего-либо к этим контактам может помешать этой связи, в том числе вызвать сбой загрузки на плату.

Вы можете использовать встроенный последовательный монитор среды Arduino для связи с платой Arduino. Нажмите кнопку последовательного монитора на панели инструментов и выберите ту же скорость передачи данных, что и при вызове begin() .

Последовательная связь на контактах TX/RX использует логические уровни TTL (5 В или 3,3 В в зависимости от платы). Не подключайте эти контакты напрямую к последовательному порту RS232; они работают при +/- 12 В и могут повредить плату Arduino.

Чтобы использовать эти дополнительные последовательные порты для связи с вашим персональным компьютером, вам потребуется дополнительный адаптер USB-последовательный, так как они не подключены к адаптеру USB-последовательный на Mega. Чтобы использовать их для связи с внешним последовательным устройством TTL, подключите контакт TX к контакту RX вашего устройства, RX к контакту TX вашего устройства, а землю вашего Mega к земле вашего устройства.

Использование Serial.read() с Arduino — Programming Electronics Academy

Вы пытаетесь использовать Serial.read() для получения данных из последовательного порта в Arduino? Возможно, вы используете окно последовательного монитора Arduino и отправляете данные, или, может быть, у вас есть программа, работающая на вашем raspberryPi, которая отправляет данные через последовательный порт на вашу плату Arduino.

Как использовать serial.read() для получения данных и правильного их объединения? В этом уроке вы точно узнаете, как использовать Serial.read() для получения данных из последовательного порта и объединения их в одно значение.

Часть 1:

  • Общая картина последовательной связи
  • Последовательный буфер
  • Серийный номер.чтение и серийный номер
  • Разработка протокола и стратегии для считывания данных из последовательного порта

Часть 2:

  • Реализовать стратегию в коде Arduino
  • БОНУС: как преобразовать последовательные данные из строки в целое число

 

Вы пытаетесь использовать Serial.read для передачи данных из последовательного порта в Arduino? Возможно, вы используете окно последовательного монитора Arduino. и отправка данных, или, может быть, у вас есть программа, работающая на вашем Raspberry Pi это отправка данных через последовательный порт на вашу плату Arduino.Как вы используете Serial.read для получения данных и правильно собрать? На этом уроке вы точно узнаете как использовать Serial.read для получения данных с последовательного порта и сшить вместе как одно значение. Следите за обновлениями. (живой телевизионный джингл)
Подпишитесь на наш канал на YouTube чтобы получить больше видео, как это. Хорошо, давайте сделаем краткий обзор того, о чем мы будем говорить здесь. Сначала мы поговорим об общей картине последовательной связи.Мы поговорим о последовательном буфере. Мы поговорим о Serial.read и Serial.available. Разработаем протокол и стратегию для чтения данных из последовательного порта. Затем мы собираемся реализовать стратегию в коде Arduino. В качестве бонуса вы узнаете, как конвертировать последовательные данные из строки в целое число. Давайте сделаем шаг назад от Serial.read и поговорим о последовательной связи. Последовательная связь — это процесс отправки одного бита данных за раз последовательно из одного места в другое, например, отправка данных с вашего Raspberry Pi к подключенному Arduino или наоборот.USB является одним из наиболее распространенных методов, используемых для последовательной связи. Отсюда и название Универсальная последовательная шина. Используя Arduino, мы можем легко отправлять и получать данные через USB-кабель. Все, что нам нужно сделать, это использовать встроенный Последовательная библиотека Arduino. Теперь, если вы не знаете, что такое библиотека Arduino, это в основном набор кода, который был связан вместе потому что это часто используется вместе. Например, допустим, вы парикмахер. Может быть, у вас есть определенный ящик в вашей парикмахерской для всех ваших парикмахерских инструментов.Каждый раз, когда кто-то заходит подстричься, ты точно знаешь, где искать в ящике для стрижки. Вот куда вы кладете все свои инструменты для стрижки. Может быть, у вас есть еще один ящик со всеми необходимыми вещами. для окрашивания волос людей. Когда кто-то входит и просит покрасить волосы в рыжий цвет, вы точно знаете, какой ящик открыть. То же самое с библиотеками Arduino. Библиотеки Arduino объединяют множество программных функций. которые помогут вам с конкретными задачами.Для последовательной связи, мы можем использовать встроенную последовательную библиотеку Arduino. В последовательной библиотеке есть такие функции, как серийное начало, чтение, доступный, parseInt, parseString, parseFloat, печать, так далее и так далее. Их куча, и они очень удобные. Хорошо, краткий обзор. Мы знаем, что последовательная связь через USB это то, как мы можем общаться между нашим Arduino и другим устройством. И мы знаем, что последовательная библиотека Arduino это набор программных инструментов, которые мы будем использовать для последовательной связи.Но где, черт возьми, данные что мы получаем с другого устройства на самом деле в конечном итоге на Arduino? Куда все это идет? Ответ — последовательный буфер, или, точнее, буфер последовательного приема. Когда биты данных начинают поступать с вашего компьютера, часть оборудования на вашем Arduino, называемая UART соберет каждый из восьми битов в байт и сохраните эти байты для вас в буфере последовательного приема. Буфер последовательного приема может содержать 64 байта.Данные, которые вы отправляете со своего компьютера на Arduino окажется в буфере последовательного приема. Так как же получить эти данные? Вот тут-то и появляется Serial.read. Serial.read — это функция последовательной библиотеки Arduino. и что он делает, так это считывает первый доступный байт из буфера последовательного приема. Когда он считывает его, он удаляет этот байт из буфера. Скажем, вы отправили фразу SubSandwich на свой Arduino. Это означает, что вы поместите 12 байтов в ваш последовательный приемный буфер.Итак, у нас есть строка кода и мы сохраняем в переменную myFirstCharacter возвращаемое значение Serial.read. Serial.read, он вернет первое значение доступны в буфере последовательного приема, которая в данном случае является заглавной S, и это оставит ubSandwich в буфере последовательного приема. Я имею в виду, убСэндвич? Я имею в виду, это может быть вкусно. Теперь персонаж, заглавная S, будет храниться в переменной myFirstCharacter и останется всего 11 байт в буфере последовательного приема.Если бы мы сделали это снова, теперь сохраняем персонажа в mySecondCharacter, тогда mySecondCharacter будет содержать значение нижний регистр u и bSandwich будут оставлены в буфере последовательного приема. Таким образом, Serial.read принимает по одному байту за раз. из буфера последовательного приема. Теперь здесь есть небольшая ошибка что вы собираетесь хотеть высматривать. Часто, когда вы отправляете данные по последовательному порту, будет невидимый завершающий символ добавлено в конце передачи.Эти завершающие символы помогают вашей программе узнать когда передача заканчивается. Так что это может быть что-то вроде возврата каретки или перевод строки, который добавит дополнительный байт в буфер последовательного приема, или даже оба могут быть добавлены что добавит два дополнительных байта в буфер. Просто есть на что обратить внимание. Если вы отправляете данные через окно последовательного монитора в Arduino IDE, справа внизу, вы увидите варианты добавления этих завершающих символов каждый раз, когда вы нажимаете кнопку отправки.При выборе без окончания строки будут отправлены только ваши символы. Итак, мы знаем, что данные поступают по серийному номеру. идет в буфер последовательного приема, и мы знаем, что можем использовать Serial.read чтобы получить первый символ в этом буфере. Но откуда нам знать, есть ли хоть что-то в буфер последовательного приема в первую очередь? Ну, так уж получилось, что есть еще одна функция в последовательной библиотеке Arduino под названием Serial.available. Мы можем использовать доступную функцию чтобы проверить, сколько байтов доступно для чтения в буфере последовательного приема.Serial.available вернет количество байтов в настоящее время хранится в буфере последовательного приема. Скажем, фраза SubSandwich была в буфере последовательного приема, тогда Serial.available вернет число 12. Если andwhat был в буфере последовательного приема, тогда Serial.available вернет значение 7. Что круто, так это то, что Serial.available не влияет на содержимое буфера последовательного приема. Он просто сообщает нам, насколько он полон.Итак, если возвращаемое значение Serial.available больше нуля, тогда мы знаем часть нашего сообщения а может все наше сообщение еще сидит в буфере последовательного приема, ожидая чтения. Итак, вся эта справочная информация замечательна. Мы говорим о Serial.read, Serial.available, но кажется, что это просто тянет один байт за раз. Что, если вы хотите отправить целую фразу, например SubSandwich на свой Arduino и сохранить его в строку? Или произнесите числовое значение 462 и сохраните его в целое число? Как собрать все эти байты вместе в одну строковую переменную или одну целочисленную переменную или один что-нибудь в этом отношении? Ладно, давайте засучим рукава и придумать стратегию.Так что здесь все должно стать немного техническим. Я думаю, это будет взрыв. Теперь, если вы новичок в программе Arduino и ты хочешь научиться делать подобные вещи, загляните в Академию программирования электроники. В программе членства есть видеокурсы которые ведут вас шаг за шагом чтобы научить вас, как программировать Arduino так что вы можете прототипировать свои собственные проекты и написать свой код. Ладно, вернемся к стратегии. Во-первых, нам нужно решить, как мы будем отправлять наши данные, которые я буду называть нашими сообщениями.То есть нам нужно определиться с протоколом, которому мы будем следовать. Давайте сделаем эти правила протокола которые мы реализуем в нашей программе Arduino. Итак, первый, новые сообщения будут прочитаны, как только они поступят. Сообщения будут не длиннее 12 байт. Каждое сообщение будет заканчиваться символом новой строки. Это будет наш завершающий персонаж. Итак, это довольно простой протокол, но это действительно не стратегия. Итак, давайте немного подумаем о стратегии.Во-первых, нам нужно место, где мы можем хранить входящие байты. который мы читаем из буфера последовательного приема. Для этого мы могли бы использовать массив символов. Затем нам нужно проверить, доступно ли что-нибудь в буфере последовательного приема. Мы могли бы использовать Serial.available для этого. Тогда нам действительно нужно прочитать байт. Мы могли бы использовать Serial.read для этого. Прежде чем мы поместим любой из байтов в наш массив, нам нужно проверить, что входящий байт не завершающий символ, который сказал бы нам, что мы находимся в конце сообщения.Итак, давайте возьмем эти идеи и типа распишите алгоритм. Во-первых, мы создаем массив символов для хранения входящих байтов. Во-вторых, мы проверяем, есть ли что-нибудь в последовательном приемном буфере для чтения. В-третьих, пока есть что почитать, то что мы делаем в первую очередь, прочитать байт во временную переменную, проверить, является ли то, что мы читаем, частью нашего сообщения или если это завершающий символ. Если это часть нашего послания, затем мы сохраним его в массиве символов.Если это завершающий символ, то мы можем вывести сообщение и подготовьтесь к следующему сообщению. Если сообщение превысило максимальную длину в протоколе, тогда нам нужно прекратить чтение большего количества байтов и вывести сообщение, или делать все, что мы хотим с сообщением в этом отношении. Итак, теперь у нас есть стратегия чтения сообщения. из буфера последовательного приема. Во второй части мы реализуем все это в коде. Я с нетерпением жду встречи с вами тогда.До свидания. (яркие электронные звуки)

Вы пытаетесь использовать Serial.read() для передачи данных из последовательного порта в Arduino? Возможно, вы используете окно последовательного монитора Arduino. и отправка данных или, может быть, у вас есть программа работает на вашем Raspberry Pi что отправка данных через последовательный порт на вашу плату Arduino. Как вы используете Serial.read() для получения данных и правильно собрать? Этот урок является продолжением первой части.В этом уроке вы изучите код для использования Serial.read() получать данные из последовательного порта и сшивать их вместе как одно значение. Следите за обновлениями. (яркая веселая музыка)
Подпишитесь на наш канал на YouTube чтобы получить больше видео, как это. Хорошо, теперь я надеюсь, что у тебя все отлично. Опять же, это вторая часть использования Serial.reads(). Итак, если вы еще не видели первую часть ты действительно захочешь это посмотреть. В первой части мы говорили об общей картине последовательной связи.Мы говорили о буфере последовательного приема Serial.read(). и Серийный.доступный(). Затем мы разработали протокол и стратегию для чтения данных из последовательного порта. В этом уроке мы будем реализовывать эта стратегия в коде Arduino. И в качестве бонуса вы узнаете, как конвертировать серийные данные из строки в целое число. Хорошо, давайте начнем. Итак, у меня открыта среда разработки Arduino IDE. и я только что написал список из двух сборов в моей программе.И это по сути тот алгоритм, о котором мы говорили о на прошлом уроке. Я просто пробежусь по тому, что нам нужно сделать. Итак, мы хотим создать массив символов для хранения входящих байтов. Мы хотим проверить, есть ли что-нибудь в последовательно полученном буфере для чтения. Пока есть что почитать затем мы хотим прочитать байт во временную переменную. Мы хотим проверить, является ли то, что мы читаем, частью нашего сообщения, или если это завершающий символ.Если это часть нашего сообщения, то мы его сохраним в массив символов. Если это завершающий символ, мы можем вывести сообщение или сделать что-то с ним и подготовить для следующего сообщения. Если сообщение превышает максимальную длину в протоколе тогда нам нужно прекратить чтение любых дополнительных байтов и просто вывести сообщение или сделать что-то с ним. Теперь мы собираемся перейти к некоторым действительно техническим вещам. Я думаю, это будет взрыв.Если вы хотите научиться программировать и создавать электронные прототипы, я определенно рекомендуем посетить Академию программирования электроники. У нас есть подробное, краткое видеообучение, которое поможет вам через все эти вещи, чтобы вы могли выйти и начните создавать свои собственные проекты. Хорошо, теперь об этом. Итак, давайте продолжим и начнем с минимальной программой Arduino с настройкой и циклом. Мы также добавим Serial.начинать к настройке, чтобы установить последовательную связь.
Обратите внимание, что в Serial.begin мы передаем значение 9600. Это называется скоростью передачи данных. Устанавливает скорость последовательной связи и представляет байты в секунду. Таким образом, это будет 9600 байт в секунду. переход между двумя устройствами. Теперь на обоих устройствах должна быть выбрана одинаковая скорость передачи данных. для работы последовательной связи. Если вы используете последовательный монитор Arduino IDE окно для отправки данных затем скорость передачи можно установить с помощью раскрывающегося меню.И есть куча общих скоростей передачи данных, которые вы можете использовать но мы не собираемся слишком углубляться в это прямо сейчас. Вам просто нужно убедиться, что отправка и принимающие устройства имеют одинаковую скорость передачи данных. Итак, мы настроили эту базовую программу. теперь давайте займемся первым шагом нашего алгоритма. Нам нужно создать массив символов для хранения входящего сообщение и переменная положения, чтобы помочь нам двигаться через каждый элемент массива.Мы также создадим константу для хранения максимальной длины нашего сообщения и использовать его для инициализации наш массив символов. Ладно, позволь мне сделать это. (тихая музыка)
Итак, мы добавили постоянное целое число без знака. Мы назвали его MAX_MESSAGE_LENGTH, и я установил его равным 12. Это произвольная длина. Это то, что ты выберешь. Затем мы создали массив символов с именем message. Массив — это тип данных, который может содержать несколько элементов.Массивы могут содержать элементы только одного типа. Итак, мы делаем массив символов. Это будет содержать символы. Таким образом, каждый из символов, которые мы читаем из последовательно полученного буфера будет идти в этот массив символов. Наконец, у нас есть эта переменная позиции сообщения. Эта переменная позволит нам выбрать, где в массив положить входящие байты. Итак, мы сделали это, я пойду дальше и отмечу что из списка, чтобы сделать здесь.Теперь, что нам нужно сделать, это проверить, чтобы увидеть если какие-либо байты доступны в буфере последовательного приема. И пока там байты, нам нужно прочитать байты in и сохраните их во временную переменную. Мы можем использовать цикл while Serial.available() и последовательное чтение, чтобы это произошло. (тихая музыка)
Хорошо, теперь у нас есть цикл while, и условие в цикле while проверяется возвращаемое значение Serial.available(). Итак, если вы вспомните из предыдущего урока Серийный.available() возвращает число байтов, доступных для чтения в буфере последовательного приема. Итак, если в последовательном полученном буфере есть какие-либо данные, это значение, это возвращаемое значение будет больше нуля. Итак, мы говорим, что в то время как в буфере последовательного приема все еще есть данные этот код будет работать снова и снова. И что мы будем делать внутри этого цикла while считываются эти байты по одному с использованием функцию Serial.read(), и мы сохраняем каждый этих байтов во временную переменную с именем «invite».Итак, мы сделали это. Я пойду вперед и вычеркну это из нашего списка. Проверьте, есть ли что-нибудь в буфере последовательного приема. Мы делаем это с помощью Serial.available. А потом пока есть что почитать, мы читаем байт во временную переменную. Так что мы просто сделали это. Итак, теперь нам нужно проверить, соответствует ли то, что мы читаем, является частью нашего сообщения или завершающим символом. Для этого мы могли бы использовать оператор if else.Если это не завершающий символ, он сделает одну вещь и если это завершающий символ будет делать что-то еще. Итак, давайте сделаем это. (мягкая оптимистичная музыка)
Итак, у нас есть оператор if L. Итак, чего мы пытаемся достичь здесь, мы хотим убедиться, что мы не дошли до конца нашего сообщения. Если мы читаем сообщение и есть другое сообщение после этого мы не хотим просто начать читать в другое сообщение.Нам нужно знать, где заканчивается первое сообщение. Вот почему у нас есть эти завершающие символы. Итак, что мы делаем, мы читаем этого персонажа и нам нужно проверить, Эй, это часть нашего сообщения или это завершающий символ и сообщает нам, что это конец сообщения. Итак, что мы делаем, так это проверяем, не является ли это новой строкой. Итак, эта мелочь — новая строка, и мы говорим не новая строка. Итак, мы проверяем, Эй, это байт, который мы только что получили? Мы хотим убедиться, что это не новая линия.Если это не новая строка, значит, это часть нашего сообщения и мы что-нибудь сделаем. Если это новая строка, то что это значит что мы получили полное сообщение а потом мы собираемся сделать что-то еще. Итак, мы делаем нашу проверку для завершающего символа. Давайте продолжим и вычеркнем это из нашего списка здесь. Ладно, займемся делами. Хорошо, если это часть нашего сообщения затем мы хотим сохранить его в массиве символов.И тогда нам также нужно будет увеличить нашу позицию в массиве символов для следующего байта. Итак, давайте сделаем это. (тихая музыка)
Хорошо. Итак, что мы здесь делаем, так это то, что у нас есть массив символов. Опять же, это будет место, где мы сохраняем входящие байты. Значение, которое находится внутри этих скобок говорит нам, куда мы ссылаемся. Так что это сообщение прямо сейчас установлено на ноль. Это то, что мы инициализировали, это ноль.Итак, что это означает в первой позиции этого массива символов мы собираемся поместить в byte. Итак, если бы у нас было сообщение, если бы мы просто отправили сообщение как саб, тогда S будет, вы знаете, что такое инвайт. И буква S будет стоять на первом месте в этом массиве. И это потому, что массивы имеют нулевой индекс. Теперь, если все это звучит для вас по-гречески, снова загляните в Академию программирования электроники. Мы говорим обо всем этом. Я знаю, ты можешь чувствовать себя мужчиной ты замалчиваешь столько всего.Что ж, есть чему поучиться, но это определенно выполнимо. Впрочем, ладно, я отвлекся. Итак, мы сохраняем эту входящую переменную в наш массив. И затем следующее, что мы делаем, это увеличиваем наша позиционная переменная. Таким образом, мы говорим позицию сообщения плюс, плюс. Мы добавляем единицу к этой переменной. Так что раньше он был нулевым, когда мы начинали. После этой строки кода она будет одна. Итак, что это значит, в следующий раз здесь когда мы извлекаем следующий байт из буфера мы собираемся сохранить его в следующей позиции.Итак, вы можете видеть, что мы собираем сообщение заново. Мы берем его из последовательного полученного буфера и мы собираем его в наш массив символов. Хорошо, позвольте мне вычеркнуть это из нашего списка здесь. Мы взяли часть нашего сообщения, а затем сохранили его в массив символов. Теперь, если мы получим завершающий символ это означает, что мы получили все наше сообщение и мы действительно можем что-то сделать с сообщением. Как и данные, которые мы получаем, мы можем делать все, что захотим.В этом случае мы напечатаем сообщение в окно серийного монитора. И что мы также сделаем, так это сбросим персонажа массив, чтобы подготовить его к следующему сообщению. Итак, давайте сделаем это. (тихая музыка)
Хорошо, когда мы получим полное сообщение, которое мы получили завершающий нулевой символ и что мы собираемся сделать, это добавить нулевой символ до конца строки. Мы распечатаем сообщение. И затем мы собираемся сбросить переменную position на ноль, чтобы настроиться на следующее сообщение, которое мы получим.Итак, мы собираемся начать с самого начала нашего массива символов, массива символов нашего сообщения. Хорошо, так что мы можем вычеркнуть это из списка но прежде чем мы сможем назвать это завершенным, мы все еще нужно обеспечить максимальную длину сообщения, о которой мы говорили о в протоколе. Что это собирается сделать, это помешает нам от превышения места, которое мы фактически выделили в нашем массиве символов. Так что я думаю, что мы добавим этого охранника. к нашему существующему оператору if.Так позвольте мне сделать это.
Итак, мы добавили дополнительное условие внутри нашего оператора if. Итак, сначала мы хотим убедиться, Эй это не завершающий символ. И теперь мы также хотим проверить, что мы не превысили длина сообщения, которое мы согласовали в протоколе, которых было 12. Итак, если наша позиция больше чем наша максимальная длина сообщения минус один, это учетная запись за то, что массив нулевой индексации и это ловит и сказать: «Эй, подождите секунду, сообщение слишком большое».Нам нужно перейти к этому, если или, скорее, это другое утверждение. И вместо этого вывести сообщение. Итак, у нас есть это, и это все. Хорошо, я знаю, что это похоже на тонну. Это вроде так, но прежде чем мы назовем это выходом Я хочу показать вам способ принять сообщение, которое мы получили и преобразовать его в целое число. Так что, если вместо слов посылать например, бутерброд или письма или что-то еще к последовательному порту, возможно, вы отправляете числовые значения как вы отправляете номер 42 или число 314 в окне серийного монитора или через ваше устройство, и они отправляются как символы ASCII.Как преобразовать эти цифры в целые числа? Что ж, есть очень крутая функция atoi(). И это займет строку с завершением Knoll и преобразовать его в целое число. Итак, строки в языке программирования C заканчиваются нулем. То есть они заканчиваются нулевой обратной косой чертой. Функция atoi() не будет работать, если только персонаж где вы проходите, имеет этот завершающий нулевой символ. Итак, давайте посмотрим, как мы можем добавить эту функцию atoi() к нашему текущему коду.
Теперь, что делает код помимо вывода сообщения он будет использовать функцию atoi() чтобы преобразовать этот массив символов в целое число. А затем мы просто напечатаем это целое число. Но вы знаете, вы можете делать с ним все, что захотите. Хорошо, ну, это было много всего. Итак, давайте сделаем быстрый обзор. Во-первых, мы говорили в целом о последовательной связи. Это средство отправки данных по одному биту за раз из одного места в другое.Мы говорили о буфере последовательного приема, и мы сказали что он содержит 64 байта. Мы обсудили основы Serial.read и Serial.available(), и мы знаем, что Serial.read удаляет по одному байту из последовательного буфера. Мы узнали, что функция serial available возвращает сколько байтов находится в буфере последовательного приема. Мы разработали простой протокол и стратегию для получения сообщений с нашего последовательного порта а затем мы реализовали стратегию в коде Arduino.Наконец, мы говорили об использовании функции atoi(). для преобразования из строки с завершающим нулем в целое число. Что ж, эй, я надеюсь, что вы найдете это действительно полезным. Если вам это нравится, вам действительно понравится следующий урок где мы будем говорить о том, как вы можете взять весь код, который у нас только что был здесь, и мы собираемся сжать всего за пару строк кода используя некоторые другие действительно удобные функции последовательной библиотеки. Успокойся, тогда увидимся.До свидания. (тихая музыка)

Общая картина последовательной связи

Давайте отойдем от Serial.read() и поговорим о последовательной связи.

Последовательная связь — это процесс передачи одного бита данных за раз, последовательно, из одного места в другое. Например, отправка данных с вашего raspberryPi на подключенный Arduino или наоборот.

USB является одним из наиболее распространенных методов, используемых для последовательной связи, отсюда и название универсальной последовательной шины.Используя Arduino, мы можем легко отправлять и получать данные по кабелю USB со встроенной последовательной библиотекой Arduino.

Теперь, если вы не знаете, что такое библиотека Arduino, это, по сути, набор кода, который был объединен вместе, потому что он часто используется вместе.

Представьте, что вы парикмахер. Может быть, у вас в парикмахерской есть специальный ящик для всех ваших инструментов для стрижки волос. Каждый раз, когда кто-то приходит на стрижку, вы точно знаете, где искать, в ящике для стрижки, и все ваши инструменты прямо там.

Может быть, у вас есть еще один ящик со всем, что вам нужно для окрашивания волос людей, когда кто-то входит и просит покрасить волосы в рыжий цвет, вы точно знаете, какой ящик нужно открыть. То же самое с библиотеками Arduino. Библиотеки Arduino объединяют множество программных функций, которые помогают вам в решении конкретных задач.

Функции последовательной библиотеки

Для последовательной связи мы можем использовать встроенную библиотеку Arduino Serial.

Библиотека Serial имеет такие функции, как:

  • Серийный номер.начало()
  • Последовательный.read()
  • Серийный.доступный()
  • Serial.parseInt()
  • Serial.parseString()
  • Serial.parseFloat()
  • Серийный.print()
  • Serial.captCrunch()

Хорошо, мы знаем, что последовательная связь через USB — это то, как мы можем общаться между одним устройством и другим, и мы знаем, что библиотека Arduino Serial — это набор инструментов, которые мы будем использовать для последовательной связи. Но куда на самом деле попадают данные, поступающие с другого устройства, на Arduino?

Последовательный буфер

Ответ: последовательный буфер или, точнее, последовательный приемный буфер.Когда биты данных начинают поступать с вашего компьютера, аппаратная часть вашего Arduino, называемая UART, соберет каждый из 8 битов в байт и сохранит эти байты для вас в буфере последовательного приема.

Буфер последовательного приема может содержать 64 байта.

Данные, которые вы отправляете с вашего компьютера на Arduino, попадут в буфер последовательного приема.

Как получить эти данные? Вот где Serial.read() приходит на помощь.

Последовательный.чтение()

Серийный номер.read() — это функция библиотеки Serial. Что он делает, так это считывает первый доступный байт из последовательного приемного буфера. Когда он считывает его, он удаляет этот байт из буфера.

Допустим, вы отправили на Arduino фразу «Sub Sandwich». Это означает, что вы поместили 12 байтов в буфер последовательного приема.

Если вы используете…

 char myFirstCharacter =  Serial  .read();

 

Затем Serial.read() вернет первое значение, доступное в буфере последовательного приема, в данном случае это «S», и оставит «ub Sandwich» в буфере последовательного приема.Теперь значение «S» будет храниться в переменной myFirstCharacter, а в последовательном буфере останется всего 11 байт….

Если бы мы сделали это снова…

 char mySecondCharacter =  Serial  .read();

 

Тогда mySecondCharacter будет содержать значение «u», а «b Sandwich» останется в буфере последовательного приема. Serial.read() берет по одному байту из буфера последовательного приема.

Здесь есть небольшая ошибка, на которую вам нужно обратить внимание.Часто при отправке данных по последовательному каналу в конец передачи добавляется невидимый завершающий символ.

Это может быть CR (возврат каретки) или LF (перевод строки) — что добавит дополнительный байт в буфер последовательного приема, или даже оба могут быть добавлены CR+LF, что добавит два дополнительных байта в буфер!

Если вы отправляете данные через окно последовательного монитора, в правом нижнем углу вы увидите опции для добавления этих завершающих символов каждый раз, когда вы нажимаете кнопку отправки.При выборе «Без окончания строки» будут отправлены только ваши символы.

Serial.available () — Серийный шпион

Мы можем использовать другую функцию библиотеки Serial, Serial.available(), чтобы проверить, есть ли что-нибудь доступное для чтения в буфере последовательного приема.

Serial.available вернет количество байтов, хранящихся в данный момент в буфере последовательного приема. Предположим, что фраза «Sub Sandwich» находилась в буфере последовательного приема, тогда функция serial. available() вернет число 12. Если «andwich» находится в буфере последовательного приема, тогда будет указано значение serial.available() вернет значение 7.

Serial.available не влияет на содержимое буфера приема Serial — он просто сообщает нам, насколько он заполнен.

Таким образом, ЕСЛИ возвращаемое значение Serial. available() больше 0, мы знаем, что часть нашего сообщения все еще находится в буфере последовательного приема.

ОК, все эти Serial.read и Serial.available — это здорово, но что, если я хочу отправить всю фразу «подбутерброд» в свой Arduino и сохранить ее в строку, или произнести значение 462 и сохранить его в целое число.

Как объединить все эти байты в одну строковую переменную, или целое число, или любой другой тип данных, если уж на то пошло?!

Как отправлять целые числа, строки и т. д. по серийному номеру

Хорошо, давайте засучим рукава и придумаем стратегию…

Вот-вот все станет немного технически — думаю, это будет круто!

Now Если вы новичок в программировании Arduino и хотите научиться делать подобные вещи, обязательно ознакомьтесь с членством в Programming Electronics Academy.В нашем членстве у нас есть видеокурсы, которые шаг за шагом расскажут вам, как программировать Arduino, чтобы вы могли создавать прототипы своих собственных проектов.

Хорошо, вернемся к нашей стратегии…

Во-первых, нам нужно решить, как мы будем отправлять наши данные (которые я буду называть «сообщениями»), то есть нам нужно выбрать протокол, которому мы будем следовать.

Наш протокол Serial.read()

Давайте сделаем это правилами протокола, которые мы будем применять в нашей программе Arduino.

  • Новые сообщения будут прочитаны, как только они поступят
  • Сообщения не должны быть длиннее 12 байт
  • Каждое сообщение будет заканчиваться символом новой строки ‘\n’, который мы будем называть завершающим символом

Это довольно простой протокол, но он поможет нам в нашей стратегии.

Сначала нам нужно место для хранения входящих байтов из буфера последовательного приема — для этого мы можем использовать массив символов. Затем нам нужно проверить, доступно ли что-нибудь в буфере последовательного приема — для этого мы можем использовать Serial.available. Затем нам нужно прочитать байт — для этого мы можем использовать Serial.read().

Прежде чем мы поместим байт в наш массив символов, нам нужно проверить входящий байт, чтобы убедиться, что это не завершающий символ.

  1. Создайте массив символов для хранения входящих байтов
  2. Проверьте, есть ли что-нибудь в буфере последовательного приема для чтения — Serial.доступно()
  3. Пока есть что почитать тогда…
    • Считать байт во временную переменную – Serial.read()
    • Проверить, является ли то, что мы читаем, частью нашего сообщения ИЛИ завершающим символом
    • Если это часть нашего сообщения, то сохранить его в массиве символов
    • Если это завершающий символ, вывести сообщение и подготовиться к следующему сообщению
    • Если сообщение превысило максимальную длину сообщения в протоколе, то прекратить чтение большего количества байтов и вывести сообщение (или сделать с ним что-то еще)

Минимальный эскиз Arduino

Давайте запустим минимальную программу Arduino с помощью setup() и loop().Мы добавим Serial.begin() в цикл, чтобы установить последовательную связь.

Обратите внимание, что в Serial.begin() мы передаем значение 9600. Это называется скоростью передачи данных. Она устанавливает скорость последовательной связи и представляет биты в секунду. Для работы последовательной связи на обоих устройствах должна быть выбрана одинаковая скорость передачи данных. Если вы используете окно последовательного монитора Arduino IDE для отправки данных, скорость передачи можно установить с помощью раскрывающегося меню.

 недействительная установка () {
  Серийный номер  .начало (9600);
}

недействительный цикл () {

}
 

Теперь давайте приступим к первому шагу нашего алгоритма — создадим массив символов для хранения входящего сообщения и переменную position, которая поможет нам перемещаться по каждому элементу массива. Мы также создадим константу для хранения максимальной длины нашего сообщения и используем ее для инициализации массива символов.

 const беззнаковое целое число MAX_MESSAGE_LENGTH = 12;

недействительная установка () {
 Серийный номер  .begin(9600);
}

недействительный цикл () {
//Создаем место для хранения входящего сообщения
статическое символьное сообщение [MAX_MESSAGE_LENGTH];
статическое целое число без знака message_pos = 0;
}

 

Теперь нам нужно проверить, доступны ли какие-либо байты в буфере последовательного приема, и пока они есть, нам нужно считать байты и сохранить их во временной переменной.Мы можем использовать цикл while, Serial.available, Serial.read(), чтобы это произошло.

 const беззнаковое целое число MAX_MESSAGE_LENGTH = 12;

недействительная установка () {
 Серийный номер  .begin(9600);
}

недействительный цикл () {

//Проверяем, доступно ли что-нибудь в буфере последовательного приема
в то время как (  серийный номер  .доступно () > 0)
{
//Создаем место для хранения входящего сообщения
статическое символьное сообщение [MAX_MESSAGE_LENGTH];
статическое целое число без знака message_pos = 0;

//Чтение следующего доступного байта в буфере последовательного приема
char inByte =  Серийный номер  .читать();
}
}

 

Теперь нам нужно проверить, является ли прочитанный нами байт завершающим символом или нет… Для этого мы можем использовать оператор if-else. Если это не завершающий символ, мы будем делать одно, а если это завершающий символ, то другое.

 // Приходит сообщение (проверьте не завершающий символ)
если ( inByte != '\n')
{
//Сделай что-нибудь
}
//Полное сообщение получено...
еще
{
// Делаем что-то еще
}
 

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

 // Приходит сообщение (проверьте не завершающий символ)
если ( inByte != '\n')
{
//Добавляем входящий байт к нашему сообщению
сообщение[сообщение_поз.] = inByte;
сообщение_pos++;
}
//Полное сообщение получено...
еще
{
//Сделай что-нибудь
}

 

Теперь, если мы получаем завершающий символ, это означает, что мы получили все наше сообщение и мы действительно можем что-то сделать с полученным сообщением или данными.В этом случае мы выведем сообщение в окно Serial Monitor. Нам также нужно сбросить наш массив символов, чтобы подготовиться к следующему сообщению.

 //Полное сообщение получено...
еще
{
//Добавить нулевой символ в строку
сообщение[сообщение_поз] = '\0';

// Печатаем сообщение (или делаем что-то другое)
 Серийный номер  .println(сообщение);

//Сброс для следующего сообщения
сообщение_поз = 0;
}

 

Прежде чем мы сможем назвать это завершенным, нам нужно обеспечить максимальную длину сообщения в протоколе.Это не позволит нам превысить пространство, которое мы выделили в нашем массиве символов. Мы можем добавить эту защиту к нашему существующему оператору if.

 если ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1))
 

Полный код Serial.read()

Вот полный код использования Serial.read() для чтения всего сообщения:

 //Большое спасибо Нику Гэммону за основу этого кода
//http://www.gammon.com.au/serial 
 const беззнаковое целое число MAX_MESSAGE_LENGTH = 12;

недействительная установка () {
 Серийный номер  .начало (9600);
}

недействительный цикл () {

//Проверяем, доступно ли что-нибудь в буфере последовательного приема
в то время как (  серийный номер  .доступно () > 0)
{
//Создаем место для хранения входящего сообщения
статическое символьное сообщение [MAX_MESSAGE_LENGTH];
статическое целое число без знака message_pos = 0;

//Чтение следующего доступного байта в буфере последовательного приема
char inByte =  Серийный номер  .read();

//Приходит сообщение (проверьте, не заканчивается ли символ) и следите за размером сообщения
если ( inByte != '\n' && (message_pos < MAX_MESSAGE_LENGTH - 1))
{
//Добавляем входящий байт к нашему сообщению
сообщение[сообщение_поз.] = inByte;
сообщение_pos++;
}
//Полное сообщение получено...
еще
{
//Добавить нулевой символ в строку
сообщение[сообщение_поз] = '\0';

// Печатаем сообщение (или делаем что-то другое)
 Серийный номер  .println(сообщение);

//Сброс для следующего сообщения
сообщение_поз = 0;
}
}
}

 

ОК. Это похоже на тонну - я знаю!

Но прежде чем мы назовем это завершением, я хочу показать вам способ вернуть эту строку c в целое число.

Как преобразовать char в Int с помощью Arduino

Что делать, если вместо отправки слов или букв через последовательный порт вы, возможно, отправляете числовые значения, например 42 или 314.Как можно преобразовать эти цифры в целые числа?

Ну, есть очень крутая функция под названием atoi() — она берет строку с завершающим нулем и преобразует ее в целое число.

Строки в языке программирования c завершаются нулем — они заканчиваются символом «\0». Функция atoi() не будет работать, если строка, которую вы передаете, не имеет завершающего нуля символа!

Итак, все, что нам нужно сделать в нашем текущем коде, это добавить что-то вроде этого:

 еще
{
//Добавить нулевой символ в строку
сообщение[сообщение_поз] = '\0';

// Печатаем сообщение (или делаем что-то другое)
 Серийный номер  .println(сообщение);

//Или преобразовать в целое число и напечатать
число int = atoi (сообщение);
 Серийный номер  .println(номер);

//Сброс для следующего сообщения
сообщение_поз = 0;
}

 

Вот и все, серийное сообщение преобразовано из строки c в целое число!

Обзор Serial.read() Урок

Давайте сделаем быстрый обзор.

Во-первых, мы говорили в целом о последовательной связи — это средство отправки данных ______________ .Мы говорили о последовательном буфере приема — вы помните, сколько байтов он может хранить?

Мы обсудили основы Serial.read() и Serial.available().

Serial.read() удаляет байт из ________________. Функция _________________ возвращает количество байтов в буфере последовательного приема.

Мы разработали простую _____________ и стратегию для получения сообщений с нашего последовательного порта.

Затем мы реализовали стратегию в коде Arduino. Наконец, мы говорили об использовании функции atoi() для преобразования строки c в целое число.

Если вам понравился этот урок, вам обязательно понравится следующий урок! В следующем уроке этой серии вы узнаете, как сократить этот код до пары строк, используя некоторые другие встроенные функции библиотеки Serial.

Альтернатива последовательному монитору Arduino

— монитор последовательного порта

Последовательный монитор Arduino

Одна из лучших особенностей платформы заключается в том, что Arduino использует последовательную связь RS232 для взаимодействия с компьютерами.Это означает, что вы можете отправлять команды на плату Arduino с компьютера, который вы используете, и получать сообщения, отправленные Arduino через USB. Для этого необходимо открыть окно Arduino Serial Monitor, которое на самом деле является частью программного обеспечения платформы и находится на панели инструментов Arduino IDE. Утилита позволяет легко считывать серийный номер Arduino и контролировать поведение устройств, сопряженных с платой.

В дополнение к отображению данных, сгенерированных платой, Serial Monitor также может быть очень полезен при разработке и отладке эскиза Arduino.С помощью функции Serial.print(), которую она предоставляет, вы можете отправлять серийный вывод Arduino на ваш компьютер и отображать его на мониторе ПК. Почему это удобно для разработки скетчей Arduino? Что ж, бывает, что после загрузки кода на плату Arduino результат, который вы получаете, отличается от того, что вы ожидали. Например, светодиод не делает того, что вам нужно, например, мигает чаще, чем должен, или что-то в этом роде. Причиной может быть то, что переменная увеличивается и выключается, поэтому Arduino Serial Monitor кажется самым простым способом увидеть ее изменяющиеся значения.

Serial Port Monitor: альтернативное решение

Благодаря ограниченной функциональности Arduino Serial Port Monitor может поддерживать базовую последовательную связь, но все остальное, например, регистрация данных или мониторинг COM-портов в режиме реального времени, не представляется возможным с помощью этой утилиты. Вот где на помощь приходит Serial Port Monitor от Electronic Team (SPM).

Теперь каждый может открывать и закрывать COM-порты, изменять их параметры во время работы или передавать данные в различных форматах (например, строковый, двоичный, восьмеричный, десятичный или шестнадцатеричный) благодаря встроенному терминалу, доступному в PRO-версии СПМ.Отправка двоичных данных блоками также не является проблемой, пока вы используете программное обеспечение.

Монитор последовательного порта

— отличный способ сравнить и проанализировать информацию, отправляемую с платы Arduino на вашу машину. Приложение может регистрировать полученные последовательные данные в отдельный файл, что делает их доступными для дальнейшего рассмотрения.

Изменяя настройки управления потоком с помощью SPM, у вас будет возможность изменить функциональность платформы Arduino. Идея проста: как только вы отключите управление потоком, вы сможете получить доступ к последовательному порту без необходимости перезагрузки платы.В результате при отладке скетча Arduino вы можете просто подключить разъем и отслеживать данные без необходимости запуска скетча заново.

Вот некоторые другие основные возможности SPM:

  • Анализ активности COM-портов
  • Приложение позволяет начать мониторинг активных последовательных портов, как только они будут обнаружены программой. Преимущество здесь в том, что, обнаружив ошибку в своем коде, вы можете сразу же ее исправить.

  • Одновременный мониторинг нескольких портов
  • Пользователи, которые хотят отслеживать активность нескольких COM-портов одновременно, могут сделать это с помощью SPM.Сбор данных основан на методе «первым пришел — первым вышел».

  • Режимы фильтрации и визуализации данных
  • Опция фильтрации, которую предлагает SPM, предназначена для упрощения анализа данных, предоставляя вам возможность видеть только релевантные сообщения. Кроме того, данные могут отображаться в разных видах: таблица, строка, дамп и терминал.

Обладая огромным количеством выдающихся функциональных возможностей, но при этом дружественный и простой в использовании, Serial Monitor от Electronic Team для Arduino предоставляет возможность мониторинга и анализа последовательных данных любому пользователю, независимо от его навыков программирования.Это делает программное обеспечение лучшим решением для мониторинга последовательной связи, доступным на сегодняшний день.

arduino uno — как работает связь через последовательный порт?

На первый вопрос уже получен отличный ответ. Я отвечаю на другие.

я не смог найти вызов функции для UART.

В MCU нет "функций UART". UART управляется чтением и записью в специальные регистры.Они имеют такие имена, как UCSR0A , UCSR0B , UCSR0C (USART 0, регистры управления и состояния A, B и C), UBRR0L , UBRR0H (младшие и старшие байты регистра USART) 0 Скорость передачи в бодах и UDR0 (регистр данных USART 0). Все эти регистры указаны в файле HardwareSerial.cpp. Вы можете проверить таблицу данных для их значения.

где определение этого серийного номера?

В HardwareSerial.cpp, в конце файла, сразу после комментария «Предварительно создать объекты».

Кажется, есть кольцевой буфер для последовательного буфера. Итак, когда данные отправляются, что и кто заполняет данные в этот буфер внутри Hardware.cpp?

На самом деле существует два кольцевых буфера : буфер приема ( _rx_buffer ) заполняется подпрограммой обработки прерывания и очищается при вызове Serial.read() . Буфер передачи ( _tx_buffer ) заполняется при вызове Serial.write() , Serial.print() или Serial.println() (строка _tx_buffer->buffer[_tx_buffer->head] = c; в HardwareSerial::write() ), и очищается подпрограммой обслуживания прерывания.

Эти подпрограммы обслуживания прерываний определены в файле HardwareSerial.cpp. Они начинаются со строк типа ISR(SOMETHING_vect) . Они запускаются аппаратным UART. ISR передачи запускается, когда UART готов принять новый байт для передачи (когда он завершил передачу байта n , он начинает передачу байта n +1 и готов принять байт n +2 в своем буфер передачи).ISR приема запускается при получении нового байта.

когда он инициализируется?

Когда вы вызываете Serial.begin() .

Последовательная связь в Arduino

Само название объясняет его значение; слово «последовательный» означает последовательно, а «связь» означает общаться. В Arduino «последовательная связь» означает последовательную передачу данных на другое устройство. В Arduino мы можем осуществлять последовательную связь либо с компьютером, либо с некоторыми другими устройствами через разъем USB и контакты TX/RX Arduino.Последовательная связь в Arduino осуществляется через контакты, предназначенные для этой цели.

Последовательная связь обеспечивает передачу каждого байта данных на другое устройство или компьютер. В этой статье последовательная связь в Arduino подробно объясняется с помощью простого примера.

Что такое последовательная связь в Arduino

В Arduino Uno два контакта; контакты 0 и 1 предназначены для последовательной связи, известной как UART (универсальный асинхронный передатчик приемника) и USART (универсальный синхронный асинхронный передатчик приемника), и они также известны как контакты Tx/Rx.Эти контакты работают при напряжении 3,3 или 5 вольт, поэтому не рекомендуется подключать их к последовательному порту RS232, поскольку он работает от 12 вольт, что может повредить плату Arduino. USB-разъем.


На приведенном выше рисунке Arduino Uno мы видим, что контакты 0 и 1 указаны с TX / RX, используемыми для последовательной связи, также присутствует разъем USB для последовательной связи с компьютером.Существуют разные типы плат, но каждая плата имеет как минимум один порт UART или USART:
ДОСКА USB CDC ИМЯ ПОСЛЕДОВАТЕЛЬНЫЕ ШТЫРЬКИ ПОСЛЕДОВАТЕЛЬНЫЙ1 КОНТАКТ ПОСЛЕДОВАТЕЛЬНЫЙ2 КОНТАКТ ПОСЛЕДОВАТЕЛЬНЫЙ 3 КОНТАКТА
Уно 0 (прием), 1 (передача)
Мега 0 (прием), 1 (передача) 19 (прием), 18 (передача) 17 (прием), 16 (передача) 15 (прием), 14 (передача)
Ноль SerialUSB (только собственный порт USB) Подключен к порту программирования 0 (прием), 1 (передача)

В приведенной выше таблице мы видим, что Arduino Mega имеет три дополнительных порта для последовательной связи.

Вывод последовательной связи можно увидеть на последовательном мониторе, доступ к которому можно получить в «Arduino IDE», щелкнув «Последовательный монитор» в раскрывающемся меню инструментов:


Для последовательной связи с компьютером подключите Arduino к компьютеру через USB-кабель.

Существуют различные встроенные функции Arduino, но наиболее часто используемые для последовательной связи:

Функции Описание
начало(скорость) Эта функция используется для установки скорости передачи данных при определенной скорости передачи данных
чтение() Эта функция используется для получения данных от другой подключенной машины
печать() Эта функция преобразует данные в текст ASCII, который легко читается людьми, и распечатывает их на последовательном мониторе
println() Эта функция работает так же, как print(), но добавляет новую строку
смыв() Эта функция обеспечивает завершение передачи исходящих последовательных данных

Пример: Последовательная связь Arduino

Мы будем использовать функцию begin() для последовательной связи с компьютером через USB-разъем Arduino и установим скорость передачи данных на уровне 9600 бод.Затем мы воспользуемся простой функцией print() для вывода текста «Добро пожаловать в LinuxHint» на последовательный монитор, для этого рассмотрим следующий код:

void setup () {

Serial.begin (9600);

Serial.print("Добро пожаловать в LinuxHint");

}

недействительный цикл(){

}


Скомпилируйте код, загрузите его на Arduino, а затем визуализируйте вывод на последовательном мониторе:


В выводе последовательного монитора видно, что вывод отображается.

Заключение

Последовательная связь в Arduino используется для передачи данных на подключенное устройство. Каждая плата Arduino содержит как минимум один порт UART или USART, через который можно осуществлять последовательную связь. В этой статье последовательная связь в Arduino объясняется на примере последовательной связи между Arduino и компьютером.

.

Добавить комментарий

Ваш адрес email не будет опубликован.