Помогите с регулируемым дозатором.
- Войдите на сайт для отправки комментариев
Пнд, 12/03/2018 - 12:46
Всем доброго дня.
Люди добрые прошу Вашей помощи в корректировке скетча (может найдется добрая душа и поможет по доброй воле).
Задача стоит такая: после включения микроконтроллера одновременно каждые 15 секунд должны срабатывать два реле (пока светодиоды) на время которое устанавливается потенциометром (от 0 до 14 секунд) . И так бесконечно, до отключения МК.
Собрал сборую солянку из нескольких скетчей, вроде что то получилось ( светодиоты включаются каждые 15 секунд, время выключения регулируется) , но не получается сделать одновременное включение каждые 15 секунд.
const int pot1=1; // потенциометр №1 пин А1
int ledPin1 = 2; // номер пина со светодиодом
int ledState1 = LOW; // состояние светодиода
unsigned long previousMillis1 = 0;// последний момент времени, когда состояние светодиода изменялось
long OnTime1 = 0; // длительность свечения светодиода (в миллисекундах)
long OffTime1 = 0; // светодиод не горит (в миллисекундах)
const int pot2=2; // потенциометр №2 пин А2
int ledPin2 = 3; // номер пина со светодиодом
int ledState2 = HIGH; // состояние светодиода
unsigned long previousMillis2 = 0;// последний момент времени, когда состояние светодиода изменялось
long OnTime2 = 0; // длительность свечения светодиода (в миллисекундах)
long OffTime2 =0; // светодиод не горит (в миллисекундах)
void setup() {
// устанавливаем цифровой пин со светодиодом как ВЫХОД
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
}
void loop() {
// выясняем не настал ли момент сменить состояние светодиода
unsigned long currentMillis = millis(); // текущее время в миллисекундах
OnTime1=(analogRead(pot1)*14); // ЗАДАЕМ ВРЕМЯ ВКЛЮЧЕНИЯ СВЕЧЕНИЯ СВЕДОДИОДА, АНАЛОГОВЫЙ ВХОД 1063* 14= 14,8 СЕКУНДЫ
OffTime1=(15000-OnTime1); // ВЫСЧИТЫМАЕМ ОСТАВШЕЕСЯ ВРЕМЯ ОТ 15 СЕКУНД. СВЕДОДИЛД НЕ СВЕТИТСЯ
// конечный автомат для 1-го светодиода
if((ledState1 == HIGH) && (currentMillis - previousMillis1 >= OnTime1))
{
ledState1 = LOW; // выключаем
previousMillis1 = currentMillis; // запоминаем момент времени
digitalWrite(ledPin1, ledState1); // реализуем новое состояние
}
else if ((ledState1 == LOW) && (currentMillis - previousMillis1 >= OffTime1))
{
ledState1 = HIGH; // включаем
previousMillis1 = currentMillis ; // запоминаем момент времени
digitalWrite(ledPin1, ledState1); // реализуем новое состояние
}
// конечный автомат для 2-го светодиода
OnTime2=(analogRead(pot2)*14);// ЗАДАЕМ ВРЕМЯ ВКЛЮЧЕНИЯ СВЕЧЕНИЯ СВЕДОДИОДА, АНАЛОГОВЫЙ ВХОД 1063* 14= 14,8 СЕКУНДЫ
OffTime2=(15000-OnTime2);// ВЫСЧИТЫМАЕМ ОСТАВШЕЕСЯ ВРЕМЯ ОТ 15 СЕКУНД. СВЕДОДИЛД НЕ СВЕТИТСЯ
if((ledState2 == HIGH) && (currentMillis - previousMillis2 >= OnTime2))
{
ledState2 = LOW; // выключаем
previousMillis2 = currentMillis; // запоминаем момент времени
digitalWrite(ledPin2, ledState2); // реализуем новое состояние
}
else if ((ledState2 == LOW) && (currentMillis - previousMillis2 >= OffTime2))
{
ledState2 = HIGH; // выключаем
previousMillis2 = currentMillis ; // запоминаем момент времени
digitalWrite(ledPin2, ledState2); // реализуем новое состояние
}
}
За ранее блогодарен.
Что такое "одновременное включение нескольких светодиодов "? И в чем разница от включения одного? Что мешает включать, как лампы в люстре - одним общим выключателем три лампочки?
Что такое "одновременное включение нескольких светодиодов "?
Скорее всего включаются одновременно, а длительнось горения СД - разная.
А может быть и нет?
ТС не очень внятно изложил суть проблемы. Он для простой задачи делает очень много лишних непогятных телодвижений. Зачем проверять Сколько времени СД осталось быть потушенным? Да и мого еще чего.
Не проще-ли
-Считать время горения (обооих) СД
-Зажечь оба
затем три делея все равно программа больше ничего не делет
- первый (тот кто меньше горит) 15 сек"-" время горения 1 СД
- выключаем 1 СД
-второй 15 сек"-" разница времени горения 1 и 2 СД
-Выключаем оба СД
-третий 15 "-" что осталось
и так по кругу (гоу туначало). Конечно грубо по рабоче-крестьянски, но работать будет, но если использовать миллис, будет красивее и можно менять время выключения в текущем цикле.
Все верно.
Светодиоды должны включаться одновременно , а длительность горения регулируется потенцеометром. Затем они снова одновременно включаются. Смысл в том , что необходимо обеспечить обновременное включение сведодиодов каждые 15 секунд.
Вся задача состоит в том, что бы каждые 15 секунд одновременно включать лампочки на "люстре" , а потенцеометром регулировать время горения каждой отдельно. Время горения всех лампочек разное и составляет от 0 до 14 секунд, время не горения все что остается до следующего цикла включения.
Время горения всех лампочек разное и составляет от 0 до 14 секунд, время не горения все что остается до следующего цикла включения.
А зачем вам его знать? Тупо каждые 15 сек включаете и все. Это абсолютно лишняя информация которая не нужна ни вам, ни ардуине и тем более лампочке. Её задача загореться когда наступят следующие 15 сек.
Ее основной задачей является регулируемое время горения и включение каждые 15 секунд.
Решил реанимировать старый дозатор жидких компонентов( очень удобный).
Каждые 15 секунд происходит слив компонентов ( горит светодиод) , время слива каждого компонента регулируется отдельно потенциометром (0-14 сек.), после паузы (светодиод не горит) которая получается тоже разной по времени, наступает цикл очередных 15 секунд и все заново.
Очень удобно проверять минутный расход жидкости слитый с дозировок.
Так вы не читаете, что вам пишут.
У вас раздельные задачи такие:
1) Каждые 15 сек. зажигать все светодиоды;
2) Каждые N секунд после наступления момента (1) гасить светодиод.
Пункт (2) повторять по количеству светодиодов.
Ее основной задачей является регулируемое время горения и включение каждые 15 секунд.
Ну и на здоровье. Еще раз просмотрите алгоритм который я предложил. Если есть неточности исправьте.
У Вас слишком все заморочено . Будьте проще.
Спасибо. Надо попробовать. Что получится отпишусь.
Успехов. Все получится программа очень простая.
Но после того как все это заработает, скорее всего придется сделать индикацию временных задержек, потому что судить о времени по положению резистора- это мягко говоря моветон.
как-то так
int reo1=0; int reo2=0; unsigned long time1 = 0; unsigned long time2 = 0; #define lamp1 2 #define lamp2 3 boolean flag1 = 0; boolean flag2 = 0; void setup() { pinMode(A1, INPUT); pinMode(A2, INPUT); pinMode(2, OUTPUT); pinMode(3, OUTPUT); digitalWrite(lamp1, LOW); digitalWrite(lamp2, LOW); start(); } void loop() { if (time2>=15000){start();} time2=millis()-time1; reo(); if (time2>=reo1 && flag1==1 ){digitalWrite(lamp1, LOW);flag1=0;} if (time2>=reo2 && flag2==1 ){digitalWrite(lamp2, LOW);flag2=0;} } void start(){ digitalWrite(lamp1, HIGH); digitalWrite(lamp2, HIGH); time1=millis(); flag1=1; flag2=1; } void reo() { reo1 = analogRead(A1); reo2 = analogRead(A2); reo1 = map(reo1, 0, 1023, 0, 14000); reo2 = map(reo2, 0, 1023, 0, 14000); }А строки 39 и 40 нужны? И сответственно проверка их и инвертирование флагов в 29 и 30 строках?
Ардуина не переломится если лишний раз выключит уже выключенный светодиод, а код будет лаконичней и понятней.
это для тех кто кричит: аааа!!! процессорное времяяя, аааа!!!! зачем лишний раз тыкать пин)))
ну и соответственно все что в фунции reo() можно в start() перенести, но тогда считывание показаний резисторов будет раз в 15 секунд
Огромное спасибо за скетч.
Все работает.
Буду изучать программирование.
это для тех кто кричит: аааа!!! процессорное времяяя, аааа!!!! зачем лишний раз тыкать пин)))
А ежели пин отщелкнется? Лучше тыкать...
специально для лучшего чтения
int reo1=0; int reo2=0; int Vr_zikl=15000; //время цикла int Vr_reo=15000; // максимальное время работы лампочки во ремя цикла unsigned long time1 = 0; unsigned long time2 = 0; #define lamp1 2 #define lamp2 3 void setup() { pinMode(A1, INPUT); pinMode(A2, INPUT); pinMode(2, OUTPUT); pinMode(3, OUTPUT); digitalWrite(lamp1, LOW); digitalWrite(lamp2, LOW); start(); } void loop() { if (millis()-time1>=Vr_zikl){start();} if (millis()-time1>=reo1){digitalWrite(lamp1, LOW);} if (millis()-time1>=reo2){digitalWrite(lamp2, LOW);} } void start(){ reo1 = map(analogRead(A1), 0, 1023, 0, Vr_reo ); reo2 = map(analogRead(A2), 0, 1023, 0, Vr_reo); digitalWrite(lamp1, HIGH); digitalWrite(lamp2, HIGH); time1=millis(); }Нечего писать. Круто. В нашей стране еще есть мозги.
Уважение.
Спасибо.
специально для лучшего чтения
Ну вот, совсем другое дело. А то как у Льва Толстого "Война и мир", читать задолбаешься и в конце уже не поймешь, зачем Анна Каренина Му- Му под поезд бросила.
И человеку помогли, теперь уже по другому будет смотреть на программирование,не просто копировать куски чужих скетчей, а сначала думать.
но ведь не поберег проц время, луп и покороче мог быть. печалька((
но ведь не поберег проц время, луп и покороче мог быть. печалька((
Нормальный Луп
Японцы такие штуки Хокку называют.
А если ищщё вот так. Вроде ничего не напутал в ночи.
uint32_t reo1 = 0, reo2 = 0, Vr_zikl = 15000, //время цикла Vr_reo = 15000, // максимальное время работы лампочки во ремя цикла time1 = 0, time2 = 0; #define lamp1 2 #define lamp2 3 void setup() { pinMode(A1, INPUT); pinMode(A2, INPUT); pinMode(2, OUTPUT); pinMode(3, OUTPUT); // На первом же проходе loop() сработает условие и вызовет start() time1 = Vr_zikl; } void loop() { digitalWrite(lamp1, !(millis() - time1 >= reo1)); digitalWrite(lamp2, !(millis() - time1 >= reo2)); if (millis() - time1 >= Vr_zikl) { reo1 = map(analogRead(A1), 0, 1023, 0, Vr_reo ); reo2 = map(analogRead(A2), 0, 1023, 0, Vr_reo); time1 = millis(); } }sadman41, тогда уж убрать строки 6, 12 и 13, а в 14 и 15 использовать lamp*.
uint32_t Vr_zikl = 15000, //время цикла Vr_reo = 15000, // максимальное время работы лампочки во ремя цикла time1 = 0; #define lamp1 2 #define lamp2 3 void setup() { pinMode(lamp1, OUTPUT); pinMode(lamp2, OUTPUT); // На первом же проходе loop() сработает условие и вызовет start() time1 = Vr_zikl; } void loop() { digitalWrite(lamp1, !(millis() - time1 >= map(analogRead(A1), 0, 1023, 0, Vr_reo ))); digitalWrite(lamp2, !(millis() - time1 >= map(analogRead(A2), 0, 1023, 0, Vr_reo))); if (millis() - time1 >= Vr_zikl) { time1 = millis(); } }Правда, немножко изменится поведение при вращении потенциометров - реакция ускорится вплоть до повторного открытия за один 15-секундный цикл.
А я не против. Но посчитал, что не очень правильно менять установки по ходу пьесы. Мало ли там чего задел случайно.
А если убрать лишние переменные, и заменить их просто числами, то будет еще лаконичнее:
uint32_t time1 = 15000; #define lamp1 2 #define lamp2 3 void setup() { pinMode(lamp1, OUTPUT); pinMode(lamp2, OUTPUT); } void loop() { digitalWrite(lamp1, !(millis() - time1 >= map(analogRead(A1), 0, 1023, 0, 15000))); digitalWrite(lamp2, !(millis() - time1 >= map(analogRead(A2), 0, 1023, 0, 15000))); if (millis() - time1 >= 15000) {time1 = millis();} }Еще можно и дефайны убрать и выхода назначить через регистры и ничего от программы не останется.
Тогда уж лучше через дефайны 15000 задавать в мапе и условии. Иначе непонятно, что они значат.
Это я так просто, для того кто пишет программу все будет ясно, а остальным продется немного подумать.
Ну а в принципе неплохая тема получилась и достаточно познавательная для начинающих.
Спасибо за помощь. С Вашей помощью у меня все получилось. Силовую часть и ящик соберем и на испытания.
А если убрать лишние переменные, и заменить их просто числами, то будет еще лаконичнее:
Они не лишние.
Кроме того, в исходном коде было две разные константы (хотя почему-то они были объявлены равными, хотя по условию должны быть разными: 14000 и 15000). И это важно.
В общем, эти правки явно в ущерб исходнику.