智能插座远程控制电器很好玩!如果你有单片机或嵌入式基础,你也可以自己动手做一个

转自嵌入式ARM

学号16020311003  姓名:杨虎成

【嵌牛导读】多尝试自己动手用嵌入式解决问题

【嵌牛鼻子】嵌入式在大部分电气中有很大的作用

【嵌牛提问】嵌入式系统在电子元件中如何工作

【嵌牛正文】

智能插座远程控制电器很好玩!如果你有嵌入式单片机基础,你也可以自己动手做一个...

——————————————————

自己DIY用的零件清单(大部分都是手头拆机的):

1)STC51系列单片机(淘宝上几块钱就能买到,自己纯手工焊了一块板子)

2)中央空调控制面板上拆的继电器,有四路,刚好可以控制四个插座

3)蓝牙POS机(淘宝上一毛钱包邮很多,我这款叫“开店宝”),用于做蓝牙串口透传

4)废旧插座一个

由于普通插座都是共火线和共零线,为了实现四路单独控制,需要改造插座,将四个插孔的火线分开,然后与四路继电器相连,

 

整个控制流:手机APP –> 蓝牙POS –> 51单片机 –> 继电器 –> 插座

手机APP通过蓝牙发送数据到蓝牙POS,蓝牙POS作为一个蓝牙透传设备,将控制指令数据通过串口发送给单片机,单片机通过GPIO口来控制继电器,最终实现对插座的控制。(其实该蓝牙POS是个STM32单片机,可以无需51单片机,直接将STM32的GPIO引出来去控制,如果你动手能力强的话,鉴于自己动手能力一般,焊接不好那么细的芯片引脚,所以干脆拿了个51单片机来中转一下)。


  

下面奉上代码:

插座的通断是通过单片机来控制,结合蓝牙POS机做透传,即可直接通过蓝牙来控制继电器。

  

51单片机代码比较简单,放出完整代码。

#include <stc89c5xrc.h>

#include <string.h>

#define FOSC 22118400L //定义晶振频率

#define BAUD 115200  //定义波特率

#define SMOD  1

#define RX_BUFF_SIZE 64

#define ERR_CODE_RSP 0xD0  //错误码

/*定义四路开关控制引脚*/

sbit PLUG_1 = P2^4 ;

sbit PLUG_2 = P2^7  ;

sbit PLUG_3 = P2^6 ;

sbit PLUG_4  = P2^5 ;

unsigned char rx_buff[RX_BUFF_SIZE] = {0}; //串口接收缓冲区

volatile unsigned char rx_count = 0; //接收计数器

volatile unsigned char pos = 0;    //读取计数器,记录当前读取字节数 

volatile unsigned char msg_code = 0x00;  //存储控制码

volatile unsigned char status_code = 0x70;  //存储状态码

/** 串口发送 **/

void byte_send(unsigned char ch)

{

    SBUF = ch ;

    while(!TI);

    TI = 0;

}

/** 判断缓存是否有数据可读取 **/

unsigned char is_rx_buffer_empty(void)

{

    return !(rx_count - pos);

}

/** 读缓冲区一个字节 **/

unsigned char uart_read(void)

{

    unsigned char c;

    c = rx_buff[pos++];

    if(rx_count == pos){

        rx_count = pos = 0;

    } 

    return c;

}

/** 消息处理 **/

/** 简单起见,就用了一个字节做控制码

    bit0 ~ bit3: 分别对应四路开关,置0为关,置为1为开

    bit4 ~ bit8: 作为参数类型(0x06:查询开关状态 0x07:设置开关状态)

**/

void msg_process(void)

{

    if(is_rx_buffer_empty()) //如果设计成多个字节作为控制码,此处要改为while循环

        return;

    msg_code = uart_read();

    switch((msg_code & 0xF0) >> 4)

    {

        case 0x6:  //Get the status

            msg_reply(status_code);

            break;

        case 0x7:  //Set and get status

            PLUG_1 = msg_code & 0x01 ;

            PLUG_2 = (msg_code & 0x02) >> 1 ;

            PLUG_3 = (msg_code & 0x04) >> 2 ;

            PLUG_4 = (msg_code & 0x08) >> 3 ;

            status_code = msg_code; //保存本次处理结果

            msg_reply(status_code);

            break;

        default:  //Err code

            msg_reply(ERR_CODE_RSP);       

    }

}

/** 消息响应 **/

void msg_reply(unsigned char msg)

{

    //byte_send(':');//unknow reason

    delay(1500);

    byte_send(msg);

    byte_send(':'); //将':'作为间隔符,蓝牙POS收到该符号,才认为一条数据接收完毕

}

/** 串口初始化 **/

void uart_init(void)

{

    SCON = 0x50 ;

    TMOD = 0x20 ;

    PCON |= 0x80 ;    //set smod

    TH1 = TL1 = 256 - FOSC*(SMOD+1)/32/12/BAUD ;

    TR1 = 1;

    ES = 1 ;

    EA = 1 ;

}

/** 串口中断处理 **/

void  serial() interrupt 4  using 1

{

    if(RI)

    {

        RI = 0;

        if(rx_count > RX_BUFF_SIZE)

            rx_count = 0;

        rx_buff[rx_count++] = SBUF ;

    }

}

/** 主函数 **/

void main(void)

{

    P2 = 0x00;

    uart_init();

    while(1)

    {

      msg_process();

    }

}

消息处理函数,一定要放在主循环中,有的开发者习惯在中断响应函数中做消息处理,容易导致串口数据丢失。中断中一定只做简单的处理,本代码中只是将中断接收到的数据存到数组中。

测试:

假设当前开关状态为: 0101

用串口助手输入16进制:

输入:0x60 返回:0x75 0x3A //查询当前开关状态,0x3A为’:’对应16进制ASCII码

输入:0x77 返回:0x77 0x3A //设置开关0、开关1、开关2 开,开关3关闭

操作成功后,会听见继电器开启、闭合的声音,可以用万用表测量是否导通或者切断。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容