Таймеры

JuF

New member
Всем привет! МОжет тема избита, прошу не пинать сильно. Есть плата W1 , она на ESP 8266. При попытке скомпилировать стандартный пример работы с таймером

#include "timer-api.h"
void setup() {
Serial.begin(9600);
// частота=1Гц, период=1с
timer_init_ISR_1Hz(TIMER_DEFAULT);
pinMode(13, OUTPUT);
}
void loop() {
Serial.println("Hello from loop!");
delay(5000);
// здесь любой код: блокирующий или неблокирующий
}
void timer_handle_interrupts(int timer) {
Serial.println("goodbye from timer");
// мигаем лампочкой
digitalWrite(13, !digitalRead(13));
}
вылезает куча ошибок про неопознанность переменных и классов таймеров
c:/users/f0481001/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\timer.ino.cpp.o:(.text.setup+0x8): undefined reference to `TIMER_DEFAULT'
c:/users/f0481001/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\timer.ino.cpp.o:(.text.setup+0xc): undefined reference to `timer_init_ISR_1Hz'
c:/users/f0481001/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/bin/../lib/gcc/xtensa-lx106-elf/4.8.2/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\timer.ino.cpp.o: in function `setup':
C:\Users\F0481001\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.7.4\cores\esp8266/HardwareSerial.h:76: undefined reference to `timer_init_ISR_1Hz'
collect2.exe: error: ld returned 1 exit status
exit status 1
Ошибка компиляции для платы Generic ESP8266 Module.

Пробовал на другом компе, переставлял ардуинку - пофигу. Получается эта плата с таймерами не работает?
 

l15ar

Member
void timer_handle_interrupts(int timer) {
Serial.println("goodbye from timer");
// мигаем лампочкой
digitalWrite(13, !digitalRead(13));
}
Вы меня извините! Запомните следующее: НИКАКОЙ ВВОД-ВЫВОД в обработчиках прерываний НЕ ДОЛЖЕН БЫТЬ СОВСЕМ!
на то они и обработчики! Получили прерывание, изменили глобальную переменную, или выполнили какое-то короткое действие, так же допустимо, изменить регистр(ы).
остальное нужно вникать..

digitalWrite(13, !digitalRead(13)) - так же, две довольно длинные операции, исходя из реализации их в arduino. !!!
 

l15ar

Member
Для тех кто не понял, поясняю. Любой ввод-вывод связан с обработкой прерываний! В частности, работа с последовательным портом.
Получается, вы пишите свой обработчик прерывания таймера, обрабатываете прерывание,
и инициируете новое прерывание(своими действиями) блокируя их обработку(поскольку вы находитесь в обработчике). Тупик!
Последнее, ну с чего вы взяли, что последовательный порт, доступен внутри обработчика прерывания? Он что глобальный экземпляр???
Не думаю! Если, что то такое нужно, нужно объявлять это в глобальную переменную, тогда, можно использовать это в обработчике!
 

nikolz

Well-known member
Для тех кто не понял, поясняю. Любой ввод-вывод связан с обработкой прерываний! В частности, работа с последовательным портом.
Получается, вы пишите свой обработчик прерывания таймера, обрабатываете прерывание,
и инициируете новое прерывание(своими действиями) блокируя их обработку(поскольку вы находитесь в обработчике). Тупик!
Последнее, ну с чего вы взяли, что последовательный порт, доступен внутри обработчика прерывания? Он что глобальный экземпляр???
Не думаю! Если, что то такое нужно, нужно объявлять это в глобальную переменную, тогда, можно использовать это в обработчике!
Ваше понимание процесса обработки внешних сигналов либо ошибочно либо неполно.
Обработка может быть не только по прерыванию, но и прямым считыванием информации из регистра пинов
в функциях обработки прерываний можете читать что хотите
ограничений особо нет.
Рекомендую почитать документацию по SDK для ESP
Там же есть примеры, которые очень простые и понятные.
 

l15ar

Member
Ваше понимание процесса обработки внешних сигналов либо ошибочно либо неполно.
Обработка может быть не только по прерыванию, но и прямым считыванием информации из регистра пинов
в функциях обработки прерываний можете читать что хотите
ограничений особо нет.
Рекомендую почитать документацию по SDK для ESP
Там же есть примеры, которые очень простые и понятные.
удивляюсь вашей удивительной ...
Так понимаю, вы не программируете на Arduino, и советы даёте очень заумные! Ппц! :\
no comment
 

nikolz

Well-known member
удивляюсь вашей удивительной ...
Так понимаю, вы не программируете на Arduino, и советы даёте очень заумные! Ппц! :\
no comment
Учите мат часть.
Ее знание поможет Вам даже при программировании на Ардуино.
---------------
Если Вы не знаете, то сообщаю Вам что в ардуино Вы можете вставлять куски на СИ.
-------------
ваши советы про обработку прерываний просто безграмотны.
Читайте учебники по микропроцессорам.
 

l15ar

Member
Учите мат часть.
Ее знание поможет Вам даже при программировании на Ардуино.
---------------
Если Вы не знаете, то сообщаю Вам что в ардуино Вы можете вставлять куски на СИ.
-------------
ваши советы про обработку прерываний просто безграмотны.
Читайте учебники по микропроцессорам.
Уже написал, про вашу "полную дурь".. Всё остальное у вас ещё хуже..
 

l15ar

Member
Почему ошибка то у меня ))
...
 

JuF

New member
Интересную особенность выявил - использую экранчик и библиотеку #include <LiquidCrystal_I2C.h> . Если вывод на экран располагаю в теле loop, все отлично работает. Но как только вынес его в отдельную функцию - таймер работать перестал. А вывод прекрасно работает. Все удалил в функции - и не работает. Почему так? Вот процедура -

void Lcd(float _h,float _t)
{
lcd.setCursor(0,0);
}
 

CodeNameHawk

Moderator
Команда форума
Вы меня извините! Запомните следующее: НИКАКОЙ ВВОД-ВЫВОД в обработчиках прерываний НЕ ДОЛЖЕН БЫТЬ СОВСЕМ!
на то они и обработчики! Получили прерывание, изменили глобальную переменную, или выполнили какое-то короткое действие, так же допустимо, изменить регистр(ы).
остальное нужно вникать..

digitalWrite(13, !digitalRead(13)) - так же, две довольно длинные операции, исходя из реализации их в arduino. !!!
С чего вы это взяли, это просто правило правильного программирования, но не обязательного.
Вы наверное шутите, что есп да за целую секунду не успеет это все выполнить.

Все удалил в функции - и не работает. Почему так? Вот процедура -
Вы на правильном пути, сократите программу до минимальной длины, но она должна быть полная для запуска другим участником беседы. И поставьте себя на его место, что вы можете сказать по куску вашего кода?
Никто не знает, что и как вы пытаетесь сделать и какие библиотеки используете.
Разве вас не научил совет выше.
 

l15ar

Member
С чего вы это взяли, это просто правило правильного программирования, но не обязательного.
Вы наверное шутите, что есп да за целую секунду не успеет это все выполнить.
Верно, вы не занимались написанием обработчиков прерываний!
Дело не в производительности контроллера!
Дело в создании ситуации - которая называется блокировка! Ничего хорошего из этого не выйдет!
Никто в здравом уме, не вызывает функции в обработчиках прерываний, не для этого они сделаны!
(что происходит при вызове функции??? запись в стек... вызов функции, чтение стека)
Особенно, такие функции который приводят к состоянию тупика.
Например, если в приемном буфере, не будет достаточно места, к чему это приведёт? Блокировке, исключению!
В этом замысел программиста?
Нафига тогда, такое делать?!
 

CodeNameHawk

Moderator
Команда форума
Верно, вы не занимались написанием обработчиков прерываний!
И зачем так кричать.
Дело не в производительности контроллера!
Конечно все дело в производительности.
Если выполнение кода завершится до возникновения другого прерывания, пишите как хотите, на результат не повлияет.
Конечно не все могут точно посчитать время выполнения кода, а некоторые даже не имеют понятия как это делается.
Никто в здравом уме, не вызывает функции в обработчиках прерываний, не для этого они сделаны!
Все кто захочет и самое важное это те, кто понимает, что делает.
Например, если в приемном буфере, не будет достаточно места, к чему это приведёт? Блокировке, исключению!
Приведет к тому, что задумал программист, если проц. быстрый все будет работать штатно.
Даже если что то пойдет не так, то никакого исключения не будет, в худшем случае затрется часть старых данных, о каком исключении вы говорите.

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

Igorka

New member
Помогите пожалуйста.Этот код работает нормально (хоть и не правильно организована "частота" опроса датчика температуры)

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS D2//ds18b20 подключен к GPIO4

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);



char auth[] = "*****";//Auth Token
char ssid[] = "*****";//имя точки доступа
char pass[] = "*****";//пароль точки доступа

void setup()
{
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
sensors.begin();

}

void sendTemps()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);
Serial.println(temp);
Blynk.virtualWrite(V1,temp);
}


void loop()
{
Blynk.run();
sendTemps();
}
Пример с таймером тоже работал (но уже с правильным опросом и отправкой)

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SimpleTimer.h>

SimpleTimer timer;


#define ONE_WIRE_BUS 2//ds18b20 подключен к GPIO4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

char auth[] = "*****";//Auth Token
char ssid[] = "*****";//имя точки доступа
char pass[] = "*****";//пароль точки доступа


void setup()
{
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
sensors.begin();
timer.setInterval(1000L, sendTemps);//каждые 1000 миллисекунд(1 сек) должна выполняться функция с именем sendTemps

}
void sendTemps()
{
sensors.requestTemperatures();
float temp = sensors.getTempCByIndex(0);//float temp переменная с плавающей точкой
Serial.println(temp);//показания температуры отправляются в терминал
Blynk.virtualWrite(V1, temp); //показания температуры выводятся на виртуальный пин V1

}
void loop()
{
Blynk.run();
timer.run();
}
Теперь заливаю последний скетч, а в ответ esp мне моргает своим синим светодиодом с периодом 1 сек, а в порт и виртуальный пин шлет -127, типа датчик не подключен.Удалял и заново ставил библиотеку SimpleTimer-master, проблема не куда не делась.Вопрос: почему моргает светодиод на плате, хотя плата не уходит в ребут, данные шлет с периодом 1 сек.?
 
Сверху Снизу