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

Theo như yêu cầu của một số anh em, mình sẽ hỗ trợ thêm nút nhấn cho cái 8 relay này. Không chỉ nút nhấn mà còn nút cảm ứng nữa nhé!

Ok, anh em cần làm các phần được yêu cầu trong bài này. Chuẩn bị sẵn phần cứng, module, phần mềm cài đặt các kiểu, vâng vâng và mây mây nha.

Anh em phải cài thêm thư viện OneButton nữa thì đoạn code bên dưới mới chạy được nhé.

Tiếp tới, phần nối dây, anh em nối theo 02 bảng sau:

Dành cho nút nhấn thường

Arduino Nút 1 Nút 2 Nút 3 Nút 4 Nút 5 Nút 6 Nút 7 Nút 8
GND Chân 1 Chân 1 Chân 1 Chân 1 Chân 1 Chân 1 Chân 1 Chân 1
2 Chân 2              
3   Chân 2            
12     Chân 2          
13       Chân 2        
A0         Chân 2      
A1           Chân 2    
A2             Chân 2  
A3               Chân 2
#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

Arduino Module chạm
5V VCC
GND GND
2 OUT1
3 OUT2
12 OUT3
13 OUT4
A0 OUT5
A1 OUT6
A2 OUT7
A3 OUT8
#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!

Những hình ảnh về dự án: 
Bài viết truyền cảm hứng: 
lên
11 thành viên đã đánh giá bài viết này hữu ích.
Các dự án được truyền cảm hứng

Select any filter and click on Apply to see results

Các bài viết cùng tác giả

Bài 6: Đọc hiệu điện thế của một nguồn điện qua cổng Analog.

Đã bao giờ, bạn từng hỏi bản thân mình làm sao cái đồng hồ điện nó đọc được hiệu điện thế của một nguồn hay chưa? Bạn vẫn thắc mắc nguyên lý và vẫn chưa tìm ra lời giải? Vậy hãy đọc bài này. Chúng ta sẽ tìm cách để đọc tín hiệu từ analog từ đó suy ra giá trị hiệu điện thế của một vị trí xác định. Hiệu điện thế này tối đa chỉ 5V thôi bạn nhé. Nếu muốn đo cao hơn, bạn phải nghiên cứu nhiều hơn nữa!

lên
7 thành viên đã đánh giá bài viết này hữu ích.

"Độ hoàn toàn" một cổng Terminal RS-232 mà không sử dụng jack 3.5mm

Ở Việt Nam, việc một bạn học sinh mua một mạch Intel Galileo khá là khó. Trong đó, khó nhất là tiền để mua một mạch Intel Galileo, tuy nhiên, khi mua được mạch về, việc bạn có sử dụng hết chức năng của Intel Galileo hay không là một việc khác. Cái hay nhất, theo tớ nghĩ trên Intel Galileo, mà Arduino không có và bạn khó tiếp cận nhất đó là hệ điều hành Linux. Thực sự thì có nhiều cách để vào Linux của Intel Galileo. Tuy nhiên, nếu bạn muốn cài một hệ điều hành xịn như Debian để biến Intel Galileo trở thành một "máy tính" siêu "xịn" thì bạn buộc phải dùng tới cổng RS - 232. Nếu ở các trung tâm công nghệ lớn thì bạn có thể dễ dàng tìm mua các cổng "RS-232 to DB9" để dễ dàng làm theo các bài hướng dẫn trước. Tuy nhiên, không phải ai cũng may mắn như vậy, trong bài viết này, chúng ta sẽ tiếp cận với một cách khác mà tớ đã sử dụng để giải quyết bài toán không có cáp "RS-232 to DB9".

lên
3 thành viên đã đánh giá bài viết này hữu ích.