Objetivo
Controlar um módulo relé 16 canais com arduino através de interface em display de cristal liquido 16x2 via modulo I2C PCA9685
Cada canal do relé pode ser usado para controlar carga em até 240V / 10A. Como lâmpadas, pequenos motores e outros eletro-eletrônicos.
O que foi utilizado
Módulo relé 16 canais
Arduino UNO R3
LCD shield
Modulo I2C PCA9685 (nativamente um modulo para controle de servomotores)
Fonte 12V
Jumpers
O Módulo relé 16 canais
>> Tensão de alimentação: 12V;
>> Possui regulador de tensão integrado 5V o que permite alimentar o arduino e demais dispositivos através dos pinos de saída 5V e GND;
>> Sinal de acionamento, lógico: Nível baixo GND. O ideal para uso com o PCA9685 seria o com acionamento em nível alto já que o módulo parece inicializar com todos os pinos em nível baixo.
O LCD shield
>> Display LCD16x2 (pinos D4 a D10 do arduino)
>> 5 botões, ligados a apenas um pino analógico do arduino, o pino A0, via divisor de tensão.
quando um botão é pressionado seu valor correspondente (entre 0 e 1023) pode ser lido com a função analogRead(A0); . Dessa forma é possível identificar qual botão foi pressionado.
O Modulo I2C PCA9685
A postagem: Controlador PWM 16 CH PCA9685 com servos e Led
trás mais detalhes sobre esse módulo.
Montagem
Como funciona
O canal desejado é selecionado via botões UP e DOWN.
O display mostrará o estado do canal selecionado: ON ou OFF
Para alterar o estado do canal pressionar o botão SELECT e em seguida LEFT ou RIGHT para alternar entre ON e OFF. Após selecionar o estado desejado pressionar novamente SELECT para validar a alteração.
Programa
O PCA9685 é um modulo PWM, saída analógica então para usá-lo com o modulo relé trabalhamos nos extremos da saída PWM: 0V para nível baixo (aciona relé) e 4095 para nível alto (desliga relé). Se estiver usando um módulo relé com acionamento por nível alto será necessário inverter no programa onde tem 4095 para 0 e vice versa no local indicado.
É necessário adicionar a biblioteca: Adafruit_PWMServoDriver
É necessário adicionar a biblioteca: Adafruit_PWMServoDriver
#include <Wire.h> #include <Adafruit_PWMServoDriver.h> #include <LiquidCrystal.h> LiquidCrystal lcd(8, 13, 9, 4, 5, 6, 7); //LiquidCrystal lcd(RS,E, D4, D5, D6, D7); // called this way, it uses the default address 0x40 Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40); int canal_state[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // BOTOES int DLY_BT = 300; boolean Right; boolean Up; boolean Down; boolean Left; boolean Select; int cnt_canal = 0; void setup() { //delay(1000); lcd.begin(16, 2); pwm.begin(); pwm.setPWMFreq(1600); // This is the maximum PWM frequency for(int a= 0; a<16; a++) pwm.setPin(a,4095); // pino, valor, inverte delay(1000); lcd.print("Modulo rele 16CH"); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("Canal "); lcd.print(cnt_canal + 1); if(canal_state[cnt_canal] == 0) lcd.print(": OFF"); else lcd.print(": ON"); } void loop() { Zera_bts(); Le_bts(); // ler botoes if( Up == true && cnt_canal > 0) { cnt_canal --; lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("Canal "); lcd.print(cnt_canal + 1); if(canal_state[cnt_canal] == 0) lcd.print(": OFF"); else lcd.print(": ON"); } else if( Down == true && cnt_canal < 15) { cnt_canal ++; lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("Canal "); lcd.print(cnt_canal + 1); if(canal_state[cnt_canal] == 0) lcd.print(": OFF"); else lcd.print(": ON"); } // if(Down == true && cnt_canal == 16} // Zera_bts(); // Le_bts(); // ler botoes if(Select == true) { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("SetCanal "); lcd.print(cnt_canal + 1); if(canal_state[cnt_canal] == 0) lcd.print(": OFF"); else lcd.print(": ON"); Zera_bts(); Le_bts(); // ler botoes while(Select != true){ Zera_bts(); Le_bts(); // ler botoes if(Right == true || Left == true) { canal_state[cnt_canal] = ! canal_state[cnt_canal]; lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("SetCanal "); lcd.print(cnt_canal + 1); if(canal_state[cnt_canal] == 0) lcd.print(": OFF"); else lcd.print(": ON"); delay(300); } } lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("Canal "); lcd.print(cnt_canal + 1); if(canal_state[cnt_canal] == 0) { lcd.print(": OFF"); pwm.setPin(cnt_canal , 4095); // trocar para 0 se o modulo } // acionar em nivel alto else { lcd.print(": ON"); pwm.setPin(cnt_canal , 0); // trocar para 4095 se o modulo } // acionar em nivel alto } } ///FUNÇÃO LÊ BOTÕES///////////////////////////// // {50, 200, 400, 600, 800 }; void Le_bts() { while( Right == false && Up == false && Down == false && Left == false && Select == false ) { int input = analogRead(0); //le o pino analogico onde esta os botoes if (input < 40) Right = true; else if(input > 50 && input < 150) Up = true; else if(input > 200 && input < 300) Down = true; else if(input > 380 && input < 450) Left = true; else if(input > 550 && input < 700) Select = true; } delay (DLY_BT); } ///FUNÇÃO ZERA BOTÕES///////////////////////////// void Zera_bts() { Right = false; Up = false; Down = false; Left = false; Select = false; }