Главное - чтобы у гайвера и с этого форума не тырил. А то конец человечеству.
Сижу изучаю тему мигания светодиодом. Вникаю в С++. Прошу подсказать нормальный ли код получился, куда обратить внимание? Вышла мигалка на прерываниях.
#include <Arduino.h>
#define TICKER_UPDATE ISR(TIMER2_COMPA_vect)
#define out(x) pinMode(x, OUTPUT)
#define toggle(x) digitalWrite(x, !digitalRead(x))
class TickerAVR
{
private:
void (*callback)();
uint32_t interval_ms, uint32_t nexttTime;
public:
TickerAVR(void (*callback)(), uint32_t interval_ms) :
callback(callback),
interval_ms(interval_ms),
nexttTime(interval_ms + millis()) {
cli(); // Настраиваем таймер каждую милисекунду
OCR2A = 249; // Устанавливаем значение для сравнения (249 + 1 = 250 циклов; 250 циклов * 4 мкс = 1000 мкс = 1 мс)
TCCR2A |= (1 << WGM21); // Выбираем режим CTC (Clear Timer on Compare Match) для таймера 2
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); // Устанавливаем предделитель на 1024
TIMSK2 |= (1 << OCIE2A); // Разрешаем прерывание по совпадению с OCR2A (TIMER2_COMPA)
sei(); // Включаем прерывания
}
void update() {
if (nexttTime <= millis()) {
callback();
nexttTime += interval_ms;
}
}
~TickerAVR(){
TCCR2A = TCCR2B = 0;
TIMSK2 &= ~(1 << OCIE2A);
}
};
TickerAVR ticker_1s([]{ toggle(LED_BUILTIN); }, 1000);
TICKER_UPDATE { ticker_1s.update(); }
void setup() { out(LED_BUILTIN); }
void loop() { delay(100000); }
Дружище Ученик, ты бы создал отдельную тему где-нибудь в подходящем разделе… что бы не засорять Wiki.
Хотя нет. Она и так уже достаточно засорена.( Продолжай!)
Ну, тренировка в С++ это да. Но, зачем такие сложности для блинка? В чём его такой сакральный смысл?)
Обычно, ведь пишешь что то, типа blink(500); и ниочём не думаешь.
Тогда как #define blink(x) every(x) и всё. А every(x) тоже одна строка. И пофигу С++ там или просто Си. Ну ведь просто же! А тогда зачем усложнять, заради чего?
Правильный блинк масштабируется на сколько угодно светодиодов.
А на таймере - сколько ты светодиодов запустишь?
подсказываю - прерывания лишние
Попробую и я кинуть свой вариант
/*Blink через автомат qwone*/
const byte Led1_Pin =/*пин*/13;
const byte Led1_init = 0;
const byte Led1_ON = 10;
const byte Led1_OFF = 20;
void (*events)() = {};
uint32_t past;
void go(byte s) {
past = millis();
switch (s) {
case Led1_init:
pinMode(Led1_Pin, OUTPUT);
case Led1_ON:
digitalWrite(Led1_Pin, HIGH);
events = {[]()
{
if (millis() - past >= 1000) go(Led1_OFF);
}
};
break;
case Led1_OFF:
digitalWrite(Led1_Pin, LOW);
events = {[]()
{
if (millis() - past >= 1000) go(Led1_ON);
}
};
break;
}
}
void setup() {
go(Led1_init);
}
void loop() {
events();
}
Тема лямбд недостаточно раскрыта.
Если бы мне, в начале пути, показали такой пример блинка, я сказал, да идите вы … с вашей ардуиной и С/С++сами этими.
вроде обычное дело - пойди туда не знаю куда и спроси там куда идти дальше )))
PS то ли дело ассемблер …
void setup() {
// Инициализируем выход LED_BUILTIN как output.
// на платах UNO, Mega, ZERO светодиод на плате подключен к пину 13
// LED_BUILTIN имеет значение пина к которому подключен светодиод на плате
// независимо от используемой платы
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // Включаем светодиод
delay(1000); // пауза 1сек
digitalWrite(LED_BUILTIN, LOW); //выключаем светодиод
delay(1000); // пауза 1сек
}
Да я на это долгооо… смотрел. Думал будет типа : svetodiod (migai!!!);
во во, а дальше понеслись вариации
void setup() {
// Инициализируем выход LED_BUILTIN как output.
// на платах UNO, Mega, ZERO светодиод на плате подключен к пину 13
// LED_BUILTIN имеет значение пина к которому подключен светодиод на плате
// независимо от используемой платы
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); // Переключаем светодиод
delay(1000); // пауза 1сек
}
и т.д.
видим к чему это приводит, в конечном итоге))
Скетч использует 1016 байт (3%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 15 байт (0%) динамической памяти, оставляя 2033 байт для локальных переменных. Максимум: 2048 байт.
Когда классический блинк на миллис:
Скетч использует 860 байт (2%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 15 байт (0%) динамической памяти, оставляя 2033 байт для локальных переменных. Максимум: 2048 байт.
Конечно, ведь определение еще одной функции “подтягивается”…
он про код от qwone1 говорит)
я так думаю…
Так тот код еще и не блокирующий. Но когда в лямду воткнуть еще ассемблер, то мир станет еще красивее.
… и розовые единороги увезут нас в мир молочных рек и кисельных берегов )))
Он же тебя цитировал…
Или только я цитатами не правильно пользуюсь?
на катушку скидку делай))
цитировал меня, а код занимающий 1016 байт , от @qwone1
как ты думаешь, у кого лучше получится засрать мозги новичкам с блинком?
// блинк 1 секунда
uint16_t n = 3032;
ISR( TIMER1_OVF_vect )
{
PORTB ^= 1 << 5;
TCNT1 = n;
}
void setup() {
DDRB = DDRB | 1 << 5;
TCCR1A = 0;
TCCR1B = B00000100;
TIMSK1 = 1 << TOIE1;
TCNT1 = n;
sei();
}
void loop() {
}