Ściemniacz i przyciski - orlicki12 - 27-01-2024
Witam.
Walczę od jakiegoś czasu z układem dimmera. Chce zrobić tak, aby układ był sterowany czterema przyciskami:
- Przycisk nr 1 - załączanie i wyłączanie przekaźnika
- Przycisk nr 2 - załączanie i wyłączanie 1 poziomu jasności
- Przycisk nr 3 - załączanie i wyłączanie 2 poziomu jasności
- Przycisk nr 4 - załączanie i wyłączanie 3 poziomu jasności
oraz za pomocą pilota IR:
- Przycisk nr 1 - załączanie przekaźnika
- Przycisk nr 2 - wyłączanie przekaźnika
- Przycisk nr 3 - załączanie 1 poziomu jasności
- Przycisk nr 4 - załączanie 2 poziomu jasności
- Przycisk nr 5 - załączanie 3 poziomu jasności
- Przycisk nr 6 - wyłączanie światła.
Na początki zrobiłem tak:
Kod: #include <ezButton.h>
#include <TimerOne.h>
#include "IRremote.h"
#define IR_RECEIVE_PIN 3
long data = 0;
const int RELAY_PIN = 12; // Arduino pin connected to relay's pin
const int BUTTON1_PIN=4;
const int BUTTON2_PIN=6;
const int BUTTON3_PIN=8;
const int BUTTON4_PIN=11;
const int LED1_PIN=5;
const int LED2_PIN=7;
const int LED3_PIN=9;
const int LED4_PIN=10;
volatile int i=0; // Variable to use as a counter
volatile boolean zero_cross=0; // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 13; // Output to Opto Triac
int dim = 0; // Dimming level (0-128) 0 = on, 128 = 0ff
int freqStep = 75; // This is the delay-per-brightness step in microseconds.
ezButton button1(BUTTON1_PIN);
ezButton button2(BUTTON2_PIN);
ezButton button3(BUTTON3_PIN);
ezButton button4(BUTTON4_PIN);
int led1State=LOW;
int led2State=LOW;
int led3State=LOW;
int led4State=LOW;
void setup() {
Serial.begin(115200);
IrReceiver.begin(IR_RECEIVE_PIN);
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(LED3_PIN, OUTPUT);
pinMode(LED4_PIN, OUTPUT);
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, HIGH);
digitalWrite(LED3_PIN, HIGH);
digitalWrite(LED4_PIN, HIGH);
button1.setDebounceTime(50);
button2.setDebounceTime(50);
button3.setDebounceTime(50);
button4.setDebounceTime(50);
digitalWrite(RELAY_PIN, HIGH);
pinMode(RELAY_PIN, OUTPUT); // set arduino pin to output mode
pinMode(AC_pin, OUTPUT); // Set the Triac pin as output
attachInterrupt(0, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
Timer1.attachInterrupt(dim_check, freqStep);
}
void zero_cross_detect()
{
zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured
i=0;
digitalWrite(AC_pin, LOW);
}
// Turn on the TRIAC at the appropriate time
void dim_check()
{
if(zero_cross == true) {
if(i>=dim) {
digitalWrite(AC_pin, HIGH); // turn on light
i=0; // reset time step counter
zero_cross=false; // reset zero cross detection
}
else {
i++; // increment time step counter
}}}
void translateIR() // takes action based on IR code received
{
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.decodedRawData != 0) {
data = IrReceiver.decodedIRData.decodedRawData;
}
switch(data)
{
case 0x24ACF947:
led1State=LOW;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
Serial.println("Light OFF");
break;
case 0xE208293C:
led1State=HIGH;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
Serial.println("Light ON");
break;
case 0xE3C01BE2:
led2State=!led2State;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
Serial.println("W1");
break;
case 0xD051C301:
led3State=!led3State;
digitalWrite(LED3_PIN, !led3State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
Serial.println("W2");
break;
case 0xC22FFFD7:
led4State=!led4State;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
Serial.println("W3");
break;
case 0x55303A3:
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
Serial.println("WOFF");
break;
default : break;
}
}
}
void loop() {
button1.loop();
button2.loop();
button3.loop();
button4.loop();
if(button1.isPressed())
{
Serial.println("The button 1 is pressed");
led1State=!led1State;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
}
if(button2.isPressed())
{
Serial.println("The button 2 is pressed");
led2State=!led2State;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
}
if(button3.isPressed())
{
Serial.println("The button 3 is pressed");
led3State=!led3State;
digitalWrite(LED3_PIN, !led3State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
}
if(button4.isPressed())
{
Serial.println("The button 4 is pressed");
led4State=!led4State;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
}
if(led2State == HIGH)
{
dim=0;
}
if(led3State == HIGH)
{
dim=0;
}
if(led4State == HIGH)
{
dim=0;
}
if(led4State == LOW && led4State == LOW && led4State == LOW)
{
dim=128;
}
if (IrReceiver.decode()) // have we received an IR signal?
{
translateIR();
delay(50);
IrReceiver.resume(); // Receive the next value
}
}
Ale niestety w tej wersji ustawienie jasności działa tylko na 3 poziomie oraz jestem w stanie wyłączyć światło. Na pozostałych dwóch poziomach pomimo ustawienia tej samej wartości dim=0 żarówka miga.
Drugi program stworzyłem tak:
Kod: #include <ezButton.h>
#include <TimerOne.h>
#include "IRremote.h"
#define IR_RECEIVE_PIN 3
long data = 0;
const int RELAY_PIN = 12; // Arduino pin connected to relay's pin
const int BUTTON1_PIN=4;
const int BUTTON2_PIN=6;
const int BUTTON3_PIN=8;
const int BUTTON4_PIN=11;
const int LED1_PIN=5;
const int LED2_PIN=7;
const int LED3_PIN=9;
const int LED4_PIN=10;
volatile int i=0; // Variable to use as a counter
volatile boolean zero_cross=0; // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 13; // Output to Opto Triac
int dim = 128; // Dimming level (0-128) 0 = on, 128 = 0ff
int freqStep = 75; // This is the delay-per-brightness step in microseconds.
ezButton button1(BUTTON1_PIN);
ezButton button2(BUTTON2_PIN);
ezButton button3(BUTTON3_PIN);
ezButton button4(BUTTON4_PIN);
int led1State=LOW;
int led2State=LOW;
int led3State=LOW;
int led4State=LOW;
void setup() {
Serial.begin(115200);
IrReceiver.begin(IR_RECEIVE_PIN);
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(LED3_PIN, OUTPUT);
pinMode(LED4_PIN, OUTPUT);
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, HIGH);
digitalWrite(LED3_PIN, HIGH);
digitalWrite(LED4_PIN, HIGH);
button1.setDebounceTime(50);
button2.setDebounceTime(50);
button3.setDebounceTime(50);
button4.setDebounceTime(50);
digitalWrite(RELAY_PIN, HIGH);
pinMode(RELAY_PIN, OUTPUT); // set arduino pin to output mode
pinMode(AC_pin, OUTPUT); // Set the Triac pin as output
attachInterrupt(0, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
Timer1.attachInterrupt(dim_check, freqStep);
}
void zero_cross_detect()
{
zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured
i=0;
digitalWrite(AC_pin, LOW);
}
// Turn on the TRIAC at the appropriate time
void dim_check()
{
if(zero_cross == true) {
if(i>=dim) {
digitalWrite(AC_pin, HIGH); // turn on light
i=0; // reset time step counter
zero_cross=false; // reset zero cross detection
}
else {
i++; // increment time step counter
}}}
void translateIR() // takes action based on IR code received
{
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.decodedRawData != 0) {
data = IrReceiver.decodedIRData.decodedRawData;
}
switch(data)
{
case 0x24ACF947:
led1State=LOW;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
Serial.println("Light OFF");
break;
case 0xE208293C:
led1State=HIGH;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
Serial.println("Light ON");
break;
case 0xE3C01BE2:
led2State=!led2State;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
Serial.println("W1");
dim=100;
break;
case 0xD051C301:
led3State=!led3State;
digitalWrite(LED3_PIN, !led3State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
Serial.println("W2");
dim=50;
break;
case 0xC22FFFD7:
led4State=!led4State;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
Serial.println("W3");
dim=0;
break;
case 0x55303A3:
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
Serial.println("WOFF");
dim=128;
break;
default : break;
}
}
}
void loop() {
button1.loop();
button2.loop();
button3.loop();
button4.loop();
if(button1.isPressed())
{
Serial.println("The button 1 is pressed");
led1State=!led1State;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
}
if(button2.isPressed())
{
Serial.println("The button 2 is pressed");
led2State=!led2State;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
dim=100;
}
if(button3.isPressed())
{
Serial.println("The button 3 is pressed");
led3State=!led3State;
digitalWrite(LED3_PIN, !led3State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
dim=50;
}
if(button4.isPressed())
{
Serial.println("The button 4 is pressed");
led4State=!led4State;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
dim=0;
}
if (IrReceiver.decode()) // have we received an IR signal?
{
translateIR();
delay(50);
IrReceiver.resume(); // Receive the next value
}
}
W tej wersji poziomy jasności ustawiają się poprawnie, ale nie wiem jak zrobić warunek, żeby pierwsze naciśnięcie przycisku od 2 do 3 ustawiło poziom jasności, a drugie naciśnięcie wyłączyło światło.
Oczywiście nie są to w 100% moje programy, bazuję na przykładach znalezionych w Internecie. Proszę o porady w którą stronę iść.
RE: Ściemniacz i przyciski - kaczakat - 27-01-2024
Jak chcesz sterować z dwóch źródeł to musisz mieć część wspólną, nie ustawiaj wyjść w zależności od przycisku ani od kodu IR, tylko ustawiaj zmienną na określoną wartość. Nie wiem po co przekaźnik, przecież dimerem można włączyć na 100% i wyłączyć.
Masz 6 stanów,
- Przycisk nr 1 - załączanie przekaźnika
- Przycisk nr 2 - wyłączanie przekaźnika
- Przycisk nr 3 - załączanie 1 poziomu jasności
- Przycisk nr 4 - załączanie 2 poziomu jasności
- Przycisk nr 5 - załączanie 3 poziomu jasności
- Przycisk nr 6 - wyłączanie światła.
zrób sobie switch case ustawiające wszystkie parametry dla tych 6 stanów, w nim ustawiaj wyjścia led i przekaźniki, nieważne co było wcześniej.
Przy przycisku tylko sprawdzasz jaki jest aktualny stan 1-6, czy tam 0-5 i wiesz, czy masz
if(button3.isPressed())
{
jeśli był stan 4 to ustaw 2 (ja bym zrobił wyłączenie przekaźnika na stanie 0) else włącz stan 4.
}
Przy IR Przycisk nr 4 przełącz zmienną stan na 4.
Potem w osobnym switch case dla zmiennej "stan" w pozycji 4 wyłącz wszystko co niepotrzebne, włącz co ma być włączone przy stanie nr 4
RE: Ściemniacz i przyciski - orlicki12 - 28-01-2024
Dzięki bardzo udało się. Poniżej zamieszczam kod. Ogólnie tak naprawdę to buduję płytkę do sterowania okapem, ponieważ w fabrycznej padł układ scalony z pamięcią i jest nie do naprawy(nowa też nie do kupienia). Posiadam płytę indukcyjną AEG z funkcją hob2hood, a okap był wyposażony w IR i można nim było sterować z pilota. Pomyślałem, że stworzę płytkę do sterowania manualnego za pomocą przycisków z funkcją sterowanie przez IR za pomocą płyty indukcyjnej. Więc tak naprawdę przekaźnik załącza i wyłącza światło, a dimmer służy do regulacji prędkości wentylatora. Nie jest to idealne rozwiązanie, ale tak było fabrycznie i takie są wyprowadzenia, a nie chce nic zmieniać w konstrukcji okapu.
Kod: #include <ezButton.h>
#include <TimerOne.h>
#include "IRremote.h"
#define IR_RECEIVE_PIN 3
long data = 0;
int speed = 0;
int light = 0;
const int RELAY_PIN = 12; // Arduino pin connected to relay's pin
const int BUTTON1_PIN=4;
const int BUTTON2_PIN=6;
const int BUTTON3_PIN=8;
const int BUTTON4_PIN=11;
const int LED1_PIN=5;
const int LED2_PIN=7;
const int LED3_PIN=9;
const int LED4_PIN=10;
volatile int i=0; // Variable to use as a counter
volatile boolean zero_cross=0; // Boolean to store a "switch" to tell us if we have crossed zero
int AC_pin = 13; // Output to Opto Triac
int dim = 128; // Dimming level (0-128) 0 = on, 128 = 0ff
int freqStep = 75; // This is the delay-per-brightness step in microseconds.
ezButton button1(BUTTON1_PIN);
ezButton button2(BUTTON2_PIN);
ezButton button3(BUTTON3_PIN);
ezButton button4(BUTTON4_PIN);
int led1State=LOW;
int led2State=LOW;
int led3State=LOW;
int led4State=LOW;
void setup() {
Serial.begin(115200);
IrReceiver.begin(IR_RECEIVE_PIN);
pinMode(LED1_PIN, OUTPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(LED3_PIN, OUTPUT);
pinMode(LED4_PIN, OUTPUT);
digitalWrite(LED1_PIN, HIGH);
digitalWrite(LED2_PIN, HIGH);
digitalWrite(LED3_PIN, HIGH);
digitalWrite(LED4_PIN, HIGH);
button1.setDebounceTime(50);
button2.setDebounceTime(50);
button3.setDebounceTime(50);
button4.setDebounceTime(50);
digitalWrite(RELAY_PIN, HIGH);
pinMode(RELAY_PIN, OUTPUT); // set arduino pin to output mode
pinMode(AC_pin, OUTPUT); // Set the Triac pin as output
attachInterrupt(0, zero_cross_detect, RISING); // Attach an Interupt to Pin 2 (interupt 0) for Zero Cross Detection
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need
Timer1.attachInterrupt(dim_check, freqStep);
}
void zero_cross_detect()
{
zero_cross = true; // set the boolean to true to tell our dimming function that a zero cross has occured
i=0;
digitalWrite(AC_pin, LOW);
}
// Turn on the TRIAC at the appropriate time
void dim_check()
{
if(zero_cross == true) {
if(i>=dim) {
digitalWrite(AC_pin, HIGH); // turn on light
i=0; // reset time step counter
zero_cross=false; // reset zero cross detection
}
else {
i++; // increment time step counter
}}}
void translateIR() // takes action based on IR code received
{
if (IrReceiver.decode()) {
if (IrReceiver.decodedIRData.decodedRawData != 0) {
data = IrReceiver.decodedIRData.decodedRawData;
}
switch(data)
{
case 0x24ACF947:
light=0;
break;
case 0xE208293C:
light=1;
break;
case 0xE3C01BE2:
speed=1;
break;
case 0xD051C301:
speed=2;
break;
case 0xC22FFFD7:
speed=4;
break;
case 0x55303A3:
speed=0;
break;
default : break;
}
}
}
void loop() {
button1.loop();
button2.loop();
button3.loop();
button4.loop();
if(button1.isPressed())
{
Serial.println("The button 1 is pressed");
if(light==1)
{
light=0;
}
else
{
light=1;
}
}
if(button2.isPressed())
{
Serial.println("The button 2 is pressed");
if(speed==0 || speed==3 || speed==2)
{
speed=1;
}
else
{
speed=0;
}
}
if(button3.isPressed())
{
Serial.println("The button 3 is pressed");
if(speed==0 || speed==1 || speed==3)
{
speed=2;
}
else
{
speed=0;
}
}
if(button4.isPressed())
{
Serial.println("The button 4 is pressed");
if(speed==0 || speed==1 || speed==2)
{
speed=3;
}
else
{
speed=0;
}
}
switch (speed) {
case 0:
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
Serial.println("WOFF");
dim=128;
break;
case 1:
led2State=!led2State;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
Serial.println("W1");
dim=60;
break;
case 2:
led3State=!led3State;
digitalWrite(LED3_PIN, !led3State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led4State=LOW;
digitalWrite(LED4_PIN, !led4State);
Serial.println("W2");
dim=55;
break;
case 3:
led4State=!led4State;
digitalWrite(LED4_PIN, !led4State);
led2State=LOW;
digitalWrite(LED2_PIN, !led2State);
led3State=LOW;
digitalWrite(LED3_PIN, !led3State);
Serial.println("W3");
dim=0;
break;
default:
break;
}
switch (light) {
case 0:
led1State=LOW;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
Serial.println("Light OFF");
break;
case 1:
led1State=HIGH;
digitalWrite(LED1_PIN, !led1State);
digitalWrite(RELAY_PIN, !led1State);
Serial.println("Light ON");
break;
default:
break;
}
if (IrReceiver.decode()) // have we received an IR signal?
{
translateIR();
delay(50);
IrReceiver.resume(); // Receive the next value
}
}
PS. Jeśli mógłbym jakoś zoptymalizować kod, wszelkie uwagi mile widziane.
RE: Ściemniacz i przyciski - kaczakat - 28-01-2024
Jak działa to nie ma co psuć.
Ja bym wywalił delay, użył funkcji czas(), znajdziesz w moich wypowiedziach, sprawdzałbym przyciski co 10ms - if (fnTik) button1.loop() i tak dla wszystkich,, jak nie chcesz odbierać kodów częściej niż co np. 50ms to nie musisz stosować delay, wystarczy zapisać czas millis gdy przyleci pierwszy kod i przez kolejne 50-100ms nic nie robić z kolejnymi, odebrać, ale zignorować, ale nie ma powodu tu stać i patrzeć w sufit.
Ale jeśli to już koniec i nic więcej nie będziesz dodawał, to nie ma znaczenia.
|