как выполнить функцию по событию и времени
- Войдите на сайт для отправки комментариев
Вс, 14/03/2021 - 20:47
всем привет, я новичок в это деле, пишу код для контроллера пеллетной горелки, не получается сделать один момент...
в общем суть такая, нужно если огонь не горит Х времени запустить функцию. огонь наблюдает аналоговый датчик огня, фильтруется через медианный фильтр.
пытался сделать таймер на миллисе, получается фингя... не работает...
timer_fire = millis();
if(val_f>1000 and start1 == 1 and (millis()-timer_fire>30000) and start_count<=2){
startWork();
}
не работает потому что надо переменную timer_fire записать один раз и от нее отталкиваться, а оно постоянно её переписывает:(
неделю уже пробую разные варианты:(
Так переписывай ее внутри if(){}. А первый раз назначь в сетапе.
пробовал, не подходит
пробовал, не подходит
Стесьняюсь спросить - а почему? Где-то еще используется - так создайте еще одну переменную. А так- это стандартный ход.
А может потому что
if(val_f>1000 && start1 == 1 && (millis()-timer_fire>30000) && start_count<=2){ startWork(); }пробовал, не подходит
Стесьняюсь спросить - а почему?
посмотри на строчку 441 и 460 кода. И таких циклов у ТС в коде полно. Понятно, что с таким кодом таймер на миллис не работает
посмотри на строчку 441 и 460 кода. И таких циклов у ТС в коде полно. Понятно, что с таким кодом таймер на миллис не работает
Не долистал. Убило наповал :)
Про цикл while() похоже неизвестно. Хотя и с ним не прокатит. А for(;;) - это что то из питона?
Про цикл while() похоже неизвестно. Хотя и с ним не прокатит. А for(;;) - это что то из питона?
это ровно то же самое, как while(1)
По действию на код абсолютно аналогично delay() . У ТС этим "прогрессивным методом" написано 80% циклов, видимо избавлялся от задержек, а миллис так и не освоил. Это даже исправлять нет смысла, по мне так выкинуть в мусор и написать заново.
Я по образованию сварщик... Не зря же я в песочнице пишу... Этот код работает. греет мастерскую котел:) я понимаю что многое не правильно, но как смог... А вот сделать условие для перезапуска если огня нет определенное время не получается...
Код, возможно, и работает, но не допускает расширения функциональности.
Т.е. добавить к нему еще что-то нельзя.
греет мастерскую котел:) я понимаю что многое не правильно, но как смог... А вот сделать условие для перезапуска если огня нет определенное время не получается...
С таким кодом и не получится.
Правильно говорят - его надо переписывать с нуля.
С какой точностью Вам нужно выдержать время?
Если, скажем, 0.1с, от это значит, что весь loop() у Вас должен гарантированно заканчиваться за 0.1с. А у Вас он сколько ждет?
из того, что мы в Песочнице - вовсе не следует что кто-то бросится переписывать код из 500 строк. Если бы в нем была пара ошибок - я бы подсказал, но, на мой взгляд, код изначально написан неверно.
Логика построения программы на delay() и на millis() абсолютно разная, поменяв пару строк один в другой не переделать. А у вас ваши циклы все являются, по сути, функцией delay(), например
for(;;){ startPWM(100); if(millis()-timer_produvka>5000){ break; } }полностью аналогично вот такому коду:
А у Вас он сколько ждет?
Не ждёт, этих for(;;) в процессе работы нету
Я никого не прошу переписывать мой код! Да он не ПРАВИЛЬНЫЙ но он работает! Я не учился этому!!! Что за люди...
Если не правильно, скажите маленьким примером как правильно, я постараюсь исправится. А просто критиковать могу все...
Если он работает, какие еще у Вас вопросы к форуму? ("работает не так, как хочется" и "не работает" - это одно и то же)
А пример - классический: blink without delay.
Да как не ждет-то, если по тому самому условию, которое у вас не работает и с которым вы пришли на форум - запускается функция startWork(). которая просто набита подобными циклами - в строке 315 на 5 секунд, в строке 331 - на 15 сек, в строке 347 - АЖНО НА 6 МИНУТ!!
Это не считая кучи других процедур, запускаемых из startWork(), в каждой из которых могут быть свои задержки...
но самое интересное - в конце! В конце этой функции startWork(), в строке 363 - вы запускаете эту же функцию из нее самой... Да, возможно в реальной программе этого не происходит, не вникал, но в коде это есть.
Рискну сказать. что этот код просто никуда не годится.
Я имел в виду что когда горит огонь в горелке никаких фор не происходит
Когда горит огонь в горелке, эта программа не нужна вовсе. Она нужна при запуске, при выключении или в случае угасания пламени. А именно в этот момент эта программа и не работает.
А если вы считаете, что эти for никак не влияют на работу - зачем вы их туда навставляли? Вычистите их из кода.
тогда вопрос, как мне сделать без delay() подачу шнеком стокера 15сек?
тогда вопрос, как мне сделать без delay() подачу шнеком стокера 15сек?
Запустить шнек, запомнить время, продолжить выполнение программы.
Когда пройдет 15 секунд - выключить шнек.
Запустить шнек, запомнить время, продолжить выполнение программы.
Когда пройдет 15 секунд - выключить шнек.
так нечего выполнять паралельно, нужно выполнить это, потом выполнить "розжиг", а потом уже выполняется work() который выбирает режим работы и работает work_timer()
Уважаемый ТС, а Вы не пытались на бумажке, обычным языком написать алгоритм программы? А то, похоже, что Вы ее писали "как получится".
Я вижу такой минимальный алгоритм:
1) Разжигаем, если несколько раз не зажигается - уходим в ошибку.
2) Пока горит - отрабатываем алгоритмы при горении
3) Если погасло - п.1
Причем розжиг останавливает и перезапускает все остальные процессы. Пока зажигаем не делаем ничего, кроме этого. Причем первый розжиг должен быть в сетапе, а последующие вызываться из программы горения.
По моему логично.
Я уже решил свою проблему, добавил библиотеку GyverTimer. Если огня нет запускается таймер, если огонь появился раньше чем таймер сработал таймер сбрасывается. Если таймер протикал и огонь не появился запускается функция которая пытается вернуть огонь...
Уважаемый ТС, а Вы не пытались на бумажке, обычным языком написать алгоритм программы? А то, похоже, что Вы ее писали "как получится".
Я вижу такой минимальный алгоритм:
1) Разжигаем, если несколько раз не зажигается - уходим в ошибку.
2) Пока горит - отрабатываем алгоритмы при горении
3) Если погасло - п.1
Причем розжиг останавливает и перезапускает все остальные процессы. Пока зажигаем не делаем ничего, кроме этого. Причем первый розжиг должен быть в сетапе, а последующие вызываться из программы горения.
По моему логично.
В сетапе мне не нужно запускать горелку... Она запускается по нажатию кнопки.
Когда два месяца назад начинал это писать был листок бумаги с алгоритмом что примерно я хочу.
Смародина, делайте что хотите. Но запомните - так писать нельзя. Тем более программы. управляющие опасным оборудованием. Когда ваша мастерская сгорит из-за того что у вас скетч тупит по 6 минут в бесконечных циклах - надеюсь что хотя бы никто из окружающих не пострадает.
Смародина, делайте что хотите. Но запомните - так писать нельзя. Тем более программы. управляющие опасным оборудованием. Когда ваша мастерская сгорит из-за того что у вас скетч тупит по 6 минут в бесконечных циклах - надеюсь что хотя бы никто из окружающих не пострадает.
Вместо того чтобы обливать гавном можно иногда пробовать дать направление...
Мне некому помочь сделать правильно.
И чего цикл бесконечный?! Он заканчивается или по появлению огня или по прошествии отведённого времени. Как можно это сделать по другому?
Вместо того чтобы обливать гавном можно иногда пробовать дать направление...
Мне некому помочь сделать правильно.
Почему вам кто-то должен помогать, вы маленькая девочка штоль? Берите книжки, читайте интернет и осваивайте. Я вам дал направление - делать таймеры на миллис. Можно даже использовать таймеры гайвера, только нужно делать это не в одной строчке, а по всему коду. И да, логику кода придется менять полностью, в итоге вы сами поймете, что написать заново проще, чем переделать это.
чтоб сделать на таймерах мне надо будет делать кучу переменных(флагов) которые будут блокировать работу других таймеров чтоб все работало своим чередом, правильно мыслю?
не обязательно делать кучу переменных, это пишется слегка по другому.
почитайте что-нибудь о "машине состояний" или "конечных автоматах"
не обязательно делать кучу переменных, это пишется слегка по другому.
почитайте что-нибудь о "машине состояний" или "конечных автоматах"
почитал о "конечных автоматах"... да... пту образования явно маловато будет...
Smarodina, ну как Вам не стыдно!
Вам уже в сообщениях № 2, 4, 5, 7, 9, 10, 13, 14, 14, 18 и 20 несколько человек "пробовали дать направление". А Вы, вместо того, чтобы хоть чуть пошевелить пальцем, только высказываете неудовольствие.
чтоб сделать на таймерах мне надо будет делать кучу переменных(флагов) которые будут блокировать работу других таймеров чтоб все работало своим чередом, правильно мыслю?
В том то и дело, что ничего никогда не должно блокировать. Если Вы в 99 случаях напишете неблокирующий код, а одном-единственном - блокирующий, это работать не будет. Код на все 100% должен быть неблокирующим.
чтоб сделать на таймерах мне надо будет делать кучу переменных(флагов) которые будут блокировать работу других таймеров чтоб все работало своим чередом, правильно мыслю?
В том то и дело, что ничего никогда не должно блокировать. Если Вы в 99 случаях напишете неблокирующий код, а одном-единственном - блокирующий, это работать не будет. Код на все 100% должен быть неблокирующим.
тогда вы просто не понимаете как оно должно работать... нельзя сделать все сразу... нужна последовательность.
тогда вы просто не понимаете как оно должно работать... нельзя сделать все сразу... нужна последовательность.
Да, чего-то я не понимаю.
В частности, не понимаю, что именно Вы хотели сказать.
Я понимаю, как следует писать программы. И понимаю, чего следует избегать при их написании.
В то же время, я не понимаю, как должна работать Ваша программа, т.к. Вы об этом нигде подробно не написали.
Что же касается "нельзя все сделать сразу" - да, делать нужно постепенно, если хотите - последовательно. Но при этом каждый очередной шаг не должен исключать возможность сделать следующий шаг. В противном случае мы остановимся на середине и не будем иметь возможности завершить проект.
тогда вы просто не понимаете как оно должно работать... нельзя сделать все сразу... нужна последовательность.
нет, это вы не понимаете. Если у вас код неблокирующий - вы можете выполнять задачи как попеременно, так и последовательно. А когда блокирующий - только ждать, пока одна закончит, чтобы сделать что-то еще. А между тем, в подобных системах всегда есть необходимость оперативного отслеживания каких-то датчиков, например датчика пламени, ОДНОВРЕМЕННО С ВЫПОЛНЕНИЕМ ДРУГИХ ОПЕРАЦИЙ. В вашем исходном коде это в принципе невозможно.
ну почему же, мой блокирующий for(;;) отслеживает датчик огня и таймер в нем тикает
если это: unsigned long fireTimer; fireTimer = millis(); for(;;){ digitalWrite(feederAugerPin, HIGH); PWM_val=80; startPWM(); digitalWrite(heatingElementPin, LOW); average_fire(); average_temp(); button(); screen(); if(val_f<=750||millis()-fireTimer>=240000){ fireTimer = millis(); break; } }заменить этим:
unsigned long fireTimer; if(millis()-fireTimer<240000 or val_f<=750){digitalWrite(heatingElementPin, LOW);} else{ fireTimer=millis();будет тоже самое, но как выполнять только его?
или "конечных автоматах"
Спасибо за наводку. Очень интересно.
будет тоже самое, но как выполнять только его?
не понимаю, в чем проблема. Когда не надо ничего выполнять параллельно - не делайте. Вы о конечных автоматах прочитали? - это как раз оно
не знаю что такие "конечное автоматы", но кажись доперло как реализовать. на днях напишу новую startWork() и выложу на ваш суд!
на днях напишу новую startWork() и выложу на ваш суд!
похоже вы опять упустили то, что вам писали Андриано и я в сообщениях #31 и #26. Нельзя переписать только startWork() - в неблокирующем стиле должен быть написан ВЕСЬ КОД, иначе это бессмысленно
я не упустил, а решил начать с startWork()
for(;;) есть только в startWork() и finishWork()
да некоторым изменениям подвергнутся и остальные части кода, но не существенно.
теперь жду комментариев где не правильно!
#define PID_INTEGER #define BTN1 4 #define BTN2 5 #define BTN3 2 #define BTN4 3 #define BTN5 A0 #include <GyverButton.h> #include <GyverTimer.h> #include <GyverTM1637.h> #include <OneWire.h> #include <DallasTemperature.h> #include <GyverPID.h> #include <arduino-timer.h> #define CLK A4 #define DIO A5 #define ONE_WIRE_BUS 11 #define FILTER_STEP_temp 100 #define FILTER_COEF_temp 0.05 GyverTM1637 disp(CLK, DIO); GyverPID pid(0.35, 0, 0, 3000); OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress insideThermometer {0x28, 0xB8, 0x86, 0xD5, 0x33, 0x20, 0x01, 0xCA }; //УКАЗАТЬ имя датчика ////////////////////кнопки//////////////////////////////////////////// GButton startButtonPin(BTN1); //пин кнопки Старт GButton stopButtonPin(BTN2); //пин кнопки Стоп GButton plusButtonPin(BTN3); //пин кнопки "+" GButton minusButtonPin(BTN4); //пин кнопки "-" GButton disp_ButtonPin(BTN5); //пин кнопки дисплея ////////////////////датчики/////////////////////////////////////////// const int temperatureSensorPin = 11; //пин датчика температуры const int photoresistorPin = 12; //пин фоторезистора const int infraredSensorPin = A3; //пин ИК датчика const int potentiometerPin = A0; //пин потенциометра ////////////////////иполнители//////////////////////////////////////// const int feederAugerPin = 6; //пин шнека питателя const int pumpPin = 7; //пин цикуляционного насоса const int heatingElementPin = 8; //пин зажигалки const int stokerAugerPin = 9; //пин шнека стокера const int pwmPin = 10; //пин для ШИМ const int firebarPin = 13; //пин подвижного колосника ////////////////////переменные/////////////////////////////////////// int desiredTemperature; byte working; byte start_count; byte photoresistor; int p_pause; int w_pause; byte start1; int val_f; int val[3]; int index; int val_temp; int val_Ftemp; byte starting; byte finishing; byte plusButton; byte minusButton; byte dispButton; int dose; byte displ; char fan_val; int PWM_val; byte start_work; byte stop_FP; byte pause_work; byte dozig; byte fanspeed_pr; byte pid_out_last; unsigned int punk; int phase; int switch_start; int switch_stop; int stop_FPB; GTimer start_timer0(MS); GTimer start_timer1(MS); GTimer start_timer2(MS); GTimer start_timer3(MS); GTimer stop_timer1(MS); GTimer AS_timer(MS); auto timer_up = timer_create_default(); auto firebar_up = timer_create_default(); int middle_of_3(int a, int b, int c) { int middle; if ((a <= b) && (a <= c)) { middle = (b <= c) ? b : c; } else { if ((b <= a) && (b <= c)) { middle = (a <= c) ? a : c; } else { middle = (a <= b) ? a : b; } } return middle; } bool test_timer_up() { digitalWrite(stokerAugerPin, !digitalRead(stokerAugerPin)); return false; } bool test_firebar_up() { digitalWrite(firebarPin, !digitalRead(firebarPin)); return false; } void setup() { switch_stop=9; switch_start=9; pid_out_last=100; dozig=0; pause_work=0; PWM_val=0; displ=0; working=0; start1=0; start_count=0; start_work=0; desiredTemperature=500; stop_FP=1; disp.clear(); disp.brightness(0); // яркость, 0 - 7 (минимум - максимум) startButtonPin.setTickMode(AUTO); stopButtonPin.setTickMode(AUTO); plusButtonPin.setTickMode(AUTO); minusButtonPin.setTickMode(AUTO); disp_ButtonPin.setTickMode(AUTO); pinMode(potentiometerPin, INPUT); pinMode(photoresistorPin, INPUT); pinMode(infraredSensorPin, INPUT); pinMode(temperatureSensorPin, INPUT); pinMode(pumpPin, OUTPUT); pinMode(feederAugerPin, OUTPUT); pinMode(stokerAugerPin, OUTPUT); pinMode(pwmPin, OUTPUT); pinMode(heatingElementPin, OUTPUT); pinMode(firebarPin, OUTPUT); digitalWrite(feederAugerPin, HIGH); digitalWrite(stokerAugerPin, HIGH); digitalWrite(heatingElementPin, HIGH); digitalWrite(pumpPin, HIGH); digitalWrite(firebarPin, HIGH); pid.setDirection(NORMAL); pid.setLimits(2,9); pid.setpoint = desiredTemperature; sensors.begin(); start_timer0.setTimeout(5000); start_timer1.setTimeout(15000); start_timer2.setTimeout(180000); start_timer3.setTimeout(10000); stop_timer1.setTimeout(60000); AS_timer.setTimeout(30000); } void loop() { button(); fillPillets(); pid_timer(); average_fire(); average_temp(); work(); startWork(); finishWork(); //start_stop(); //auto_start(); //fire_bar(); startPWM(); screen(); } void pid_timer(){ //Функция таймер ПИД регулятора unsigned long timer_pid; if(working==1){ if(millis() - timer_pid >= 1000){ timer_pid = millis(); pid.input = val_Ftemp; pid.setpoint = desiredTemperature; pid.getResult(); } } } void fire_bar(){ //Функция таймера работы подвижного колосника int phase_firebar; unsigned long firebar_punk; digitalWrite(firebarPin, HIGH); firebar_punk = firebar_up.tick(); if (firebar_punk<=10) { phase_firebar = digitalRead(firebarPin); if (phase_firebar == LOW){ firebar_up.cancel(); firebar_up.in(10000, test_firebar_up); } if (phase_firebar == HIGH){ firebar_up.cancel(); firebar_up.in(300000, test_firebar_up); } } } void average_temp(){ //Функция обработки сигнала датчика температуры unsigned long filter_temp_timer; int currentTemp; sensors.requestTemperatures(); currentTemp = sensors.getTempC(insideThermometer)*10; if (millis() - filter_temp_timer > FILTER_STEP_temp) { filter_temp_timer = millis(); val_temp = currentTemp; val_Ftemp = val_temp * FILTER_COEF_temp + val_Ftemp * (1 - FILTER_COEF_temp); } } void average_fire(){ //Функция обработки сигнала датчика огня if (++index > 2) index = 0; val[index] = analogRead(A3); val_f = middle_of_3(val[0], val[1], val[2]); } void startPWM() { //функция управления ШИМ вентилятора int fanspeed; //fan_val=constrain(fan_val,-20,20); fanspeed_pr = PWM_val;//+fan_val; fanspeed_pr = constrain(fanspeed_pr, 0, 100); fanspeed = map(fanspeed_pr, 0, 100, 0, 253); analogWrite(pwmPin, fanspeed); } void start_stop(){ //Функция автоматической оставноки и запуска горелки по температуре if((desiredTemperature - val_temp) >= 50 and pause_work==1 and photoresistor == HIGH and val_f>1000){ pause_work=0; working=1; switch_start=0; } if((val_temp - desiredTemperature) >= 50 and start1==1 and val_f<1000){ pause_work=1; working==0; switch_stop=0; } } void button(){ //Функция обработки кнопок desiredTemperature = constrain(desiredTemperature, 300, 800); stop_FP = digitalRead(stokerAugerPin); if(disp_ButtonPin.isClick()){ displ = displ+1; if(displ >= 4){ displ=0; } } if(startButtonPin.isClick() and photoresistor==1 and val_f>900){ switch_start=0; } if(startButtonPin.isPress() and val_f<900){ working=1; start1=1; } if(stopButtonPin.isClick()){ stop_FPB=1; working=0; start1=0; switch_stop=0; } } void auto_start(){ //Функция автостарта горелки при потере огня if(val_f>1000 and start1==1 and start_count<2 and pause_work==0){ if(AS_timer.isReady())switch_start=5;}else{AS_timer.reset();} if(start_count>=3){ start1=0; working=0; //сюда надо подкючить сирену или какое то еще оповещение о аварии. } } void screen(){ //функция вывода информации на дисплей int for_disp; switch (displ){ case 0 : for_disp = desiredTemperature * 10; for_disp = for_disp + val_temp/10; disp.displayInt(for_disp); disp.point(true); if(plusButtonPin.isPress()){ desiredTemperature = desiredTemperature + 10; } if(minusButtonPin.isPress()){ desiredTemperature = desiredTemperature - 10; } break; case 1 : disp.displayInt(dose); disp.point(false); break; case 2 : disp.displayInt(fanspeed_pr); disp.displayByte(0, 0x71); //disp.displayInt(fan_val); disp.point(false); if(plusButtonPin.isPress()){ fan_val = fan_val + 1; } if(minusButtonPin.isPress()){ fan_val = fan_val - 1; } break; case 3 : disp.displayInt(val_f); disp.point(false); break; } } void fillPillets() { //Функция подачи пеллет из бункера в стокер photoresistor = digitalRead(photoresistorPin); if(stop_FPB==0){ if (photoresistor == 0 and stop_FP==1) { digitalWrite(feederAugerPin, LOW);} else { digitalWrite(feederAugerPin, HIGH);} } } void startWork(){ //функция розжига switch(switch_start){ case 0: PWM_val=100; break; case 1: PWM_val=20; digitalWrite(feederAugerPin, HIGH); digitalWrite(stokerAugerPin, LOW); break; case 2: digitalWrite(stokerAugerPin, HIGH); switch_start=3; break; case 3: PWM_val=80; digitalWrite(heatingElementPin, LOW); break; case 4: digitalWrite(heatingElementPin, HIGH); PWM_val=80; dose=1111; break; case 5: digitalWrite(heatingElementPin, HIGH); start_count=start_count+1; if(start_count<=3){ switch_start=0;} break; case 6: start1=1; working=1; switch_start=9; break; } if(switch_start==0){ if(start_timer0.isReady())switch_start=1;}else{start_timer0.reset();} if(switch_start==1){ if(start_timer1.isReady())switch_start=2;}else{start_timer1.reset();} if(switch_start==3){ if(val_f<750)switch_start=4;} if(switch_start==3){ if(start_timer2.isReady())switch_start=5;}else{start_timer2.reset();} if(switch_start==4){ if(start_timer3.isReady())switch_start=6;}else{start_timer3.reset();} } void work() { //Функция выбора варианта работы горелки if (working == 1) { start_count = 0; if (pid_out_last != pid.output){ digitalWrite(stokerAugerPin,HIGH); switch (pid.output) { case 0 :p_pause=10000;w_pause=100;PWM_val=20;dose = 180;break; case 1 :p_pause=8500;w_pause=100;PWM_val=25;dose = 210;break; case 2 :p_pause=7500;w_pause=100;PWM_val=30;dose = 240;break; case 3 :p_pause=6000;w_pause=100;PWM_val=35;dose = 300;break; case 4 :p_pause=5000;w_pause=100;PWM_val=40;dose = 360;break; case 5 :p_pause=4500;w_pause=100;PWM_val=45;dose = 400;break; case 6 :p_pause=2500;w_pause=125;PWM_val=65;dose = 850;break; case 7 :p_pause=3750;w_pause=200;PWM_val=80;dose = 1000;break; case 8 :p_pause=3000;w_pause=200;PWM_val=95;dose = 1630;break; case 9 :p_pause=3000;w_pause=250;PWM_val=100;dose = 2000;break; } timer_up.cancel(); timer_up.in(p_pause,test_timer_up); } pid_out_last = pid.output; work_timer(); } } void work_timer(){ //Функция таймер работы горелки punk = timer_up.tick(); if (punk<=10) { phase = digitalRead(stokerAugerPin); if (phase == LOW){ timer_up.cancel(); timer_up.in(w_pause, test_timer_up); } if (phase == HIGH){ timer_up.cancel(); timer_up.in(p_pause, test_timer_up); } } } void finishWork(){ //Функция остановки работы горелки switch(switch_stop){ case 0: p_pause=3000; w_pause=250; PWM_val=100; work_timer(); break; case 1: PWM_val=100; break; } if(switch_stop==0){ if(val_f<1000){switch_stop=0;}} if(switch_stop==0){ if(val_f>1000){switch_stop=1;}} if(switch_stop==1){ if(stop_timer1.isReady()){switch_stop=3;stop_FPB=0;PWM_val=0;}else{stop_timer1.reset();}} }и попутно вопрос, ячейка EEPROM Хранит значение 0...255 и только? или -128...127
в логику кода пока не вникал. но сразу замечания по структуре
1. Зачем условия в строчках 390-402 вынесены отдельно, почему бы не добавить их в Switch строка 350
2. Длинный Switch cтрочки 412-472 легко заменяется 4 строчками кода. если предварительно положить значения изменяющихся переменных в массивы с индексом по значению ключа свитча
в логику кода пока не вникал. но сразу замечания по структуре
1. Зачем условия в строчках 390-402 вынесены отдельно, почему бы не добавить их в Switch строка 350
2. Длинный Switch cтрочки 412-472 легко заменяется 4 строчками кода. если предварительно положить значения изменяющихся переменных в массивы с индексом по значению ключа свитча
1. Сначала делал их в Switch но не работает. вынес и все заработало.
2. к сожалению еще не умею.
А сворачивать код при публикации тоже "еще не умеете"?
Размещать без сворачивания код длиной больше чем один экран - mauvais ton.
А сворачивать код при публикации тоже "еще не умеете"?
Размещать без сворачивания код длиной больше чем один экран - mauvais ton.
свернул
А сворачивать код при публикации тоже "еще не умеете"?
Размещать без сворачивания код длиной больше чем один экран - mauvais ton.
а по коду комментарии будут?
и попутно вопрос, ячейка EEPROM Хранит значение 0...255 и только? или -128...127
Ячейка хранит 8 бит, а EEPROM хранит то, что скажешь. char - 1 байт, int - 2 байта, float - 4 байта. Как скажете - так и будет.
и попутно вопрос, ячейка EEPROM Хранит значение 0...255 и только? или -128...127
Ячейка хранит 8 бит, а EEPROM хранит то, что скажешь. char - 1 байт, int - 2 байта, float - 4 байта. Как скажете - так и будет.
помогите примером пожалуйста, как хранить переменную char у которой диапазон от -30 до 30. спасибо
по коду вот еще :)
искать среднее из трех значений можно быстрее, чем так:
int middle_of_3(int a, int b, int c) { int middle; if ((a <= b) && (a <= c)) { middle = (b <= c) ? b : c; } else { if ((b <= a) && (b <= c)) { middle = (a <= c) ? a : c; } else { middle = (a <= b) ? a : b; } } return middle; }вот например так
int middle_of_3(int a, int b, int c) { int x[2]; if (a > b) {x[0] = b; x[1] = a;} else {x[0] = a; x[1] = b;} if (x[1] > c) {return (x[0]< c) ? c : x[0];} else {return x[1] } }