Появилась тут задача: надо сделать быстро контроллер сварочного аппарата для точечной сварки. Отсеивая всякие рассуждения, задачу можно свести к тому, что надо замыкать пару контактов на определенное время. То есть нажал на кнопку, он бабахнул и все, стоит ждет пока ты кнопку отпустишь.
Так как задача класса “быстро и не гламурно”, то было решено взять из закромов макетную плату, ардуинку и из этого сделать всю положенную обвязку для одной-единственной релюшки.
Для проверки “а пойдет” рисую схему
Светодиодиками буду показывать, какое время импульса выбрано, энкодером выбирать и релюшкой щелкать. После предварительной обкатки набросал печатную плату. Именно набросал, ибо реализовывать буду все равно на макетной, а тут просто прикинул наиболее лучшее взаимное расположение деталей, что бы лишних проводков не тянуть.
Потом посмотрел, как оно будет выглядеть “в реале”
Вроде ничего, гламурно даже. Правда, в процессе пайки мне стало лень паять столько резисторов и я взял резисторную сборку. Ну и немного поменял расположение компонентов, ибо макетная плата у меня “не ровная”. В общем, получилось вот так
Теперь добавляем щепотку “магии”
#include <EEPROM.h> int pinAch = 2; //Энкодер вывод А включен на interrupt 0 (D2) int pinBch = 3; // Энкодер вывод Б - D3 int pinled = 5; // Куда включен первый сетодиодик int ledcount = 8; // Сколько светодиодиков int pinButton = A5; // куда включена кнопка "пуск" int pinRelay = A0; // Куда подключено реле int impulsTime = 50; // Время включения реле по умолчанию (50 мс) int relayShift = 2; // Время реакции реле unsigned long bl; // переменная для хранения состояния "мигающего" светодиода unsigned long dr; // переменная для антидребезга энкодера int out=0; // мы бабахнули? void setup() { Serial.begin(9600); pinMode(pinAch, INPUT_PULLUP); pinMode(pinBch, INPUT_PULLUP); pinMode(pinled, OUTPUT); pinMode(pinled+1, OUTPUT); pinMode(pinled+2, OUTPUT); pinMode(pinled+3, OUTPUT); pinMode(pinled+4, OUTPUT); pinMode(pinled+5, OUTPUT); pinMode(pinled+6, OUTPUT); pinMode(pinled+7, OUTPUT); pinMode(13, OUTPUT); // светодиодик, впаянный в ардуинку pinMode(pinButton, INPUT_PULLUP); pinMode(pinRelay, OUTPUT); digitalWrite(pinled, HIGH); // все светодидиоды включить для проверки digitalWrite(pinled+1, HIGH); digitalWrite(pinled+2, HIGH); digitalWrite(pinled+3, HIGH); digitalWrite(pinled+4, HIGH); digitalWrite(pinled+5, HIGH); digitalWrite(pinled+6, HIGH); digitalWrite(pinled+7, HIGH); digitalWrite(pinRelay,LOW); // для безопасности dr=millis(); bl=millis(); if(EEPROM.read(0)==1) { impulsTime=EEPROM.read(1); } attachInterrupt(0, encoderClick, RISING); } void loop() { // Зажигаем светодиодики в зависимости от уровня impulsTime for(int i=pinled;i<(pinled+ledcount);i++) { int s=(i-pinled+1)*10; // время импульса для зажигания светодиода // то есть для 1 светодиода 10, для 2 - 20 и так далее if((impulsTime-s)<0 && (impulsTime-s)>-10) // этот светодиодик промежуточный, поэтому пусть мигает. { if((millis()-bl)<500) { digitalWrite(i,HIGH); } else { digitalWrite(i,LOW); if((millis()-bl)>1000) { bl=millis(); } } } else { if(s<=impulsTime) { digitalWrite(i,HIGH); } else { digitalWrite(i,LOW); } } } if(digitalRead(pinButton)==LOW && out==0) // оппа, кнопку нажали и еще не бабахали { delay(100); // ждем 100мс - вдруг рука дрогнула if(digitalRead(pinButton)==LOW) // точно нажата? { digitalWrite(13,HIGH); digitalWrite(pinRelay,HIGH); out=1; delay(impulsTime+relayShift); digitalWrite(13,LOW); digitalWrite(pinRelay,LOW); out=1; EEPROM.write(0, 1); // ставим флаг EEPROM.write(1, impulsTime); } } if(digitalRead(pinButton)==HIGH && out==1) // Кнопку отпустили после бабханья { delay(100); // ждем 100мс - вдруг рука дрогнула if(digitalRead(pinButton)==HIGH) // до сих пор отпущена? { out=0; // Хорошо, можно еще раз бабахнуть } } // Serial.println(impulsTime); // delay(300); } // обработка энкодера void encoderClick(){ if((millis()-dr)>10) // От предидущего прерывания прошло больше 10мс? если нет, то это дребезг { dr=millis(); int valA = digitalRead(pinAch); int valB = digitalRead(pinBch); if (valA != valB){ impulsTime--; } else{ impulsTime++; } if(impulsTime < 5) { impulsTime=5; } if(impulsTime > 100) { impulsTime=100; } Serial.println(impulsTime); } }
И проверяем, насколько полученное устройство соответствует заявленным мной же спецификациям
Импульс в 20 миллисекунд
В 50
и 75, что бы не было ровных чисел.
Теперь осталось только устроить ресурсные испытания релюшке и узнать, сколько времени она выдержит в таком режиме. Но это уже не так интересно, ибо стоимость релюшки около 100 рублей и перепаять ее – дело буквально пяти минут.
Задача выполнена быстро и с перерасходом ресурсов, как и положено для такого класса задач 🙂