Добрый день! Есть необходимость получать по сети информацию о пинах, на которые подключены датчики. Для этого в setupe обращаюсь с помощью запроса к серверу. После получения данных нужно объявить функцию OneWire ds(Номер полученного пина). Обычно это делается до setup. Как это сделать до setup, что бы в loope можно было использовать эту функцию?
Ну и вообще, для OneWire нужен специфический подтягивающий резистор, так что чего там по сети не передавай, а совместимые линии от этого не изменятся. Нецелесообразно.
Так если в setup переменную объявить она не будет видна в loop. Или библиотека OneWire.h уже объявила ее при подключении? Про резистор я помню.
У меня еще вопрос: как сравнить имя переменной с неким параметром? Пришло на ум использовать структуру. Но со стринг не компилируется, зависает и все. Так работает: Код (C++): typedef struct { int var; word id; } State; State lightVar[1] = {}; int namevar = 5; void setup() { pinMode(13, OUTPUT); lightVar[0].var = 5; } void loop() { if (namevar == lightVar[0].var) { digitalWrite(13, HIGH); delay (1000); digitalWrite(13, LOW); } delay (1000); } А так нет Код (C++): typedef struct { String var; word id; } State; State lightVar[1] = {}; String namevar = "5"; void setup() { pinMode(13, OUTPUT); lightVar[0].var = "5"; } void loop() { if (namevar == lightVar[0].var) { digitalWrite(13, HIGH); delay (1000); digitalWrite(13, LOW); } delay (1000); }
А так да: Код (C++): typedef struct { String var; word id; } State; State lightVar = {}; String namevar = "5"; void setup() { pinMode(13, OUTPUT); lightVar.var = "5"; } void loop() { if (namevar == lightVar.var) { digitalWrite(13, HIGH); delay (1000); digitalWrite(13, LOW); } delay (1000); }
Так действительно да. Но предполагается, что lightVar.var будет не одна, а несколько Код (C++): lightVar[0].var; lightVar[1].var; lightVar[2].var;
Так замените структуру на класс. У класса есть конструктор. И создавать объект используя указатель на класс. Можно организовать массив указателей на класс. Или вообще список указателей на вновь созданых объектов.
И это тоже не проблема. Код (C++): typedef struct { String var; word id; } State; // Создаем массив из 10 структур с индексами от 0 до 9 включительно State lightVar[10]; // Строки с несколькими именами задач String namevar = "name_new"; String taskvar = "task_new"; void setup() { pinMode(9, OUTPUT); pinMode(13, OUTPUT); // Инициализируем поля структур в массиве lightVar[0].var = "name_new"; lightVar[9].var = "task_new"; } void loop() { // Сравниваем if (namevar == lightVar[0].var) { digitalWrite(13, HIGH); delay (1000); digitalWrite(13, LOW); } if (taskvar == lightVar[9].var) { digitalWrite(9, HIGH); delay (1000); digitalWrite(9, LOW); } delay (1000); }
И что? Главное что у класса есть конструктор. Структуру надо не только создать, но и загрузить. Если создание стуктуры находится за пределами setup и loop,то для загрузки структуры нужна дополнительная функция. А вот в классе уже есть встроеная такая функция - конструктор.
В общем надо было вместо Код (C++): State lightVar[1] = {}; Писать Код (C++): State lightVar[1]; или Код (C++): State lightVar[] = {}; А как лучше: указать размер массива с запасом, например, 10 (если точно не знаешь сколько будет) или не определять размер?
Так с запасом, или размер в прнципе не известен на этапе компиляции? К стати какой смысл объявлять пустой массив? В него же ничего нельзя записать, даже если компилятор не ругается.
Почему? У меня этот код работает Код (C++): typedef struct { String var; word id; } State; State lightVar[] = {}; String namevar = "5"; void setup() { pinMode(13, OUTPUT); lightVar[0].var = "5"; } void loop() { if (namevar == lightVar[0].var) { digitalWrite(13, HIGH); delay (1000); digitalWrite(13, LOW); } delay (1000); }
Такой код может случайно заработать. Я точно не знаю как компилятор память распределяет. Думаю за массивом {} нет никаких критичных данных. А lightVar это указатель на массив {}.
Не определять размер совершенно неправильно, выше вам уже сказали, что такой код работает только по причине отсутствия других переменных в памяти по тем адресам, к которым вы обращаетесь в этом примере. Как только там что-то появится, вы запишите свои значения, сотрете старые, и дальше у вас в программе будет происходить что угодно. Самый простой вариант, указать размер массива с запасом, он же и самый надежный. Динамическое выделение памяти в случае с микроконтроллерами - вариант требующий аккуратности и должного внимания при реализации. Во-первых, памяти у вас не так много (в Uno - 2Кб) и возможен случай, когда запрос на выделение новой памяти просто не будет удовлетворен. Во-вторых, когда дополнительная память программе уже не требуется, её желательно вернуть и в полном объеме, иначе возникнут утечки памяти. Если вам все-таки очень хочется связываться с динамическими данными, попробуйте реализовать их на основе контейнеров STL, например векторах. Стандартная библиотека возьмет на себя большую часть забот по размещению данных в памяти и, главное, это точно будет корректно. Ну или сделайте с помощью классов и операции new.