millis() не могу разобраться
- Войдите на сайт для отправки комментариев
Пт, 15/01/2021 - 20:53
Объясните пожалуйста на примере данного кода, как работает millis()?
const int ledPin12 = 12;
const int ledPin13 = 13;
const int vhod_9 = 9;
unsigned long last_time;
void setup() {
pinMode (ledPin12, OUTPUT);
pinMode (ledPin13, OUTPUT);
pinMode (vhod_9, INPUT);
}
void loop() {
if (digitalRead(vhod_9))
{digitalWrite(ledPin12, HIGH);
digitalWrite(ledPin13, LOW);
if (millis() - last_time >= 1000){
digitalWrite(ledPin12, LOW);
digitalWrite(ledPin13, HIGH);
last_time = millis();
if (millis() - last_time >= 1000){
digitalWrite(ledPin12, HIGH);
digitalWrite(ledPin13, LOW);
}}}}
написал это просто, что бы попробовать разобраться, ибо никак не могу понять.
По моей идее при подаче на вход 9 светодиод на 12 должен гореть, на 13 не гореть и через секунду наоборот. Что я делаю не так?
А почитать про "великое переполнение миллис"? Да и вообще - про правила форума - лениво?
И, кстати void loop() работает по кругу, а не так, как Вам кажется.
Здравствуйте, спасибо за ответ. Великое переполнение millis() это же вроде которое через 49,7 дней не?
Про void loop я вкурсе, такой конец у кода, потому что нифега не работало (и не работает), просто попробовал дописать.
Миллис работает так: каждую миллисекунду возвращаемое значение увеличивается на 1.
Т.е. в любой момент времени millis() возвращает количество миллисекунд прошедшее с начала старта программы.
Теперь зная это самостоятельно сможете разобраться как с помощью этого значения замерять нужные отрезки времени ?
Запомнили сколько было, при начале замера, сравниваем с тем, сколько сейчас, когда дошли до нужной разницы, что то делаем
Что я делаю не так?
Правила не читаете, код вставляете неправильно.
const int ledPin12 = 12; const int ledPin13 = 13; const int vhod_9 = 9; unsigned long last_time; void setup() { pinMode (ledPin12, OUTPUT); pinMode (ledPin13, OUTPUT); pinMode (vhod_9, INPUT); } void loop() { if (digitalRead(vhod_9)) {digitalWrite(ledPin12, HIGH); digitalWrite(ledPin13, LOW); if (millis() - last_time >= 1000){ digitalWrite(ledPin12, LOW); digitalWrite(ledPin13, HIGH); last_time = millis(); if (millis() - last_time >= 1000){ digitalWrite(ledPin12, HIGH); digitalWrite(ledPin13, LOW); }}}}Прошу прощения.
Спасибо за ответ, да я вроде это понимаю, не понимаю, почему в данном коде это не работает.
переменная last_time при объявление должна ровняться нулю же вроде, а millis увеличивается каждую миллисекунду на 1.
А почему 18-я строка, а не 22-я? Какой тут императив?
А вообще - бред. Можете простыми словами описать то, что Вы хотите сделать? В программе - бредятина.
Скобки нужны в правильных местах согласно задуманному алгоритму, а строки 19-21 вообще лишние, достаточно в строках 16 17 написать digitalWrite(13, !digitalRead(13)); строки 13 14 перенести в сетап.
Спасибо за ответ, да я вроде это понимаю, не понимаю, почему в данном коде это не работает.
переменная last_time при объявление должна ровняться нулю же вроде, а millis увеличивается каждую миллисекунду на 1
Таких строки две. Одна не будет работать никогда.
Он написал в первом комментарии темы, что хочет чтобы вроде 10, 11, 12 светодиоды через промежутки времени зажигались. Хочет короче попробовать delay() на millis() поменять
Напишу Вам алгоритм, а Вы его запрограммируйте.
При инициации горит А, Б, не горит В: считываем миллис
В основной программе
Если ((миллис-минус-считыная миллис) больше (какое-то там значение)){
Меняем значение всех пинов на противоположные
считываем миллис
}
Ты ещё кнопку забыл, после нажатия которой должно происходить всё остальное.
const int ledPin12 = 12; const int ledPin13 = 13; const int vhod_9 = 9; unsigned long last_time; void setup() { pinMode (ledPin12, OUTPUT); pinMode (ledPin13, OUTPUT); pinMode (vhod_9, INPUT); } void loop() { if (digitalRead(vhod_9)) { digitalWrite(ledPin12, HIGH); digitalWrite(ledPin13, LOW); if (millis() - last_time >= 1000) { digitalWrite(ledPin12, LOW); digitalWrite(ledPin13, HIGH); last_time = millis(); if (millis() - last_time >= 1000) { digitalWrite(ledPin12, HIGH); digitalWrite(ledPin13, LOW); } } } }Прошу прощения.
Ты ещё кнопку забыл, после нажатия которой должно происходить всё остальное.
Пусть без кнопки напишет. Потом добавит.Дам одно "если" и одна переменная
Она уже была в программе - строка 12.
Она уже была в программе - строка 12.
И правда! О как!
Ну допишите алгоритм! Это-ж легко!
Я уже всё расписал в #8 Сделать эти исправления и заработает как надо.
Как то так
const int ledPin12 = 12; const int ledPin13 = 13; const int vhod_9 = 9; unsigned long last_time; bool f_kn = 0; void setup() { pinMode (ledPin12, OUTPUT); pinMode (ledPin13, OUTPUT); pinMode (vhod_9, INPUT); } void loop() { if (digitalRead(vhod_9) && f_kn == 0) { f_kn = 1; last_time = millis(); //Засекаем время digitalWrite(ledPin12, HIGH); digitalWrite(ledPin13, LOW); } if (f_kn == 1) { if (millis() - last_time >= 1000) { //проверяем прошла ли секунда digitalWrite(ledPin12, LOW); digitalWrite(ledPin13, HIGH); f_kn = 0; } } }Я уже всё расписал в #8 Сделать эти исправления и заработает как надо.
Да ну!
void loop(){ oldmillis=millis(); while(knopka){ if(millis()-oldmillis>mytimes){ digitalWrite(A, !digitalRead(A)); ..... oldmillis=millis(); } } }И кстати еще интересней так:
void loop(){ while(!knopka){ digitalWrite(A, "к примеру 1")); ..... } oldmillis=millis(); while(knopka){ if(millis()-oldmillis>mytimes){ digitalWrite(A, !digitalRead(A)); ..... oldmillis=millis(); } } }Привет, всем спасибо за ответы!
Этот код:
Как то так
const int ledPin12 = 12; const int ledPin13 = 13; const int vhod_9 = 9; unsigned long last_time; bool f_kn = 0; void setup() { pinMode (ledPin12, OUTPUT); pinMode (ledPin13, OUTPUT); pinMode (vhod_9, INPUT); } void loop() { if (digitalRead(vhod_9) && f_kn == 0) { f_kn = 1; last_time = millis(); //Засекаем время digitalWrite(ledPin12, HIGH); digitalWrite(ledPin13, LOW); } if (f_kn == 1) { if (millis() - last_time >= 1000) { //проверяем прошла ли секунда digitalWrite(ledPin12, LOW); digitalWrite(ledPin13, HIGH); f_kn = 0; } } }Зажигает светодиод на 12 и примерно через 3 сек. он тухнет и загорается на 13ти. Не понятно почему. В коде мне вроде бы всё понятно, кроме того почему он не работает.
Этот код:
Дерьмовый. Плохо читали.
Привет всем. Я новенький, первый раз на форуме. Совсем недавно начал изучать ардуино. Есть вопрос по синхронизации мигания светодиодов на 3 ардуино. Суть в чём, есть 3 платы (самопал аля UNO). На каждой реле, светодиод в роли маяка, модуль nRF24 и датчик. Запустили платы в разное время. На каждой плате, датчик мониторит вокруг на наличие "посетителей", при обнаружении "коих" через него, плата подаёт команду по nRF (работаю как и должны китайские модули) остальным платам включить реле на Н-секунд. Маяки на платах начинают синхронно мигать (+-0,05 сек), НО вот при выключении реле появляется рассинхрон в их мигании на платах. Мигание маяками сделано через millis. Понимаю, что проблема как раз в этом зарыта. Можете объяснить, чего не учёл.
// библиотеки #include <SPI.h> #include <nRF24L01.h> #include <RF24.h> RF24 radio(9, 10); // CE - CSN // вводим директивы имён #define adres1 0xAABBCCDD11LL #define adres2 0xAABBCCDD22LL #define adres3 0xAABBCCDD33LL #define mayak 5 #define rele 7 #define datchik A0 // данные и переменные int val; // переменная для датчика int data[1]; //массив отправки по РД int kodProverki = 777; //код передачи и проверки данных int lvlSrab = 100; //уровень срабатывания по датчику int timeRele = 25; //время работы реле int a = 0; // переменная для цикла // мигающий светодиод для визуального контроля работы int mayakOn = 150; // светодиод включен int mayakOff = 850; // светодиод выключени bool statusMayak; // переменная статуса маяка uint32_t timerMayak; // переменная отсчета millis для маяка void setup() { delay(3000); //задержка перед началом работы //натройка пинов МК pinMode(rele, OUTPUT); // пин реле на выход digitalWrite(rele, LOW); // начальное состояние реле - выклюяено pinMode(mayak, OUTPUT); // пин светодиода digitalWrite(mayak, statusMayak = LOW); // светодиод выключен, задан статус //Serial.begin(9600); // настройка монитора порта //настройка модуля nRF24 radio.begin(); //инициализация модуля radio.setChannel (120); // канал работы (0-127) (115 - 127 без wifi) radio.setDataRate (RF24_250KBPS); // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS) radio.setPALevel (RF24_PA_MAX); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm) //выбираем адреса прослушиваемых труб //radio.openReadingPipe (1, adres1); // Открываем 1 трубу с идентификатором 1 передатчика 0xAABBCCDD11, для приёма данных radio.openReadingPipe (2, adres2); // Открываем 2 трубу с идентификатором 2 передатчика 0xAABBCCDD22, для приёма данных radio.openReadingPipe (3, adres3); // Открываем 3 трубу с идентификатором 3 передатчика 0xAABBCCDD33, для приёма данных //включаем режим приемника, слушаем выбранные трубы radio.startListening (); } void RELE() //срабатывание реле { digitalWrite(rele, HIGH); //включаем реле for( a; a < timeRele; a++) //цикл для отработки реле положенного времени { digitalWrite(mayak, HIGH); delay(mayakOn); digitalWrite(mayak, LOW); delay(mayakOff); //Serial.println(a); // контроль действий по монитору порта } digitalWrite(rele, LOW); a = 0; } void PEREDACHA() // перевод в режим передатчика и отправка данных { // т.к. модули ПОЛУДУПЛЕКСНЫЕ, то работаем по следующему алгоритму radio.stopListening(); //выключаем режим передатчика //Serial.println("выключаем прослушивание"); // контроль действий по монитору порта /* radio.openWritingPipe(adres1); // открывание для передачи 1 трубу radio.write(data, 1); // передаем данные по 1 трубе delay(50); //задержка для передачи Serial.println("передали по 1 трубе"); // контроль действий по монитору порта */ radio.openWritingPipe(adres2); // открываем для передачи 2 трубу radio.write(data, 1); // передаем данные по 2 трубе delay(50); // задержка для передачи //Serial.println("передали по 2 трубе"); // контроль действий по монитору порта radio.openWritingPipe(adres3); // открываем для передачи 3 трубу radio.write(data, 1); // передаем данные по 3 трубе delay(50); // задержка для передачи //Serial.println("передали по 3 трубе"); // контроль действий по монитору порта } void PRIEMNIK() // перевод в режим приемника для прослушивания данных { //radio.openReadingPipe (1, adres1); radio.openReadingPipe (2, adres2); radio.openReadingPipe (3, adres3); radio.startListening(); //Serial.println("слушаем эфир"); } void MAYAK() { if(millis() - timerMayak > (statusMayak ? mayakOn : mayakOff)) // если разница будет больше, то { statusMayak = !statusMayak; // инвертируем статус маяка digitalWrite(mayak, statusMayak); // выводм на пин маяка его статус (вкл или выкл) timerMayak = millis(); // сбрасываем таймер отсчета } } void loop() { val = analogRead(datchik); if( val < lvlSrab) { data[0] = kodProverki; // назначаем в данные код PEREDACHA(); RELE(); PRIEMNIK(); timerMayak = millis(); } if(radio.available()) // проверяем буфер на имеющиеся принятые данные, если они есть, то { radio.read(data,1); // читаем данные if(data[0] == kodProverki) // сверяем пришедшие данные с теми что есть, если равны то { RELE(); } } MAYAK(); }Стандартная практика: ОДНА ардуина должна всем посылать синхроимпульсы, не надеясь на их внутренний millis(), иначе будешь наблюдать такие Лиссажу, как наблюдаешь сейчас.
Стандартная практика: ОДНА ардуина должна всем посылать синхроимпульсы, не надеясь на их внутренний millis(), иначе будешь наблюдать такие Лиссажу, как наблюдаешь сейчас.
Поскольку радиомодули nRF24L01+ полудуплексные ,то пока не представляю, как одна ардуино может получить команду на включение реле, если она не в режиме приёмника, а в режиме передатчика (который передаёт синхроимпульсы остальным). Возможно ли синхронизировать по радиокоманде millis не через WDT?
Думай. На то тебе и образование дадено.
Корифеи, вы таки будете смеяться, но у меня только что возник академический интерес в теме, смежной с micros()!! :-D
Сейчас рядом тему заппилю
[/quote]
Зажигает светодиод на 12 и примерно через 3 сек. он тухнет и загорается на 13ти. Не понятно почему. В коде мне вроде бы всё понятно, кроме того почему он не работает.
[/quote]
По моей идее при подаче на вход 9 светодиод на 12 должен гореть, на 13 не гореть и через секунду наоборот. Что я делаю не так?
И что там не так РАБОТАЕТ
Поскольку радиомодули nRF24L01+ полудуплексные ,то пока не представляю, как одна ардуино может получить команду на включение реле, если она не в режиме приёмника, а в режиме передатчика (который передаёт синхроимпульсы остальным). Возможно ли синхронизировать по радиокоманде millis не через WDT?
ну как? - передал синхроимпульс и слушаешь до следующего...
Привет всем. Я новенький, первый раз на форуме. Совсем недавно начал изучать ардуино. ...... На каждой реле, светодиод в роли маяка, модуль nRF24 и датчик.
Осмелюсь дать рекомендацию по поводу использования nrf24. Потратил на них впустую много времени. Утром работает, а к обеду нет. К ночи оживает. Меняешь модуль и все по новой. Очень глючные они и нестабильные даже в одной посылке. Заниматься решением проблем с ними - заведомо терять ценное время. Если нужна локальная радиосвязь, я бы смотрел на другие технические решения, благо их много. Тем более у НРФ совсем убогие условия и на топологию, и на протокол.
Если нужна локальная радиосвязь, я бы смотрел на другие технические решения, благо их много.
А можете порекомендовать что-то конкретное (кроме ZigBEE). В дальнейшем планирую использовать LoRa RA-02 (433).
ну как? - передал синхроимпульс и слушаешь до следующего...
Спасибо за совет. Попробую.
А можете порекомендовать что-то конкретное (кроме ZigBEE). В дальнейшем планирую использовать LoRa RA-02 (433).
Использую ESP (8266, 32) во всех проектах. В использовании AVR теперь не вижу никакого смысла. У меня везде покрытие WiFi. И дома и на даче и на работе. Это и определило выбор. Для передачи одиночных пакетов данных использую протокол UDP. О преимуществах пакета UDP над убогим 32-байтным пакетом nRF24 умолчу. Плюс, возможность "из коробки" управлять всем зоопарком устройств хоть blynk'ом, хоть putty. А собственный VPN сильно упрощает адресацию модулей на удаленных территориях - все в одной подсети. Для передачи данных "в поле" без интернета рассматривал LoRa. Даже заказал из китая несколько модулей, но до практической части пока не дошел.
Есть и другие варианты, но я с ними не экспериментировал, поскольку ESP полностью закрыли вопрос межмодульной коммуникации. В одном я убежден - любой из этих вариантов будет заведомо перспективнее nFR24. Не зря даже сам разработчик этого ублюдочного решения, устрашившись содеянного быстро свернул производство. Теперь NRF только из самых трущобных китайских подвалов появляются