Определение структуры в библиотеке

Sled
Offline
Зарегистрирован: 27.08.2017

Приветствую!

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

 

 

b707
Offline
Зарегистрирован: 26.05.2017

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

Для продолжения разговора четче формулируйте проблему.

Sled
Offline
Зарегистрирован: 27.08.2017

Спасибо, за ответ!

Но все же не получается у меня. Приведу исходный работающий код:


// Скрипт проверки работы таймеров на основе счетчика миллисекунд - 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 сработал");  // Выводим в терминал сообщение
  }
}

 

Sled
Offline
Зарегистрирован: 27.08.2017

Соответственно пытаюсь вынести определение структуры "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 сработал");  // Выводим в терминал сообщение
  }
}

 

Sled
Offline
Зарегистрирован: 27.08.2017

Сам файл прокта находится в папке "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

 

Sled
Offline
Зарегистрирован: 27.08.2017

И код в файле "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;
    }  
}

 

Sled
Offline
Зарегистрирован: 27.08.2017

В результате ошибка: " expected initializer before 'myStructT' " на строке №4 в проекте:

04 myStructT Timer1;

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

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

Sled
Offline
Зарегистрирован: 27.08.2017

Простите, не понял, где ее пропустил?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

сообщение №4 14 строка скетча

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

очень плохо, что сами не нашли. Такие ошибки глаз должен находить сразу. Их по диагностике искать трудно, как в Вашем случае - сообщение компилятора никак не помогает.

Sled
Offline
Зарегистрирован: 27.08.2017

Спасибо, добрый человек!

Я и не подумал о завершении описания функции в хедер файле.

Пасиб!

Sled
Offline
Зарегистрирован: 27.08.2017

Просто, не каждый день приходится использовать хедер файлы - раз в десять лет иногда стакиваюсь...

b707
Offline
Зарегистрирован: 26.05.2017

Во первых, в файле MyLib1.h после обьявления функции Timer не хватает точки с запятой.

Во-вторых - это уже по сути самого кода - весь код работы с millis в функции Timer - неправильный. Если записать проверку интервала в строке 11 файла MyLib1.cpp как вычитание, а не как сложение - весь остальной код из этого файла можно будет выкинуть, все эти мудреные проверки на переполнение millis станут не нужны.

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

b707
Offline
Зарегистрирован: 26.05.2017

Sled пишет:

Просто, не каждый день приходится использовать хедер файлы - раз в десять лет иногда стакиваюсь...

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

Sled
Offline
Зарегистрирован: 27.08.2017

Пасиб, за замечания! Буду вникать. Сам Ардуино не использую, просто товарищу помогаю продвигаться в теме.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

b707 пишет:

 Если записать проверку интервала в строке 11 файла MyLib1.cpp как вычитание, а не как сложение - весь остальной код из этого файла можно будет выкинуть, все эти мудреные проверки на переполнение millis станут не нужны.

Ну их, этих новичков! Я для себя решил, что море невежества в Ардуино - это естественная сторона популярности и простоты вхождения. Их всех - не переделать.

Но это я утром такой трезвый и добрый. Внимательно созерцаю, как падают капли самогона в кастрюлю... Дзен, чё!

Вечером такое бы кончилось матюгами и калометанием.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Ну и передавать объекты (здесь - структура) по значению - не лучший стиль. Используй хотя бы константную ссылку.

Sled
Offline
Зарегистрирован: 27.08.2017

На указателях уже пример сделал, застрял на создании своей библиотеки.

Sled
Offline
Зарегистрирован: 27.08.2017

Насчет вычитания в 11-ой строке, вариантов не нашел, возможно не понимаю правильно if или еще какой-нибудь момент. Упростить могу только до такого состояния:

// Функция проверяет срабатывание таймера. 
bool Timer( myStructT T )
{
    if( millis()  >  T.Start )
	    return( millis()  >  (T.Start + T.Period) );
    else						
        return( millis()  >  ( T.Period - (4294967295 - T.Start) ) );
}

Если Вам несложно скиньте ссылку, где приведен лучший вариант.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Я эту конструкцию разворачиваю через класс.

Sled
Offline
Зарегистрирован: 27.08.2017

Согласен, это следующий этап. Тут структуру и массив тяжело донести, а класс...

Sled
Offline
Зарегистрирован: 27.08.2017

wdrakula пишет:

b707 пишет:

 Если записать проверку интервала в строке 11 файла MyLib1.cpp как вычитание, а не как сложение - весь остальной код из этого файла можно будет выкинуть, все эти мудреные проверки на переполнение millis станут не нужны.

Ну их, этих новичков! Я для себя решил, что море невежества в Ардуино - это естественная сторона популярности и простоты вхождения. Их всех - не переделать.

Но это я утром такой трезвый и добрый. Внимательно созерцаю, как падают капли самогона в кастрюлю... Дзен, чё!

Вечером такое бы кончилось матюгами и калометанием.

Понимаю Ваше разочарование, может - "не нужно очаровываться чтобы не разочаровываться" ).

А по сути на заклаке Программирование (http://arduino.ru/Reference) не нашел - struct.

Также нет примера по созданию библиотеки. Нет полного описания if, только true/false. И все изобретают свой велосипед с millis(), тоже нет дубового примера как я привел выше и нет примера максимально сжатого - иди ищи на задворках инета. Было бы неплохо справку разделить на уровни... чтобы можно было просвещаться и сравнивать от простого к сложному.

nik182
Offline
Зарегистрирован: 04.05.2015

https://playground.arduino.cc/Code/Struct
Святцы посмотреть ,не?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Sled пишет:

...Нет полного описания if, только true/false. И все изобретают свой велосипед с millis(), тоже нет дубового примера как я привел выше и нет примера ....

1. а с хера ли искать описания конструкций языка на сайте? Вы не здоровы? В сети мало учебников по С и С++?Начните с Кернигана и Ритчи.

2. про то что есть и нет на сайте: "мопед не мой". Никто из участников форума не имеет никакого отношения к сайту, он конечно дерьмо, но захер он нужен, если есть arduino.cc, то есть первооснова? Или Вы не читаете по аглицки? Если нет, то марш в дворники! Им язык не нужен, а в программировании и электронике, да в любой нормальной науке, английский - основной.

3. пример с правильным исполльзованием миллис называется "блинк без делей". О чудо! Этот пример есть даже на местном наречии. Вот прям на этом сайте. Только нужно глаза промыть.

Sled
Offline
Зарегистрирован: 27.08.2017

Спасибо, Великий Гуру-Спаситель, что посетил нас-червяков косноязычных на своей Вайтмане и даровал нам Великое Знание! 

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

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Sled пишет:

и работает первые ~50 дней

а, после 50-ти что делает?

*никогда такого не было... и, вот - снова. ткнине палкой дохлого атмина сайта - пусть жирным шрифтом напишет, что пример работает ВЕЧНО.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Sled пишет:

и работает первые ~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:

}

 

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

wdrakula пишет:

Нет никакого переполнения.

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Клапауций 112 пишет:

wdrakula пишет:

Нет никакого переполнения.

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

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Клапауций 112 пишет:

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

Цитата"Изведал враг в тот день немало, Но нашим тоже перепало"

Logik
Offline
Зарегистрирован: 05.08.2014

Bart Eating Popcorn GIF - Popcorn Thesimpsons Bart GIFs

 

Предлагаю новичков регить после присяги - "Верую что блинк без делея работает испокон веков и до кончины по ребуту!"

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

От ведь шлемазл! ;) (эт я тебе, Логик)

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Logik пишет:

Предлагаю новичков регить после присяги - "Верую что блинк без делея работает испокон веков и до кончины по ребуту!"

предлагаю сбрасывать всех новичков в пропасть.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Клапауций 112 пишет:

Logik пишет:

Предлагаю новичков регить после присяги - "Верую что блинк без делея работает испокон веков и до кончины по ребуту!"

предлагаю сбрасывать всех новичков в пропасть.

А может быть он прав?

Sled
Offline
Зарегистрирован: 27.08.2017

)))

Sled
Offline
Зарегистрирован: 27.08.2017

Если достопочтенный Джин (Админ) приложил бы этот скрин, то у меня бы вопросов не возникло:

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

199, Карл!

Sled
Offline
Зарегистрирован: 27.08.2017

Я с Вами согласен!

Не нужно это наглядно показывать в статье - нужно рыться во всех портянках инета и вычитывать все "умные" мысли... где-то, в какой-то из кучек говна должен быть бриллиант, почему же не роетесь в говне?

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Sled пишет:

Я с Вами согласен!

Не нужно это наглядно показывать в статье - нужно рыться во всех портянках инета и вычитывать все "умные" мысли... где-то, в какой-то из кучек говна должен быть бриллиант, почему же не роетесь в говне?

ну, и кто со мной спорил, что?:

Клапауций 112 пишет:

предлагаю сбрасывать всех новичков в пропасть.

они хуже баб - те, хоть не задают вопросов, чётко исполняя инструкции.

а, этим вечно яйца мешают.

Sled
Offline
Зарегистрирован: 27.08.2017

Согласен! Ваши яйца вне всякого сравнения, они прелестны! Так сияют!

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Sled пишет:

Согласен! Ваши яйца вне всякого сравнения, они прелестны! Так сияют!

нда. усрётся, но не признает, что ступил - не покается и не поблагодарит.

Logik
Offline
Зарегистрирован: 05.08.2014

В пропасть. Из гуманизма.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Sled пишет:

А по сути на заклаке Программирование (http://arduino.ru/Reference) не нашел - struct.

Также нет примера по созданию библиотеки. Нет полного описания if, только true/false. И все изобретают свой велосипед с millis(), тоже нет дубового примера как я привел выше и нет примера максимально сжатого - иди ищи на задворках инета. Было бы неплохо справку разделить на уровни... чтобы можно было просвещаться и сравнивать от простого к сложному.

Сэр искренне полагает, что в пользовательской инструкции к телевизору должно содержаться подробное разъяснение, как работает транзистор, формулировка закона Ома, а также характеристики заряженных частиц?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ТС,

в скетче из поста №4 в начале строки 14 добавьте слово extern

Коллеги,

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sled пишет:

на заклаке Программирование (http://arduino.ru/Reference) не нашел

нет примера

Нет полного описания if,

тоже нет дубового примера

Было бы неплохо ...

Так вот и займитесь!!!

Я понимаю, что лично Вы написать все эти примеры не можете. Не беда - оплатите профессионалу, чтобы он написал! Не хотите платить сами, найдите спосора или организуйье краудфандинг - работайте!

Или Вы считаете, что кто-то другой обязан это для Вас сделать?

Sled
Offline
Зарегистрирован: 27.08.2017
b707
Offline
Зарегистрирован: 26.05.2017

Вот здорово! и двух лет не прошло!

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ох, матьтваю, как долго доходило то.... 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Sled пишет:

использует беззнаковый тип - 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() {}

Запускаем и (о ужас!!!) обнаруживаем полное отсутствие присутствия проблемы переполнения!

a=32760  b=32760  (a-b)=0
a=32761  b=32760  (a-b)=1
a=32762  b=32760  (a-b)=2
a=32763  b=32760  (a-b)=3
a=32764  b=32760  (a-b)=4
a=32765  b=32760  (a-b)=5
a=32766  b=32760  (a-b)=6
a=32767  b=32760  (a-b)=7
a=-32768  b=32760  (a-b)=8
a=-32767  b=32760  (a-b)=9
a=-32766  b=32760  (a-b)=10
a=-32765  b=32760  (a-b)=11
a=-32764  b=32760  (a-b)=12
a=-32763  b=32760  (a-b)=13
a=-32762  b=32760  (a-b)=14
a=-32761  b=32760  (a-b)=15
a=-32760  b=32760  (a-b)=16
a=-32759  b=32760  (a-b)=17
a=-32758  b=32760  (a-b)=18
a=-32757  b=32760  (a-b)=19

Полюбуйтесь на строки №№ 8 и 9 в листинге. Где проблема-то?

Боюсь, что "ключ к пониманию" по-прежнему на дне пруда и Тортила его всё ещё не отдала :(

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DetSimen пишет:

ох, матьтваю, как долго доходило то.... 

Не торопи события, пока ещё не дошло (см. мой предыдущий пост). Нужен ещё год :)