Доброго времени и пространства неравнодушным!) Бъюсь над задачей входа/выхода микроконтроллера в режим сна при долгом нажатии кнопки(3секунды например). Пока делаю на arduino. - Нашел скетч для засыпания, работает. - Сделал скетч для долгого нажатия с использованием millis. Помогите правильно объединить!!! КНОПОШНЫЙ КОД вот: Код (C++): const int ledPin = 13; int buttonPin = 3; //choose the input pin for a pushbutton int buttonVal = 1; int ledState = HIGH; // этой переменной устанавливаем состояние светодиода unsigned long previousMillis = 0; // храним время последнего переключения светодиода unsigned long interval = 3000; void setup() { pinMode(ledPin, OUTPUT); pinMode(buttonPin, INPUT); Serial.begin(9600); } void loop(){ unsigned long currentMillis = millis(); buttonVal = digitalRead(buttonPin); if(currentMillis - previousMillis < 10) { ledState = HIGH; } if(buttonVal == HIGH && ledState == HIGH && currentMillis - previousMillis >= interval) { digitalWrite(ledPin, HIGH); ledState = LOW; } if(buttonVal == LOW && ledState == LOW && currentMillis - previousMillis >= interval) { digitalWrite(ledPin, LOW); previousMillis = currentMillis; ledState = HIGH; } if(buttonVal == LOW && ledState == HIGH && currentMillis - previousMillis < interval) { digitalWrite(ledPin, LOW); ledState = LOW; } if(buttonVal == HIGH && ledState == LOW && currentMillis - previousMillis < interval) { digitalWrite(ledPin, LOW); previousMillis = currentMillis; ledState = HIGH; } } примерный СОННЫЙ КОД вот: Код (C++): #include <avr/sleep.h> unsigned long eventTime = 0; int buttonstate = 0; int wakePin = 2; // pin used for waking up int sleepStatus = 0; // variable to store a request for sleep int count = 0; // counter const int buttonPin = 0; void wakeUpNow() // here the interrupt is handled after wakeup { } void setup() { pinMode(buttonPin, INPUT); pinMode(wakePin, INPUT); Serial.begin(9600); attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function // wakeUpNow when pin 2 gets LOW } void sleepNow() // here we put the arduino to sleep { set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here sleep_enable(); // enables the sleep bit in the mcucr register // so sleep is possible. just a safety pin attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function // wakeUpNow when pin 2 gets LOW sleep_mode(); // here the device is actually put to sleep!! // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP sleep_disable(); // first thing after waking from sleep: // disable sleep... detachInterrupt(0); // disables interrupt 0 on pin 2 so the // wakeUpNow code will not be executed // during normal running time. } void loop() { int reading = analogRead(buttonPin); // проверял, работает ли ацп Serial.println(reading); if (Serial.available()) { int val = Serial.read(); if (val == 'S') { Serial.println("Serial: Entering Sleep mode"); delay(100); // this delay is needed, the sleep //function will provoke a Serial error otherwise!! sleepNow(); // sleep function called here } } }
трудновато будет, ибо в скетче c millis накручена какая-то непонятная хрень, явно более сложная. чем просто удержание кнопки... поищите другой пример и, кстати. неясно почему вы поместили это в раздел микроконтроллеры... надо было в самый первый. для чайников, так как вопрос соответсвующий. из разряда "я нуб и не хочу учиться. напишите за меня"
Не знаете как отличить короткое нажатие от длинного? Кстати, про спящий режим. Он имеет смысл только при отключении периферии, даже у Уно разница в потреблении почти не заметна. Делать будете на голом МК?
это мне или ТС? Странная логика. "Даже у Уно". У модельных плат разница именно потому и невелика, что основными потребителями там является "обвязка" - светодиоды, USB-модуль и схема питания, которые не зависят от режима сна. А на голом МК можно получить очень интересные результаты. И не так уж "не заметна" разница даже на ардуинах. Заметна и весьма. На Нано без отключения периферии, даже без удаления светодиодов и регулятора напряжения спящий режим в несколько раз экномичнее дефолтного. Понятно, что ни о какой длительной работе речь не идет, но говорить, что 50ма и 8 - это не разница?
Вот так "в целом" работает, но цикл loop не повторяется. Можно включить светодиод прерыванием и усыпить через millis, удерживая 3с. Есть супермозги, кто поможет докрутить? ; -) Микроконтроллер Attiny84 + nrf24 и все работает. Вот только цифровой кнопки вкл/выкл нехватает ну очень!! И да, наворотил там условий.. Изначально не прогер, буду рад решению поизящнее!) Код (C++): #include <avr/sleep.h> #include <SoftwareSerial.h> int buttonVal = 1; int ledState = HIGH; // этой переменной устанавливаем состояние светодиода unsigned long previousMillis = 0; // храним время последнего переключения светодиода unsigned long interval = 3000; int ledPin = 10; int wakePin = 2; // pin used for waking up int sleepStatus = 0; // variable to store a request for sleep int count = 0; // counter int APin = 9; int analog = 1; void wakeUpNow() // here the interrupt is handled after wakeup { } SoftwareSerial mySerial (0, 1); // Rx, Tx void setup() { pinMode(wakePin, INPUT); pinMode(ledPin, OUTPUT); pinMode(APin, INPUT); mySerial.begin(9600); attachInterrupt(0, wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function // wakeUpNow when pin 2 gets LOW } void sleepNow() // here we put the arduino to sleep { set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here sleep_enable(); // enables the sleep bit in the mcucr register // so sleep is possible. just a safety pin attachInterrupt(0,wakeUpNow, LOW); // use interrupt 0 (pin 2) and run function // wakeUpNow when pin 2 gets LOW sleep_mode(); // here the device is actually put to sleep!! // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP sleep_disable(); // first thing after waking from sleep: // disable sleep... detachInterrupt(0); // disables interrupt 0 on pin 2 so the // wakeUpNow code will not be executed // during normal running time. } void loop(){ //analog = digitalRead(APin); buttonVal = digitalRead(wakePin); unsigned long currentMillis = millis(); if(buttonVal == LOW && ledState == HIGH && currentMillis - previousMillis < interval) { digitalWrite(ledPin, HIGH); delay(900); ledState = HIGH; } if(buttonVal == HIGH && ledState == HIGH && currentMillis - previousMillis < interval) { ledState = HIGH; sleepNow(); previousMillis = currentMillis; } if(buttonVal == LOW && ledState == HIGH && currentMillis - previousMillis >= interval) { digitalWrite(ledPin, LOW); ledState = LOW; delay(1000); } if(buttonVal == LOW && ledState == LOW && currentMillis - previousMillis >= interval) { previousMillis = currentMillis; ledState = HIGH; } if(buttonVal == LOW && ledState == LOW && currentMillis - previousMillis < interval) { previousMillis = currentMillis; ledState = HIGH; } }