Пока лучшие итальянские умы работают над версией 1.0, нас посетила очередная ArduinoIDE 0019. По традиции, я устраиваю разбор ReleaseNotes, тем более, что изменения весьма существенные. Начнем, как всегда, с ядра arduino и прочих важных моментов, оказывающих влияние на совместимость.
Класс String
Наверное, многие знатоки C/C++ с недоумением взирали на скетчи с пачками строк типа:
Serial.print("Current values: s1 =");
Serial.print(s1);
Serial.print(", s2 =");
Serial.print(s2);
Serial.print(", s3 =");
Serial.println(s3);
и тому подобное, которые тут же хотелось заменить на
sprintf("Current values: s1=%d, s2=%d, s3=%d\n",s1,s2,s3)
Да собственно, так и делали, добавляя #include<stdio.h> и расходуя на такую роскошь определенное количество progmem.
С точки зрения C++ и его класса String все выглядело еще хуже - надо было подключать
библиотеку стандартных шаблонов C++, а уж виртуальные темплейты точно выходят за пределы здравого смысла. Поэтому, обычно использовали
string.h.
Только одно плохо - все эти #include со стандартными библиотеками отдаляли Wiring от его первооснов (простоты, интуитивности и доступности для НЕпрограммистов) и приближали к банальному C/С++.
Зато теперь - другое дело, в ядро arduino официально добавлен класс String. Благодаря ему вы можете запросто писать так:
String S1 = "millis() value: " + millis();
Serial.println(S1);
или
String stringOne = "Content-Type: text/html";
if (stringOne.substring(19) == "html") {
Serial.println("It's an html file");
}
Память под строку распределяется при помощи C-шного API malloc() и free(), чего в arduino отродясь не практиковалось (готовьте ~1000 байт памяти программ). Это также стоит учитывать при планировании расхода памяти данных, с ней-то вообще в ATmega напряженно (1K в ATmega8/168 и 2K в ATmega328P). Класс устроен таким образом, что при увеличении строки пытается перераспределить больший фрагмент памяти.
И советую поизучать на досуге примеры в каталоге examples - там аж 12 разных скетчей на тему String.
Новый оператор shiftIn
То, чего мне так не хватало в статье
Размножение входов или shiftIn. Функция полностью комплементарна оператору
shiftOut, только не выводит, а
считывает восемь бит и возвращает их в виде байта.
Абстрактный класс Stream
Небольшое изменение иерархии классов - теперь Serial не порожден от Print напрямую, а (о, ужас!) через "прослойку" под названием Stream. Дэвид утверждает, что теперь писателям и пользователям библиотек взаимодействия по последовательному протоколу будет легче - можно воспользоваться полиморфизмом: писателю достаточно включить наследование от Stream, а пользователю - использовать методы Stream. Тогда, при определенной организации кода, можно обойтись минимумом изменений, поскольку для работы с любым порожденным от Stream классом всего и нужно-то available(), read() и flush() (многообразные функции вывода организует базовый класс Print).
Serial.peek()
Специальная функция в HardwareSerial, возвращает символ в хвосте приемного буфера или -1, если буфер пуст. Так сказать "try before buy" - можно "подглядеть" первый символ, который вернет read(), не забирая его из буфера.
Поддержка Mega
Тут сплошные улучшения. В ядре реализована возможность выбрать внутренний источник напряжения - в ATmega1280 он может быть
1.1 или
2.56 В. Побочный эффект - константа
INTERNAL при компиляции для
Arduino Mega перестает существовать и заменяется на
INTERNAL1V1 и
INTERNAL2V56, так что в итоге придется просматривать и править существующий код. Улучшена
Firmata - вроде бы она и раньше поддерживала ATmega1280, но теперь код явно "причесали" - появился
Boards.h с широкой секцией поясняющих комментариев. Видимо, как всегда - в процессе причесывания заметили ошибки ;)
Новая библиотека SPI
Полностью базируется на аппаратной реализации ATmega. Неоспоримое преимущество - возможность работы по прерываниям. С одной стороны, кода там совсем немного, с другой - приходится каждый раз повторно писать его в библиотеку работы с очередным устройством по SPI. И вот теперь - вынесли отдельно, ура!
Библиотека Ethernet
Не прошло и года с момента моей публикации
Arduino по UDP, как возможность работать с
UDP появилась и в стандартной библиотеке. Из минусов - работу с Wiznet5100 перевели на вышеупомянутую библиотеку SPI, но строчку
#include <SPI.h> почему-то требуется писать именно в скетче. Поэтому - быстренько поправьте все ваши скетчи, работающие с Ethernet - иначе они не будут компилироваться.
Общие улучшения ядра
- Добавлены алиасы для аналоговых пинов - A0, A1, A2... Стало понятнее - вместо pinMode(14,OUTPUT) можно писать pinMode(A0,OUTPUT);
- Повышена точность delay(). Теперь она использует не millis(), а micros();
- При обращении к регистрам портав в pinMode() и digitalWrite() запрещаются прерывания. Там внутри стоят операторы типа *out |= bit и *out &= ~bit, которые на самом деле есть сокращенная запись трех операций - считывания, логики и записи. Сами понимаете, что могло бы быть, если в этот момент происходило прерывание (советую обновиться всем, кто использовал attachInterrupt в скетчах);
- После завершения tone повторно разрешается PWM (если он был активен).
Менее значительные, но не менее важные изменения коснулись и самой IDE. Традиционно, обновлен список плат - туда добавили
Arduino FIO.
Наконец-то пофиксили застарелую проблему с неработой автосброса под Linux. Проявлялось это только под Linux и только со специфическими FTDI-кабелями, в которых вместо DTR-а для автосброса был наивно выведен RTS. Видимо под Windows это работало исключительно из-за того, что при открытии порта драйвер "шаловливыми ручками" дергал RTS. Ну что же... бывают неожиданные неприятности и от слишком хорошо написанного кода - теперь ArduinoIDE будет дергать и RTS тоже.
Подтянулись до последней версии
Processing, немного улучшили
Serial Monitor - добавили отключение автоскроллинга и управление интерпретацией перевода строки:
Но самое интересное, на мой взгляд, коснулось файла boards.txt для разработчиков стороннего оборудования. Как известно, в каталоге sketchbook можно создавать подкаталоги для совместимых с Arduino платформ, где можно описать любую новую плату, у которой будут свои специфичные настройки и даже свое собственное ядро. При старте ArduinoIDE описания стандартных и дополнительных платформ соединяются и все вместе дружно появляются в меню.
Так вот - теперь можно указывать в boards.txt строку вида:
newboard.upload.using=otherplatform:programmer
Такая опция указывает, как загружать результат компиляции - в данном случае, будет использовано описание программатора из
otherplatform, например
arduino:parallel. По большому счету, эта опция позволяет не создавать собственный
programmers.txt и в конечном итоге работать вообще без бутлоадера, если под рукой есть любой поддерживаемый
avrdude программатор.
Вот и все, что мне удалось накопать. Ну а пока мир застыл в ожидании, глядя на невозможное - изменился бессменный баннер на заглавной странице
arduino.cc:
Думаю, где-то к октябрю интригу, наконец, раскроют. Может быть, гибкая плата? ;)