Программируем Arduino. Основы работы со скетчами
Шрифт:
Создание строк
Создать строку можно из массива элементов типа char, а также из значения типа int или float, как показано в следующем примере:
String message = "Temp: ";
String temp = String(123);
Конкатенация строк
Строки типа String можно объединять друг с другом и с данными других типов с помощью оператора +. Попробуйте добавить следующий код в функцию setup пустого скетча:
Serial.begin(9600);
String message = "Temp: ";
String temp = String(123);
Serial.println(message + temp + " C");
Обратите
Другие строковые функции
В табл. 6.1 перечислены еще несколько удобных функций из библиотеки String. Полный список доступных функций можно найти по адресу http://arduino.cc/en/Reference/StringObject.
Таблица 6.1. Некоторые полезные функции в библиотеке String
Функция
Пример
Описание
[]
char ch = String("abc")[0]
Переменная ch получит значение "a"
trim
String s = " abc ";
s.trim;
Удалит пробелы с обеих сторон от группы символов abc. Переменная s получит значение "abc"
toInt
String s = "123";
int x = s.toInt;
Преобразует строковое представление числа в значение типа int или long
substring
String s = "abcdefg";
String s2 = s.substring(1, 3);
Возвращает фрагмент исходной строки. Переменная s2 получит значение "bc". В параметрах передаются: индекс первого символа фрагмента и индекс символа, следующего за последним символом фрагмента
replace
String s = "abcdefg";
s.replace("de", "DE");
Заменит все вхождения "de" в строке на "DE". Переменная s2 получит значение "abcDEfg"
Использование ЭСППЗУ
Содержимое всех переменных, используемых в скетче Arduino, теряется при выключении питания или выполнении сброса. Чтобы сохранить значения, их нужно записать байт за байтом в память ЭСППЗУ. В Arduino Uno имеется 1 Кбайт памяти ЭСППЗУ.
ПРИМЕЧАНИЕ
Это не относится к плате Arduino Due, не имеющей ЭСППЗУ. В этой модели данные следует сохранять на карту microSD.
Для чтения и записи данных в ЭСППЗУ требуется использовать библиотеку, входящую в состав Arduino IDE. Следующий пример демонстрирует, как записать единственный байт в ЭСППЗУ, в данном случае операция выполняется в функции setup:
#include <EEPROM.h>
void setup
{
byte valueToSave = 123
EEPROM.write(0, valueToSave);
}
В первом аргументе функции write передается адрес в ЭСППЗУ, куда должен быть записан байт данных, а во втором — значение для записи в этот адрес.
Для чтения данных из ЭСППЗУ используется команда read. Чтобы прочитать единственный байт, достаточно выполнить следующую команду:
EEPROM.read(0);
где 0 — это адрес в ЭСППЗУ.
Пример использования ЭСППЗУ
Следующий пример демонстрирует типичный сценарий записи значения в процессе нормального выполнения программы и его чтения в момент запуска.
Приложение реализует кодовый замок двери и дает возможность вводить и изменять шифр с помощью монитора последовательного порта. Шифр хранится в ЭСППЗУ, поэтому его можно менять. Если бы шифр должен был сбрасываться при каждом запуске Arduino, не было бы смысла давать пользователю возможность изменять его.В дискуссии, приведенной далее, будут обсуждаться отдельные фрагменты скетча. Желающие увидеть полный код скетча могут открыть скетч sketch_06_06_EEPROM_example в Arduino IDE, доступный в пакете примеров для этой книги на сайте www.simonmonk.org. Опробуйте этот скетч у себя, чтобы получить более полное представление о его работе. Он не требует подключения дополнительного аппаратного обеспечения к Arduino.
Функция setup содержит вызов функции initializeCode.
void initializeCode
{
byte codeSetMarker = EEPROM.read(0);
if (codeSetMarker == codeSetMarkerValue)
{
code = readSecretCodeFromEEPROM;
}
else
{
code = defaultCode;
}
}
Задача этой функции — записать значение в переменную code (шифр). Это значение обычно читается из ЭСППЗУ, но при этом возникает несколько сложностей.
Содержимое ЭСППЗУ может быть не очищено в момент выгрузки нового скетча; значение, однажды записанное в ЭСППЗУ, может измениться только в результате записи нового значения поверх старого. То есть при первом запуске скетча нет никакой возможности узнать, не было ли значение оставлено в ЭСППЗУ предыдущим скетчем. В результате можно оказаться перед закрытой дверью, не зная, какой шифр хранится в ЭСППЗУ.
Для решения этой проблемы можно написать отдельный скетч, устанавливающий шифр по умолчанию. Этот скетч потребовалось бы установить в плату Arduino перед основным скетчем.
Второй, менее надежный, но более удобный способ — использовать специальный признак, который записывается в ЭСППЗУ и указывает, что шифр действительно был записан. Недостатком этого решения является малая вероятность того, что в ячейке ЭСППЗУ, где должен храниться признак, уже будет записано его значение. Из-за этого обстоятельства данное решение неприемлемо для коммерческих продуктов, но в данном случае мы можем так рискнуть.
Функция initializeCode читает первый байт из ЭСППЗУ, и, если он равен переменной codeMarkerValue, которой где-то в другом месте присваивается значение 123, она считает, что ЭСППЗУ содержит установленный пользователем шифр, и вызывает функцию readSecretCodeFromEEPROM:
int readSecretCodeFromEEPROM
{
byte high = EEPROM.read(1);
byte low = EEPROM.read(2);
return (high << 8) + low;
}
Эта функция читает двухбайтный шифр типа int из байтов с адресами 1 и 2 в ЭСППЗУ (рис. 6.5).
Рис. 6.5. Хранение значения типа int в ЭСППЗУ
Чтобы из двух отдельных байтов получить одно значение int, нужно сдвинуть старший байт влево на 8 двоичных разрядов (high << 8) и затем прибавить младший байт.
Чтение хранимого кода из ЭСППЗУ выполняется только в случае сброса платы Arduino. Но запись шифра в ЭСППЗУ должна выполняться при каждом его изменении, чтобы после выключения или сброса Arduino шифр сохранился в ЭСППЗУ и мог быть прочитан в момент запуска скетча.