Об’єкт String в Arduino і команди через послідовний порт

Скільки не вивчаю Arduino, вона не перестає дивувати мене своєю простотою. Наприклад, збираючи і тестуючи систему "розумного будинку", я думав, що подача команд з комп'ютера буде найскладнішою частиною - це треба приймати рядок з послідовного порту, розпізнавати його, стежити, щоб не виникало помилок. Однак виявилося достатньо почитати сайт Arduino.cc і потішити кілька прикладів, як стало зрозуміло - розробники постаралися, щоб захистити нас від написання довгого і похмурого коду. До речі, із завданням у підсумку я впорався за вечір, під кінець навіть подумуючи: "а яку б ще команду прикрутити."

До речі, не слід забувати прописати в setup()

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

Далі, що робити з отриманим рядком? Ті, хто запропонують порівнювати побайтове рядок з відомими значеннями (а така думка напевно комусь може спасти на думку) після прочитання статті перемістяться вперед у часі років на 20. З минулого, я маю на увазі :)

Пошук документації Arduino IDE дає два варіанти, що таке string. Це сам string як рядок char'ів, і String, що є об'єктом. Що таке об'єкт? Згідно з вікіпедією, це "деяка сутність у віртуальному просторі, що має певний стан і поведінку, має задані значення властивостей (атрибутів) і операцій над ними (методів)". Іншими словами - змінна із вбудованими функціями, які роблять щось із цією змінною. Щоб почати працювати з цим об'єктом, напишемо щось таке:

Тут до input будуть додаватися нові символи, поки буфер не вичерпається. Тоді можна буде аналізувати отриманий рядок, наприклад, так:

Код використовує дуже зручніфункції, вбудовані в об'єкт 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 і прочитати про них:)