今天小编给大家分享来自印度的maker Arnov Sharma的基于XIAO ESP32C3制作的家庭自动化控制板,该控制板具有板载电源和双路继电器模块,通过wed端的应用程序可以直接使用交流电供电控制两条线路的通断。
材料清单
硬件
- 定制PCB板
- XIAO ESP32 C3/S3
- 5V继电器模块
- ac转5V 开关电源模块
- AO3400 场效应管
- 10K电阻
- 1K电阻
- 0603 绿色LEDM7二极管
- 3D打印框架
- DC 螺丝端子连接器
- M2 螺丝
软件
- Arduino IDE
原理图
我们将使用两个 5V 继电器模块来控制交流负载;为了驱动这些继电器,我们使用了MOSFET开关设置,该开关用作开关,可以通过向栅极提供电压来打开或关闭。
一个 10K 电阻器将 MOSFET 的栅极连接到 XIAO MCU 的 I/O 引脚。
此外,我们还在XIAO MCU的I/O引脚上安装了一个指示灯,并将其放置在每个继电器附近。当继电器打开或关闭时,LED 指示灯将亮起。
我们安装了一个隔离式 SMPS,用交流电源为这种布置供电,将交流 240V 转换为 MCU 运行所需的稳定 5V。
PCB设计
随后,我们从原理图中导出网表,并将整个电路板转换为PCB文件。为了将交流和直流组件分开,我们首先绘制电路板的方形轮廓,将 SMPS 和继电器放在一侧,将 XIAO 和其余电子设备放在另一侧。
后来,我们在PCB上添加了一些美学标记,并将其发送给Seeed Fusion进行样品。
Seeed Fusion PCB服务
PCB采用带有白色丝印的蓝色阻焊层订购。
PCB在一周内收到,考虑到费率,它们的质量非常好,这也是相当低的。
Seeed Fusion PCB Service 为 PCB 制造和 PCB 组装提供一站式原型设计, 因此, 他们在 7 个工作日内生产出优质的 PCB 和快速交钥匙 PCBA.
这款 XIAOHOME AUTOMATION 板的 PCB 质量超酷!
Seeed Studio Fusion PCB 组装服务负责整个制造过程,从 Seeed Studio Fusion 敏捷制造和硬件定制到零件采购、组装和测试服务,因此您可以确保他们获得优质产品。
在衡量市场兴趣并验证工作原型后,Seeed Propagate Service 可以通过专业指导和强大的人脉网络帮助您将产品推向市场。
接下来是PCB组装过程.
PCB组装
使用焊膏注射器,我们首先将焊膏(我们使用的是普通的 SnPb 63/37 焊膏)添加到 PCB 组装过程中每个组件的焊盘上。
然后选择SMD电阻器、LED、MOSFET、XIAO模块和二极管,并将其排列在适当的位置。
焊接贴片元件
为了将PCB加热到焊膏熔化温度,我们小心地提起电路板并将其放在SMT加热板上。焊膏熔化,一旦电路板达到焊膏的熔化温度,元件就会附着在焊盘上。
该板正在利用先前完成的PCB加热板项目进行回流焊;有关详细信息,请参阅此文章。
https://www.hackster.io/Arnov...
THT 组件
随后,我们收集每个THT组件,包括继电器模块、螺丝连接器和SMPS模块。
使用标准烙铁,我们将它们全部排列在适当的位置,并将它们固定在焊盘上。
接下来,我们将WiFi天线添加到XIAO的BT / WIFI天线连接器中。
PCB现已完成。
3D打印支架
这一步是可选的,但我们为家庭自动化板设计了一个基本的支架,将其稍微抬离地面。它还具有四个安装支架,可用于使用螺钉或电缆扎带将电路板固定到任何东西上。
该支架由40%填充的白色PLA制成,并通过0.8 mm喷嘴打印0.2 mm的层高。
为了将电路和 3D 安装座固定在一起,使用了四颗 M2 螺钉。
程序代码
#include <WiFi.h>
// Replace with your network credentials
const char *ssid = "ADDYOURSSID";
const char *password = "ASSYOURPASS";
// Set web server port number to 80
WiFiServer server(80);
// Variable to store the HTTP request
String header;
// Auxiliar variables to store the current output state
String output1State = "off";
String output2State = "off";
// Assign output variables to GPIO pins
const int output1 = 0; //RELAY1
const int output2 = 3; //RELAY2
const int ledPin1 = 1; //LED1
const int ledPin2 = 2; //LED2
void setup() {
Serial.begin(115200);
// Initialize the output variables as outputs
pinMode(output1, OUTPUT);
pinMode(output2, OUTPUT);
//LEDs
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
// Set outputs to LOW
digitalWrite(output1, LOW);
digitalWrite(output2, LOW);
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address and start web server
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
}
void loop(){
WiFiClient client = server.available(); // Listen for incoming clients
if (client) { // If a new client connects,
Serial.println("New Client."); // print a message out in the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected()) { // loop while the client's connected
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println();
// turns the GPIOs on and off
if (header.indexOf("GET /1/on") >= 0) {
Serial.println("LOAD1 on");
output1State = "on";
digitalWrite(output1, HIGH);
digitalWrite(ledPin1, HIGH);
} else if (header.indexOf("GET /1/off") >= 0) {
Serial.println("LOAD1 off");
output1State = "off";
digitalWrite(output1, LOW);
digitalWrite(ledPin1, LOW);
} else if (header.indexOf("GET /2/on") >= 0) {
Serial.println("LOAD2 on");
output2State = "on";
digitalWrite(output2, HIGH);
digitalWrite(ledPin2, HIGH);
} else if (header.indexOf("GET /2/off") >= 0) {
Serial.println("LOAD2 off");
output2State = "off";
digitalWrite(output2, LOW);
digitalWrite(ledPin2, LOW);
}
// Display the HTML web page
client.println("<!DOCTYPE html><html>");
client.println("<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
client.println("<link rel=\"icon\" href=\"data:,\">");
// CSS to style the on/off buttons
// Feel free to change the background-color and font-size attributes to fit your preferences
client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}");
client.println(".button { background-color: #5B196A; border: none; color: white; padding: 16px 40px;");
client.println("text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}");
client.println(".button2 {background-color: #5B196A;}</style></head>");
// Web Page Heading
client.println("<body><h1>HOME AUTOMATION DUAL OUTPUT</h1>");
// Display current state, and ON/OFF buttons for OUTPUT1
client.println("<p>LOAD1 - State " + output1State + "</p>");
// If the output1State is off, it displays the ON button
if (output1State=="off") {
client.println("<p><a href=\"/1/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/1/off\"><button class=\"button button2\">OFF</button></a></p>");
}
// Display current state, and ON/OFF buttons for GPIO 4
client.println("<p>LOAD2 - State " + output2State + "</p>");
// If the output4State is off, it displays the ON button
if (output2State=="off") {
client.println("<p><a href=\"/2/on\"><button class=\"button\">ON</button></a></p>");
} else {
client.println("<p><a href=\"/2/off\"><button class=\"button button2\">OFF</button></a></p>");
}
client.println("</body></html>");
// The HTTP response ends with another blank line
client.println();
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
}
// Clear the header variable
header = "";
// Close the connection
client.stop();
Serial.println("Client disconnected.");
Serial.println("");
}
}
此代码使用 ESP32/ESP8266(具有 WiFi 功能的 Arduino)设置一个简单的 Web 服务器,以通过 Web 界面控制两个负载(可能是继电器)。让我们分解一下主要组件和功能:
包括库:
#include <WiFi.h>
该系列包括 ESP32/ESP8266 的 WiFi 库,允许设备连接到 WiFi 网络。
网络配置:
const char *ssid = "ADDYOURSSID";
const char *password = "ASSYOURPASS";
将“ADDYOURSSID”替换为您的 WiFi 网络名称,将“ASSYOURPASS”替换为您的 WiFi 密码。
Web 服务器设置:
WiFiServer server(80);
在端口 80 上创建 Web 服务器。
引脚分配:
const int output1 = 0; // RELAY1
const int output2 = 3; // RELAY2
const int ledPin1 = 1; // LED1
const int ledPin2 = 2; // LED2
将GPIO引脚与负载(继电器)和LED相关联。
设置功能:
void setup() {...}
初始化串行通信并设置引脚。
连接到 WiFi 网络。
打印本地 IP 地址并启动 Web 服务器。
循环功能:
void loop() {...}
侦听传入的客户端(Web 浏览器请求)。
当客户端连接时,它会读取 HTTP 请求。
分析请求以确定用户是打开还是关闭负载(RELAY1 和 RELAY2)。
更新负载和相应 LED 的状态。
向客户端发送包含当前状态和用于控制负载的按钮的 HTML 响应。
HTML 响应:HTML 响应包括一个简单的网页,其中包含用于控制加载的按钮。显示每个负载的状态(ON 或 OFF),按钮允许用户切换状态。
该网页还包括一些带有 CSS 的基本样式。
响应将发送回客户端或浏览器进行显示。
注意:此代码假定负载连接到GPIO引脚0和3,LED连接到GPIO引脚1和2。
功能非常简单:ESP32/ESP8266 充当 Web 服务器,用户可以通过 Web 界面远程控制两个负载。通过单击 ESP32/ESP8266 提供的网页上的按钮来打开或关闭负载。
上传草图后,我们复制串口监视器中显示的IP地址;此 IP 地址将用作 Web 应用链接。
安装照明灯
我们在家庭自动化设备的交流端子上添加了一根交流电源线。为确保设备获得正确的电压,我们使用万用表检查交流电压。
接下来,我们将交流灯连接到继电器模块的交流端子,并按照提供的接线原理图打开交流电源。
上传草图后,我们使用从串行监视器获得的 IP 地址通过 Web 应用程序进行连接。
使用 web 应用程序,我们可以通过按下 web 应用程序中的按钮来打开和关闭交流灯。
结论
这个项目之所以成功,是因为我们可以用这块板子把任何设备变成智能物联网设备。我们可以将继电器直接连接到现有的电源板,并将交流开关与其并联,以转移通过继电器的电流并打开连接到该开关的交流电器。
由于此配置本质上是连接到两个端口和断开两个端口的开关,因此我们还可以添加带有继电器的直流负载。
通过在这个项目中使用 XIAO,我们获得了超快的 IEEE 802.11 b/g/n WiFi 连接,这提高了连接范围,使一切运行得超快。
通过将SMPS电源添加到PCB,我们可以轻松地通过交流电源为整个电路板供电,如果我们想将这种设置安装在难以获得5V电压的外部,这将特别有用。
此项目已完成,所有文件都可用。如果您需要有关此项目的其他信息,请告诉我。
感谢 Seeed Studio 对这个项目的支持。如果您需要出色的 PCB 和模板服务,可以以更低的成本和更高的质量检查它们。