Управление реле через ультразвуковой датчик расстояния
- Войдите на сайт для отправки комментариев
Сильно не ругайтесь, если что :)
Я только сегодня стал счастливым обладателем ардуинки. Уже успел помигать светодиодом с небольшими усовершенствованиями (двойное короткое мигание + пауза), научился работать с реле, определять расстояние с УЗ-датчика расстояния (для удобства вынес в отдельную функцию).
Для случая, когда включаем реле при поднесении руки ближе чем на 15см к УЗ-датчику, проблем нет, это элементарная логика: определяем расстояние, затем если оно меньше 15см, то включаем реле, иначе отключаем.
Проблема возникла когда появилась идея при первом поднесении руки включать реле, при втором - выключать, и так далее. Сложность не в ардуинке, и не в языке программирования, а именно в мозгу - не могу понять, как правильно обрабатывать такие условия, какие переменные выставлять, как запоминать в переменных факт наведения, и в конечном итоге - в каком случае включать/отключать реле, а в каком - ничего не делать.
На данный момент вот такой код, но он явно не рабочий, и получится в результате мучений, проб и ошибок:
const int pinUltraSonicTrig = 8;
const int pinUltraSonicEcho = 4;
const int pinRelay = 2;
const int pinLed = 13;
boolean RelayOn = false;
boolean LastDistIsLow = false;
boolean DistChanged = true;
void setup() {
Serial.begin(9600);
pinMode(pinUltraSonicTrig,OUTPUT);
pinMode(pinUltraSonicEcho,INPUT);
pinMode(pinRelay,OUTPUT);
pinMode(pinLed,OUTPUT);
}
void loop() {
int cm = GetDistance(pinUltraSonicTrig, pinUltraSonicEcho);
boolean LowDist = cm<=15;
Serial.print(cm);
Serial.print("cm");
Serial.println();
if(LowDist) {
if(DistChanged){
if(RelayOn) {
digitalWrite(pinRelay,HIGH);
} else {
digitalWrite(pinRelay,LOW);
}
RelayOn = !RelayOn;
LastDistIsLow = true;
}
}
if(LastDistIsLow == LowDist) {
DistChanged = true;
}
digitalWrite(pinLed,HIGH);
delay(100);
digitalWrite(pinLed,LOW);
delay(100);
}
int GetDistance(int pinTrig, int pinEcho)
{
digitalWrite(pinTrig, LOW);
delayMicroseconds(2);
digitalWrite(pinTrig, HIGH);
delayMicroseconds(10);
digitalWrite(pinTrig, LOW);
pinMode(pinEcho, INPUT);
long duration = pulseIn(pinEcho, HIGH);
long cm = duration / 29 / 2;
return cm;
}
Но тут вся логика проверка не та.. Нужно как-то по-другому. Буду благодарен всем, кто откликнется.
Хватило поужинать, отдохнуть, поиграть с ребенком, и после этого за 5 минут все заново переписал. Вот что значит голова перестает соображать. А то я уж испугался: если такое не получается самостоятельно сделать, то что же будет дальше..
Если кому-то вдруг пригодится, то вот:
const int pinUltraSonicTrig = 8; const int pinUltraSonicEcho = 4; const int pinRelay = 2; const int pinLed = 13; boolean firstMove = true; boolean lastIsNear = false; boolean relayOn = false; void setup() { Serial.begin(9600); pinMode(pinUltraSonicTrig,OUTPUT); pinMode(pinUltraSonicEcho,INPUT); pinMode(pinRelay,OUTPUT); pinMode(pinLed,OUTPUT); } void loop() { int cm = GetDistance(pinUltraSonicTrig, pinUltraSonicEcho); if(cm>0) { Serial.println(cm); boolean IsNear = cm<=15; if (IsNear && !lastIsNear) { if(relayOn) { digitalWrite(pinRelay,LOW); digitalWrite(pinLed,LOW); } else { digitalWrite(pinRelay,HIGH); digitalWrite(pinLed,HIGH); } relayOn = !relayOn; } lastIsNear = IsNear; } delay(100); } int GetDistance(int pinTrig, int pinEcho) { digitalWrite(pinTrig, LOW); delayMicroseconds(2); digitalWrite(pinTrig, HIGH); delayMicroseconds(10); digitalWrite(pinTrig, LOW); pinMode(pinEcho, INPUT); long duration = pulseIn(pinEcho, HIGH); long cm = duration / 29 / 2; return cm; }