Не работает Delay на millis()
- Войдите на сайт для отправки комментариев
Сб, 30/04/2022 - 02:24
Привет друзья.
У меня код любительский, ничего особенного, костыли, как и положено новичку. Но все работает кроме одного - Delay на millis в обозначенный в строках 52-59. Загружаю код, монитор порта пишет ХХХХХХХХХХХХХХ (ну и выполняет остальное что там есть в if) без задержки, но хотелось бы чтобы была задержка в 1 сек. Где подвох?
#include <EEPROM.h>
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const byte interruptPin = 2;
volatile double Micros;
volatile double Last_Micros;
volatile double T;
float Wheel_Speed = 0;
volatile double Flag;
volatile double LastFlag;
float ODO;
byte Array [10];
volatile float k = 0.0000580952380952381;
void blink();
byte Time_NoSpeed = 0;
double timing;
volatile bool Flag2;
double timing2;
float V; //Battery Voltage
double timer;
void setup() {
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
pinMode (3,OUTPUT);
lcd.begin(16, 2);
//TCCR2B = TCCR2B & B11111000 | B00000010;
analogWrite(3,127);
Serial.begin(9600);
EEPROM.get(4, Flag);
lcd.clear();
}
void loop() {
/*for (int i = 0; i < 20; i++)
{
Array [i] = 209142.9/(T);
Wheel_Speed+= Array [i];
}
Wheel_Speed/=21;
*/
if (millis()-timer>1000);
{
Serial.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
lcd.setCursor(9,0);
lcd.print(" V=");
lcd.print(V,1);
timer = millis();
}
Wheel_Speed = 209142.9/(T);
ODO = Flag *k;
int Vo = analogRead(0);
int D;
D = map(Vo,0,1018,0,585);
V=D/static_cast<float>(10);
lcd.setCursor(0, 0);
//lcd.print("SPEED ");
lcd.print(Wheel_Speed,0);
lcd.print(" km/h ");
lcd.setCursor(0,1);
//lcd.print("ODO ");
lcd.print(ODO,1);
lcd.print(" km");
if (Flag == LastFlag)
{
if (((millis()-timing)>50000)&& Flag2==LOW){
//Serial.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
Flag2=HIGH;
EEPROM.put(4, Flag);
timing = millis();
}
}
LastFlag=Flag;
T=4000000000;
//Serial.print("Millis ");
//Serial.println(millis());
Serial.print ("Voltage ");
Serial.println(V);
//Serial.print("Timing ");
//Serial.println (timing);
/* Serial.print ("Wheel_Speed");
Serial.print ("\t");
Serial.print ("\t");
Serial.print ("T");
Serial.print("\t");
Serial.print ("\t");
Serial.print ("ODO");
Serial.print ("\t");
Serial.print ("\t");
Serial.println ("Flag");
Serial.print ("\t");
Serial.print (Wheel_Speed);
Serial.print("\t");
Serial.print ("\t");
Serial.print (T);
Serial.print("\t");
Serial.print ("\t");
Serial.print(ODO);
Serial.print("\t");
Serial.print ("\t");
Serial.println(Flag);
*/}
void blink() {
Micros = micros();
T = Micros - Last_Micros;
Last_Micros = Micros;
Flag++;
Flag2=LOW;
}
во-первых, поменяй типы переменных, хранящих миллисекунды с double на uint32_t
а во-вторых, ошибка здесь:
if(millis()-timer>1000);сам найдёшь?Гыггг, классика ))))
Если починить 52 строку, то все равно будет что то странное ... если только на if на while поменять ...
Дык типы ещё в порядок привести. Что ещё?
Если починить 52 строку, то все равно будет что то странное ... если только на if на while поменять ...
А ты без если - почини и проверь. Но, сдается мне, ты ошибку не понял
v258 всё я проверил. Видимо у меня с ТС разной понимание функции delay...
Не работает Delay на millis()
Не кормите!
«Если кто не хочет трудиться, то и не ешь» (Второе послание к Фессалоникийцам святого апостола Павла 3:10)
v258 всё я проверил. Видимо у меня с ТС разной понимание функции delay...
Упс, с телефона не разглядел, думал, что это ТС ))
А я не понял, чего там не так в логе от komandir? Раз в секунду выводится «ХХХХХ», вроде это и хотел ТС, не?
А я не понял, чего там не так в логе от komandir? Раз в секунду выводится «ХХХХХ»,
Скверное ощущение, так то....
А я не понял, чего там не так в логе от komandir? Раз в секунду выводится «ХХХХХ»,
это да, вот я тут с одним готовым скетчем экспериментирую так у него loop() аж 60000 миллисекунд )))
это да, вот я тут с одним готовым скетчем экспериментирую так у него loop() аж 60000 миллисекунд )))
Такое себе...
Тут, было ,и на сутки делеили , особо одаренные...
Я вот тут давеча кормушку своей альтернативнолохматой кошечке мастерил. Её ,в виду усиленного метаболизма кормить нужно несколько раз в сутки, а сжирает она своим экскаваторным хлебальником, насыпанное все и сразу. От этого потом страдает недержанием желудка, тк сухари в объеме увеличиваются неимоверно. Отвлекся... Написал там дисплеи, меню, RTC, прочие плюшки. Все нормально работало пол-года. Но решил, что нужно энергию беречь и решил все это дело включать , посредством умной интернет-розетки(500р/шт у китайцев), на 10минут (+/-5 мин кормления), мало ли куда часы ускачут. Так вот теперь думаю, нафига я изголялся. Можно было просто к той же самой розетке прикрутить и шагать двигателем при включении , нужное количество шагов. Вот и получается, что хорошая мысля, она приходит опосля ..
//кормушка для кошки #include <avr/wdt.h> #include <Wire.h> #include <DS1307RTC.h> #include <LiquidCrystal_1602_RUS.h> #include <kakmyc_btn.h> #include <EEPROM.h> #include <AccelStepper.h> #define EEPROM_MODE_ADDRESS 100 #define EEPROM_TIME_ADDRESS 200 #define BACKLIGHT_PIN 13 #define STEP_PIN 10 #define DIR_PIN 11 #define ENABLE_PIN 12 #define MAX_SPEED 1000 #define SPEED 400 #define C_FEED 100 AccelStepper motor(AccelStepper::FULL2WIRE,STEP_PIN,DIR_PIN); #define EncA 2 #define EncB 3 #define EncBtn A0 kakmyc_btn encBtn(EncBtn,INPUT_PULLUP,2); LiquidCrystal_1602_RUS lcd(8, 9,4,5,6,7);// RS,E,D4,D5,D6,D7 tmElements_t tm; enum BUTTON_STATE{ RELEASE,SHORT,DOUBLE,LONG=255 }; BUTTON_STATE btnState=RELEASE; enum ENCODER_STATE{ BACK=-1,STAND,FORWARD }; volatile ENCODER_STATE encTick=STAND; volatile boolean updateFlag=1; enum MODE_STATE{ WAIT,WORK,SET }; MODE_STATE stateMode=WAIT; enum WORK_MODE{AUTO,MANUAL}; WORK_MODE workMode=AUTO; volatile uint32_t encDebounce=0; volatile uint32_t timer10sec; boolean blink=0; uint32_t blinkTime=0; void ENC_ISR(){ timer10sec=millis(); delayMicroseconds(50000); if(digitalRead(EncBtn)){ digitalRead(EncB)?encTick=BACK:encTick=FORWARD; } updateFlag=1; wdt_reset(); } struct FEED_SESSION{ boolean isOn; tmElements_t time; int value; }; FEED_SESSION session[5]; struct Menu { int menu_id; char *menu_name; struct Menu *next; struct Menu *prev; struct Menu *ok; void (*func)(); }; Menu setTimeMenu,modeMenu,feedMenu,currentMenu; void SetTime(); void SetAuto(); void SetFeed(); void init_menu(){ setTimeMenu={1,"ДАТА И ВРЕМЯ",&modeMenu,&feedMenu,&setTimeMenu,&SetTime}; modeMenu={2,"РЕЖИМ ",&feedMenu,&setTimeMenu,&modeMenu,&SetAuto}; feedMenu={3,"КОРМ ",&setTimeMenu,&modeMenu,&feedMenu,&SetFeed}; currentMenu=setTimeMenu; } int CheckTime(){ for(int i=0;i<5;i++){ if(tm.Hour==session[i].time.Hour&&tm.Minute==session[i].time.Minute&&tm.Second<1&&session[i].isOn){ // Serial.println("ok"); // delay(50); return i+1;} } return 0; } void PrintMainMenu(struct Menu &menu){ if(encTick){ timer10sec=millis(); BackLight(1); switch(encTick){ case FORWARD: if(menu.next)currentMenu=*menu.next; break; case BACK: if(menu.prev)currentMenu=*menu.prev; break; } encTick=STAND; } char topRow[33]; char bottomRow[33]; sprintf(topRow,"%d.%s",menu.menu_id,menu.menu_name); sprintf(bottomRow,"%d.%s",menu.next->menu_id,menu.next->menu_name); lcd.setCursor(0,0); lcd.print(">"); lcd.print(topRow); lcd.setCursor(1,1); lcd.print(bottomRow); } void SetFeed(){ int nSession=0; int item=0; uint32_t exitTimer=millis(); while(1){ if(millis()-exitTimer>=10000){ lcd.clear(); updateFlag=1; break; } FEED_SESSION *ses=&session[nSession]; tmElements_t *sT=&session[nSession].time; int hour=sT->Hour; int minute=sT->Minute; if(encTick){ exitTimer=millis(); switch (item){ case 0://номер программы nSession+=encTick; nSession=constrain(nSession,0,4); break; case 1://вкл/выкл программы if(encTick==FORWARD)ses->isOn=1; if(encTick==BACK)ses->isOn=0; break; case 2://настройка часа hour+=encTick; hour=constrain(hour,0,23); sT->Hour=hour; break; case 3://настройка минут minute+=encTick; minute=constrain(minute,0,59); sT->Minute=minute; break; case 4://настройка количества ses->value+=encTick; ses->value=constrain(ses->value,0,99); break; }//end switch encTick=STAND; } byte btnState=encBtn.read(); if(btnState==SHORT){ item++; if(item>4)item=0; } if(btnState==LONG){ EEPROM.put(EEPROM_TIME_ADDRESS,session); lcd.clear(); updateFlag=1; break; } char topRow[32]; char bottomRow[32]; char sptr[6]=" : "; sptr[item]='<'; char *onText; ses->isOn?onText=" ВКЛ":onText="ВЫКЛ"; sprintf(topRow," ВЫДАЧА КОРМА "); sprintf(bottomRow,"%d%c%4s%c%02d%c%02d%c%02d%c",nSession+1,sptr[0],onText,sptr[1],sT->Hour,sptr[2],sT->Minute,sptr[3],ses->value,sptr[4]); lcd.setCursor(0,0); lcd.print(topRow); lcd.setCursor(0,1); lcd.print(bottomRow); wdt_reset(); }//end while } void SetAuto(){ lcd.setCursor(0,1); for(int i=0;i<16;i++)lcd.print(" "); while(1){ lcd.setCursor(8,1); workMode==AUTO?lcd.print("АВТО "):lcd.print("РУЧНОЙ"); if(encTick){ if(encTick>0){ workMode=AUTO; } if(encTick<0){ workMode=MANUAL; } encTick=STAND; } if(encBtn.read()){ EEPROM.put(EEPROM_MODE_ADDRESS,workMode); lcd.clear(); updateFlag=1; break; } wdt_reset(); }//end while } void SetTime(){ int parametr=0; int hour=tm.Hour; int minute=tm.Minute; int second=tm.Second; int day=tm.Day; int month=tm.Month; int year=tm.Year; uint32_t returnTimer=millis(); while(1){ wdt_reset(); if(millis()-returnTimer>=10000){ lcd.clear(); updateFlag=1; break; } if(encTick){returnTimer=millis();}; byte btnState=encBtn.read(); if(btnState==SHORT){ returnTimer=millis(); parametr++; if(parametr>5){ parametr=0; } } if(btnState==LONG){ tm.Hour=hour; tm.Minute=minute; tm.Second=second; tm.Day=day; tm.Month=month; tm.Year=year; RTC.write(tm); lcd.clear(); updateFlag=1; break; } switch(parametr){ case 0://hour hour+=encTick; hour=constrain(hour,0,23); break; case 1://minute minute+=encTick; minute=constrain(minute,0,59); break; case 2://second if(encTick)second=0; break; case 3://year year+=encTick; year=constrain(year,0,60); break; case 4://month month+=encTick; month=constrain(month,1,12); break; case 5://day day+=encTick; day=constrain(day,1,31); break; }//end switch encTick=STAND; char timeTop[33]; char timeBottom[33]; char sptr[7]={":: .."}; sptr[parametr]='<'; sprintf(timeTop,"ДАТА %02d%c%02d%c%04d%c",day,sptr[5],month,sptr[4],year+1970 ,sptr[3]); sprintf(timeBottom,"ВРЕМЯ %02d%c%02d%c%02d%c",hour,sptr[0],minute,sptr[1],second,sptr[2]); lcd.setCursor(0,0); lcd.print(timeTop); lcd.setCursor(0,1); lcd.print(timeBottom); } } void BackLight(boolean val){ digitalWrite(BACKLIGHT_PIN,val); } void setup_mark(); void setup(){ lcd.begin(16,2); pinMode(EncA,INPUT_PULLUP); pinMode(EncB,INPUT_PULLUP); pinMode(EncBtn,INPUT_PULLUP); pinMode(BACKLIGHT_PIN,OUTPUT); pinMode(ENABLE_PIN,OUTPUT); digitalWrite(ENABLE_PIN,1); attachInterrupt(0,ENC_ISR,FALLING); init_menu(); Serial.begin(9600); EEPROM.get(EEPROM_MODE_ADDRESS,workMode); EEPROM.get(EEPROM_TIME_ADDRESS,session); motor.setMaxSpeed(MAX_SPEED); motor.setSpeed(SPEED); motor.setAcceleration(1000); motor.setCurrentPosition(0); } void ModeWait(){ boolean light=0; if(millis()-timer10sec>=10000){ light=0; }else{ light=1; } BackLight(light); char topRow[32]; char bottomRow[32]; char *mode; workMode?mode="РУЧНОЙ": mode="АВТО "; sprintf(topRow,"РЕЖИМ:%s",mode); char doublePoint; blink?doublePoint=' ':doublePoint=':'; sprintf(bottomRow,"%02d%c%02d%c%02d",tm.Hour,doublePoint,tm.Minute,doublePoint,tm.Second); if(updateFlag){ lcd.setCursor(3,0); lcd.print(topRow); lcd.setCursor(4,1); lcd.print(bottomRow); updateFlag=0; } switch(encBtn.read()){ case SHORT: lcd.clear(); stateMode=SET; encTick=STAND; timer10sec=millis(); case LONG : if(workMode==MANUAL){ BackLight(1); wdt_disable(); digitalWrite(ENABLE_PIN,0); motor.setSpeed(400); timer10sec=millis(); while(!digitalRead(EncBtn)){ motor.runSpeed(); //крутим шнек } digitalWrite(ENABLE_PIN,1); wdt_enable(WDTO_4S); } break; } } void ModeWork(int num){ lcd.clear(); lcd.setCursor(4,0); lcd.print("КОРМЛЕНИЕ"); BackLight(1); timer10sec=millis(); long position=session[num].value*C_FEED; digitalWrite(ENABLE_PIN,0); wdt_disable(); // motor.moveTo(position); motor.runToNewPosition(position); wdt_enable(WDTO_4S); wdt_reset(); digitalWrite(ENABLE_PIN,1); motor.setCurrentPosition(0); lcd.clear(); updateFlag=1; } void ModeSet(){ if(updateFlag){ PrintMainMenu(currentMenu); updateFlag=0; } byte btnState=encBtn.read(); if(btnState==LONG){ lcd.clear(); updateFlag=1; timer10sec=millis(); BackLight(1); stateMode=WAIT; } if(millis()-timer10sec>=10000){ stateMode=WAIT; timer10sec=millis(); updateFlag=1; lcd.clear(); } if(btnState==SHORT){ timer10sec=millis(); BackLight(1); btnState=RELEASE; if(currentMenu.ok&¤tMenu.func){ currentMenu.func(); } } } void loop(){ if(millis()-blinkTime>=500){ blinkTime=millis(); blink=!blink; RTC.read(tm); updateFlag=1; } int workNum=0; if(workMode==AUTO){ workNum=CheckTime(); } if(workNum){ stateMode=WORK; } wdt_reset(); switch (stateMode){ case WAIT: ModeWait(); break; case WORK: ModeWork(workNum-1); stateMode=WAIT; workNum=0; break; case SET: ModeSet(); break; } }это да, вот я тут с одним готовым скетчем экспериментирую так у него loop() аж 60000 миллисекунд )))
дело не в скетче, сторонний сервер может считать задачу неопределённое время ответ выдает по защищённому протоколу и, подтверждения принятия пакетов нету, так что девайс, если не получает ответ проще прорезетить, чем разруливать ситуацию...
Спасибо друзья, что не обошли стороной и всяк в силу своего разумения внес так сказать лепту. Косяк нашел, как сказал BOOM, классика. Тем кто читает это в поисках ответа на свой похожий вопрос - не ставьте ; после условия if ()!
Да прибудет сила с этим форумом и снизойдет благодать вселенская на всех тут.
Как вот объяснить, что delay на millis не нужно делать ? За такое сразу по рукам надо давать )