Arduino:Библиотеки/NewSoftSerial

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Библиотека NewSoftwareSerial[1]

Библиотека NewSoftSerial – это библиотека Arduino для работы с «программными» последовательными портами, и она является прямым потомком библиотеки AFSoftSerial, разработанной Лимор Фрид. Ее главное отличие от оригинальной SoftwareSerial заключается в том, что она обрабатывает входящие данные при помощи прерываний, а не опросов.

Если прерывания не использовать, возможности скетча становятся весьма ограниченными, т.к. ему нужно постоянно делать опросы последовательного порта – короткими и регулярными интервалами. По этой причине практически невозможно использовать SoftwareSerial, к примеру, для получения GPS-данных и их дальнейшей переработки в приемлемую форму. Ваш скетч слишком занят тем, что пытается успеть за прибывающими NMEA символами, поэтому у него не хватает времени, чтобы собрать из них что-то толковое. Тут-то на помощь и приходит AFSoftSerialNewSoftSerial) со своими прерываниями. С их помощью скетч записывает только что присланные данные в буфер, одновременно с этим обрабатывая данные, присланные чуть ранее.

Примечание

С декабря 2011 года (т.е. начиная с IDE Arduino версии 1.0) библиотека NewSoftSerial официально заменяет оригинальную SoftwareSerial. Это значит, что если вы работаете с IDE Arduino версии 1.0 и выше, то вам эту библиотеку загружать не нужно – она уже будет в комплекте с IDE Arduino. Таким образом, чтобы переделать код под IDE Arduino 1.0, просто поменяйте все отсылки к SoftwareSerial на NewSoftSerial.

Улучшения

Вот список улучшений библиотеки NewSoftSerial:

  • Наследует от встроенного класса Print, что позволяет избавиться от 4-600 байтов дублирующего кода
  • Использует кольцевой буфер, что делает обработку данных на RX более эффективной
  • Поддерживает все (т.е. с 0-ого по 19-ый) контакты Arduino (на Arduino Miniс 0-ого по 21-ый), а не только с 0-ого по 13-ый
  • Поддерживает одновременную коммуникацию с несколькими девайсами, подключенными через программные последовательные порты. Впрочем, тут есть ограничение, связанное с использованием нескольких экземпляров, читайте о нем в разделе ниже
  • Поддерживает более широкий диапазон скоростей передачи данных. Впрочем, при использовании скоростей «300» и «1200» нужно быть осторожнее. На этих скоростях обработчик прерываний становится слишком объемным, из-за чего прерывания начинают зависать, а функция millis(), в свою очередь, перестает работать во время получения данных
  • Внедряет функцию overflow(), определяющую переполнение буфера. Тип данных – boolean
  • Высокие скорости передачи данных были отрегулированы – в целях повышения корректности
  • Поддерживает ATMega328 и 168
  • Поддерживает процессоры на 8 МГц
  • Использует прямой порт I/O – чтобы операции выполнялись быстрее и корректней
  • Поддерживает программную инверсию сигнала (начиная с версии 10)
  • Поддерживает процессоры на 20 МГц
  • Может работать на Teensy и Teensy++
  • Поддерживает функцию end() – в дополнение к begin()

Использование нескольких экземпляров

Хотя в описании библиотеки заявлено, что она поддерживает одновременно коммуникацию с несколькими девайсами, у этой функции все же есть ограничения. Обработка данных, асинхронно присылаемых от двух, трех, четырех и более устройств, подключенных через программные последовательные порты, может оказаться очень сложной, а то и вовсе неразрешимой проблемой. Представьте, что к Arduino подключено четыре устройства, и все передают данные на скорости 38400 бод. У процессора Arduino есть всего 26 микросекунд, чтобы обработать каждый из 4 входящих битов, иначе они будут попросту потеряны.

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

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

#include <NewSoftSerial.h>
 
// это GPS-девайс, подключенный к контактам 3 и 4:
NewSoftSerial gps(4,3);
 
// это термометр, подключенный к контактам 5 и 6:
NewSoftSerial therm(6,5);
 
// это LCD, подключенный к контактам 7 и 8:
NewSoftSerial LCD(8,7); 
 
void loop()
{
  ...
  // несколько секунд собираем данные от GPS-устройства:
  gps.listen();
  read_gps_data();  // в качестве активного устройства используем GPS-устройство
  // собираем температурные данные от термометра:
  therm.listen();
  read_thermometer_data(); // теперь используем термометр
  // здесь активным устройством становится LCD:
  LCD.listen();
  LCD.print("Data gathered..."); // "Данные собраны..."
  ...
}

В данном примере функция read_gps_data() использует объект gps, а функция read_thermometer_data() – объект therm. Объект, вызываемый с функцией listen(), становится «активным», в то время как предыдущий объект деактивируется, а его буфер опустошается. Важный момент в том, что если объект неактивен, то функция available() всегда возвращает «0». Это значит, что вы не можете написать код типа такого:

void loop()
{
  device1.listen();
  if (device1.available() > 0)
  {
    int c = device1.read();
    ...
  }
  device2.listen();
  if (device2.available() > 0)
  {
    int c = device2.read();
    ...
  }
}

Этот код не способен сделать ничего, кроме переключения с одного объекта на другой.

Инверсия сигнала

В «нормальной» транзисторно-транзисторной логике (или ТТЛ) стартовым битом является «0» (или LOW), а стоповым – «1» (или HIGH). Однако у некоторых девайсов, работающих через последовательный порт, эта логика перевернута, что называют «инверсией сигнала». Библиотека NewSoftSerial поддерживает такие устройства, начиная с 10 версии – инвертированная логика включается через указание третьего boolean-параметра при создании экземпляра.

NewSoftSerial myInvertedConn(7, 5, true); // у этого девайса инвертированный сигнал
NewSoftSerial myGPS(3, 2); // у этого – нет

Версия библиотеки

Информацию о версии библиотеки можно получить, вызвав статический член library_version().

int ver = NewSoftSerial::library_version();

Потребление ресурсов

Ссылка на библиотеку NewSoftSerial добавляет размеру вашего скетча примерно 2000 байт.

Загрузка

Последняя версия NewSoftSerial доступна здесь. Не загружайте ее, если у вас установлен IDE Arduino версии 1.0 и выше – NewSoftSerial уже включена в ядро Arduino, где называется SoftwareSerial.

См.также

Внешние ссылки