发帖
13 1 0

【电子DIY作品】433遥控网关-WB2

业余菜狗
论坛元老

26

主题

126

回帖

3446

积分

论坛元老

积分
3446
电子DIY 174 13 6 天前

前言

自从接触智能家居之后,我就变得很依赖智能家居(绝对不是我懒!).

我是在深圳租房住,租房嘛总有各种不方便,比如卧室灯,就在进门的地方,进门开灯很方便,但是晚上睡觉关灯就很不方便,之前是买了一款WiFi灯,是用手机APP操作,刚开始用的时候感觉很方便,后面用久了,觉得每次都要开APP操作也很烦,所以就在网上查了一下,有那种无线开关,按一下就能开关灯,把按钮贴在床头,需要开关灯就点一下,比点APP更方便!

但是网上卖的那种无线按钮开关可不便宜,以小米为例,官方价39一个,还得配一个百多两百的网关,众所周知菜狗的时薪是14.4(听说25年3月深圳统一调薪了,要下个月发工资才知道实际是多少),所以这种方案我是拒绝的.

那?就没有便宜的方案了吗???还真让我找到了,那就是433射频开关,淘宝或多多上(用券之后)才3块多一个,但是我用的Home Assistant系统是不能直接接入433开关的,所以我就用WB2自己DIY了一个433网关,将433遥控信号转发给Home Assistant.

我已经测试几个月了,还是比较稳的

成品长这样,找个充电头插上就好了

9958497807e33ca40f08a2c780ed1d6.jpg

一.DIY思路

数据处理流程:433按钮-->433接收模块-->WB2-->HA-->灯

433按钮:当按下433按钮时发送键值

433接收模块:接收到433键值后用uart发送给WB2

WB2:uart收到键值之后,将键值用mqtt发送给HA

HA:收到WB2的mqtt信息之后,根据用户设定控制灯(或其它设备)

灯:HA让我亮,那我就亮,让我灭,我就灭

二.准备工作

1.一个433按钮开关

2.Ai-WB2-12F模组及开发环境

3.一个433接收模块(我这里用的是蜂鸟无线的R1A模块)

4.一个USB公头,一片PCB,一堆小零件

5.一个3D打印的外壳

三.编程开发

因为433按钮是现成的,所以不需要开发,只有WB2和HA部分需要编程,HA部分还好,主要是WB2需要大量的代码

WB2射频网关代码思路

整体思路是这样的,wb2启动后开始链接WiFi和mqtt服务器,连上之后,发送设备信息给HA,让HA发现wb2并生成设备实体;

然后在433接收到遥控键值之后,用串口(uart)通信给wb2,wb2收到串口数据后,分析数据,并将数据通过mqtt发送给HA,至此完成一次传送.

如果你不想看下面的代码,那你只需要改这两个地方就能用了

main.c里面的WiFi账号密码

#define wifi_ssid "WiFi名称"
#define wifi_pass "WiFi密码"

yycg_mqtt.h里面的mqtt服务器信息

//设定MQTT服务器
#define mqtt_host "192.168.31.158"
#define mqtt_port 1883
#define mqtt_username "Ai-Thinker-WB2-433gateway"
#define mqtt_password ""

main函数

启动之后,先初始化uart,并连接wifi及mqtt,这里使用了多任务,wifi和mqtt是一个任务,uart也用了一个任务,软时钟任务,这几个任务是并行的

void main(){
    //初始化LED
    bl_gpio_enable_output(LED_IO, 1, 0);
    bl_gpio_output_set(LED_IO, 0);

    //初始化配对按钮
    bl_gpio_enable_input(pair_IO, 1, 0);

    //初始化uart,初始化之后,自带的log会失效,算是一个bug   
    uart_init();
    uart0_print("开始运行用户代码\n\0");
    vTaskDelay(1000);

    //读取保存的WiFi账号信息
    if(get_flash_wifi_data() == 1){
        uart0_print("已读取WiFi数据\n\0");
    }else{
        uart0_print("未找到WiFi数据,正在写入预设数据\n\0");
        set_flash_wifi_data(wifi_ssid, wifi_pass);
        get_flash_wifi_data();
    }

    vTaskDelay(1000);

    //启动WiFi和mqtt任务
    xTaskCreate(Task_mqtt, "Task_mqtt", 20480, NULL, 15, NULL);

    //启动软时钟任务
    xTaskCreate(Task_time, "Task_time", 2048, NULL, 5, NULL);

    //启动uart任务
    xTaskCreate(Task_Uart, "Task_Uart", 2048, NULL, 10, NULL);
}

uart任务

void Task_Uart(void *param){
    //初始化uart
    uint8_t data[32];
    int ret;

    hosal_uart_dev_t uart_dev_echo = {
        .config = {
            .uart_id = 0,
            .tx_pin = 6, // TXD GPIO
            .rx_pin = 4, // RXD GPIO
            .cts_pin = 255,
            .rts_pin = 255,
            .baud_rate = 9600,
            .data_width = HOSAL_DATA_WIDTH_8BIT,
            .parity = HOSAL_NO_PARITY,
            .stop_bits = HOSAL_STOP_BITS_1,
            .mode = HOSAL_UART_MODE_POLL,
        },
    };

    bl_gpio_output_set(LED_IO, 1);
    hosal_uart_init(&uart_dev_echo);
    ret = hosal_uart_receive(&uart_dev_echo, data, sizeof(data));

    //进入死循环读取串口数据
    while(1) {
        uint8_t uart_433_data[16];
        uint8_t mqtt_433_data[6];
        uint8_t mqtt_433_data_old[6];
        uint8_t mqtt_st;
        ret = hosal_uart_receive(&uart_dev_echo, data, sizeof(data));
        if (ret > 0){
            size_t x = 0;
            for (size_t i = 0; i < ret; i++){
                uart_433_data[x] = data[i];
                x++;
            }
            vTaskDelay(40);//可能是因为波特率是9600速度比较慢,一次接收会不完整,所以等待一下接收两次
            ret = hosal_uart_receive(&uart_dev_echo, data, sizeof(data));
            for (size_t i = 0; i < ret; i++){
                uart_433_data[x] = data[i];
                x++;
            }
            uart0_send(uart_433_data, x);
            mqtt_st = 0;
            //mqtt_433_data[6] = '\0';

            //将接收到的uart赋值给mqtt信息变量,并判断新旧数据是否一样(433数据可能重复)
            for(size_t i = 0; i < 6; i++){
                mqtt_433_data[i] = uart_433_data[i+3];
                if(mqtt_433_data[i] != mqtt_433_data_old[i]){
                    mqtt_st = 1;
                }
            }

            //打印出新旧数据
            uart0_send(mqtt_433_data_old, 6);
            uart0_send((uint8_t *)"\n", 1);
            uart0_send(mqtt_433_data, 6);

            //判断
            while(1){//二级循环
                if(!(mqtt_st == 1 || time_nv>100))break;//判断是否重复,当数据重复且间隔大于1s(软时钟作用)仍然发送
                if(!(pair_event == 0))break;//判断433模块是不是处于配对状态
                if(!(mqtt_event == 1))break;//判断mqtt服务器是否连接正常

                //发送mqtt数据,并将数据保存到变量方便下次对比
                ha_text_send(R1A_ID1, (char*)mqtt_433_data);
                for(size_t i = 0; i < 6; i++){
                    mqtt_433_data_old[i] = mqtt_433_data[i];
                }
                time_nv = 0;
                break;
            }
        }
        vTaskDelay(5);
    }
}

软时钟任务

//软时钟函数,time_nv变量10ms自加一次
void Task_time(void *param){
    while(1){
        time_nv++;
        vTaskDelay(10);
    }
}

MQTT订阅回调函数

void mqtt_topic_data(char * topic, char * data){
    char topic2[128];

    //收到HA的上线信息,发送HA自动发现信息
    if(strcmp(topic, "homeassistant/status")==0){
        ha_config_code();
    }

    //处理"配对"
    connect_topic_str(topic2, "button", R1A_ID2, "cmd_t");
    if (strcmp(topic, topic2)==0){
        pair_event = 1;
        //模拟连续按两下进入配对模式
        bl_gpio_enable_output(pair_IO, 1, 0);

        bl_gpio_output_set(pair_IO, 0);
        vTaskDelay(50);
        bl_gpio_output_set(pair_IO, 1);

        vTaskDelay(200);

        bl_gpio_output_set(pair_IO, 0);
        vTaskDelay(50);
        bl_gpio_output_set(pair_IO, 1);

        bl_gpio_enable_input(pair_IO, 1, 0);
        char X = 1;
        time_nv = 0;
        while(X){
            if(!(bl_gpio_input_get_value(pair_IO))){
                time_nv = 0;
            }
            if (time_nv>200){
                X = 0;
            }
            vTaskDelay(200);
        }
        uint8_t data[16];
        uart1_get(data);
        pair_event = 0;
    }

    //处理"重置"
    connect_topic_str(topic2, "button", R1A_ID3, "cmd_t");
    if (strcmp(topic, topic2)==0){
        pair_event = 1;
        //模拟长按10S清除配对的遥控
        bl_gpio_enable_output(pair_IO, 1, 0);

        bl_gpio_output_set(pair_IO, 0);
        vTaskDelay(10000);
        bl_gpio_output_set(pair_IO, 1);

        bl_gpio_enable_input(pair_IO, 1, 0);
        char X = 1;
        time_nv = 0;
        while(X){
            if(!(bl_gpio_input_get_value(pair_IO))){
                time_nv = 0;
            }
            if (time_nv>200){
                X = 0;
            }
            vTaskDelay(200);
        }
        uint8_t data[16];
        uart1_get(data);
        pair_event = 0;
    }
  
    vTaskDelay(1000);
}

HA初始化函数

void ha_config_code(){
    //注册"433键值","433配对"按钮,"433重置"按钮
    ha_text_config(R1A_ID1, "433键值");
    ha_button_config(R1A_ID2, "433配对");
    ha_button_config(R1A_ID3, "433重置");
    vTaskDelay(1000);
    //发送设备上线信息
    mqtt_pub(mqtt_lwt_topic, "online");
}

HA设置部分

在你烧录好代码之后你的HA中会自动出现一个mqtt设备

342da57d475889683682da0c045dd6d.png

点击左边那个MQTT INFO复制433键值下面的topic内容,每个设备中间部分会不一样

我的就是:

homeassistant/text/7CB94CD1F767/433_R1A_001/config

image.png

去自动化设置里面,新建一个自动化,设置为当收到某个 MQTT 消息时,主题填入刚才的内容

image.png

或者你也可以直接复制我这段代码贴上(记得改主题)

topic: homeassistant/text/7CB94CD1F767/433_R1A_001/state
trigger: mqtt

然后在下面的"就执行"里面判断键值,先设置一个短延迟,防止数据还没来得及更新

image.png

这个也可以复制代码不过

choose:
  - conditions:
      - condition: template
        value_template: "{{ \"8FE004\" == states(\"text.wb2wang_guan_433_433jian_zhi\") }}"
        alias: 键值判断
    sequence:
      - action: light.toggle
        target:
          device_id: a38cb2e40595fabed52aab4309efb240
        data: {}
    alias: 菜狗86遥控-1-B键-8FE004-开关卧室灯

现在按下433按钮,就能开关灯了

四.硬件、PCB和外壳

硬件接线和PCB

R1A的TX连接WB2的IO4,重置按键"K/O"连接WB2的IO5.

PCB基本上去就是一个傻瓜板很简陋,我放附件了有需要的可以改一下自己用

image.png

image.png

外壳

外壳是随便画的,我不太会3D建模,我的要求就是能把PCB装进去就行了

image.png

image.png

好了今天就分享到这了,请各位大佬回帖指教

实用至上,点亮便利生活

upload 附件:mqtt_gateway_433代码.zipupload 附件:PCB文件_WB2-433_2025-03-19.zipupload 附件:嘉立创EDA标准版_PCB工程_20250319.zipupload 附件:外壳.zip

──── 1人觉得很赞 ────

使用道具 举报

沙发
狗哥的灯是市电吗
为狗哥点赞👍
WildboarG 发表于 2025-3-20 08:25
狗哥的灯是市电吗

是的,易来的WiFi灯泡
不错不错,交作业了~
狗哥15 pro都整上了,不整个全屋智能家居 /doge
1055173307 发表于 2025-3-20 09:16
狗哥15 pro都整上了,不整个全屋智能家居 /doge

正在整,跟着莫工学习
学习了
433穿墙比较厉害
您需要登录后才可以回帖 立即登录
高级模式
12下一页
统计信息
  • 会员数: 28167 个
  • 话题数: 39945 篇