Arduino:Библиотеки/NewSoftSerial
Содержание | Знакомство с Arduino | Продукты | Основы | Справочник языка Arduino | Примеры | Библиотеки | Хакинг | Изменения | Сравнение языков Arduino и Processing |
Библиотека NewSoftwareSerial[1]
Библиотека NewSoftSerial – это библиотека Arduino для работы с «программными» последовательными портами, и она является прямым потомком библиотеки AFSoftSerial, разработанной Лимор Фрид. Ее главное отличие от оригинальной SoftwareSerial заключается в том, что она обрабатывает входящие данные при помощи прерываний, а не опросов.
Если прерывания не использовать, возможности скетча становятся весьма ограниченными, т.к. ему нужно постоянно делать опросы последовательного порта – короткими и регулярными интервалами. По этой причине практически невозможно использовать SoftwareSerial, к примеру, для получения GPS-данных и их дальнейшей переработки в приемлемую форму. Ваш скетч слишком занят тем, что пытается успеть за прибывающими NMEA символами, поэтому у него не хватает времени, чтобы собрать из них что-то толковое. Тут-то на помощь и приходит AFSoftSerial (и NewSoftSerial) со своими прерываниями. С их помощью скетч записывает только что присланные данные в буфер, одновременно с этим обрабатывая данные, присланные чуть ранее.
Примечание. С декабря 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.