• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Ściemniacz i przyciski
#1
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ść.
 
Odpowiedź
#2
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
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
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.
 
Odpowiedź
#4
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.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości