Есть 4 светодиода. Мне надо чтобы 1 светодиод горел 8 секунд, а остальные 3 по 500 миллисекунд. Как это сделать? Код:
byte r1 = 2;
byte y1 = 3;
byte b1 = 4;
byte r2 = 5;
void setup() {
pinMode(r1, OUTPUT);
pinMode(y1, OUTPUT);
pinMode(b1, OUTPUT);
pinMode(r2, OUTPUT);
}
void Svet1()
{
digitalWrite(r2, LOW);
digitalWrite(r1, HIGH);
}
void Svet2()
{
digitalWrite(r1, LOW);
digitalWrite(y1, HIGH);
}
void Svet3()
{
digitalWrite(y1, LOW);
digitalWrite(b1, HIGH);
}
void Svet4()
{
digitalWrite(b1, LOW);
digitalWrite(r2, HIGH);
}
void loop() {
}
Вот часть библиотеки, использующей сторожевой таймер для этой цели
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned long int cikle;
class Interval{
unsigned long int temp;
bool f1;
public:
bool interval(unsigned int time, void (*func)(),bool f=1); //выполнение функции через определённые интервалы времени (мс). должна находиться в цикле
};
void delay(unsigned long int time); //создание задержки (мс)
void wBegin(); //инициализация сторожевого таймера
unsigned long int getCicle(); //возвращает время(кратное 16) в миллисекундах с начала запуска программы
//################################################
ISR(WDT_vect)
{
cikle+=16;
}
unsigned long int getCicle(){
return cikle;}
void wBegin(){
WDTCSR |= 1 << WDCE;
WDTCSR |= 0b01000000; // 1 переполнение -- 16 мс
sei();
}
void delay(unsigned long int time){
unsigned long int t=getCicle();
while(getCicle()-t<(time));
return;
}
bool Interval::interval(unsigned int time, void (*func)(),bool f) {
if (f) {
if(f1){
f1 = 0;
temp = getCicle();
func();
return 1;
}
else {
if (getCicle() - temp >= time)f1 = 1;
return 0;
}
}
return 0;
}
Если вставить её в начало или вынести в отдельную библиотеку , то дальше можно сделать так
//тут вставить верхний код
byte r1 = 2;
byte y1 = 3;
byte b1 = 4;
byte r2 = 5;
boolean L1 = 0;
boolean L2 = 0;
boolean L3 = 0;
boolean L4 = 0;
void Svet1();
void Svet2();
void Svet3();
void Svet4();
Interval Led1, Led2, Led3, Led4;
void setup() {
pinMode(r1, OUTPUT);
pinMode(y1, OUTPUT);
pinMode(b1, OUTPUT);
pinMode(r2, OUTPUT);
wBegin();
}
void loop() {
Led1.interval(8000,Svet1,1);
Led1.interval(500,Svet2,1);
Led1.interval(500,Svet3,1);
Led1.interval(500,Svet4,1);
}
void Svet1()
{
if(L1) digitalWrite(r1, HIGH);
else digitalWrite(r1, LOW);
}
void Svet2()
{
if(L2) digitalWrite(r2, HIGH);
else digitalWrite(r2, LOW);
}
void Svet3()
{
if(L3) digitalWrite(r3, HIGH);
else digitalWrite(r3, LOW);
}
void Svet4()
{
if(L4) digitalWrite(r4, HIGH);
else digitalWrite(r4, LOW);
}
Я бы сделал так: создал структуру с двумя полями. Первое: описание состояния светодиодов (горит/не горит) второе: длительность работы этого состояния. Объединил все состояния в массив. В обработчике таймера сделал счетчик, который сравнивал с длительностью текущего состояния. Если меньше - выходим из обработчика, увеличив счетчик. Если равно (или больше) - счетчик в ноль, переходим к следующему состоянию, зажигаем светодиоды так, как записано в структуре. Ну, и, конечно, нужна переменная статик с номером текущего состояния. Вот набросок кода:
struct SD { // Структура, описывающая состояние светодоидов.
bool sd1;
bool sd2;
bool sd3;
bool sd4
}
struct States { // Состояние сисетмы и длительность состояния.
SD state;
int time;
}
State[5] stm; // Набор сосятояний.
interrupt Timer1 {
static int curr_state = 0; // Текущее состояние
static unsigned int count; // время с начала состояния
if (count >= stm[curr_state]) {
curr_state = (curr_state >=4) ? 0 : (++curr_state);
count = 0;
// Здесь выполняем установку нового состояния диодов
}
else ++count;
}
Когда-то давно вендингом занимался, тоже надо было написать легковестную библиотеку которая бы не блокировала основной поток Delay'ями
https://github.com/latdev/eugenetaskstool
Вот пример использования
#include <ectask.h>
TasksTool timelib;
void Once30sec() {
Serial.println("This will run once 30 seconds from Arduino starts");
timelib.once(1000, ThisWillRunOnceAfter30SecondOnce);
}
void Every15sec() {
Serial.println("This will runs every 15 seconds");
}
void Every40sec() {
Serial.println("This will runs every 40 seconds");
timelib.once(1000, ThisWillRunNotOnceAfter40SecondOnce);
}
void ThisWillRunNotOnceAfter40SecondOnce() {
Serial.println("One second after 40 passed");
}
void ThisWillRunOnceAfter30SecondOnce() {
Serial.println("One second after 30 passed");
}
void setup() {
Serial.begin(9600);
timelib.once(30000, Once30sec);
timelib.every(15000, Every15sec);
timelib.every(40000, Every40sec);
}
void loop() {
timelib.loop(); // This is important part of timers
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как найти и вывести на экран, например, три максимальных или минимальных элемента массива, на языке программирования "Си"? Например массив,
Посоветуйте какой стек сейчас популярен для web разработки на java, и с чего лучше начать учить