Tworzenie klas obsługujących przekaźniki.
Zanim napiszesz cały program musisz napisać klasy obsługujące przekaźniki.
Pierwsza klasa Relay() będzie obsługiwać zwykłe przekaźniki podłączone do określonych pinów. Każda klasa składa się z dwóch plików pliku.h i pliku.cpp. Druga klasa RFSwitch() będzie obsługiwać przekaźniki sterowane za pomocą pilota na częstotliwość radiowej 433MHz lub 866MHz. Takie przekaźniki można kupić w różnych marketach. Ja swoje kupiłem w Biedronce. Zestaw składa się z trzech przekaźników na 230V i jednego pilota.
Program będzie mógł obsługiwać jednym przyciskiem zwykły przekaźnik podłączony do określonego pinu i przekaźnik sterowany radiem. W tym przypadku głównymi przekaźnikami będą przekaźniki sterowane radiem. Przekaźniki zwykłe nie będą podłączone. Potrzebna by była płytka PCB z zamontowanymi przekaźnikami. Płytkami PCB zajmiemy się w innym czasie.
Zacznij od klasy Relay(). Należy utworzyć plik Relay.h. Zawartość poniżej. Plik ten zawiera zmienną pin, konstruktor, destruktor i nazwy funkcji jakie ma posiadać klasa Relay(). Najnowsza wersja tego programu znajduje się tutaj.
/* * Relay.h * * Copyright (c) 2016. All rights reserved. * * Author: Jan Trzciński <poljant@post.pl> * * Klasa Relay umożliwia obsługę i kontrolę pracy przkaźnika * podłączonego do określonego pinu. */ #ifndef RELAY_H_ #define RELAY_H_ class Relay { int pin;//nr pinu public: Relay();//konstruktor virtual ~Relay();//destruktor void setPin(int); //ustaw nr pinu void begin(int); //uruchom obiekt na podanym pinie void begin(); //uruchom obiekt void setOn(); //załącz przekaźnik void setOff(); //wyłącz przekaźnik int read(); //czytaj stan przekaźnika }; #endif /* RELAY_H_ */
Wszystkie te dane są rozbudowane w pliku Relay.cpp (piszemy w języku C++). Stosowanie poszczególnych funkcji przedstawię w dalszej części. Zawartość tego pliku poniżej.
/* * Relay.cpp * * Copyright (c) 2016. All rights reserved. * * Author: Jan Trzciński <poljant@post.pl> */ #include "Relay.h" Relay::Relay() { //konstruktor pin = 0; } Relay::~Relay() //destruktor tu nic nie robi { } //uruchom obiekt na podanym pinie void Relay::begin(int p) //przyporządkowanie przekaźnika do pinu { pin = p;//zapamiętaj nr pinu pinMode(pin, OUTPUT);//ustaw pin na OUPUT digitalWrite(pin, LOW);//wyłącz przekaźnik } //uruchom obiekt void Relay::begin() { pinMode(pin, OUTPUT); digitalWrite(pin, LOW); } // załącz przekaźnik void Relay::setOn(void) { digitalWrite(pin, HIGH); } //wyłącz przekaźnik void Relay::setOff(void) { digitalWrite(pin, LOW); } // czytaj stan przekaźnika int Relay::read(void) { return digitalRead(pin); } // ustaw nr pinu void Relay::setPin(int p){ pin = p; }
Jak widzisz funkcje te są bardzo proste. Co robią poszczególne funkcje wynika z ich nazw. Najnowszy kod tego programu znajduje się tutaj.
Następną klasą jest klas RFSwitch() i jest trochę bardziej rozbudowana. Klasa ta wykorzystuje bibliotekę RCSwitch.h.
Utwórz plik RFSwitch.h, który zawiera deklaracje klasy RFSwitch.
/* * RFSwitch.h * * Created on: 20.02.2017 * Author: Jan Trzciński * * Klasa RFSwitch umożliwia nadawanie kodów załączenia i wyłączenia przekaźników * sterowanych radiem na 433MHz lub 866MHz. * Jest to zestaw tanich i popularnych przekaźników 230V. * Do uruchomienia układu potrzebny jest nadajnik RF na 433MHz lub 866MHz */ #ifndef RFSWITCH_H_ #define RFSWITCH_H_ #include <RCSwitch.h> class RFSwitch { //zmienne prywatne uint32_t ncodOn; //kod załączenia uint32_t ncodOff; //kod wyłączenia public: //zmienne publiczne uint16_t lengthLH; //długość impulsu w us uint8_t protocol; // nr protokołu (zależy od typu przekaźnika) uint8_t RF; //stan przekaźnika 0 - wyłączony, 1 - załączony public: RFSwitch(); //konstruktor virtual ~RFSwitch(); //destruktor void begin(uint8_t); //rozpocznij i ustaw pint Tx void sendOn(void); // wyślij kod załączenia void sendOff(void); // wyślij kod wyłączenia uint8_t readRF(void); // czytaj stan wyłącznika RF void writeRF(uint8_t); // zapisz stan wyłącznika RF void setCodOn(uint32_t); //ustaw kod załączenia void setCodOff(uint32_t); // ustaw kod wyłączenia void setRF(uint8_t, uint8_t, uint8_t); //ustaw parametry wyłącznika RF void readCod(uint8_t); //czyta kod z odbiornika podłączonego do podanego pinu void readCod(void); //czyta kod z odbiornika podłączonego do pinu RFpinRx uint32_t getCodOn(void); //czytaj kod On przekaźnika RF uint32_t getCodOff(void); //czytaj kod Off przekaźnika RF }; #endif /* RFSWITCH_H_ */
Gdy już wiemy co ma zawierać klasa utwórz plik RFSwitch.cpp.
/* * RFSwitch.cpp * * Created on: 20.02.2017 * Author: Jan Trzciński */ #include <RCSwitch.h> #include "RFSwitch.h" RCSwitch rcread; //utwórz objekt rcread //konstruktor RFSwitch::RFSwitch() { //zmienne prywatne ncodOn = 0; //kod załączenia ncodOff = 0; //kod wyłączenia lengthLH =200; //długość impulsu wysokiego protocol = 1; // nr protokołu RF = 0; //stan przekaźnika } //destruktor RFSwitch::~RFSwitch() { } //zainicjuj nadawanie na pinie pTx void RFSwitch::begin( uint8_t pTx){ //włącz system nadawania na pinie pTx rcread.enableTransmit(pTx); } //zapisz podany kod załączenia void RFSwitch::setCodOn(uint32_t cod){ ncodOn = cod; } //zapisz podany kod wyłączenia void RFSwitch::setCodOff(uint32_t cod){ ncodOff = cod; } //wyślij kod wyłączenia przekaźnika void RFSwitch::sendOff(void){ //ustaw rodzaj protokołu i długość impulsu HIGH rcread.setProtocol(protocol,lengthLH); rcread.send(ncodOff,24);//wyślij kod 24 bitowy RF=0; //przekaźnik wyłączony } //wyślij kod załączenia przekaźnika void RFSwitch::sendOn(void){ //ustaw rodzaj protokołu i długość impulsu HIGH rcread.setProtocol(protocol,lengthLH); rcread.send(ncodOn,24);//wyślij kod 24 bitowy RF=1; //przekaźnik załączony } //odczytaj stan przekaźnika uint8_t RFSwitch::readRF(){ return RF; } //ustaw stan RF void RFSwitch::writeRF(uint8_t rf){ RF=rf; } //czytaj z pilota kod załączenia void RFSwitch::readCod(uint8_t pinRx){ pinMode(RFONRX, OUTPUT);//ustaw pin zasilania odbiornika jako OUTPUT digitalWrite(RFONRX, HIGH); //załącz zasilanie odbiornika delay(100);//poczekaj na ustabilizowanie napięcia na odbiorniku rcread.resetAvailable();//resetuj poprzednio odczytane dane rcread.enableReceive(digitalPinToInterrupt(pinRx)); // włacz program przerwania na pinRx uint32_t timeread = millis()+1000;//ustal czas oczekiwania na 1 sek. // czekaj max 1 sekundę na pobranie kodu while (timeread > millis()){ if (rcread.available()){ ncodOn = (rcread.getReceivedValue());//ustaw pobrany kod załączenia ncodOff = ncodOn+((((ncodOn) & 3) > 1)? (9) : (3)); //oblicz kod wyłączenia //ustaw odczytany protokół i długość trwania impulsu HIGH lengthLH = rcread.getReceivedDelay(); //długość impulsu HIGH protocol = rcread.getReceivedProtocol();//nr protokołu rcread.setProtocol(protocol,lengthLH); timeread = 0;//zeruj czas oczekiwania - wyjście z pętli } } rcread.disableReceive(); // wyłącz program przerwania na pinRx digitalWrite(RFONRX, LOW); //wyłącz zasilanie odbiornika return; } //pobierz kod załączenia uint32_t RFSwitch::getCodOn(void){ return (ncodOn); } //pobierz kod wyłączenia uint32_t RFSwitch::getCodOff(void){ return (ncodOff); }
Każda linijka programu jest szczegółowo opisana. Nie powinno być problemów ze zrozumieniem działania programu. Utwórz jeszcze jeden plik RFSwitch3.h, gdzie zdefiniujesz wszystkie piny. 3 w nazwie oznacza 3 przekaźniki. Tu możemy zmieniać poszczególne piny. Przy każdym jest opis do czego służy.
/* * RFSwitch3.h * * Created on: 01.03.2017 * Author: Jan Trzciński */ #ifndef RFSWITCH3_H_ #define RFSWITCH3_H_ #define pinled0 D4 // led wbudowany. Gaśnie po uzyskaniu połączenia z WiFi #define pinrelay1 D1 //pin dla przekaźnika nr 1 #define pinrelay2 D2 //pin dla przekaźnika nr 2 #define pinrelay3 D3 //pin dla przekaźnika nr 3 #define RFONRX D0 //zasilanie odbiornika #define RFPINRX D5 //pin do którego podłączono DATA odbiornika #define RFPINTX D8 //pin DATA nadajnika #endif /* RFSWITCH3_H_ */
Plik ten jest dołączany do wszystkich plików. Pliki te powinieneś wgrać do katalogu głównego każdego programu, w którym będziesz stosował przekaźniki. W dalszej części opiszę pliki tworzące stronę www.