• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Делюсь опытом Как асимметрично мигать светодиодом в фоне без блокировки

ivy

New member
В Ардуино есть базовый пример как мигнуть светодиодом. И пример даже асимметричный - 1 сек включено, 2 сек выключено. Проблема в том, что при использовании задержки ESP ничего другого делать не может.

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

Предлагаю метод асимметричного мигания светодиодом в фоновом режиме (без блокировки ESP) с использованием только встроенных комманд, без доп. инклюдов.

Код:
#define LED_ON_PULSE 200   // ms
#define LED_PIN 4
#define CYCLE_TIME 5000    // ms

static unsigned long m_last_sample_time = millis();

void setup() {
  pinMode(LED_PIN, OUTPUT);     // Initialize the LED pin as an output
}

void loop() {
  // Do a job every cycle (not logical)
  unsigned long now = millis();

  if (digitalRead(LED_PIN) == LOW && now - m_last_sample_time > LED_ON_PULSE) {
      // turn off led
      digitalWrite(LED_PIN, HIGH);
      pinMode(LED_PIN, INPUT_PULLUP);
    }
  if (digitalRead(LED_PIN) == HIGH && now - m_last_sample_time < LED_ON_PULSE) {
      // turn on led
      pinMode(LED_PIN, OUTPUT);
      digitalWrite(LED_PIN, LOW);
    }

  // Wait 5 sec. Run loop once in 5 sec.
  if (now - m_last_sample_time < CYCLE_TIME)
    return;

  m_last_sample_time = now;  // Register full logical cycle passed
  // Do a job once in logical cycle time

}
 

Atom

Member
Браво, вы делаете успехи. Еще немного - и откроете стек сообщений. А там и до создания свей операционки не далеко ;-)
 
  • Like
Реакции: pet

tretyakov_sa

Moderator
Команда форума
В примерах есть
В Ардуино есть базовый пример как мигнуть светодиодом. И пример даже асимметричный - 1 сек включено, 2 сек выключено. Проблема в том, что при использовании задержки ESP ничего другого делать не может.
 

tretyakov_sa

Moderator
Команда форума
Все гораздо проще, есть библиотека Ticker!

Код:
#include <Ticker.h>
Ticker tickerSetHigh;
Ticker tickerSetLow;
int ledPin=12;
void setPin(int state) {
  digitalWrite(ledPin, state);
}

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
   tickerSetLow.attach_ms(500, setPin, 0);
   tickerSetHigh.attach_ms(1000, setPin, 1);
}

void loop() {
}
 
  • Like
Реакции: ivy

nikolz

Well-known member
Все гораздо проще, есть библиотека Ticker!

Код:
#include <Ticker.h>
Ticker tickerSetHigh;
Ticker tickerSetLow;
int ledPin=12;
void setPin(int state) {
  digitalWrite(ledPin, state);
}

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
   tickerSetLow.attach_ms(500, setPin, 0);
   tickerSetHigh.attach_ms(1000, setPin, 1);
}

void loop() {
}
-------------------------------------
первоисточник здесь:
Arduino/libraries/Ticker at master · esp8266/Arduino · GitHub
 

dimanoid 999

New member
@tretyakov_sa подозреваю, что @dimanoid 999 хочет его для avr. Для avr тикера нет.
Для avr зато есть Умное мигание светодиодом в Ардуино
Да Вы сразу поняли. Одна проблема я новичок. и Разобраться с ходу не могу со всеми этими прерываниями. некоторые вещи в коде тайм он мне вовсе не понятны. А надо очень для моей задумки.
 

Сергей_Ф

Moderator
Команда форума
@dimanoid 999 если надо, придется разбираться. Доступнее чем в статье, ничего нет. Если сложно с таймером, используйте миллис - там просто. Если что, спрашивайте. Только за Вас делать никто не будет.
 

dimanoid 999

New member
@dimanoid 999 если надо, придется разбираться. Доступнее чем в статье, ничего нет. Если сложно с таймером, используйте миллис - там просто. Если что, спрашивайте. Только за Вас делать никто не будет.
Спасибо. В том то и дело что самому хочется разобраться, поэтому позвольте спросить :
1. вот это что uint8_t ?
2. if( blink_mode & 1<<(blink_loop&0x07) ) вот эти красным переменные что означают ? и почему & одиночная, а << двойная. на ARDUINO.Ru я ответа не нашел .
3.Timer1.initialize(125000) вот эта красным переменная что означает?

Понятно дело можете махнуть рукой объяснять тебе нуб очевидные вещи. Скажите что почитать я и этому буду рад.
 

Сергей_Ф

Moderator
Команда форума
@dimanoid 999
1. Давай я поищу в Яндекс вместо тебя
2. Просто константы 1 и 7 в шестнадцатиричном виде. Потому что такие операнды << и &
(blink_loop&0x07) это равносильно нахождению остатка от деления на 7, нам нужны только цифры от 0 до 7
1<<(blink_loop&0x07) сдвигаем влево 1-цу на остаток от деления - таким образом выбираем нужный бит в маске
( blink_mode & 1<<(blink_loop&0x07) ) из маски выбираем нужный бит и делаем выбор оператором if, если он не равен 0
3. Константа - задает коэффициент, кажется
а вообще с Вашим багажом знаний надо читать книжки по языку C и C++. Благо их в сети полно. Если совсем просто, то на arduino.ru свет клином не сошелся, есть первоисточник arduino.cc . А если плохо с английским, то хотя бы arduino.ua .
 
Последнее редактирование:

nikolz

Well-known member
uint8_t -это определение типа данных - беззнаковый байт(8бит) т е страший бит не является знаком числа.
& - побитовое И
Выбирайте учебник на свой вкус и цвет и учите мат часть:
http://cppstudio.com/
 

Casper

Member
Есть ли rtos для esp в среде Arduino ide? И как работать с таймерами, что бы можно было создать диспетчер задач! На avr использовал диспетчер задач, удобная штука. Его брал с сайта easyelectronics и его так же встраивал в Arduino, прямо в системные файлы, там где таймер 0 на прерывание 1мс настроен под функцию delay. Сейчас так же хочется сделать для esp. Кто, что подскажет? Может есть варианты готовые и проще?
 

nikolz

Well-known member
Есть ли rtos для esp в среде Arduino ide? И как работать с таймерами, что бы можно было создать диспетчер задач! На avr использовал диспетчер задач, удобная штука. Его брал с сайта easyelectronics и его так же встраивал в Arduino, прямо в системные файлы, там где таймер 0 на прерывание 1мс настроен под функцию delay. Сейчас так же хочется сделать для esp. Кто, что подскажет? Может есть варианты готовые и проще?
и non-os и в любой ос уже есть диспетчер задач его не надо вставлять.
Другое дело, что на ардуине он спрятан.
Совет простой - пишите на СИ. Если у Вас не более 3 задач то вполне подойдет non-os - работать проще и это решение компактнее.
 

Casper

Member
и non-os и в любой ос уже есть диспетчер задач его не надо вставлять.
Другое дело, что на ардуине он спрятан.
Совет простой - пишите на СИ. Если у Вас не более 3 задач то вполне подойдет non-os - работать проще и это решение компактнее.
Я имел ввиду либо rtos использовать, либо диспетчер задач. Скорее всего больше 3 задач будет.. Вполне должно хватить диспетчера задач, вот только в системные файлы не очень хочется лезть, чтобы его туда встраивать. Есть ли в esp свободный таймер, чтобы настроить его на прерывание от 1 до 10 мс.?
 

nikolz

Well-known member
Я имел ввиду либо rtos использовать, либо диспетчер задач. Скорее всего больше 3 задач будет.. Вполне должно хватить диспетчера задач, вот только в системные файлы не очень хочется лезть, чтобы его туда встраивать. Есть ли в esp свободный таймер, чтобы настроить его на прерывание от 1 до 10 мс.?
Так non-os это и есть диспетчер задач. Вообще любая ос - это и есть диспетчер задач.
Вы не путаете задачи с колбеками - обработчиками событий.
В том числе по таймеру.
Это Все уже есть. Не надо ничего городить это вам не AVR.
 
Сверху Снизу