专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

教你用智能手机遥控电灯

作者:佚名   来源:本站原创   点击数:  更新时间:2013年11月19日   【字体:
ALL BY 陈歌
前言:
    虽然一路坎坷,但经过近半年的不懈努力,我终于完成了本人在上海大学申报的创新项目——智能手机遥控电灯研究,在此感谢那些给予过我帮助的人,特别感谢老爸给予的技术上的帮助。
    好东西自然不能独享,为了让大家也能体验一下集物联网、智能家居和一大堆现代科技名词为一体的现代化居家生活,所以决定发一篇教程,帮助大家用手机来遥控电灯(高手请绕道)。
    吐槽一下:上海大学校级创新项目经费3000元,武汉大学1000 
    废话不多说了,正文开始:

开发环境:
64位WINDOWS 7下的WINDOWS XP虚拟机(因为win7下jtag没驱动,这驱动困扰了我好长时间,还因为装双系统失败而重装系统,资料都没了。最终用Vmware Workstation解决)。
采用AVR128单片机,C语言编写程序,avrstudio4setup.exe4.19 + WinAVR-20100110-install.exe + vr-toolchain编辑、编译、仿真。
所需器材:
1.USB接口JTAG仿真器+AVR128单片机(用jtag连接电脑后将后文中的C程序代码通过avrstudio4这个软件烧写进单片机的CPU中,至于avrstudio4的使用说明网上有很多,这里不再说明):

2.SRD-5VDC-SL-C 1路 5V继电器驱动模块 :

3.TCP232-T 串口转以太网双向以太网转串口TCP,IP转串口、RJ45转TTL。

4.智能手机一部


5.电灯....


 

1、系统设计

智能家居物联网控制器

1.AVR128 PORTD 操作继电器模块(后文有开发板和继电器的原理图,及连接方式

2.AVR128 Usart0 TCP232-T通讯,接收指令转换PORTD电平

3.继电器模块, 实现火线通断控制,进一部控制电器设备,本例控制电灯

4.TCP232-T模块,实现串行通讯与TCP通讯的通明传输。工作模式为ClientTCP协议,主动连接远程服务器。接收AVR128的指令,

遥控端

 

智能手机,通过WEB网页或者应用软件控制远程电灯

 

2、指令协议(由遥控端发送到服务器,再由服务器广播到TCP232-T模块,再由单片机进行接下来的控制继电器部分,最后达到控制电灯的目的)

 

1.开灯指令:1212140400DBBF PORTD输出低电平,继电器模块获得低电位,常开状态转换为闭合状态

2.关灯指令:12121404FF9BFF PORTD输出低电平,继电器模块获得低电位,常开状态转换为闭合状态

3.查询灯状态指令:12121404AAxxxx 获取PORTD状态并返回。

    其中12121404为本例标识。TCP232-T模块成功连接服务端后,发送设备设备标识。 本例为12121404,控制指令以12121404起头。

十六进制

实例

    发送1212140400DBBF

其中12121404为标识,00为开灯指令,DBBFCRC检验码(用来检验控制端发送的16进制代码和服务器端收到的16进制代码是否相同,详见后文的C程序代码

控制器返回[123.4.244.144:20108] 45

其中123.4.244.144为控制器IP地址,20108为控制器TCP端口,45表示指令格式正确,并被正确执行

控制器返回[123.4.244.144:20108] 4BDBBF

4BDBBF表示指令标识正确,但是CRC不正确,正确的CRCDBBF

控制器返回[123.4.244.144:20108] 4B

非指令或者其他错误。

 

3、智能家居物联网控制器功能设计

电源,采用2205V/200mA统一供电,其他部件由单片机提供VDD5VVCC3.3V,单片机工作在5V状态(注意跳线)。

其中TCP232-T 需要50mA才能稳定工作,SRD-5VDC-SL-C也需要50mA才能正确动作。所以采用独立电源。

共地设计。

花絮:实验过程中,使用计算机USB2.0)供电,单独编程实验继电器能能正常动作,单独使用TCP232-T也能正常连接网络。联合调试的时候,继电器不动作。分析原因,起初以为单片机提供电流有限,负载能力差,后来考虑到单片机本身需要100mA左右电流,随采用独立电源供电,以提供更大电流。实验成功。

AVR单片机开发板

有两供电方,USB和独立电源,并有5V3.3跳线。本例单片机工作在5V状态。
 

 

继电器模块电源设计

使用5V供电,3个接线柱,分别为电源正,控制线(低电位有效),电源地。分别连接到电源正,AVRPORTD口,电源地。

继电器模块输出(连接被控制设备,本例为电灯电源线中的火线),有3个接口,中间为公共地,一端为常开状态,另一端为常闭状态。本例使用常开状态,接收用户指令,实现常开和闭和动作。

TCP232-T模块电源设计

电源使用5V供电,串行通讯为TTL电平(<3.3V03.5-5V1。串口为-9V - +9V电平,〈0V0,〉1V1。两种接口不能接错),TTL电平可以直接接单片机端口。

如果是TTL电平,直接POARTE0POARTE1,如果是串口模块,接单片机开发板串口。串口只使用235三根线。
 

 

4、原理图

AVR开发板

PORTD接继电器模块,为简单,写端口0x00或者0xFF,以控制端口电平,实现控制继电器动作。

PORTE8LED,一般用来在开发过程中指示工作状态,本例最终版本无用。

POARTE0POARTE1TTL电平的TCP232-T模块的TXDRXD

POARTE0POARTE1另外设计连接MAX232转换芯片和接口,供串口设备通讯。

USART1485转换口

另有电源总开关、复位键和4个键盘。
 

 

继电器模块

输入端,分别接电源正,PORTD任意一个,和电源地

输出端,使用常开接口,只能控制1条线路。其他空置悬空。

电源,电源正接VDD,电源地接GND

TCP232-T模块

?  RJ45接口,标准的网口,使用1236四根线

?  串口端,TTL电平,RXDPOARTE0POARTE1TXD

?  电源,电源正接VDD,电源地接GND

?  CFG空置,如果被拉底,比如接GND,则模块工作于串口设置模式,不响应网络连接。

?  复位,接PORTF,复位通讯模块。
 

 

5、使用说明
服务器:
本软件使用VB编写
   Modbus协议规定的传输媒介有串行总线和以太网两种,其中串行总线规定了ASCII模式和RTU模式两种传输方式。本软件以GB/T19582-2008为蓝本,实现Modbus协议的TCP模式、ASCII模式和RTU模式之间相互转换;并将UDP协议纳入TCP模式,实现广播通讯;模拟应答,没有物理设备也可以调试系统。扩展了TCP模式,开发出微型Webserver,实现了3种模式与HTTP协议之间的转换,使通用浏览器(比如Window IE或者Andriod 的浏览器)成为控制器。
 

外部接口:

RJ45 ,网口

J1,控制线,23公共,1为常开,4为常闭。可以控制250V以下电压,2A电流。

电源,5V

开关,总电源开关

网络接口设置

本例使用RJ45口网络配置,专用软件。工作于Client模式,通过有线内部网络,连接公网SERVER。根据网络环境,设置静态IP,不支持DHCP

可设置本机IP,网关,端口20108,和远程SERVER地址和端口8234。心跳设计,断网自动连接。
 

 

智能手机TCP应用软件模式:

 

用于局域网和广域网,本例为安卓应用软件
网上找到有个叫easytcp的软件比较好使,可以配合SERVER使用

 

智能手机WEB模式(不太稳定):

用于广域网,本例为通用浏览器,支持HTML即可。HTTP协议,端口9000
 

 

6、程序设计

控制器采用C设计

这里给出核心代码

 

//*************************************************************************

//                         继电器模块编程设计

//*************************************************************************

 

#define Lamp_IO             PORTD                     //继电器模块所在数据口

#define Lamp_DDR        DDRD                       //方向寄存器

Lamp_IO=0xFF;                                              //数据口为输出

Lamp_DDR=0xFF;

 

if((data_buf[RX_length-1]==0xFF) ||(data_buf[RX_length-1]==0x00))

{

         usart_send(0x45);                      //将接收到的数据再发出去

         Lamp_Display(data_buf[RX_length-1]);         //PORTD,控制继电器模块,继电器低电平有效,0xFF为关灯,0x00为开灯

}

 

//*************************************************************************

//                         USART通讯设计

//*************************************************************************

 

//由于采用通明传输,因此本例只涉及USART通讯编程,使用USART0,也就是PORTE0PORTE1

//初始化

#define baud           9600                                     //设置波特率的大小

#define baud_setting   (uint)((ulong)F_CPU/(16*(ulong)baud)-1)  //波特率计算公式

#define baud_h         (uchar)(baud_setting>>8)                 //提取高位

#define baud_l         (uchar)(baud_setting)                    //低位

void usart_init()

{

 UCSR0A=0x00;                                 //单倍速模式

 UCSR0B=0xF8;                                 //接收中断和发送中断允许                              

 UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);              //UCSRC寄存器,异步通信无校验,8位数据1位停止位

 UBRR0H=baud_h;                               //写波特率的值

 UBRR0L=baud_l;

}

 

//发送数据

void usart_send(uchar data)

{

 

         while( !( UCSR0A & (1<<UDRE0)) );         //等待发送缓冲器为空

             UDR0 = data;                                       //接收到的数据再发回电脑

         delay_ms(2);

}

//数据接收结束中断向量

SIGNAL(SIG_USART0_RECV)                       //中断服务程序

{

   uchar RxTemp;

         RxTemp=UDR0;                            //将接收到的数据取出

         usart_rx_data[RxReadIndex]=RxTemp;

         if(++RxReadIndex> Rx_Buf_Size)          //如果写接收缓冲区索引大于接收缓冲区的长度

               RxReadIndex=0;                  //则索引重新清0

         rx_flag=1;

}

//*************************************************************************

//                         CRC检验和判断

//*************************************************************************

 

uint get_crc(uint n)

{

   uchar i,j;

   CRC_word=0xffff;//赋值:0xffff

   for(i=0;i<n;i++)

     {

        CRC_word^=(uint)data_buf[i];//计算CRC_word

        for(j=0;j<8;j++)

         {

            if(CRC_word&0x0001)

              {

                CRC_word=CRC_word>>1;

                CRC_word^=0xa001;

              }

            else

              {

               CRC_word>>=1;

              }  

         }

     }

   return CRC_word;

}

判断

RX_length=RxReadIndex-2;//*256+data_buf[3];//取数据长度数据

RX_CRC_word=data_buf[RX_length+1]*256+data_buf[RX_length];//CRC校验码

CRC_word=get_crc(RX_length);//计算接收数据校验码

if(CRC_word==RX_CRC_word)//校验数据比较

{}

两位CRC码提取

(CRC_word%256);

(CRC_word/256);

 

//*************************************************************************

//                         主程序

//*************************************************************************

int main(void)

{

 system_init();                             //系统初始化

 usart_init();                              //usart串口初始化配置

 SREG|=0x80;                                //开启全局中断

 while(1)

 { 

          _delay_ms(50);                         //为串口中断方式延迟,这个很重要,本例通讯数据少,因此设置50

         if((RxReadIndex>0) && (rx_flag==1))

         {       

                   cli();           //全局中断无效,同SREG=0x00;

                   RX_data=&usart_rx_data[0];//指针接收数组首地址

                   for(read_count=0;read_count<RxReadIndex;read_count++)//copy

                        {

                            data_buf[read_count]=*RX_data++;

                            usart_send(data_buf[read_count]);

                             }

                   receive_code_fun();

                   _delay_us(5);

                      RxReadIndex=0;//接收中断次数清零

                   rx_flag=0;

                   sei();//开全局中断,同SREG|=0x80;

         }

  }

}

 

server采用VB设计

 

使用控件,创建微WEB服务器,接受并解析HTTP协议,执行指令后返回HTML数据流。

指令只转发给受控制端。

 

主页源代码如下:

===========================

<html>

<head>

<title>MODBUS调试  --- 上海大学 陈歌</title>

</head>

<body>

<imgsrc="/img/shu.gif">MODBUS协议转换助手

<form name="f"action="modbus.html" method=post>

ID<input type="text"name="ID" maxlength="30" >

地址<input type="text" name="AD"maxlength="30" ><br>

数据<input type="text" name="DATA_LEN"maxlength="50" >

<select name="FUNC">

 <option value ="01">读开关量</option>

 <option value ="02">02</option>

 <option value="03">读寄存器</option>

 <option value="04">04</option>

</select>

<input type="submit"value="" ></form>

<textarea rows="10"cols="50">

这里显示的是,返回数据

</textarea>

<form name="N"action="modbus.html" method=post>

普通数据发送<input type="text" name="post_send_str"maxlength="80" >

<select name="hexstr">

 <option value ="16">16进制</option>

 <option value ="01">字符串</option>

</select>

<input type="submit"value="发送" ></form>

</form>

</body>

</html>

==================================

 

 


 
关闭窗口

相关文章