Электрификация

Справочник домашнего мастера

HTML parser online

Содержание

Arduino библиотека Serial

Библиотека Serial — это стандартная библиотека, которая подключается в скетчи автоматически. Она используется для передачи данных через последовательный порт Arduino. В большинстве плат ардуино доступен 1 интерфейс Serial. Последовательный порт работает с двумя цифровыми пинами Ардуино 0-ой (RX) и 1-ый (TX). В Arduino Mega таких интерфейсов 3. Для доступа к интерфейсу связи необходимо использовать ключевой слово Serial (Serial1 и Serial2 для Arduino Mega).

Теперь рассмотрим доступные функции библиотеки Serial:

if(Serial)

Условие с проверкой готовности порта к работе. Используется такая конструкция довольно редко, потому что обычно интерфейс доступен.

Синтаксис, параметры, возвращаемые значения, пример

1 2 3 if(!Serial) { /* Блок кода, которой будет исполняться если Serial интерфейс не доступен */ }

available()

Проверяет число байтов доступных для считывания. Данная функция показывает какое количество данных уже пришло и хранится в буфере обмена. Размер буфера последовательного порта 64 байта.

Синтаксис, параметры, возвращаемые значения, пример

Синтаксис

Serial.available()

Параметры

Нет

Возвращаемые значения

Число байт доступных для чтения

availableForWrite()

Проверяет число байтов доступных для записи в буфер обмена, без блокировки функции записи.

Синтаксис, параметры, возвращаемые значения, пример

Serial.availableForWrite()

Нет

Число байт доступных для записи

begin()

Данная функция устанавливает соединение на определенной скорости.

Синтаксис, параметры, возвращаемые значения, пример

Serial.begin(speed, config)

Нет

1 2 3 void setup() { Serial.begin(9600); // Установка соединения на скорости передачи данных на 9600 бит/сек }

end()

Отключает соединение через последовательный порт и освобождает пины RX и TX.

Синтаксис, параметры, возвращаемые значения, пример

Serial.end();

Нет

Нет

find()

Считывает данные из буфера обмена до тех пор пока не найдет заданную строку.

Синтаксис, параметры, возвращаемые значения, пример

Serial.find(needle)

needle — Обязательный параметр. Строка которую нужно найти

true — Если строка найдена.
false — Если строка не найдена.

findUntil()

Считывает данные из буфера обмена до тех пор пока не найдет заданную строку или терминальную строку.

Синтаксис, параметры, возвращаемые значения, пример

Serial.findUntil(needle, terminal);

needle — Обязательный параметр. Строка которую нужно найти
terminal — Обязательный параметр. Терминальная строка которую нужно найти

true — Если строка найдена.
false — Если строка не найдена.

flush()

Очищает буфер обмена последовательного порта

Синтаксис, параметры, возвращаемые значения, пример

Serial.flush();

Нет

Нет

parseFloat()

Возвращает первое найденное в буфере обмена число с плавающей точкой. Все остальные символы игнорируются.

Синтаксис, параметры, возвращаемые значения, пример

Serial.parseFloat();

Нет

Число с плавающей точкой (float)

parseInt()

Возвращает первое найденное в буфере обмена целое число. Все остальные символы игнорируются.

Синтаксис, параметры, возвращаемые значения, пример

Serial.parseInt(skipChar);

skipChar — необязательный параметр. Символ который будет пропускаться при поиске

Целое число (long) или 0, если не найдено цифр.

peek()

Возвращает первый байт данных из буфера.

Синтаксис, параметры, возвращаемые значения, пример

Serial.peek();

Нет

Первый байт входящих последовательных данных (int). Если данных нет то вернет «-1»

print()

Функция отправляет данные в последовательный порт в виде ASCII-текста.

Синтаксис, параметры, возвращаемые значения, пример

Serial.print(val, format);

val — обязательный параметр. Данные, которые необходимо отправить.
format — Необязательный параметр. Форматирует отправляемые данные. Может принимать следующие значения:
BIN — Двоичный формат.
OCT — Восьмеричный формат.
DEC — Десятичный формат
HEX — Шестнадцатиричный формат.
0 — Округление числа до целых.
2 — Округление число до сотых.

Количество записанных байтов (long)

println()

Отправляет данные в виде ASCII-текста в последовательный порт с символом конца строки (\r) и символом новой строки (\n)

Синтаксис, параметры, возвращаемые значения, пример

Serial.printIn(val, format)

val — обязательный параметр. Данные, которые необходимо отправить.
format — Необязательный параметр. Форматирует отправляемые данные. Может принимать следующие значения:
BIN — Двоичный формат.
OCT — Восьмеричный формат.
DEC — Десятичный формат
HEX — Шестнадцатиричный формат.
0 — Округление числа до целых.
2 — Округление число до сотых.

Количество записанных байтов (long)

read()

Считывает данные из последовательного порта.

Синтаксис, параметры, возвращаемые значения, пример

Serial.read()

Нет

Первый доступный байт (int).

readBytes()

Считывает символы из последовательного порта в буфер. Завершает свою работу, если сосчитает данные заданной длины или если выйдет время. Время указывается при помощи функции serial.setTimeout().

Возвращаемое значение — количество символов, помещенных в буфер. Если функция вернет значение «0», это значит, что нужных данных найдено не было.

Синтаксис, параметры, возвращаемые значения, пример

Serial.readBytes(buffer, length);

buffer — буфер, в который будут сохраняться входящие байты (char или byte)
length — количество считанных байтов (int)

Байт

readBytesUntil()

Считывает символы из буфера последовательного порта в массив. Завершает свою работу, если обнаружит терминальный символ, если сосчитает данные заданной длины или если выйдет время. Время указывается с помощью функции Serial.setTimeout().

Синтаксис, параметры, возвращаемые значения, пример

Serial.readBytesUntil(character, buffer, length);

character — символ, который нужно найти (char)
buffer — буфер, в который будут сохранены входящие байты (char или byte)
length — количество байтов, которые нужно сосчитать (int)

Байт.

readString()

Считывает данные из буфера последовательного порта в строку. Завершает свою работу, если выйдет время. Время указывается в функции Serial.setTimeout().

Синтаксис, параметры, возвращаемые значения, пример

Serial.readString()

Нет.

Строка с данными, считанными из буфера последовательного порта.

readStringUntil()

Считывает символы из буфера последовательного порта в строку. Завершает свою работу, если наткнется на терминальный символ или если выйдет время. Время указывается в функции Serial.setTimeout().

Синтаксис, параметры, возвращаемые значения, пример

Serial.readStringUntil(terminalChar);

terminalChar— искомый символ (char)

Строка, считанная из буфера последовательного порта (до символа, завершающего работу функции).

setTimeout()

Синтаксис, параметры, возвращаемые значения, пример

Serial.setTimeout(time);

time — время ожидания в миллисекундах (long).

Нет

write()

Передает через последовательный порт данные в двоичном виде. Данные передаются как байт или как серия байтов. Если вам нужно отправить символы, представляющие цифры какого-либо числа, используйте функцию print().

Синтаксис, параметры, возвращаемые значения, пример

Serial.write(val, len)

val — значение, строка или буфер для отправки.
len — размер буфера

Байт или количество отправленных байтов

Парсер данных из интернета на Arduino


Всем привет, в данной самоделки я покажу как можно сделать дешевый, простой, но в то же время эффективный парсер данных из интернета на базе платформы Arduino с Wifi модулем. С помощью нее, легко можно узнать практически любую информацию из сети за считанные секунды. Это может быть кол-во подписчиков на youtube, кол-во входящих сообщений Вконтакте, опубликовали ли самоделку и т.д.
Вот простая схема, которую необходимо собрать.

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

Нам потребуется:
-Платформа на базе семейства ESP, в моем случаи и это WeMos D1 R2

-LCD дисплей для вывода информации, у меня популярный LCD 1602 с модулем I2C
-провода и кнопка (хотя она возможно вам и не понадобится)
А так же
-USB кабель (для загрузки прошивки)
-WiFI точка доступа
— Необязательное
— собственный сайт и домен (для обработки сложных запросов популярных сайтов)
Перед тем, как приступить к следующим этапам, убедитесь что среда, через которую вы будете загружать скетч поддерживается семейство микроконтроллеров ESP. Для настройки Arduino IDE, перейдите на habr и следуйте инструкциям по установке. Ссылка: https://habr.com/ru/post/371853/
Подробное описание изготовления:
Условно этапы можно разделить на 2 части.
1 Сборка «железной» части
2 Загрузка программы и ее настройка
Сборка первого этапа заканчивается очень быстро. Собираем ее по изображению выше и все.
Модуль дисплея
VCC — 5V
GND — GND
SCL — D15
SDA — D14
Buttun — GND to D7
Все эти настройки можно изменить и в самом скетче, если у вас другая платформа или версия микроконтроллера.
Второй этап немного сложней, открываем Arduino IDE, выбираем соответствующую плату и указываем порт на котором она находится. В моем случаи плата: WeMos D1 R1 И порт 3

Все остальные настройки можно оставить по умолчанию.
Сам скетч:
Обратите внимание что у вас должна быть еще дополнительно установлены 2 библиотеки.Это ArduinoJson.h и LiquidCrystal_I2C.h !

Затем изменяем в настройках скетча важные переменные, это SSID (имя Wifi точки) и password (пароль Wifi точки)

После чего, можно загружать прошивку.
Если дисплей был подключен верно, то на нем будет выводится следующая информация.

Если этого не происходит, проверьте следующую настройку.

Укажите правильный I2C адресc. В любом случаи, лучше первый раз после загрузки скетча открыть Serial порт, и убедится что соединение было успешно установлено.

Если этого не происходит, перепроверьте данные Wifi точки.
Если все успешно загрузилось и подключилось, то на дисплеи вы должны увидеть следующее:

Можете так же нажать на кнопку, и проверить обновляются ли данные (если вы ее подключили).
Все, на этом этапе 95% работы выполнено, осталось только указать в настройка данные, которые необходимо парсить. Все они находятся в константе «A»
const String A = «http://jsonplaceholder.typicode.com/users/1,name,User 1:;http://jsonplaceholder.typicode.com/users/2,name,User 2:;»;
Итак, синтаксис записи прост. Все источники разделены между собой на группы, отделяющиеся точка с запятой (;).
Каждая группа состоит из 3 главных параметров, это
— URL, на который будет идти запрос
— Значение, которое нужно извлечь.
— Дополнительный текст, выводимый на дисплей.
Таким образом http://jsonplaceholder.typicode.com/users/1,name,User 1: ==
URL = http://jsonplaceholder.typicode.com/users/1
KEY = name
text = «User 1:»
Если сейчас перейти по ссылке http://jsonplaceholder.typicode.com/users/1То можно увидеть следующую информацию
Где собственно и видно откуда взялось значение «name».
Таким образом, можно уже извлекать информацию с простеньких сайтов. Но этот метод не годится для работы с «серьезными» сайтами, которые работаю с SSL сертификатами, которые проверяют запросы и выводят всякую если им что-то не нравится, да и к тому же вывод данных слишком сложен, что бы обработать их «силами ардуино». Как я не пробовал «обходить» все это, но есть вещи которые или работают очень не стабильно или вовсе не работают. Постоянные обновления сертификатов не сильно то помогают. Поэтому как я считаю, наиболее разумным решением будет создание собственного сайта, «внутри» которого все эти запросы будут выполниться, обрабатываться и выводится самой ардуино в «упрощенном» виде. Как создать сайта есть множество статей/видео/форумов и т.д, в нынешнее время это не проблема. Предположим у Вас он есть, тогда загрузите на него следующий файл. Назовите его как вам удобно, ну скажем «pars.php».
<?php /* Код для парсинга информации с сайтов, и дальнейшеий вывод на дисплей Код написан каналом MEGAVOLT https://www.youtube.com/MEGAVOLT Версия v0.1, если будут какие либо ошибки просьба написать комментарий под видео */ header(‘Content-Type:text/plain;charset=utf-8’); function C($url){ return json_decode(file_get_contents($url)); } if (isset($_GET)){ switch($_GET){ case «test»: echo json_encode(array(«test» => «Good»)); break; case «yt1»: $key_youtube = «»; // в гугле пишем «как получить ключ api youtube» $a = C(«https://www.googleapis.com/youtube/v3/channels?part=statistics&id=UC-lHJZR3Gqxm24_Vd_AJ5Yw&key=» . $key_youtube); echo json_encode(array(«count_sub» => $a->items->statistics->subscriberCount)); break; case «vk»: $key_vk = «»; // в гугле пишем «как получить ключ api vk» $a = C(«https://api.vk.com/method/groups.getMembers?group_id=155504801&sort=id_asc&access_token=» . $key_vk . «&v=5.102»); echo json_encode(array(«count_sub» => $a->response->count)); break; case «surs»: $a = C(«https://www.cbr-xml-daily.ru/daily_json.js»); echo json_encode(array(«curs» => $a->Valute->USD->Value)); break; } } ?>
В данный момент реализовано 3 позиции:
Парсинг подписчиков на youtube
Парсинг подписчиков в группе vk.com
Парсинг курса USD
Обратите внимание что там необходимо иметь собственные API ключи доступа, получить их так же не проблема.
Запрос выполняется следующим образом.
http://mysite.ru/pars.php?type=sursтогда в скетче переменная A будет иметь следующий вид
const String A = «http://mysite.ru/pars.php?type=сurs,curs,USD: ;»;
Таким методом можно парсить сложные сайты, и выдавать только ту информацию, которая нужна. Еще одним плюсом такого подхода заключается то, что можно заранее в настройках скетча вписать сайты, а для изменения информации вывода использовать изменение на серверной стороне. Таким образом платформа будет являться только «связующим» звеном между Вашим сайтом.
Спасибо за внимание! Удачи в начинаниях. Доставка новых самоделок на почту

Получайте на почту подборку новых самоделок. Никакого спама, только полезные идеи!

*Заполняя форму вы соглашаетесь на обработку персональных данных

В уроке рассказываю о текстовых строках в Ардуино, о классе String, о преобразовании различных типов данных в текстовые строки и об обратной операции — преобразовании строк в числа.

Предыдущий урок Список уроков Следующий урок

Собирался разрабатывать драйвер шагового двигателя с управлением от компьютера, но столкнулся с необходимой для разработки темой, которую мы еще не изучали. Поэтому на один урок я отвлекусь от шаговых двигателей и расскажу о текстовых строках и операциях с ними.

  • Текстовые строки в Ардуино.
  • Способы объявления и инициализации текстовых строк.
  • Управляющие символы.
  • Конвертирование различных типов данных Ардуино в текстовую строку:
    • через встроенные функции классов ввода-вывода;
    • целочисленных данных в строку через функции itoa, ltoa, ultoa;
    • с помощью функции sprintf;
    • данных типа float.
  • Конвертирование текстовой строки в различные типы данных:
    • с помощью функций atoi, atol, atof.
    • с помощью функции sscanf.
  • Класс String Ардуино.
  • Основные функции класса String.
  • Конвертирование данных в строку String:
    • int в String;
    • float в String.
  • Конвертирование строки String в различные типы данных:
    • String в int, long;
    • String в float.

Текстовые строки в Ардуино.

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

В Ардуино признаком конца строки является число 0, в текстовом виде ‘\0’. При объявлении строковых переменных в некоторых случаях необходимо явно указывать признак конца строки, а в некоторых он формируется по умолчанию.

Способы объявления и инициализации текстовых строк.

char myStr1;

Объявлен символьный массив определенного размера. При заполнении его символами необходимо позаботиться о записи в конце строки байта со значением 0 – признака окончания строки.

char myStr2 = {‘S’, ‘t’, ‘a’, ‘r’, ‘t’};

Объявлен массив и присвоено значение элементам. В конце строки компилятор прибавит признак конца строки автоматически.

char myStr3 = {‘S’, ‘t’, ‘a’, ‘r’, ‘t’, ‘/0’};

То же самое, только завершающий признак мы объявили явно.

char myStr4 = “Start”;

Массив инициализирован строковой константой. Компилятор автоматически задаст размер массива и добавит завершающий символ.

char myStr5 = “Start”;

То же самое, только размер массива указан явно.

char myStr 6 = “Start”;

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

  • Строковые константы объявляются внутри двойных кавычек (”Start”).
  • Отдельные символы задаются внутри одинарных (‘S’).

Длинные строки допускают объявление в таком виде:

char myStr7 = “Текстовая строка может быть”
“ объявлена”
“ таким образом”;

Ничего не мешает задавать массивы строк. Поскольку сами строки являются массивами, массивы строк будут двумерными массивами.

char * myStrArray = { “Сообщение 1”, “Сообщение 2”, “Сообщение 3”, “Сообщение 4”, “Сообщение 5”, “Сообщение 6”};

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

Управляющие символы.

В текстовых строках могут содержаться не только текстовые символы, но и управляющие. Управляющие символы не отображаются на экране в графическом виде. Они используются для управления передачей данных и выводом на экран. Таких символов несколько десятков. Я выделю наиболее важные.

Код символа в HEX (DEC) Название Обозначение

Описание

0 (0) Конец строки \0 Признак конца строки
0D (13) Возврат каретки \r Перемещает курсор в крайнюю левую позицию
0A (10) Перевод строки \n Перемещает курсор на одну строку вниз

Для того чтобы вывести текст с новой строки необходимо использовать символы ‘\r’ и ‘\n’.

Простая программа, демонстрирующая использование управляющих символов для печати с новой строки.

// управляющие символы
void setup() {
Serial.begin(9600); // скорость 9600
}

На экране монитора последовательного порта увидим:


Часто управляющие символы ‘\r’ и ‘\n’ применяют для завершения команды в символьном виде, например AT команды. Такой способ управления будем использовать в следующем уроке для драйвера шагового двигателя.

Конвертирование различных типов данных Ардуино в текстовую строку.

Задача преобразования различных типов данных в символьный вид и наоборот возникает:

  • при выводе данных на дисплей или индикаторы;
  • передаче данных на другие устройства, например компьютер;
  • некоторые электронные компоненты требуют обмена данными с помощью AT команд в символьном виде, например GSM модемы, WiFi модули и т.п.

Существует достаточно много способов для решения этой задачи. Я подробно опишу несколько из них, на мой взгляд, самых удачных.

Конвертирование данных в строку через встроенные функции классов ввода-вывода.

Самый удобный, предпочтительный способ преобразования данных в символьный вид. Многие библиотеки ввода-вывода имеют функции преобразования данных в текстовый формат.

Если необходимо передавать данные через последовательный порт, почему бы не воспользоваться стандартными функциями класса Serial (урок 12).

Преобразование Функция класса Sreial

Описание

int в DEC текст print(int d) Преобразует переменную int в строку с десятичным представлением числа
int в DEC текст print(int d, DEC) Преобразует переменную int в строку с десятичным представлением числа
int в HEX текст print(int d, HEX) Преобразует переменную int в строку с шестнадцатеричным представлением числа
int в OCT текст print(int d, OCT) Преобразует переменную int в строку с восьмеричным представлением числа
int в BIN текст print(int d, BIN) Преобразует переменную int в строку с двоичным представлением числа
float в текст print(float d) Преобразует переменную float в строку с двумя знаками после запятой
float в текст print(float d, N) Преобразует переменную float в строку с N знаками после запятой

Например, конвертирование числа int в строку будет выглядеть так.

int x= 24562;
Serial.print(x);

Преобразование переменной float в строку можно выполнить так.

float x= 12.657;
Serial.print(x);

Преобразование будет выполнено при передаче данных на другое устройство. Функции класса Serial подробно описаны в уроке 12.

Если выводите данные на LCD дисплей с помощью библиотеки LiquidCristal, то для преобразования данных типа int можно использовать метод print (урок 23).

Преобразование Функция класса LiquidCristal Описание
int в DEC текст print(int d, DEC) Преобразует переменную int в строку с десятичным представлением числа
int в HEX текст print(int d, HEX) Преобразует переменную int в строку с шестнадцатеричным представлением числа
int в OCT текст print(int d, OCT) Преобразует переменную int в строку с восьмеричным представлением числа
int в BIN текст print(int d, BIN) Преобразует переменную int в строку с двоичным представлением числа

В библиотеке LiquidCristal нет функции для вывода данных типа float. Можно воспользоваться способом, предложенным в уроке 20 для библиотеки Led4Digits. Стандартная функция класса Led4Digits позволяет отображать на LED индикаторах только целые числа, но добавив простые вычисления можно легко выводить данные с плавающей запятой.

Конвертирование целочисленных данных в строку через функции itoa, ltoa, ultoa.

Функции простые, позволяют конвертировать числа целых форматов в текстовую строку.

itoa (int data, char* string, int radix); // преобразование int

ltoa (long data, char* string, int radix); // преобразование long

ultoa (unsigned long data, char* string, int radix); // преобразование unsigned long

  • data – это конвертируемая переменная;
  • char* string – указатель на строку (имя массива);
  • radix – система исчисления результата в строке:
    • 10 для DEC;
    • 8 для OCT;
    • 16 для HEX;
    • 2 для BIN.

Например, конвертирование переменой x типа int в строку myStr1 можно сделать так.

Вот программа для проверки работы этих функций.

void setup() {
Serial.begin(9600); // скорость 9600
}

Serial.write(myStr, 20);
x++;
delay(500);
}

В цикле каждые 0,5 секунд происходит:

  • Текстовая строка myStr заполняется пробелами, в конце добавляются управляющие символы возврат каретки и перевод строки.
  • Переменная x конвертируется одной из функцией. Результат оказывается в буфере myStr.
  • Функция Serial.write(myStr, 20); передает через последовательный порт 20 байтов массива myStr в виде байтов.
  • Прибавляется 1 к переменной x.

Чтобы проверить нужную функцию необходимо освободить ее от признака комментарий. Я проверил все.

Для вывода чисел с плавающей запятой можно опять предложить метод из урока 20.

Конвертирование данных в строку с помощью функции sprintf.

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

sprint это функция форматированного вывода. Ее широко используют в приложениях на компьютерах. Она дает самые широкие возможности для преобразования данных в строку. Но в системе Ардуино sprintf не поддерживает формат чисел с плавающей запятой.

int sprintf( char *string, const char *format , argument1, argument2 … )

Функция возвращает число преобразованных символов. В случае ошибки возвращает число – 1.

  • argument – это переменные, которые необходимо преобразовать;
  • format – управляющая строка:

% тип_формата

Флаг и ширина — необязательные поля.

Тип формата Тип выходных данных
c Символ
s Символьная строка
d, i Целое десятичное число
u Целое без знаковое десятичное число
o Целое восьмеричное число
x Целое шестнадцатеричное число

Флаги.

Знак Действие
Выравнивание результата влево
+ Выводит знак числа
Пробел Выводит знак пробел перед положительными числами
0 Заполняет поле 0

Ширина – минимальный размер поля для вывода символов. Если длина числа меньше, то добавляются пробелы. Если перед шириной стоит 0, то добавляются нули.

На примерах из таблицы все должно быть понятно.

int x= 125; int y= 34;

Можете загрузить следующую программу и проверить работу sprintf в реальном контроллере Ардуино.

void setup() {
Serial.begin(9600); // скорость 9600
}

Serial.write(myStr, 20);
x++;
delay(500);
}

Конвертирование данных типа float в текстовую строку.

Самый простой способ преобразования float в текстовую строку – использование функции dtostrf.

char* dtostrf(double data, signed char width, unsigned char prec, char *string)

  • data – это конвертируемая переменная;
  • width – число значащих разрядов;
  • prec – число разрядов после запятой;
  • char* string – указатель на строку (имя массива).

float x= 12.728;
dtostrf(x, 2, 3, myStr3); // выводим в строку myStr3 2 разряда до, 3 разряда после запятой

Вот программа для проверки такого способа.

void setup() {
Serial.begin(9600); // скорость 9600
}

// преобразование переменной float x в строку
dtostrf(x, 2, 3, myStr);
Serial.write(myStr, 20);
x+= 0.01;
delay(500);
}

У меня работает.

Конвертирование текстовой строки в различные типы данных.

В следующем разделе речь идет об обратном преобразовании – текстовой строки в число.

Преобразование строки в данные с помощью функций atoi, atol, atof.

Хороший, удобный метод. Функции простые, имеют вид:

int atoi(const char* string); // преобразование в int

long atol(const char* string); // преобразование в long

double atof(const char* string); // преобразование в float

В качестве аргумента функций указывается указатель на строку с числом в десятичном виде. Возвращают – конвертированное значение числа.

Например, преобразование строки myStr4 в переменную x типа int будет выглядеть так.

int x;
x= atoi(myStr4);

Для чисел с плавающей запятой.

float x;
x= atof(myStr4);

Вот программа проверки atoi и atol.

// проверка преобразования текстовой строки в число
// с помощью atoi
char myStr= «123»; // текстовый массив

void setup() {
Serial.begin(9600); // скорость 9600
}

А в этой программе я проверил работу atof.

// проверка преобразования текстовой строки в число
// с помощью atof
char myStr= «123.456»; // текстовый массив

void setup() {
Serial.begin(9600); // скорость 9600
}

void loop() {
Serial.println(atof(myStr),3); // преобразование строки в float
delay(1000);
}

Конвертирование текстовой строки в числа с помощью функции sscanf.

Функция является обратной функцией для sprintf с такими же недостатками и достоинствами. Но она позволяет конвертировать числа в восьмеричном и шестнадцатеричном форматах. Тип float эта функция на Ардуино не поддерживает.

int sscanf( char *string, const char *format , address1, address2 … )

Все аргументы и форматы такие же, как у sprintf. Только указываются адреса переменных (address1, address2 … ).

Конвертирование строки myStr5 в переменную x типа int будет выглядеть так.

Вот скетч проверки функции для целочисленных операций.

// проверка преобразования текстовой строки в число
// с помощью sscanf
int x;
char myStr= «123»; // текстовый массив

void setup() {
Serial.begin(9600); // скорость 9600
}

void loop() {
sscanf(myStr,»%d», &x);
Serial.println(x); // преобразование строки в int
delay(1000);
}

Класс String Ардуино.

В Ардуино существует класс String. Он предоставляет более широкие возможности для работы с текстовыми строками.

Надо четко различать:

Принято имена текстовых строк начинать как обычные переменные с маленькой буквы (myStr), а экземпляры String – с большой буквы (MyStr).

Экземпляры класса String занимают больше памяти, медленнее обрабатываются, но зато они позволяют расширять , объединять строки, производить поиск, замену символов и многое другое. Пользоваться текстовыми строками или классом String – решать Вам. В оптимальных по ресурсам приложениях лучше использовать строки.

Несколько основных функций класса String.

Я опишу только минимум функций, необходимых для работы с классом String.

String()

Конструктор, создает экземпляр класса String. Объект типа String может быть создан из разных типов данных:

При создании объекта из числа, сформированная строка будет содержать ASCII (символьное) представление числа. По умолчанию используется десятичная система счисления, но можно указать другую. Т.е. функция String может осуществлять преобразование целочисленных данных в текстовую строку.

toCharArray(*buf, length)

Копирует текст экземпляра класса String в указанный массив.

MyStr.toCharArray(*buf, length)

  • buf – указатель на массив;
  • length – количество символов.

MyStr.toCharArray(myStr, 10); // копируем 10 символов в массив myStr

int length()

Функция возвращает длину строки String в символах без учета завершающего признака нуля.

int len =MyStr.length(); // получаем длину строки MyStr

long toInt()

Функция преобразовывает объект String в целое число.

int x = MyStr.toInt(); // конвертирование строки MyStr в int

Конвертирование данных в строку String.

Для целочисленных форматов все очень просто.

Программа для проверки.

// проверка преобразования числа в String
int x=0; // переменная, которая выводится
String MyStr;

void setup() {
Serial.begin(9600); // скорость 9600
}

void loop() {

MyStr= String(x, DEC); // int -> DEC
//MyStr= String(x, HEX); // int -> HEX
//MyStr= String(x, BIN); // int -> BIN

Serial.println(MyStr);
x++;
delay(500);
}

Для плавающей запятой надо использовать функцию dtostrf(). С помощью нее получить строку-массив, а затем занести ее в объект String.

Программа для проверки преобразования float.

// проверка преобразования числа в String
float x=0; // переменная, которая выводится
String MyStr;
char myStr;

void setup() {
Serial.begin(9600); // скорость 9600
}

void loop() {

Конвертирование строки String в различные типы данных.

Для целых чисел используем функцию toInt().

String MyStr = «123»;
int x = MyStr.toInt();

Проверяем.

// проверка преобразования String в число
// с помощью toInt
String MyStr = «123»;

void setup() {
Serial.begin(9600); // скорость 9600
}

void loop() {
Serial.println(MyStr.toInt()); // преобразование строки в int
delay(1000);
}

Для плавающей запятой.

Получим данные из объекта String в массив и выполним преобразование функцией atof().

Программа для проверки.

// проверка преобразования String в число
// с помощью toInt
String MyStr = «34.123»;
char myStr;

void setup() {
Serial.begin(9600); // скорость 9600
}

void loop() {
MyStr.toCharArray(myStr, MyStr.length());
Serial.println(atof(myStr)); //
delay(1000);
}

Arduino String – основная библиотека для работы со строками в ардуино. С ее помощью существенно упрощается использование массивов символов и строк в скетче. Объект типа String содержит множество полезных функций для создания и объединения строк, преобразований string to int (парсинг чисел) и int to string (форматирование чисел). Строки используются практически в любых проектах, поэтому и вероятность встретить String в скетче очень высока. В этой статье мы постараемся рассмотреть основные методы этого класса и наиболее часто возникающие ситуации.

Для чего нужен String в ардуино

Стандартным способом работы со строками в языке C является использование массива символов. Это все означало необходимость работы с указателями и понимания адресной арифметики. В ардуино и C++ у программистов появилось гораздо больше возможностей. Все “низкоуровневые” операции по работе со строкой выделены в отдельный класс, а для основных операций даже переопределены операторы. Например, для объединения срок мы просто используем хорошо знакомый знак “+”, а не зубодробильные функции типа malloc и strcpy. С помощью String мы работаем со строкой как с целым объектом, а не рассматриваем его как массив символов. Это позволяет сосредоточиться на логике скетча, а не деталях реализации хранения символов в памяти.

Естественно, у любого “упрощения” всегда есть свои подводные камни. String всегда использует больше оперативной памяти и в некоторых случаях функции класса могут медленнее обрабатываться. Поэтому в реальных больших проектах придется тщательно взвешивать все плюсы и минусы и не забывать, что никто не мешает нам работать со строками в стиле С. Все обычные функции обработки массивов char остаются в нашем арсенале и в arduino.

Создание строк в ардуино с помощью String

В ардуино у нас есть несколько способов создать строку, приведем основные:

  • char myCharStr = “Start”; – массив типа char с завершающим пустым символом;
  • String myStr = “Start”; – объявляем переменную, создаем экземпляр класса String и записываем в него константу-строку.
  • String myStr = String(“Start”); – аналогичен предыдущему: создаем строку из константы
  • String myStr(myCharStr); – создаем объект класса String с помощью конструктра, принимающего на вход массив типа char и создающего из char String.
  • String myStr = String(50); – создаем строку из целого числа (преобразование int to string).
  • String myStr = String(30, H); – создаем строку – представление числа в 16-чной системе (HEX to String)
  • String myStr = String(16, B); – создаем строку – представление числа в двоичной системе (Byte to String).

Каждый раз, когда мы объявляем в коде строку с использованием двойных кавычек, мы создаем неявный объект класса String, являющийся константой. При этом обязательно использование именно двойных кавычек: “String” – это строка. Одинарные кавычки нужны для обозначения отдельных символов. ‘S’ – это символ.

Функции и методы класса String

Для работы со строками в String предусмотрено множество полезных функций. Приведем краткое описание каждой из них:

  • String() – конструктор, создает элемент класса данных string. Возвращаемого значения нет. Есть множество вариантов, позволяющих создавать String из строк, символов, числе разных форматов.
  • charAt() возвращает указанный в строке элемент. Возвращаемое значение – n-ный символ строки.
  • compareTo() – функция нужна для проверки двух строк на равенство и позволяет выявить, какая из них идет раньше по алфавиту. Возвращаемые значения: отрицательное число, если строка 1 идет раньше строки 2 по алфавиту; 0 – при эквивалентности двух строк; положительное число, если вторая строка идет раньше первой в алфавитном порядке.
  • concat() – функция, которая объединяет две строки в одну. Итог сложения строк объединяется в новый объект String.
  • startsWith() – функция показывает, начинается ли строка с символа, указанного во второй строке. Возвращаемое значение: true, если строка начинается с символа из второй строки, в ином случае false.
  • endsWith() – работает так же, как и startsWith(), но проверяет уже окончание строки. Также возвращает значения true и false.
  • equals() – сравнивает две строки с учетом регистра, т.е. строки «start» и «START» не будут считаться эквивалентными. Возвращаемые значения: true при эквивалентности, false в ином случае.
  • equalsIgnoreCase() – похожа на equals, только эта функция не чувствительна к регистру символов.
  • getBytes() – позволяет скопировать символы указанной строки в буфер.
  • indexOf() – выполняет поиск символа в строке с начала. Возвращает значение индекса подстроки val или -1, если подстрока не обнаружена.
  • lastIndexOf() –выполняет поиск символа в строке с конца.
  • length() – указывает длину строки в символах без учета завершающего нулевого символа.
  • replace() – заменяет в строке вхождения определенного символа на другой.
  • setCharAt() – изменяет нужный символ в строке.
  • substring() – возвращает подстроку. Может принимать два значения – начальный и конечный индексы. Первый является включительным, т.е. соответствующий ему элемент будет включаться в строку, второй – не является им.
  • toCharArray() – копирует элементы строки в буфер.
  • toLowerCase() – возвращает строку, которая записана в нижнем регистре.
  • toUpperCase() – возвращает записанную в верхнем регистре строку.
  • toInt() – позволяет преобразовать строку в число (целое). При наличии в строке не целочисленных значений функция прерывает преобразование.
  • trim() – отбрасывает ненужные пробелы в начале и в конце строки.

Объединение строк Arduino

Объединить две строки в одну можно различными способами. Эта операция также называется конкатенацией. В ее результате получается новый объект String, состоящий из двух соединенных строк. Добавить к строке можно различные символы:

Важно осторожно объединять две строки из разных типов данных, так как это может привести к ошибке или неправильному результату.

Arduino string to int и string to float

Для конвертации целочисленных значений string to int используется функция toInt().

String MyStr = “111”;

int x = MyStr.toInt();

Если нужно конвертировать объект с плавающей запятой, применяется функция atof().

String MyStr = “11.111”;

char myStr1;

MyStr.toCharArray(myStr1, MyStr.length()); // копируется String в массив myStr1

float x = atof(myStr1); // преобразование в float

Преобразование int to string

Для создания строки из числа не требуется делать особых телодвижений. Мы можем просто объединить строку и число:

int i = 50;

String str = “Строка номер “+ i;

Можем создать объект, используя конструктор

String str = String(50);

Можем объединить оба способа:

String str = “Строка номер “+ String(50);

Преобразование String в массив char

Тип данных Char позволяет объявлять текстовые строки несколькими способами:

  • char myStr1; – в данном случае объявлен массив определенного размера.
  • char myStr2 = {‘a’, b, ‘c’, ‘d’, ‘e’}; – объявлен сам массив. Конечный символ не записанявно, его прибавит сам компилятор.
  • char myStr3 = {‘a’, b, ‘c’, ‘d’, ‘e’’/0’}; – объявлен массив, при этом в конце прописан признак окончания строки.
  • char myStr4 = “abcde”; – инициализация массива строковой постоянной. Размер и завершающий символ добавляются автоматически компилятором.
  • char myStr5 = “abcde”; – инициализация массива с точным указанием его размера.
  • char myStr 6 = “abcde”; – аналогично, но размер указан больше для возможности использования строк большей длины.

Еще раз напомним, что в типе данных char строковые константы нужно записывать в двойные кавычки «Abcde», а одиночные символы – в одинарные ‘a’.

Конвертировать строку в массив сhar array можно при помощи следующего кода:

String stringVar = “111”;

char charBufVar;

stringVar.toCharArray(charBufVar, 20);

Можно сделать обратное преобразование – char to string.

char chArray = “start”;

String str(chArray);

Пример преобразования String to const char*. Указание звездочкой char*означает, что это массив указателей.

String stringVar=string (`start);

Char charVar;

stringVar.toCharArray(charVar, sizeof(charVar));

Заключение о String и ардуино

В этой статье мы рассмотрели основные вопросы использования String для работы со строками arduino. Как показывают примеры, ничего страшного и сложного в этом классе нет. Более того, зачастую мы можем даже не догадываться, что работаем с классом String: мы просто создаем переменную нужного типа, присваиваем ей строку в двойных кавычках. Создав строку, мы используем все возможности библиотеки String: можем без проблем модифицировать строку, объединять строки, преобразовывать string в int и обратно, а также делать множество других операций с помощью методов класса.

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

Строки

Строка (String), как понятно из названия, это совокупность символов. По сути строка это одномерный массив типа данных char, про массивы мы уже недавно говорили и вы должны понять, о чём идёт речь. Как и в случае с массивом символов, к каждому элементу строки можно обратиться при помощи квадратных скобок. Основным отличием строки от массива символов является тот факт, что строка – динамический массив, у которого не нужно указывать размер. Также строка является не просто типом данных, а объектом, объектом очень мощного класса String.

Давайте рассмотрим большой пример, из которого будет понятно, как объявить строку и как с ней работать, а также учтены некоторые тонкости:

String string0 = «Hello String»; // заполняем словами в кавычках String string1 = String(«lol «) + String(«kek»); // сумма двух строк String string2 = String(‘a’); // строка из символа в одинарных кавычках String string3 = String(«This is string»); // конвертируем строку в String String string4 = String(string3 + » more»); // складываем строку string3 с текстом в кавычках String string5 = String(13); // конвертируем из числа в String String string6 = String(20, DEC); // конвертируем из числа с указанием базиса (десятичный) String string7 = String(45, HEX); // конвертируем из числа с указанием базиса (16-ричный) String string8 = String(255, BIN); // конвертируем из числа с указанием базиса (двоичный) String string9 = String(5.698, 3); // из float с указанием количества знаков после запятой (тут 3) // строки можно складывать друг с другом String string10 = string0 + string1; // string10 равна Hello Stringlol kek // можно формировать название из кусочков, например для работы с файлами. Даже из дефайнов #define NAME «speed» #define TYPE «-log» #define EXT «.txt» // при сложении достаточно указать String 1 раз для первой строки String filename = String(NAME) + TYPE + EXT; // filename будет равна speed-log.txt // доступ к элементу строки работает по такому же механизму, как массив string1 = «a»; // теперь вместо Hello String у нас aello String

Как вы могли заметить, строки можно объявлять большим количеством способов, а также буквально складывать строки, как числа, оператором +. Я уже говорил, что строки являются объектами класса String, и у этого класса есть огромное количество удобных методов по работе со строками, далее мы их все рассмотрим с некоторыми примерами. Но для начала запомните вот что: строки – очень тяжёлый инструмент, очень медленный и занимающий кучу памяти: уже просто само наличие строк (от одной и более) в прошивке занимает +5% Flash памяти, т.к. подключается сам “инструмент” – класс String. Для небольших проектов это не страшно, памяти всегда будет навалом.

Инструменты для String

Итак, методы для работы со строками. Как и все методы, они применяются к своим объектам (к строкам) через точку. В рассмотренных ниже примерах строка называется myString.

charAt()

myString.charAt(index);

Возвращает элемент строки myString под номером index. Аналог – myString;

setCharAt()

myString.setCharAt(index, val);

Записывает в строку myString символ val на позицию index. Аналог – myString = val;

compareTo()

myString.compareTo(myString2);

  • Возвращает отрицательное число, если myString идёт до myString2
  • Возвращает положительное число, если myString идёт после myString2
  • Возвращает 0, если строки одинаковы

concat()

myString.concat(value);

Присоединяет value к строке (value может иметь любой численный тип данных). Возвращает true при успешном выполнении, false при ошибке. Аналог – сложение, myString + value;

endsWith()

myString.endsWith(myString2);

Проверяет, заканчивается ли myString символами из myString2. В случае совпадения возвращает true

startsWith()

myString.startsWith(myString2);

Проверяет, начинается ли myString символами из myString2. В случае совпадения возвращает true

equals()

myString.equals(myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв важен

equalsIgnoreCase()

myString.equalsIgnoreCase(myString2);

Возвращает true, если myString совпадает с myString2. Регистр букв неважен

indexOf()

myString.indexOf(val);
myString.indexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет слева направо, возвращает номер первого символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

lastIndexOf()

myString.lastIndexOf(val);
myString.lastIndexOf(val, from);

Ищет и возвращает номер (позицию) значения val в строке, ищет справа налево, возвращает номер последнего символа в совпадении. val может быть char или String, то есть ищем в строке другую строку или символ. Можно искать, начиная с позиции from. В случае, когда не может найти val в строке, возвращает -1.

length()

myString.length();

Возвращает длину строки в количестве символов

remove()

myString.remove(index);
myString.remove(index, count);

Удаляет из строки символы, начиная с index и до конца, либо до указанного count

replace()

myString.replace(substring1, substring2);

В строке myString заменяет последовательность символов substring1 на substring2.

String myString = «lol kek 4eburek»; // заменить чебурек на пельмень myString.replace(«4eburek», «pelmen»);

reserve()

myString.reserve(size);

Зарезервировать в памяти количество байт size для работы со строкой

c_str()

myString.c_str();

Преобразовывает строку в “СИ” формат (null-terminated string) и возвращает указатель на полученную строку

trim()

myString.trim();

Удаляет пробелы из начала и конца строки. Действует со строкой, к которой применяется

substring()

myString.substring(from);
myString.substring(from, to);

Возвращает кусок строки, содержащейся в myString начиная с позиции from и до конца, либо до позиции to

String myString = «lol kek 4eburek»; String chebur = myString.substring(8); // строка chebur содержит в себе «4eburek»

toCharArray()

myString.toCharArray(buf, len);

Раскидывает строку в массив – буфер buf (типа char ) с начала и до длины len

getBytes()

myString.getBytes(buf, len);

Копирует указанное количество символов len (вплоть до unsigned int) в буфер buf (byte )

toFloat()

myString.toFloat();

Возвращает содержимое строки в тип данных float

toDouble()

myString.toDouble();

Возвращает содержимое строки в тип данных double

toInt()

myString.toInt();

Возвращает содержимое строки в тип данных int

String myString = «10500»; int val = myString.toInt(); // val теперь 10500

toLowerCase()

myString.toLowerCase();

Переводит все символы в нижний регистр. Было ААААА – станет ааааа

toUpperCase()

myString.toUpperCase();

Переводит все символы в верхний регистр. Было ааааа – станет ААААА

Длина строки

Небольшой комментарий по поводу длины строки: мы можем узнать длину строки двумя способами, при помощи оператора sizeof() и метода length(). Давайте разберём отличия между ними:

String textString = «Hello»; sizeof(textString); // вернёт 6 textString.length(); // вернёт 5

Оператор sizeof вернёт размер строки в байтах. Строка содержит “нулевой символ” на конце, этот символ тоже весит один байт, соответственно оператор вернёт число 6. Метод length возвращает длину строки в количестве символов, не считая завершающий нулевой, поэтому результат будет 5.

F() macro

Строки являются очень тяжёлым с точки зрения использования памяти инструментом, ведь текст в строке хранится в оперативной памяти микроконтроллера, а её не так уж и много. Есть готовый инструмент, позволяющий удобно хранить текстовые данные во Flash памяти микроконтроллера. Этот способ хорош для вывода фиксированных текстовых данных, например, в монитор порта:

Serial.println(F(«Hello, World!»));

Строка “Hello, World!” будет записана во Flash память и не займёт 14 байт (13 + нулевой) в оперативной.

Массивы символов

Массивы символов, они же char array, являются ещё одним способом работы с текстовыми данными. Этот вариант имеет гораздо меньше возможностей по работе с текстом, но зато занимает меньше места в памяти (не используется элемент String) и работает значительно быстрее. К массиву символов применяются те же правила, какие работают для обычных массивов. Рассмотрим пример, в котором объявим массив символов, поработаем с ним, и выведем в порт:

// объявить массив текста длиной 6 символов // и задать текст char helloArray = «Hello!»; // объявить массив текста длиной 100 символов // и задать в его начало текст char textArray = «World»; Serial.println(helloArray); // выведет Hello! Serial.println(textArray); // выведет World textArray = ‘L’; // заменим элемент Serial.println(textArray); // выведет Lorld

В отличие от строк, массивы символов нельзя:

helloArray += textArray; // складывать textArray = «new text»; // присваивать ТЕКСТ после инициализации

Длина строки char array

Для определения длины текста можно использовать оператор strlen, который возвращает количество символов в массиве. Сравним его работу с оператором sizeof:

char textArray = «World»; sizeof(textArray); // вернёт 100 strlen(textArray); // вернёт 5

Здесь оператор sizeof вернул количество байт, занимаемое массивом. Массив я специально объявил с размером бОльшим, чем содержащийся в нём текст. А вот оператор strlen посчитал и вернул количество символов, которые идут с начала массива и до нулевого символа в конце текста.

Массив строк

Очень мощной фишкой массивов символов является возможность создать один массив с несколькими строками, и обращаться к ним по номеру. Выглядит это следующим образом:

// объявляем массив строк const char *names = { «Period», // 0 «Work», // 1 «Stop», // 2 }; // выводим третий элемент Serial.println(names); // выведет Stop

Данный способ работы со строками хорош тем, что строки хранятся под номерами, и это крайне удобно при работе с дисплеями и в частности создании текстового меню: практически все библиотеки дисплеев умеют выводить массив символов одной командой.

Экономия памяти

“Строки” в массиве строк тоже хранятся в оперативной памяти, что не очень здорово. Ещё больше не здорово то, что применить рассмотренный F() macro к ним нельзя, потому что фактически это не строки. То есть вот такой код приведёт к ошибке:

const char *names = { F(«Period»), // 0 F(«Work»), // 1 F(«Stop»), // 2 };

Как же быть? Массив строк можно сохранить в PROGMEM, программной памяти микроконтроллера, то есть во Flash. Вот такую конструкцию можно использовать как шаблон:

// объявляем наши «строки» const char array_1 PROGMEM = «Period»; const char array_2 PROGMEM = «Work»; const char array_3 PROGMEM = «Stop»; // объявляем таблицу ссылок const char* const names PROGMEM = { array_1, array_2, array_3, }; void setup() { Serial.begin(9600); char arrayBuf; // создаём буфер // копируем в arrayBuf при помощи встроенного strcpy_P strcpy_P(arrayBuf, (char*)pgm_read_word(&(names))); Serial.println(arrayBuf); // выведет Work }

Да, сложно и громоздко, но при большом объёме текстовых данных это может спасти проект!

Важные страницы

  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макро, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете

string

Описание

Текстовые строки могут быть объявлены двумя способами: можно использовать тип данных String, который входит в ядро, начиная с версии 0019; либо объявить строку как массив символов char с нулевым символом в конце. На этой странице описан второй способ. Для получения более подробной информации об объекте String, предоставляющем больше возможностей ценой большего расхода памяти, см. страницу String — объект.

Примеры

Ниже представлены примеры правильного объявления строк.

char Str1; char Str2 = {‘a’, ‘r’, ‘d’, ‘u’, ‘i’, ‘n’, ‘o’}; char Str3 = {‘a’, ‘r’, ‘d’, ‘u’, ‘i’, ‘n’, ‘o’, ‘\0’}; char Str4 = «arduino»; char Str5 = «arduino»; char Str6 = «arduino»;

Допускаемые операции при объявлении строк

  • Объявить массив символов без его инициализации (Str1)
  • Объявить массив символов с одним избыточным элементом, компилятор сам добавит требуемый нулевой символ (Str2)
  • Добавить нулевой символ явно (Str3)
  • Инициализировать массив с помощью строковой константы, заключенной в кавычки; компилятор создаст массив необходимого размера с нулевым символом в конце (Str4)
  • Инициализировать массив с помощью строковой константы, явно указав его размер (Str5)
  • Инициализировать массив избыточного размера, оставив место для более длинных строк (Str6)

Нулевой завершающий символ

Как правило, все строки завершаются нулевым символом (ASCII код 0), который позволяет функциям (подобным Serial.print()) определять длину строки. Без этого символа они продолжали ли бы последовательно считывать байты памяти, которые фактически уже не являлись бы частью строки.

По сути, это означает, что длина вашей строки должна быть на 1 символ больше, чем текст, который вы хотели бы в ней хранить. Именно поэтому Str2 и Str5 должны быть длиной 8 символов, несмотря на то, что слово «arduino» занимает всего 7 — последняя позиция автоматически заполняется нулевым символом. Размер Str4 автоматически станет равным 8 — один символ требуется для завершающего нуля. В строке Str3 мы самостоятельно указали нулевой символ (обозначается ‘\0’).

Следует иметь в виду, что в целом можно объявить строку и без завершающего нулевого символа (например, если задать длину Str2 равной 7, а не 8). Однако это приведет к неработоспособности большинства строковых функций, поэтому не следует намеренно так делать. Такая ошибка может быть причиной странного поведения или появления сторонних символов при работе со строками.

Одинарные или двойные кавычки?

Строки всегда объявляются в двойных кавычках («Abc»), а символы всегда объявляются в одинарных кавычках (‘A’).

Перенос длинных строк

Длинные строки можно переносить так:

char myString = «This is the first line» » this is the second line» » etcetera»;

Массивы строк

При работе с большими объемами текста (например, в проектах, работающих с LCD-экраном) часто удобно использовать массивы строк. Поскольку строки сами по себе являются массивами, то фактически, это — пример двумерного массива.

В нижеследующей программе звездочка после указания типа данных char «char*» показывает, что переменная является массивом «указателей». Все имена массивов фактически являются указателями, поэтому звездочка необходима для создания массива массивов. Указатели в C — одна из наиболее сложных вещей для начинающих, но в данном случае глубокого понимания указателей для их эффективного использования вовсе не требуется.

Arduino:Примеры/StringSubstring

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

Контакты:

  • Skype: cubewriter
  • E-mail: cubewriter@gmail.com
  • Максим Кузьмин на freelance.ru

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

Строковая функция Substring

Функция substring(), простите за тавтологию, функционально близка к функциям charAt(), startsWith() и endsWith(). Она позволяет искать в строке определенные символы.

Необходимое оборудование

  • Плата Arduino;

Цепь

Цепь для этого примера не нужна, просто подключите Arduino к компьютеру (при помощи USB).

Код

Функция substring(), в которой задан всего один параметр, ищет от заданной позиции и до конца строки. То есть подразумевается, что искомая подстрока длится до самого конца строки. Например,

Этот код верен, тогда как этот:

…не верен, поскольку после подстроки «htm» в строке еще присутствует символ «l».

При этом substring() с двумя параметрами ищет от одной заданной позиции и до другой. Например,

В этом фрагменте функция ищет слово «text», находящееся с 14-ой позиции по 18-ую.

Внимание! Убедитесь, что заданные вами позиции находятся в пределах строки, иначе такой код может повлечь непредвиденные результаты. Эту ошибку бывает особенно трудно найти, если в substring() указано два параметра – когда первый из них меньше длины строки, а второй нет.

Объект String в Arduino и команды через последовательный порт

Сколько ни изучаю Arduino, она не перестаёт удивлять меня своей простотой. К примеру, собирая и тестируя систему «умного дома», я думал, что подача команд с компьютера будет самой сложной частью — это же надо принимать строку из последовательного порта, распознавать её, следить, чтобы не возникало ошибок… Однако оказалось достаточно почитать сайт Arduino.cc да потестить пару примеров, как стало ясно — разработчики постарались, чтобы оградить нас от написания длинного и унылого кода. К слову сказать, с задачей в итоге я справился за вечер, под конец даже подумывая: «а какую бы ещё команду прикрутить?..»

Итак, предположим, вы уже умеете программировать Arduino и можете разобраться в своём или чужом коде. Одним из основных понятий являются переменные и их типы. Ну-ка навскидку? byte, int, long, char, string… Два последних — по сути одно и то же, ибо string — массив переменных типа char (Кто-нибудь сейчас должен возразить, что char представляется в виде байтового числа, но речь не об этом). Итак, всё, что принимается из последовательного порта, следует читать, как char:

char inChar = » «; byte z = 0; while (Serial.available()) { inChar = Serial.read(); z++; }

Это первый пример, который может придти в голову. Создаём пустую строку, затем, если есть, что читать из последовательного порта, посимвольно её заполняем. Функция Serial.available() возвращает количество байт, доступных для чтения, а если там пусто — то 0, очевидно. Этим можно пользоваться, чтобы узнать длину поданной команды, хотя мы и так её узнаем в приведённом примере — это величина переменной z на выходе из цикла. Да, строка из пробелов (ASCII код пробела — не ноль!) — это терпимо, но всё-таки не очень хорошо, по возможности избегайте этого. А догадливый читатель сможет похвалить себя, если сразу догадается, что стоит исправить в вышеприведённом коде. Для тех, кто не догадался — подсказка: char inchar — строка длиной 6 символов. Если строке присваивается значение, компилятор позволяет не указывать явно её длину, поэтому в примере квадратные скобки пустые.

Кстати, не стоит забывать прописать в setup()

Serial.begin(9600);

А во встроенном мониторе порта, в который, собственно, и будут отправляться команды, указать скорость — 9600 бод, иначе увидите крякозябры.

Далее, что делать с полученной строкой? Те, кто предложат сравнивать побайтово строку с известными значениями (а такая мысль наверняка кому-то может придти в голову) после прочтения статьи переместятся вперёд во времени лет на 20. Из прошлого, я имею в виду 🙂

Поиск по документации Arduino IDE даёт два варианта, что такое string. Это сам string как строка char’ов, и String, являющийся объектом. Что такое объект? Согласно википедии, это «некоторая сущность в виртуальном пространстве, обладающая определённым состоянием и поведением, имеющая заданные значения свойств (атрибутов) и операций над ними (методов)». Другими словами — переменная со встроенными функциями, делающими что-то с этой переменной. Чтобы начать работать с этим объектом, напишем что-нибудь такого вида:

String input = «»; while (Serial.available()) { input += Serial.read(); }

Здесь к input будут добавляться всё новые символы, пока буфер не иссякнет. Тогда можно будет анализировать полученную строку, например, так:

input.toLowerCase(); if(input.startsWith(«pause»)) { String toWait = input.substring(5); toWait.trim(); int delaytime = toWait.toInt(); if(delaytime>0) { if(delaytime<10000) { delay(delaytime); } } }

Код использует очень удобные функции, встроенные в объект String. Это startsWith(), которая возвращает единицу, если строка начинается с того, что записано в скобках, substring(), возвращающая кусок строки, начинающийся в данном случае с 5-го символа (считается, начиная с нуля), trim(), отбрасывающий всё лишнее по краям строки, ну и toInt(), превращающий то, что осталось, в число типа Int. Это число неплохо ещё и проверить на предмет попадания в рамки ожидаемого. В итоге, если дать команду «PauSe 567 «, то МК подождёт ровно 567 миллисекунд.

Про trim() стоит написать отдельно. Он нужен не только для того, чтобы отбросить пробел в начале получившейся строки, но в первую очередь — чтобы избавиться от символов в её конце. Это служебные символы, добавляющиеся при отправке сообщения — NL (новая строка) и CR (возврат каретки). Они нужны как раз для того, чтобы сигнализировать о конце команды, но могут и помешать. Поэтому, несмотря на то, что в мониторе порта можно выбрать, какие из этих символов посылать или не посылать ничего, лучше перестраховаться. Тем более, что делается это в одну строчку кода.

А вот и список функций (методов) объекта String.

  • charAt() — возвращает символ, стоящий на указанном месте

  • concat() — функция конкатенации, т.е слияния двух строк в одну. Правда string1 = string1 + string2 это то же самое, что и string1.concat(string1, string2), а записывается проще и понятнее.

  • equals() — возвращает единицу, если строка посимвольно равна тому, что написано в скобках. Есть ещё equalsIgnoreCase(), который игнорирует регистр (верхний или нижний)

  • endsWith() — который работает аналогично startsWith()

  • indexOf() — возвращающий место в строке символа(или строки) в скобках. Ищет с конца и возвращает -1, если не найдено.

  • length() — выдающий длину строки

  • setCharAt() — требующий место и символ, который надо поставить на это место, например: string1.setCharAt(3, ‘d’) поставит d третьим символом в строке взамен того, что там стояло

  • И ещё несколько других, которые вряд ли вам понадобятся, если вы не в силах залезть на arduino.cc и прочитать о них 🙂

Вот и всё, что хотел рассказать. Надеюсь, эта статья поможет не бояться ООП и научить вашего домашнего робота на Arduino повиноваться сигналам с компа

Теги:

admin

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Наверх