1.2.22. fejezet, Eventually: az esemény vezérelt programozás egyszerűen

Hasznos linkek

Hasonló projektek

Minta alkalmazás

Ez egy WC lámpa kapcsoló algoritmusa. Mikor kinyílik az ajtó, felkapcsolódik a világítás. Mikor becsulódik, ellenőrzi az ülőkétől mért a távolságot egy ultrahangos távolságmérő. A távolságmérés azért jobb a mozgásérzékelésnél, mert mozgás hiányában lekapcsolhat a lámpa. A program az Eventually könyvtárat használja.

Az Eventually könyvtár EvtPinListener csak a gombnyomás tényéről értesítene. Ezért implementálni kell a EvtPinChangeListener-t a pinevent.h-ban.

class EvtPinChangeListener : public EvtListener {
  protected:
	int pin;
	int lastRead;
  public:
	EvtPinChangeListener(int pin, EvtAction t);
	void setupListener();
	bool isEventTriggered();
};
 
EvtPinChangeListener::EvtPinChangeListener(int pin, EvtAction t) {
  this->lastRead = -1;
  this->pin = pin;
  this->triggerAction = t;
}
 
void EvtPinChangeListener::setupListener() {
 
}
 
bool EvtPinChangeListener::isEventTriggered() {
  int readed = digitalRead(pin);
  bool result;
  if (lastRead == -1) {
	this->lastRead = readed;
	result = false;
  } else {
    result = this->lastRead != readed;
    this->lastRead = readed;
  }
  return result;
}

A következő kód végzi a vezérlést.

#include <Eventually.h>
#include "pinevent.h"
 
EvtManager mgr;
 
const char buttonPin = 5;
const char TRIGGERPIN=6;
const char ECHOPIN=7;
const int ledPin =  13;
 
int buttonState = 0;
int lastOffTimer = 0;
 
void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  pinMode(buttonPin, INPUT);
  pinMode(TRIGGERPIN,OUTPUT); 
  pinMode(ECHOPIN,INPUT);
  Serial.begin(9600);
  Serial.println("Setup...");
  mgr.addListener(new EvtPinChangeListener(buttonPin, (EvtAction)checkDoor));
  Serial.println("Listeners started.");
}
 
bool checkDoor() {
  Serial.println("Door swith changed.");
  buttonState = digitalRead(buttonPin);
  mgr.resetContext();
  if (buttonState == HIGH) {
    Serial.println("Switch Led on.");
    digitalWrite(ledPin, LOW);
    mgr.addListener(new EvtPinChangeListener(buttonPin, (EvtAction)checkDoor));
  } else {
    Serial.println("Check distance.");
    mgr.addListener(new EvtTimeListener(500, true, (EvtAction)checkDistance));
    mgr.addListener(new EvtPinChangeListener(buttonPin, (EvtAction)checkDoor));    
  }
}
 
bool checkDistance() {
  long duration, distance;
  digitalWrite(TRIGGERPIN,LOW);
  delayMicroseconds(3);
  digitalWrite(TRIGGERPIN,HIGH);
  delayMicroseconds(12);
  digitalWrite(TRIGGERPIN,LOW);
  duration = pulseIn(ECHOPIN,HIGH);
  distance = 10 * duration / 58.2;
  Serial.print("distance:");
  Serial.print(distance);
  Serial.println(" mm");
  if (distance < 500) {
    lastOffTimer = 0;
  } else {
    lastOffTimer += 1;
    if (lastOffTimer > 10){
      lastOffTimer = 0;
      digitalWrite(ledPin, HIGH);
      mgr.resetContext();
      mgr.addListener(new EvtPinChangeListener(buttonPin, (EvtAction)checkDoor));
    }
  }
  return true;
}
 
USE_EVENTUALLY_LOOP(mgr)

A példában jól látható hogyan lehet új eseménykezelőt definiálni. Egy, a soros portról érkező eseményeket például az alábbi serialevent.h-ban definiált EvtSerialListener osztály végezheti:

class EvtSerialListener : public EvtListener {
  protected:
    Stream * _serial;
  public:
    EvtSerialListener(Stream *serial, EvtAction t);
    void setupListener();
    bool isEventTriggered();
};
 
EvtSerialListener::EvtSerialListener(Stream *serial, EvtAction t) {
  this->_serial = serial;
  this->triggerAction = t;
}
 
void EvtSerialListener::setupListener() {
 
}
 
bool EvtSerialListener::isEventTriggered() {
  return _serial->available();
}

Ez a kód - ügyelve a Serial globális változó inicializálására, pedig a soros port echo funkcióját végzi:

#include <Eventually.h>
#include "serialevent.h"
 
EvtManager mgr;
char inChar;
bool serialAction() {
  while(Serial.available() > 0) {
    inChar = Serial.read();
    Serial.print(inChar);
  }
  return true;
}
 
void setup() {
  Serial.begin(9600);
  while(!Serial);
  mgr.addListener(new EvtSerialListener(&Serial, (EvtAction) serialAction));
  Serial.println("Listeners started.");
}
 
USE_EVENTUALLY_LOOP(mgr)