Tự làm công tắc cảm ứng điều khiển 8 relay qua Internet

28/06/2022
tu-lam-cong-tac-cam-ung-dieu-khien-8-relay-qua-internet

Bài này tôi hướng dẫn các bạn làm bộ điều khiển bằng 8 nút nhấn

Chuẩn bị

1. Arduino Uno R3

2. Nút nhấn 8 cái

3. Module Relay 8 kênh hoặc 8 module riêng lẻ

#include<OneButton.h> // thư viện one button
#include <Wire.h>
#define N_SENSOR  8
float sensors[N_SENSOR]; //biến lưu trữ danh sách cảm biến

#define RELAY_COUNT 8
//Relay kích ở mức thấp thì như thế này
#define ON  LOW
#define OFF HIGH
//Xóa comment 2 dòng dưới nếu là relay kích ở mức cao
//#define ON HIGH
//#define OFF LOW
const int relayPins[RELAY_COUNT] = {4, 5, 6, 7, 8, 9, 10, 11};


//Nếu bạn dùng INPUT_PULLUP thì uncomment dòng dưới
#define BUTTON_TYPE true
//Nếu bạn dùng Nút cảm ứng thì uncomment dòng dưới
//#define BUTTON_TYPE false
const int buttonPins[RELAY_COUNT] = {2, 3, 12, 13, A0, A1, A2, A3}; 

OneButton button0(buttonPins[0], BUTTON_TYPE);
OneButton button1(buttonPins[1], BUTTON_TYPE);
OneButton button2(buttonPins[2], BUTTON_TYPE);
OneButton button3(buttonPins[3], BUTTON_TYPE);
OneButton button4(buttonPins[4], BUTTON_TYPE);
OneButton button5(buttonPins[5], BUTTON_TYPE);
OneButton button6(buttonPins[6], BUTTON_TYPE);
OneButton button7(buttonPins[7], BUTTON_TYPE);

void toggle0() {
  digitalWrite(relayPins[0], !digitalRead(relayPins[0]));
}

void toggle1() {
  digitalWrite(relayPins[1], !digitalRead(relayPins[1]));
}

void toggle2() {
  digitalWrite(relayPins[2], !digitalRead(relayPins[2]));
}

void toggle3() {
  digitalWrite(relayPins[3], !digitalRead(relayPins[3]));
}

void toggle4() {
  digitalWrite(relayPins[4], !digitalRead(relayPins[4]));
}

void toggle5() {
  digitalWrite(relayPins[5], !digitalRead(relayPins[5]));
}

void toggle6() {
  digitalWrite(relayPins[6], !digitalRead(relayPins[6]));
}

void toggle7() {
  digitalWrite(relayPins[7], !digitalRead(relayPins[7]));
}
 
void setup() {
  Serial.begin(9600);
 
 
  Wire.begin(10); //Theo như yêu cầu của iNut Platform, các bạn sẽ dùng cổng I2C với địa chỉ là 10.
  Wire.onRequest(i2cRequestEvent); //Mỗi khi iNut - Cảm biến yêu cầu thì sẽ chạy hàm này nhằm mục tiêu gửi dữ liệu lên cho iNut - Cảm biến, cứ 01 giây sẽ yêu cầu gửi 01 lần
  //Đăng ký lệnh lắng nghe lệnh từ iNut - Cảm biến. iNut Cảm biến => Arduino
  Wire.onReceive(receiveEvent); 

  for (int i = 0 ; i < RELAY_COUNT; i++) {
    pinMode(relayPins[i], OUTPUT);
    digitalWrite(relayPins[i], OFF);
  }

  button0.attachClick(toggle0);
  button1.attachClick(toggle1);
  button2.attachClick(toggle2);
  button3.attachClick(toggle3);
  button4.attachClick(toggle4);
  button5.attachClick(toggle5);
  button6.attachClick(toggle6);
  button7.attachClick(toggle7);
 
  Serial.println("Xin chao iNut Platform");
}
 
void i2cRequestEvent()
{
  //phải có nhé, chỉ cần 02 dòng này là data đã được gửi đi
  char *data = (byte*)&sensors; 
  Wire.write(data, sizeof(sensors));
 
 
  //debug - Kiểm tra cho bạn dễ hình dung dữ liệu được gửi đi
  Serial.print("sizeof(sensors): ");
  Serial.println(sizeof(sensors));
  Serial.print("sizeof(float): ");
  Serial.println(sizeof(float));
}

//Các biến lưu trữ lệnh khi nhận được lệnh từ iNut - Cảm biến
volatile char buffer[33];
volatile boolean receiveFlag = false;
 
//Khi nhận được lệnh từ iNut cảm biến thì lắng nghe
void receiveEvent(int howMany)
{
  Wire.readBytes((byte *)buffer, howMany);
  buffer[howMany] = 0;
  receiveFlag = true;
}
 
void loop() {
  for (int i = 0 ; i < RELAY_COUNT; i++) {
    int state = digitalRead(relayPins[i]); // đọc trạng thái của các relay
    if (state == ON) {
      sensors[i] = (i + 1) * 10 + 2;
    } else if (state == OFF) {
      sensors[i] = (i + 1) * 10 + 1;
    }
  }
  
  button0.tick();
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
  button5.tick();
  button6.tick();
  button7.tick();

  if (receiveFlag) { //khi có tín hiệu là đã nhận được lệnh
    
    String command = buffer; //chép lệnh vào biến String cho dễ xử lý
    
    
    Serial.print(command);// in ra lệnh
    Serial.print(' ');
    Serial.println(millis());//in ra thời gian theo millis tính từ lúc arduino chạy để debug

    int index = command[0];
    int state = command[1];

    if ('1' <= index && index <= '8') { // Chúng ta chỉ có 8 relay, đánh số từ 0-7
      index -= '1'; // Chuyển từ ký tự số sang số. '1' => 0, '2' => 1. Vì khi lập trình, mảng bắt đầu bằng số 0
      Serial.print("Relay thu ");
      Serial.println(index);
      if (state == '1' || state == '2') { // Nếu state truyền là 0 => Tắt relay, 1 => Bật relay
        if (state == '1') {
          Serial.println("OFF");
          digitalWrite(relayPins[index], OFF);
        } else if (state == '2') {
          Serial.println("ON");
          digitalWrite(relayPins[index], ON);
        }
      }
    }
    
 
    receiveFlag = false; //đánh dấu đã xử lý xong lệnh, không cần đọc nữa
  }
}
Dành cho nút cảm ứng loại 8 chạm

 

#include<OneButton.h> // thư viện one button
#include <Wire.h>
#define N_SENSOR  8
float sensors[N_SENSOR]; //biến lưu trữ danh sách cảm biến

#define RELAY_COUNT 8
//Relay kích ở mức thấp thì như thế này
#define ON  LOW
#define OFF HIGH
//Xóa comment 2 dòng dưới nếu là relay kích ở mức cao
//#define ON HIGH
//#define OFF LOW
const int relayPins[RELAY_COUNT] = {4, 5, 6, 7, 8, 9, 10, 11};


//Nếu bạn dùng INPUT_PULLUP thì uncomment dòng dưới
//#define BUTTON_TYPE true
//Nếu bạn dùng Nút cảm ứng thì uncomment dòng dưới
#define BUTTON_TYPE false
const int buttonPins[RELAY_COUNT] = {2, 3, 12, 13, A0, A1, A2, A3}; 

OneButton button0(buttonPins[0], BUTTON_TYPE);
OneButton button1(buttonPins[1], BUTTON_TYPE);
OneButton button2(buttonPins[2], BUTTON_TYPE);
OneButton button3(buttonPins[3], BUTTON_TYPE);
OneButton button4(buttonPins[4], BUTTON_TYPE);
OneButton button5(buttonPins[5], BUTTON_TYPE);
OneButton button6(buttonPins[6], BUTTON_TYPE);
OneButton button7(buttonPins[7], BUTTON_TYPE);

void toggle0() {
  digitalWrite(relayPins[0], !digitalRead(relayPins[0]));
}

void toggle1() {
  digitalWrite(relayPins[1], !digitalRead(relayPins[1]));
}

void toggle2() {
  digitalWrite(relayPins[2], !digitalRead(relayPins[2]));
}

void toggle3() {
  digitalWrite(relayPins[3], !digitalRead(relayPins[3]));
}

void toggle4() {
  digitalWrite(relayPins[4], !digitalRead(relayPins[4]));
}

void toggle5() {
  digitalWrite(relayPins[5], !digitalRead(relayPins[5]));
}

void toggle6() {
  digitalWrite(relayPins[6], !digitalRead(relayPins[6]));
}

void toggle7() {
  digitalWrite(relayPins[7], !digitalRead(relayPins[7]));
}
 
void setup() {
  Serial.begin(9600);
 
 
  Wire.begin(10); //Theo như yêu cầu của iNut Platform, các bạn sẽ dùng cổng I2C với địa chỉ là 10.
  Wire.onRequest(i2cRequestEvent); //Mỗi khi iNut - Cảm biến yêu cầu thì sẽ chạy hàm này nhằm mục tiêu gửi dữ liệu lên cho iNut - Cảm biến, cứ 01 giây sẽ yêu cầu gửi 01 lần
  //Đăng ký lệnh lắng nghe lệnh từ iNut - Cảm biến. iNut Cảm biến => Arduino
  Wire.onReceive(receiveEvent); 

  for (int i = 0 ; i < RELAY_COUNT; i++) {
    pinMode(relayPins[i], OUTPUT);
    digitalWrite(relayPins[i], OFF);
  }

  button0.attachClick(toggle0);
  button1.attachClick(toggle1);
  button2.attachClick(toggle2);
  button3.attachClick(toggle3);
  button4.attachClick(toggle4);
  button5.attachClick(toggle5);
  button6.attachClick(toggle6);
  button7.attachClick(toggle7);
 
  Serial.println("Xin chao iNut Platform");
}
 
void i2cRequestEvent()
{
  //phải có nhé, chỉ cần 02 dòng này là data đã được gửi đi
  char *data = (byte*)&sensors; 
  Wire.write(data, sizeof(sensors));
 
 
  //debug - Kiểm tra cho bạn dễ hình dung dữ liệu được gửi đi
  Serial.print("sizeof(sensors): ");
  Serial.println(sizeof(sensors));
  Serial.print("sizeof(float): ");
  Serial.println(sizeof(float));
}

//Các biến lưu trữ lệnh khi nhận được lệnh từ iNut - Cảm biến
volatile char buffer[33];
volatile boolean receiveFlag = false;
 
//Khi nhận được lệnh từ iNut cảm biến thì lắng nghe
void receiveEvent(int howMany)
{
  Wire.readBytes((byte *)buffer, howMany);
  buffer[howMany] = 0;
  receiveFlag = true;
}
 
void loop() {
  for (int i = 0 ; i < RELAY_COUNT; i++) {
    int state = digitalRead(relayPins[i]); // đọc trạng thái của các relay
    if (state == ON) {
      sensors[i] = (i + 1) * 10 + 2;
    } else if (state == OFF) {
      sensors[i] = (i + 1) * 10 + 1;
    }
  }
  
  button0.tick();
  button1.tick();
  button2.tick();
  button3.tick();
  button4.tick();
  button5.tick();
  button6.tick();
  button7.tick();

  if (receiveFlag) { //khi có tín hiệu là đã nhận được lệnh
    
    String command = buffer; //chép lệnh vào biến String cho dễ xử lý
    
    
    Serial.print(command);// in ra lệnh
    Serial.print(' ');
    Serial.println(millis());//in ra thời gian theo millis tính từ lúc arduino chạy để debug

    int index = command[0];
    int state = command[1];

    if ('1' <= index && index <= '8') { // Chúng ta chỉ có 8 relay, đánh số từ 0-7
      index -= '1'; // Chuyển từ ký tự số sang số. '1' => 0, '2' => 1. Vì khi lập trình, mảng bắt đầu bằng số 0
      Serial.print("Relay thu ");
      Serial.println(index);
      if (state == '1' || state == '2') { // Nếu state truyền là 0 => Tắt relay, 1 => Bật relay
        if (state == '1') {
          Serial.println("OFF");
          digitalWrite(relayPins[index], OFF);
        } else if (state == '2') {
          Serial.println("ON");
          digitalWrite(relayPins[index], ON);
        }
      }
    }
    
 
    receiveFlag = false; //đánh dấu đã xử lý xong lệnh, không cần đọc nữa
  }
}

Chúc các bạn thành công!

Mọi ý đóng góp bạn hãy comment bên dưới

 

Bình luận (2)
binh-luan

yêu lập trình

28/06/2022

Cảm ơn admin có bài biết hay
binh-luan

Hoàn

28/06/2022

Bài viết hay nhưng em chưa làm được, anh có hướng dẫn em được không?
VIẾT BÌNH LUẬN CỦA BẠN