Как мигать светодиодом на Ардуино: 3 варианта

Светодиод Программирование

Казалось бы, что может быть проще, чем мигание светодиода?

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

В данной статье рассмотрим множество способов и вариаций программы, выполняющей мигание диодом.

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

void setup() {

pinMode(13, OUTPUT);

}

void loop() {

digitalWrite(13,1);

delay(500);

digitalWrite(13,0);

delay(500);

}

то же самое, но с использованием пинов:

void setup() {

pinMode(13, OUTPUT);

digitalWrite(13, LOW);

}

void loop() {

digitalWrite(13,HIGH);

delay(500);

digitalWrite(13,LOW);

delay(500);

}

Также, данную программу можно написать с использованием флагов, чем мы упростим ее:

void setup() {

pinMode(13, OUTPUT);

}

boolean flag = 0;

void loop() {

digitalWrite(13, flag = !flag);

delay(500);

}

Мигание светодиодом с использованием функции digitalRead. Подадим любое значение на пин, а затем прочитаем его:

void setup() {

pinMode(13, OUTPUT);

}

void loop() {

digitalWrite(13, digitalRead(13));

delay(500);

}

Команду “мигать” светодиоду можно дать без использования встроенных функций библиотеки Arduino:

#include <util/delay.h>

int main() {

DDRB |= (1 << PB5);

for (;;) {

PORTB |= (1 << PB5);

_delay_ms(500);

PORTB &= ~(1 << PB5);

_delay_ms(500);

}

}

В следующей программе просим светодиод мигать при помощи счетчика:

void setup() {

pinMode(13, 1);

EECR |= (1 << EERIE) | (1 << EERE);

}

volatile uint32_t top = 50000;

volatile uint32_t counter = 0;

ISR(EE_READY_vect) {

EECR |= (1 << EERE);

if (++counter >= top) {

counter = 0;

digitalWrite(13, !digitalRead(13));

}

}

Прицепим тон на 2 и 5 пин, затем подключим внешнее аппаратное прерывание и создадим счетчик:

void setup() {

pinMode(13, 1);

pinmode(5, 1);

tone(5, 32);

attachInterrupt(0, isr, RISING);

}

uint32_t count = 0;

void isr() {

if (++count >= 10) {

count = 0;

digitalWrite(13, !digitalRead(13));

}

}2 9

Воспользуемся функцией Assembler Jump(asm volatile (“jmp 0x0000”)) для возврата в начало команды без сбрасывания регистров(выходных данных):

void setup() {

pinMode(13, 1);

digitalWrite(13, !digitalRead(13));

delay(500);

asm volatile(“jmp 0x0000”);

}

void loop() {

}

Подсоединяем к любом пинам тон, затем после задержки читаем состояние пина:

#include <EEPROM.h>

void setup() {

byte state = EEPROM.read(0);

pinMode(13, 1);

digitalWrite(5, 1);

pinMode(5, 1);

digitalWrite(13, state);

state = !state

EEPROM.write(0, state);

delay(500);

digitalWrite(5, 0);

}

void loop() {

}

От автора: Советую остановить свое изучение данной темы на этом моменте, поскольку все, что идёт далее-нужно скорее всего не радиолюбителям, а тем, кто планирует создавать крупные системы типа автосигнализации или RGB подсветки. Дальнейшие действия очень сложны для понимания и требуют очень много времени. К тому же, мощность Ардуино ограничена, возможны различные ошибки из-за недостатка памяти.3 6

Задача с “часами”

Понимаю, что данный способ для понимания довольно сложен, но постараемся донести его. Для начала, мы настраиваем пин как выход. Затем включаем в цикле диод командой SBI, вызываем задержку, после чего “гасим” наш светодиод и вызываем переход с данного цикла. Далее, наш код похож чем то на обычные часы. Когда секундная стрелка делает полный оборот, то минутная-делает небольшой шаг.

void setup() {

asm volatile

(

“setup: \n\t”

“SBI %[DDR], %[PIN] \n\t” //Настраиваем PIN как выход(PB5 как OUTPUT)

“loop: \n\t”

“SBI %[PORT], %[PIN] \n\t” //Включаем диод командой SBI(PB5 в HIGH)

“CALL delay \n\t” //Задержка

“CBI %[PORT], %[PIN] \n\t” //”Гасим” светодиод(PB5 в LOW)

“CALL delay \n\t” //Задержка

«RJMP loop \n\t» //повторение цикла, Jump с одного на другой

«delay: \n\t» //

«LDI r16, 0x00 \n\t»

«LDI r17, 0xD4 \n\t»

«LDI r18, 0x30 \n\t»

«delay_loop: \n\t»

«SUBI r16, 1 \n\t»

«SBCI r17, 0 \n\t»

«SBCI r18, 0 \n\t»

«BRNE delay_loop \n\t»

«RET \n\t»

:

: [PORT] «I» (_SFR_IO_ADDR(PORTB)),

[DDR] «I»(_SFR_IO_ADDR(DDRB)),

[PIN] «I»(PB5)

:»r16″, «r17», «r18»

);

}

Обрабатываем битовую матрицу состояния светодиода. Просто делаем “нарастание вспышек”.4 7

Введем несколько состояний светодиода-будем обрабатывать битовую матрицу, уменьшая время срабатывания события до 0.125 секунд и в 1 байт вкладываем 8 битов состояний.

byte modes[] = {

0B00000000, //выключен

0B11111111, //постоянно

0B00001111, //Мигание по 0.5 сек

0B00000001, //Короткая вспышка раз в секунду

0B00000101, //Две вспышки раз в секунду

0B00010101, //Три вспышки раз в секунду

0B01010101 //Частые короткие вспышки (4 раза в секунду)

};

uint32_t ms, ms1 = 0, ms2 = 0;

uint8_t blink_loop = 0;

uint8_t blink_mode = 0;

uint8_t modes_count = 0;

void setup() {

pinMode(13, OUTPUT);

digitalWrite(13, LOW);

modes_count = 1;

blink_mode = modes[modes_count];

}

void loop() {

ms = millis();

// срабатывает 125 мс

if( ( ms — ms1 ) > 125|| ms < ms1 ){

ms1 = ms;

// битовая маска используется для поиска состояния

if( blink_mode & 1<<(blink_loop&0x07) ) digitalWrite(13, HIGH);

else digitalWrite(13, LOW);

blink_loop++;

}

 

// демонстрация переключения режимов

// меняем эффект раз в 5 сек.

if( ( ms — ms2 ) > 5000|| ms < ms2 ){

ms2 = ms;

blink_mode = modes[modes_count++];

if( modes_count >= 7 )modes_count = 1;

}

}

Тоже самое с использованием библиотеки Ticker для платы ESP8266:

#include <Ticker.h>

 

uint8_t blink_loop = 0;

uint8_t blink_mode = 0;

uint8_t modes_count = 0;

 

Ticker blinker;

 

void timerIsr()

{

if( blink_mode & 1<<(blink_loop&0x07) ) digitalWrite(13, HIGH);

else digitalWrite(13, LOW);

blink_loop++;

}

 

void setup() {

pinMode(13,OUTPUT);

blink_mode = 0B00000000;

blinker.attach(0.125, timerIsr);

}

 

void loop() {

blink_mode = 0B00001111; //Мигание по 0.5 сек

delay(5000);

blink_mode = 0B00000001; //Короткая вспышка раз в секунду

delay(5000);

blink_mode = 0B00000101; //Две короткие вспышки раз в секунду

delay(5000);

blink_mode = 0B00010101; //Три короткие вспышки раз в секунду

delay(5000);

blink_mode = 0B01010101; //Частые короткие вспышки (4 раза в секунду)

delay(5000);

}

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

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

Оцените статью
Информация об Ардуино
Добавить комментарий

Нажимая на кнопку "Отправить комментарий", я принимаю политику конфиденциальности.