Управление двигателем
- Войдите на сайт для отправки комментариев
Сб, 28/12/2019 - 22:02
Добрый день всем, андруиной занялся не давно, написал скеч для управления двигателем, в кратце суть что должно быть, через час например двигатель должен закрыть заслонку и потом через 10 сек открыть и так в цикле. А у меня получилось, что при следующем цикле закрытия, время открытие сбивается. как подправить этот косячек.
Попробуйте для начала почитать тему ПЕСОЧНИЦА. ДЛЯ ВСЕХ НОВИЧКОВ, только внимательно. А потом, запостите Вашу хотелку снова, но, на этот раз, правильно.
unsigned long freq=500; //периодичность включения в минутах таймера 1 unsigned long dlit=80; //длительность работы в секундах таймера 2 unsigned long freq_last_time; unsigned long freq_last_time2; bool _k8 = 0; //закрытие месячное bool _k9 = 0; //открытие месячное void setup() { pinMode(0, OUTPUT); //закрытие мотор pinMode(1, OUTPUT); //открытие мотор } void loop(){ R1(); R2(); } void R1() { _k8=0; if( (millis()-freq_last_time)>(freq*60) ) { digitalWrite (0, 1); _k8=1; freq_last_time=millis(); }} void R2() { _k9=0; if( (millis()-freq_last_time2)>((freq*60+dlit*60)) ) { digitalWrite (1, 1); _k9=1; freq_last_time2=millis(); }}Моторы перетягивают друг друга?
нет , управление идет на микросхеме L293D, остальною часть выполняет другая часть скетча, но выкладывать смысла пока нет чтоб не вводить в заблуждение, она прекрасно работает. Так же есть переменные которые и управляют другой частью скетча, Можно перефразировать мотор на светодиоды, первый светодиод включился (_k8), а через 10 сек включился второй (_k9). потом цикл повторяется.
наверное надо организовать таймера, а управлять уже в скетче
Возможно это сделать и в первой части это в (R1). включение второго светодиода (_k9). Но у меня пока мысли не приходят, как для начинающего. Не могу начало подправить, но напишу здесь. двигатель который управляет заслонкой через час должен ее закрыть, и открыть через 10 секунд, и через час повторить это до бесконечности. Надо для того это, чтоб заслонка не прикипела.
может так?
unsigned long freq=500; //периодичность включения в минутах таймера 1 unsigned long dlit=80; //длительность работы в секундах таймера 2 unsigned long freq_last_time; bool _k8 = 0; //закрытие месячное bool _k9 = 1; //открытие месячное void setup() { pinMode(0, OUTPUT); //закрытие мотор pinMode(1, OUTPUT); //открытие мотор } void loop(){ if(_k9==1){R1();} if(_k8==1){R2();} } void R1() { _k8=0; if( (millis()-freq_last_time)>(freq*60) ) { digitalWrite (0, 1); _k8=1; _k9=0; freq_last_time=millis(); }} void R2(){ _k9=0; if( (millis()-freq_last_time)>((dlit*60)) ){ digitalWrite (1, 1); _k9=1; _k8=0; freq_last_time=millis(); } }Не работает как надо, но примерно похоже как нужно, осталось убрать постоянную единицу на _k9, все время команда на открытие идет.
Не работает как надо, но примерно похоже как нужно, осталось убрать постоянную единицу на _k9, все время команда на открытие идет.
да ну, а у меня всё работает, смотрим на светлодиодик...
unsigned long freq=5000; //периодичность включения в минутах таймера 1 unsigned long dlit=800; //длительность работы в секундах таймера 2 unsigned long freq_last_time; bool _k8 = 0; //закрытие месячное bool _k9 = 1; //открытие месячное void setup() { pinMode(0, OUTPUT); //закрытие мотор pinMode(1, OUTPUT); //открытие мотор pinMode(13, OUTPUT); digitalWrite(13,LOW); freq_last_time=millis(); } void loop(){ if(_k9==1){R1();} if(_k8==1){R2();} } void R1() { _k8=0; if( (millis()-freq_last_time)>(freq) ) { digitalWrite (0, 1); _k8=1; _k9=0; freq_last_time=millis(); digitalWrite(13,HIGH); }} void R2(){ _k9=0; if( (millis()-freq_last_time)>((dlit)) ){ digitalWrite (1, 1); _k9=1; _k8=0; freq_last_time=millis(); digitalWrite(13,LOW); } }если эти переменные не что иное, как разрешение на открытие, то сделано всё идеологически через одно место, во первых надо определиться с временем работы мотора на перемещение заслонки из одного положения в другое, далее сигналов будет три, DIR1, DIR2, ENABLE, они и задают режим управления заслонкой (ну так принято), таймеров будет три, время открытого состояния заслонки, время закрытого состояния заслонки, время перемещения
bool _k1 = 0; bool _tim1I = 0; bool _tim1O = 0; unsigned long _tim1P = 0; bool _ktim1 = 0; bool _k2 = 0; bool _k3 = 0; bool _k4 = 0; bool _k5 = 0; bool _k10 = 0; bool _tim2I = 0; bool _tim2O = 0; bool _tim3I = 0; bool _tim3O = 0; unsigned long _tim2P = 0; bool _ktim2 = 0; unsigned long _tim3P = 0; bool _ktim3 = 0; bool _gen1I = 0; bool _gen1O = 0; unsigned long _gen1P = 0; bool _kgen1 = 0; bool _k6 = 0; bool _bounseInput3S = 0; bool _bounseInput3O = 0; unsigned long _bounseInput3P = 0; bool _bounseInput4S = 0; bool _bounseInput4O = 0; unsigned long _bounseInput4P = 0; bool _bounseInput5S = 0; bool _bounseInput5O = 0; unsigned long _bounseInput5P = 0; bool _bounseInput6S = 0; bool _bounseInput6O = 0; unsigned long _bounseInput6P = 0; bool _bounseInput7S = 0; bool _bounseInput7O = 0; unsigned long _bounseInput7P = 0; unsigned long freq=500; //периодичность включения в минутах таймера 1 unsigned long dlit=90; //длительность работы в секундах таймера 2 unsigned long freq_last_time; unsigned long freq_last_time2; bool _k8 = 0; //закрытие месячное bool _k9 = 1; //открытие месячное bool _k11 = 0; void setup() { pinMode(9, INPUT); //кнопка закрытие мотор 1 и 2 pinMode(1, OUTPUT); //открытие мотор 2 pinMode(10, INPUT); //кнопка снятие аварии pinMode(3, INPUT); //вход датчик pinMode(4, INPUT); //вход датчик pinMode(5, INPUT); //вход датчик pinMode(6, INPUT); //вход датчик pinMode(7, INPUT); //вход датчик pinMode(2, OUTPUT); //открытие мотор 1 pinMode(0, OUTPUT); //закрытие мотор 1 и 2 pinMode(8, OUTPUT); //выход светодиод авария-закрытие pinMode(14, OUTPUT); //светодиод открытия pinMode(15, INPUT); //кнопка открытие мотор 1 pinMode(16, INPUT); //кнопка открытие мотор 2 pinMode(13, OUTPUT); pinMode(11, OUTPUT); _bounseInput3O = digitalRead(3); _bounseInput4O = digitalRead(4); _bounseInput5O = digitalRead(5); _bounseInput6O = digitalRead(6); _bounseInput7O = digitalRead(7); } void loop(){ if(_k9==1){R1();} if(_k8==1){R2();} R3(); } void R1() { _k8=0; if( (millis()-freq_last_time)>(freq*60) ) { digitalWrite (11, 1); _k8=1; _k9=0; freq_last_time=millis(); }} void R2(){ _k9=0; if( (millis()-freq_last_time)>((dlit*60)) ){ digitalWrite (13, 1); _k9=1; _k11=1; _k8=0; freq_last_time=millis(); _k11=0; } } //void R1() //{ // _k8=0; //if( (millis()-freq_last_time)>(freq*60) ) //{ _k8=1; // freq_last_time=millis(); //}} //void R2() //{ //_k9=0; //if( (millis()-freq_last_time2)>((freq*60+dlit*60)) ) //{ freq_last_time2=millis(); //_k9=1; //}} void R3() { bool _bounceTmp3 = (digitalRead (3)); if (_bounseInput3S) { if (millis() >= (_bounseInput3P + 40)) {_bounseInput3O= _bounceTmp3; _bounseInput3S=0;} } else { if (_bounceTmp3 != _bounseInput3O ) {_bounseInput3S=1; _bounseInput3P = millis();} } bool _bounceTmp4 = (digitalRead (4)); if (_bounseInput4S) { if (millis() >= (_bounseInput4P + 40)) {_bounseInput4O= _bounceTmp4; _bounseInput4S=0;} } else { if (_bounceTmp4 != _bounseInput4O ) {_bounseInput4S=1; _bounseInput4P = millis();} } bool _bounceTmp5 = (digitalRead (5)); if (_bounseInput5S) { if (millis() >= (_bounseInput5P + 40)) {_bounseInput5O= _bounceTmp5; _bounseInput5S=0;} } else { if (_bounceTmp5 != _bounseInput5O ) {_bounseInput5S=1; _bounseInput5P = millis();} } bool _bounceTmp6 = (digitalRead (6)); if (_bounseInput6S) { if (millis() >= (_bounseInput6P + 40)) {_bounseInput6O= _bounceTmp6; _bounseInput6S=0;} } else { if (_bounceTmp6 != _bounseInput6O ) {_bounseInput6S=1; _bounseInput6P = millis();} } bool _bounceTmp7 = (digitalRead (7)); if (_bounseInput7S) { if (millis() >= (_bounseInput7P + 40)) {_bounseInput7O= _bounceTmp7; _bounseInput7S=0;} } else { if (_bounceTmp7 != _bounseInput7O ) {_bounseInput7S=1; _bounseInput7P = millis();} } _k1 = ((_bounseInput7O) || (_bounseInput6O) || (_bounseInput5O) || (_bounseInput4O) || (_bounseInput3O)); _k2 = ((((_k1) || (_k2))) &&((!_k4))); digitalWrite (8, ((_ktim1) || (_k6))); _k3 = ((_k1) || ((digitalRead (9))) || (_k8)); if (_k3) { _tim1O = 1; _tim1I = 1; } else { if (_tim1I) { _tim1I = 0; _tim1P = millis(); } else { if (_tim1O) {if ( _isTimer(_tim1P, 4000)) _tim1O = 0; } } } if(_tim1O) {_ktim1 = 1;} else {_ktim1 = 0;} digitalWrite (0, (!_ktim1)); _k4 = (digitalRead (10)); _k5 = (((digitalRead (15))) || (_k11) &&((!_k2))); if (_k5) { _tim2O = 1; _tim2I = 1; } else { if (_tim2I) { _tim2I = 0; _tim2P = millis(); } else { if (_tim2O) {if ( _isTimer(_tim2P, 4000)) _tim2O = 0; } } } if(_tim2O) {_ktim2 = 1;} else {_ktim2 = 0;} digitalWrite (14, _ktim2); digitalWrite (2, (!_ktim2)); _k10 = ((((digitalRead (16))) || (_k11)) &&((!_k2))); if (_k10) { _tim3O = 1; _tim3I = 1; } else { if (_tim3I) { _tim3I = 0; _tim3P = millis(); } else { if (_tim3O) {if ( _isTimer(_tim3P, 4000)) _tim3O = 0; } } } if(_tim3O) {_ktim3= 1;} else {_ktim3= 0;} digitalWrite (14, _ktim3); digitalWrite (1, (!_ktim3)); if (((_k2) &&((!_k4)))) { if (! _gen1I) { _gen1I = 1; _gen1O = 1; _gen1P = millis(); } } else { _gen1I = 0 ; _gen1O= 0; } if (_gen1I ) { if ( _isTimer ( _gen1P , 500 )) { _gen1P = millis(); _gen1O = ! _gen1O; } } if(_gen1O) {_kgen1 = 1;} else {_kgen1 = 0;} _k6 = _kgen1; } bool _isTimer(unsigned long startTime, unsigned long period ) { unsigned long endTime; endTime = startTime+period; return (millis() >= endTime); }все хорошо но не могу все это внедрить в общую часть, все время единица на открытие. через еще константу тоже не получилось обмануть
Опять флпрог притащили на форум.
лучше схему привести
ну часть стырена из него,
схему изделия.
это он такой кошмарный код рожает? да уж!!!
кнопок надо две - пуск и стоп, два концевика на заслонку и один реверсивный мотор, всё!!!
пины уже не совпадают, но принцип понятен, как мне начинающему это подошло для того что мне нужно, подправил для себя, возможно если будет время перепишу. концевеки стоят в моторе, но чтоб все время подавалась напряжение, тоже не хорошо. У меня три кнопки, третья на снятие аварии. пока на нее не нажмешь, открытие не возможно.
ну начинать надо с самого простого, подключить пока только мотор, для это требуются пины 7 и 8, пока всё, при включении питания на ардуину, надо установить их в состояние торможения, то-есть ноль на этих пинах. Это и сделайте, сможете?
sergb59,
судя по описанию задачи, устройство должно работать долго - днями, месяцами и годами, а не "включил на пять минут и выключил". Правильно?
В таком случае, обратите внимание на строки №№ 302-307 из #11. И подумайте, что произойдёт, когда millis перевалит за своё максимальное значение и начнёт снова с нуля. Боюсь, Ваша программа отреагирует не совсем адекватно.
да это сделано, просто из вашего примера, у меня работает кнопка закрыть. а вот открытие все время логическая единица, и мотор все время открывается. Из простого надо чтоб через время в константе freq, появилась единица на кнопке закрытие, тайминг закрытия у меня отрабатывает дальнейший скетч, и секонд через 10 , появился сигнал на кнопку открытие, остальное опять делает последующий скетч под R3. И так по кругу до бесконечности.
Да Евгений, можно было конечно заморочиться и поставить часы, но это удорожает все и программу увеличивает. Это нужно только для того чтоб не закисли заслонки.
можно было конечно заморочиться и поставить часы,
А можно и не заморачиваться, просто написать этот кусок кода правильно.
Так вот у меня загвозка на открытие, на закрытие все пучком , а вот открытие оно либо со временем забегает в моем случае, а в случае ua6em у меня все время мотор на открытие работает. Да и тут точность не нужна, можно через час сделать, сутки, месяц.
Спасибо, все справился, огромное спасибо ua6em , дополнительно поставил дополнительные переменные, и дальше в скетче (R3) в этих дополнительных переменных надо единичку превратить в ноль.
Спасибо, все справился, огромное спасибо ua6em , дополнительно поставил дополнительные переменные, и дальше в скетче (R3) в этих дополнительных переменных надо единичку превратить в ноль.
На некорректную работу с миллисом, что Евгений говорил, решили болт забить?
Я не настоящий сталевар, поэтому неблокирующий код сделал бы приблизительно так: (кнопки не подключал)
#define DIR1 7 #define DIR2 8 #define LED 13 #define TIMER1 10000 // время открытого состояния заслонки #define TIMER2 3000 // время закрытого состояния заслонки #define TIMER3 1000 // время перемещения заслонки volatile unsigned long timerTime; bool _t1 = 0; bool _t2 = 0; bool _t3 = 0; bool flag_t3 = 0; // 0 - CW, 1 - CCW bool flag_motor = 0; // 0 - OFF 1 - ON void setup() { Serial.begin(115200); // для отладки pinMode(DIR1,OUTPUT); pinMode(DIR2,OUTPUT); pinMode(LED,OUTPUT); setMotor(); _t1 = 1; timerTime = millis(); } void setMotor(void){ if(!flag_motor){ // режим стоп, торможение digitalWrite(DIR1,LOW); delayMicroseconds(4); digitalWrite(DIR2,LOW); digitalWrite(LED,LOW); }else{ if(!flag_t3){ // режим CW digitalWrite(DIR1,HIGH); delayMicroseconds(4); digitalWrite(DIR2,LOW); digitalWrite(LED,HIGH); }else{ // режим СCW digitalWrite(DIR1,LOW); delayMicroseconds(4); digitalWrite(DIR2,HIGH); digitalWrite(LED,HIGH); } } } // End setMotor void myTimer(unsigned long mytimer){ if(millis() - timerTime >= mytimer){ if(_t3==1){_t3=0; flag_motor =!flag_motor; timerTime=millis();} if(_t2==1){_t2=0; _t3=1; flag_t3 = !flag_t3; flag_motor =!flag_motor; timerTime=millis();} if(_t1==1){_t1=0;_t3=1; flag_t3 = !flag_t3; flag_motor =!flag_motor; timerTime=millis();} if(_t3==0){ if(flag_t3){_t2=1;}else{_t1=1;}}}} // End Timer void loop() { setMotor(); if(_t1==1){myTimer(TIMER1);} if(_t2==1){myTimer(TIMER2);} if(_t3==1){myTimer(TIMER3);} } // END LOOPДа, блин!
Питона на Вас нет!
Да, блин!
Питона на Вас нет!
так вроде читабельно, нет???
так вроде читабельно, нет???
Нет. Совершенно не читабельно, честно.
так вроде читабельно, нет???
Нет. Совершенно не читабельно, честно.
я жеж говорю, я не настоящий сталевар, в своих каракулях ориентируюсь неплохо )))
Конечно начало надо было написать иначе, как-то так:
#define SECONDS(x) ((x) * 1000UL) #define MINUTES(x) (SECONDS(x) * 60UL) #define HOURS(x) (MINUTES(x) * 60UL) #define DAYS(x) (HOURS(x) * 24UL) #define WEEKS(x) (DAYS(x) * 7UL) unsigned long timer1 = SECONDS(10); // время открытого состояния заслонки unsigned long timer2 = SECONDS(3); // время закрытого состояния заслонки unsigned long timer3 = SECONDS(1); // время перемещения заслонки #define CW 4 // кнопки закрытия, открытия и стоп #define CCW 5 #define STOP 6 #define DIR1 7 #define DIR2 8 #define LED 13 volatile unsigned long timerTime; bool _t1 = 0; bool _t2 = 0; bool _t3 = 0; bool flag_t3 = 0; // 0 - CW, 1 - CCW bool flag_motor = 0; // 0 - OFF 1 - ON void setup() { // Serial.begin(115200); // для отладки pinMode(DIR1,OUTPUT); pinMode(DIR2,OUTPUT); pinMode(LED,OUTPUT); pinMode(CW,INPUT); pinMode(CCW,INPUT); pinMode(STOP,INPUT); setMotor(); _t1 = 1; timerTime = millis(); } void setMotor(void){ if(!flag_motor){ // режим стоп, торможение digitalWrite(DIR1,LOW); delayMicroseconds(4); digitalWrite(DIR2,LOW); digitalWrite(LED,LOW); }else{ if(!flag_t3){ // режим CW digitalWrite(DIR1,HIGH); delayMicroseconds(4); digitalWrite(DIR2,LOW); digitalWrite(LED,HIGH); }else{ // режим СCW digitalWrite(DIR1,LOW); delayMicroseconds(4); digitalWrite(DIR2,HIGH); digitalWrite(LED,HIGH); } } } // End setMotor void myTimer(unsigned long mytimer){ if(millis() - timerTime >= mytimer){ if(_t3==1){_t3=0; flag_motor =!flag_motor; timerTime=millis();} if(_t2==1){_t2=0; _t3=1; flag_t3 = !flag_t3; flag_motor =!flag_motor; timerTime=millis();} if(_t1==1){_t1=0;_t3=1; flag_t3 = !flag_t3; flag_motor =!flag_motor; timerTime=millis();} if(_t3==0){ if(flag_t3){_t2=1;}else{_t1=1;}} } } // End Timer void loop() { byte cw,ccw,st; cw=digitalRead(CW); ccw=digitalRead(CCW); st=digitalRead(STOP); if(cw){_t1=0;_t2=0;_t3=1;flag_t3 = 0;flag_motor = 1; timerTime=millis();} if(ccw){_t1=0;_t2=0;_t3=1;flag_t3 = 1;flag_motor = 1; timerTime=millis();} if(st){_t1=0;_t2=0;_t3=0;flag_motor = 0;} setMotor(); if(_t1==1){myTimer(timer1);} if(_t2==1){myTimer(timer2);} if(_t3==1){myTimer(timer3);} } // END LOOPДак всё ясно-понятно. Кубофутурист в наших рядах.
Берет — как бомбу, берет — как ежа, как бритву обоюдоострую, берет, как гремучую в 20 жал змею двухметроворостую. Моргнул многозначаще глаз носильщика, хоть вещи снесет задаром вам. Жандарм вопросительно смотрит на сыщика, сыщик на жандарма.не )))
Я достаю из широких штанин...
смотрите, завидуйте, я гражданин...
PS а вот ТС Евгений Петровича напрасно не прислушался )))
ЗЗЫ в моем коде зато проблемы millis() НЕТ!
Если нужны интервалы в минуты-часы-сутки, то лучше это делать не на милисе напрямую. На милисе формировать некий базовый, например 1 секунда или другой удобный. По этому интервалу инкрементить счётчик. Дальше интервалы формировать на этом счетчике. Если нужны еще больше интервалы - можно повторить изавести второй счетчик для больших интервалов. Тогда и переполнения не страшны, и реализация проще.
Если нужны интервалы в минуты-часы-сутки, то лучше это делать не на милисе напрямую. На милисе формировать некий базовый, например 1 секунда или другой удобный. По этому интервалу инкрементить счётчик. Дальше интервалы формировать на этом счетчике. Если нужны еще больше интервалы - можно повторить изавести второй счетчик для больших интервалов. Тогда и переполнения не страшны, и реализация проще.
Нет, не проще, а даже строго наоборот. Считать по миллисекундам нужный интервал это проще, чем считать по миллисекундам промежуточный интервал, а потом по промежуточному интервалу считать нужный. Что за мода не думать, перед тем как пишешь?
ТС, никак антипротечку делаешь? У мня каждый день, вентиля закрываюца/открываются в час ночи, чтоб не закисли. Нада, наерна, праэктик выкласть.
"блинк" с часовой задержкой,не?
"блинк" с часовой задержкой,не?
по сути да
Тогда и переполнения не страшны
С какого бодуна? Хоть какие счётчики заводи, а если с миллис работать, как в #11, косяк с переполнением никуда не денется.
Тогда и переполнения не страшны
С какого бодуна? Хоть какие счётчики заводи, а если с миллис работать, как в #11, косяк с переполнением никуда не денется.
косяк не только с миллис, а полное отсутствие информации о реальном положении заслонки при включении?
Команды - исходное положение принять - нету )))
ТС, никак антипротечку делаешь? У мня каждый день, вентиля закрываюца/открываются в час ночи, чтоб не закисли. Нада, наерна, праэктик выкласть.
так в чём дело - выкладывай, коль спрос есть