Cat hungry.png
Здравствуйте! Собираем деньги на перевод материалов по электронике(https://www.allaboutcircuits.com/education/). Реквизиты указаны здесь.

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

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

Перевод: Максим Кузьмин (Cubewriter)
Перевел 2686 статей для сайта.

Контакты:

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


Ambox content.png Черновик


Библиотека 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, но лишь в том случае, если пойдет на небольшую уступку. Эта библиотека создавалась на принципе, что вы можете подключить столько девайсов, сколько будут позволять ограничения по ресурсам – до тех пор, пока одновременно используется только один из них. Если вы сможете переработать свой код в соответствии с этим требованием, то никаких проблем возникнуть не должно.

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

  1. #include <NewSoftSerial.h>
  2.  
  3. // это GPS-девайс, подключенный к контактам 3 и 4:
  4. NewSoftSerial gps(4,3);
  5.  
  6. // это термометр, подключенный к контактам 5 и 6:
  7. NewSoftSerial therm(6,5);
  8.  
  9. // это LCD, подключенный к контактам 7 и 8:
  10. NewSoftSerial LCD(8,7); 
  11.  
  12. void loop()
  13. {
  14.   ...
  15.   // несколько секунд собираем данные от GPS-устройства:
  16.   gps.listen();
  17.   read_gps_data();  // в качестве активного устройства используем GPS-устройство
  18.   // собираем температурные данные от термометра:
  19.   therm.listen();
  20.   read_thermometer_data(); // теперь используем термометр
  21.   // здесь активным устройством становится LCD:
  22.   LCD.listen();
  23.   LCD.print("Data gathered..."); // "Данные собраны..."
  24.   ...
  25. }

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

  1. void loop()
  2. {
  3.   device1.listen();
  4.   if (device1.available() > 0)
  5.   {
  6.     int c = device1.read();
  7.     ...
  8.   }
  9.   device2.listen();
  10.   if (device2.available() > 0)
  11.   {
  12.     int c = device2.read();
  13.     ...
  14.   }
  15. }

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

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

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

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

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

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

  1. int ver = NewSoftSerial::library_version();

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

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

Загрузка

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

См.также

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

  1. arduiniana.org - NewSoftSerial