Определение структуры в библиотеке
- Войдите на сайт для отправки комментариев
Вс, 27/08/2017 - 00:38
Приветствую!
Подскажите, как перенести определение структуры в библиотечный файл и также функцию, которая использует эту структуру. Пробовал, но ощибки, не пойму как нужно правильно писать. Если можно пример кода. Спасибо!
пример есть в любой работающей библиотеке. Не забываем о необходимсти помещать обьявления структур и функций в заголовочный файл и подключать его в основном скетче.
Для продолжения разговора четче формулируйте проблему.
Спасибо, за ответ!
Но все же не получается у меня. Приведу исходный работающий код:
// Скрипт проверки работы таймеров на основе счетчика миллисекунд - millis //--------------------------------------------------------------------------------------------------- typedef struct{ unsigned long Start; // Переменная хранения начального значения счетчика миллисекунд int Period; // Переменная хранения периода таймера } myStructT; //--------------------------------------------------------------------------------------------------- myStructT Timer1; myStructT Timer2; myStructT Timer3; //--------------------------------------------------------------------------------------------------- bool Timer( myStructT T ) { if( millis() > T.Start ) // Проверяем на переполение счетчика миллисекунд { // Счетчик миллисекунд не переполнился: // Проверяем превышение текущего значение миллисекунд над заданным периодом таймера if( millis() > (T.Start + T.Period) ) return true; else return false; } else // Счетчик миллисекунд переполнился: { // Проверяем превышение текущего значение миллисекунд над заданным периодом таймера if( millis() > (T.Period - (4294967295 - T.Start) ) ) return true; else return false; } } //--------------------------------------------------------------------------------------------------- void setup() { Serial.begin(9600); // Настраиваем скорость обмена с терминалом - 9600 б/сек // Задаем начальные значения для таймеров Timer1.Start = millis(); // Сохраняем текущее значение счетчика миллисекунд Timer1.Period = 1000; // Сохраняем период Таймера №1 Timer2.Start = millis(); // Сохраняем текущее значение счетчика миллисекунд Timer2.Period = 5000; // Сохраняем период Таймера №2 Timer3.Start = millis(); // Сохраняем текущее значение счетчика миллисекунд Timer3.Period = 10000; // Сохраняем период Таймера №3 } //--------------------------------------------------------------------------------------------------- void loop() { if( Timer( Timer1 ) ) // Проверка срабатывания Таймера №1 { Timer1.Start = millis(); // Сохранение текущего значения счетчика миллисекунд Serial.println("Timer1 сработал"); // Выводим в терминал сообщение } if( Timer( Timer2 ) ) // Проверка срабатывания Таймера №2 { Timer2.Start = millis(); // Сохранение текущего значения счетчика миллисекунд Serial.println("Timer2 сработал"); // Выводим в терминал сообщение } if( Timer( Timer3 ) ) // Проверка срабатывания Таймера №3 { Timer3.Start = millis(); // Сохранение текущего значения счетчика миллисекунд Serial.println("Timer3 сработал"); // Выводим в терминал сообщение } }Соответственно пытаюсь вынести определение структуры "myStructT" и функции "Timer" в свою библиотеку.
Код в файле проекта:
// Скрипт проверки работы таймеров на основе счетчика миллисекунд - millis #include <MyLib1.h> //------------------------------------------------------------------------------------------------- myStructT Timer1; myStructT Timer2; myStructT Timer3; //------------------------------------------------------------------------------------------------- void setup() { Serial.begin(9600); // Настраиваем скорость обмена с терминалом - 9600 б/сек // Задаем начальные значения для таймеров Timer1.Start = millis(); // Сохраняем текущее значение счетчика миллисекунд Timer1.Period = 1000; // Сохраняем период Таймера №1 Timer2.Start = millis(); // Сохраняем текущее значение счетчика миллисекунд Timer2.Period = 5000; // Сохраняем период Таймера №2 Timer3.Start = millis(); // Сохраняем текущее значение счетчика миллисекунд Timer3.Period = 10000; // Сохраняем период Таймера №3 } //------------------------------------------------------------------------------------------------- void loop() { if( Timer( Timer1 ) ) // Проверка срабатывания Таймера №1 { Timer1.Start = millis(); // Сохранение текущего значения счетчика миллисекунд Serial.println("Timer1 сработал"); // Выводим в терминал сообщение } if( Timer( Timer2 ) ) // Проверка срабатывания Таймера №2 { Timer2.Start = millis(); // Сохранение текущего значения счетчика миллисекунд Serial.println("Timer2 сработал"); // Выводим в терминал сообщение } if( Timer( Timer3 ) ) // Проверка срабатывания Таймера №3 { Timer3.Start = millis(); // Сохранение текущего значения счетчика миллисекунд Serial.println("Timer3 сработал"); // Выводим в терминал сообщение } }Сам файл прокта находится в папке "C:\Users\QWE\Documents\Arduino\sketch_aug26a"
Код в файле "MyLib1.h", который находится в папке "C:\Users\QWE\Documents\Arduino\libraries\MyLib1":
#ifndef MyLib1_h // Если библиотека MyLib1 не подключена #define MyLib1_h // Тогда подключаем ее #include "Arduino.h" //------------------------------------------------------------------------------------------------- typedef struct{ unsigned long Start; // Переменная хранения начального значения счетчика миллисекунд int Period; // Переменная хранения периода таймера } myStructT; //------------------------------------------------------------------------------------------------- // Функция проверяет срабатывание таймера. bool Timer( myStructT T ) #endifИ код в файле "MyLib1.cpp", который находится в папке "C:\Users\QWE\Documents\Arduino\libraries\MyLib1":
#include "Arduino.h" // Подключаем файл Arduino.h #include <MyLib1.h> // Подключаем файл MyLib1.h //--------------------------------------------------------------------------------------------------- // Функция проверяет срабатывание таймера. bool Timer( myStructT T ) { if( millis() > T.Start ) // Проверяем на переполение счетчика миллисекунд { // Счетчик миллисекунд не переполнился: // Проверяем превышение текущего значение миллисекунд над заданным периодом таймера if( millis() > (T.Start + T.Period) ) return true; else return false; } else // Счетчик миллисекунд переполнился: { // Проверяем превышение текущего значение миллисекунд над заданным периодом таймера if( millis() > (T.Period - (4294967295 - T.Start) ) ) return true; else return false; } }В результате ошибка: " expected initializer before 'myStructT' " на строке №4 в проекте:
я искренне надеюсь, что Вы самостоятельно обнаружите место, где Вы ее пропустили.
Простите, не понял, где ее пропустил?
сообщение №4 14 строка скетча
очень плохо, что сами не нашли. Такие ошибки глаз должен находить сразу. Их по диагностике искать трудно, как в Вашем случае - сообщение компилятора никак не помогает.
Спасибо, добрый человек!
Я и не подумал о завершении описания функции в хедер файле.
Пасиб!
Просто, не каждый день приходится использовать хедер файлы - раз в десять лет иногда стакиваюсь...
Во первых, в файле MyLib1.h после обьявления функции Timer не хватает точки с запятой.
Во-вторых - это уже по сути самого кода - весь код работы с millis в функции Timer - неправильный. Если записать проверку интервала в строке 11 файла MyLib1.cpp как вычитание, а не как сложение - весь остальной код из этого файла можно будет выкинуть, все эти мудреные проверки на переполнение millis станут не нужны.
Прежде чем спорить на тему переполнения - пройдитесь поиском по форуму, тема обсуждалась десятки раз и является просто красной тряпкой для большинства старожилов.
Просто, не каждый день приходится использовать хедер файлы - раз в десять лет иногда стакиваюсь...
при чем здесь хедер или нет - есть базовый синтаксис языка. он един для всех файлов...
Пасиб, за замечания! Буду вникать. Сам Ардуино не использую, просто товарищу помогаю продвигаться в теме.
Если записать проверку интервала в строке 11 файла MyLib1.cpp как вычитание, а не как сложение - весь остальной код из этого файла можно будет выкинуть, все эти мудреные проверки на переполнение millis станут не нужны.
Ну их, этих новичков! Я для себя решил, что море невежества в Ардуино - это естественная сторона популярности и простоты вхождения. Их всех - не переделать.
Но это я утром такой трезвый и добрый. Внимательно созерцаю, как падают капли самогона в кастрюлю... Дзен, чё!
Вечером такое бы кончилось матюгами и калометанием.
Ну и передавать объекты (здесь - структура) по значению - не лучший стиль. Используй хотя бы константную ссылку.
На указателях уже пример сделал, застрял на создании своей библиотеки.
Насчет вычитания в 11-ой строке, вариантов не нашел, возможно не понимаю правильно if или еще какой-нибудь момент. Упростить могу только до такого состояния:
// Функция проверяет срабатывание таймера. bool Timer( myStructT T ) { if( millis() > T.Start ) return( millis() > (T.Start + T.Period) ); else return( millis() > ( T.Period - (4294967295 - T.Start) ) ); }Если Вам несложно скиньте ссылку, где приведен лучший вариант.
Я эту конструкцию разворачиваю через класс.
Согласен, это следующий этап. Тут структуру и массив тяжело донести, а класс...
Если записать проверку интервала в строке 11 файла MyLib1.cpp как вычитание, а не как сложение - весь остальной код из этого файла можно будет выкинуть, все эти мудреные проверки на переполнение millis станут не нужны.
Ну их, этих новичков! Я для себя решил, что море невежества в Ардуино - это естественная сторона популярности и простоты вхождения. Их всех - не переделать.
Но это я утром такой трезвый и добрый. Внимательно созерцаю, как падают капли самогона в кастрюлю... Дзен, чё!
Вечером такое бы кончилось матюгами и калометанием.
Понимаю Ваше разочарование, может - "не нужно очаровываться чтобы не разочаровываться" ).
А по сути на заклаке Программирование (http://arduino.ru/Reference) не нашел - struct.
Также нет примера по созданию библиотеки. Нет полного описания if, только true/false. И все изобретают свой велосипед с millis(), тоже нет дубового примера как я привел выше и нет примера максимально сжатого - иди ищи на задворках инета. Было бы неплохо справку разделить на уровни... чтобы можно было просвещаться и сравнивать от простого к сложному.
https://playground.arduino.cc/Code/Struct
Святцы посмотреть ,не?
...Нет полного описания if, только true/false. И все изобретают свой велосипед с millis(), тоже нет дубового примера как я привел выше и нет примера ....
1. а с хера ли искать описания конструкций языка на сайте? Вы не здоровы? В сети мало учебников по С и С++?Начните с Кернигана и Ритчи.
2. про то что есть и нет на сайте: "мопед не мой". Никто из участников форума не имеет никакого отношения к сайту, он конечно дерьмо, но захер он нужен, если есть arduino.cc, то есть первооснова? Или Вы не читаете по аглицки? Если нет, то марш в дворники! Им язык не нужен, а в программировании и электронике, да в любой нормальной науке, английский - основной.
3. пример с правильным исполльзованием миллис называется "блинк без делей". О чудо! Этот пример есть даже на местном наречии. Вот прям на этом сайте. Только нужно глаза промыть.
Спасибо, Великий Гуру-Спаситель, что посетил нас-червяков косноязычных на своей Вайтмане и даровал нам Великое Знание!
Примерчик с миллисами уж очень прост и работает первые ~50 дней, а речь у нас была про оптимизацию моей функции...
и работает первые ~50 дней
а, после 50-ти что делает?
*никогда такого не было... и, вот - снова. ткнине палкой дохлого атмина сайта - пусть жирным шрифтом напишет, что пример работает ВЕЧНО.
и работает первые ~50 дней,
Идиот! Зачем Вы полезли программировать?
Запустите и посмотрите. Нет никакого переполнения. Эта тема уже ...... вкрай.
Хоть кто-то в школе математику учит ?
void setup() { // put your setup code here, to run once: Serial.begin(57600); while (!Serial); uint32_t a,b; b = 4294967000; for (uint32_t i = 0; i<1000; i++) { a = i + 4294967000; Serial.print("a="); Serial.print(a); Serial.print("b="); Serial.print(b); Serial.print("a-b="); Serial.println(a-b); } } void loop() { // put your main code here, to run repeatedly: }Нет никакого переполнения.
переполнение есть, но пример работает - много наших полегло в попытках доказать друг-другу, почему...
Нет никакого переполнения.
переполнение есть, но пример работает - много наших полегло в попытках доказать друг-другу, почему...
переполнение есть, но пример работает - много наших полегло в попытках доказать друг-другу, почему..
Цитата"Изведал враг в тот день немало, Но нашим тоже перепало. "
Предлагаю новичков регить после присяги - "Верую что блинк без делея работает испокон веков и до кончины по ребуту!"
От ведь шлемазл! ;) (эт я тебе, Логик)
Предлагаю новичков регить после присяги - "Верую что блинк без делея работает испокон веков и до кончины по ребуту!"
предлагаю сбрасывать всех новичков в пропасть.
Предлагаю новичков регить после присяги - "Верую что блинк без делея работает испокон веков и до кончины по ребуту!"
предлагаю сбрасывать всех новичков в пропасть.
А может быть он прав?
)))
Если достопочтенный Джин (Админ) приложил бы этот скрин, то у меня бы вопросов не возникло:
199, Карл!
Я с Вами согласен!
Не нужно это наглядно показывать в статье - нужно рыться во всех портянках инета и вычитывать все "умные" мысли... где-то, в какой-то из кучек говна должен быть бриллиант, почему же не роетесь в говне?
Я с Вами согласен!
Не нужно это наглядно показывать в статье - нужно рыться во всех портянках инета и вычитывать все "умные" мысли... где-то, в какой-то из кучек говна должен быть бриллиант, почему же не роетесь в говне?
ну, и кто со мной спорил, что?:
предлагаю сбрасывать всех новичков в пропасть.
они хуже баб - те, хоть не задают вопросов, чётко исполняя инструкции.
а, этим вечно яйца мешают.
Согласен! Ваши яйца вне всякого сравнения, они прелестны! Так сияют!
Согласен! Ваши яйца вне всякого сравнения, они прелестны! Так сияют!
нда. усрётся, но не признает, что ступил - не покается и не поблагодарит.
В пропасть. Из гуманизма.
А по сути на заклаке Программирование (http://arduino.ru/Reference) не нашел - struct.
Также нет примера по созданию библиотеки. Нет полного описания if, только true/false. И все изобретают свой велосипед с millis(), тоже нет дубового примера как я привел выше и нет примера максимально сжатого - иди ищи на задворках инета. Было бы неплохо справку разделить на уровни... чтобы можно было просвещаться и сравнивать от простого к сложному.
Сэр искренне полагает, что в пользовательской инструкции к телевизору должно содержаться подробное разъяснение, как работает транзистор, формулировка закона Ома, а также характеристики заряженных частиц?
ТС,
в скетче из поста №4 в начале строки 14 добавьте слово extern
Коллеги,
зачем кого-то сбрасывать в пропасть? Проблема воспрашающих и нуждающихся в помощи давно решена в классической литературе. Только сегодня в другой теме цитировал бессмертный рассказ Марка Твена. Вот, почитайте первую часть про благодарного пуделя и продолжение к ней. Особенно, обратите внимание на завет, который умирающий доктор дал нам со смертного одра.
на заклаке Программирование (http://arduino.ru/Reference) не нашел
нет примера
Нет полного описания if,
тоже нет дубового примера
Было бы неплохо ...
Так вот и займитесь!!!
Я понимаю, что лично Вы написать все эти примеры не можете. Не беда - оплатите профессионалу, чтобы он написал! Не хотите платить сами, найдите спосора или организуйье краудфандинг - работайте!
Или Вы считаете, что кто-то другой обязан это для Вас сделать?
Итог: https://sledleo.blogspot.com/2019/04/delay-millis.html
Итог: https://sledleo.blogspot.com/2019/04/delay-millis.html
Вот здорово! и двух лет не прошло!
ох, матьтваю, как долго доходило то....
использует беззнаковый тип - unsigned long - это и есть ключ к понимаю!
А что, если бы он использовал беззнаковый unsigned int или даже просто вполне себе знаковый int - это что-то в корне изменило бы?
Давайте проверим. Вот по сути тот же пример от wdrakula, переделанный под обычный знаковый int
#include <Printing.h> void setup() { Serial.begin(57600); int a = (digitalRead(3) + 1) * 32760, b = 32760; for (int i = 0; i < 20; i++, a++) { printf("a=%d b=%d (a-b)=%d\r\n", a, b, a - b); } } void loop() {}Запускаем и (о ужас!!!) обнаруживаем полное отсутствие присутствия проблемы переполнения!
Полюбуйтесь на строки №№ 8 и 9 в листинге. Где проблема-то?
Боюсь, что "ключ к пониманию" по-прежнему на дне пруда и Тортила его всё ещё не отдала :(
ох, матьтваю, как долго доходило то....
Не торопи события, пока ещё не дошло (см. мой предыдущий пост). Нужен ещё год :)