本人目前大二,物联网专业本科生,就读于西北民族大学。第一篇博客打算写一点和自己专业有关系的,一个简单的家具控制,也就是物联网中所说的智能家居。
直接进入正题,首先将整个系统分成三个部分:手机端,服务器端,被控端。手机端和被控端在开启时都会向服务器发送连接请求,请求接入。同时发送连接密钥(暂时定为0x00),接入时服务器会开辟一个线程,进行服务(手机端和被控端是两个不同的线程),之后服务器可以进行消息的转发,从而进行远程控制。
因为时间关系并没有加入验证机制,比如登陆验证,命令发送成功验证等。
开发板采用STM32F103的一款开发板,内置有4个颜色的LED等,主要是打算通过手机对这四个灯进行控制,开发板上可以直接板载ESP8266,通过ESP8266以及TCP透传,就可以完成命令的接受以及处理。
-
手机端
利用android,编写APP,主界面如下:
通过在IP编辑框以及Port编辑框中输入IP地址以及端口号就可以连接到服务器上(Socket)。
整个代码分成三个部分,辅助模块、监听器模块以及主程序模块。代码已经上传,需要使用或者测试的可以直接下载。
-
服务器端。
服务器端采用多线程以及SocketServer,让手机端和被控端能够接入。
一个有4个类,分别对应了数据类,Main类,手机线程类以及单片机类。
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
private final static int PORT = 1234;
private static InputStream input;
private static int flag;
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(PORT);
Data data = new Data();
int socketNum = 0;
int mobileNum = 0;
int scmNum = 0;
while (true) {
System.out.println("等待连接:");
Socket socket = server.accept();
System.out.println("连接完成");
input = socket.getInputStream();
while ((flag = input.read()) != -1)
;
if (flag == 0x00) {
System.out.println("手机连接");
Thread mobile = new Thread(new MobilePhoneThread(socket,
data));
mobileNum++;
mobile.start();
} else {
System.out.println("单片机连接");
scmNum++;
Thread scm = new Thread(new SCMThread(socket, data));
scm.start();
}
socketNum++;
System.out.println("当前接入总数:" + socketNum + ",手机总数:" + mobileNum
+ ",单片机:" + scmNum);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在接入时,手机端和硬件端向服务器发送的命令不同,可以将接入的手机和硬件进行分类,从而启动不同的线程进行控制。
-
硬件端(被控端)
有一个ESP8266以及4个LED。直接贴代码:
//单片机头文件
#include "stm32f10x.h"
//网络设备
#include "esp8266.h"
//硬件驱动
#include "delay.h"
#include "led.h"
#include "usart.h"
//C库
#include <string.h>
void Hardware_Init(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断控制器分组设置
Delay_Init(); //systick初始化
Usart1_Init(115200); //串口1,打印信息用
Usart2_Init(115200); //串口1,打印信息用
Led_Init(); //LED初始化
ESP8266_Init();
UsartPrintf(USART_DEBUG, " Hardware init OK\r\n");
}
void LED_Control(char c){
int num = (int)(c-'0');
int i;
switch(num){
case 0x21:Led2_Set(LED_ON);break;
case 0x20:Led2_Set(LED_OFF);break;
case 0x31:Led3_Set(LED_ON);break;
case 0x30:Led3_Set(LED_OFF);break;
case 0x41:Led4_Set(LED_ON);break;
case 0x40:Led4_Set(LED_OFF);break;
case 0x51:Led5_Set(LED_ON);break;
case 0x50:Led5_Set(LED_OFF);break;
default:
break;
}
}
int main(void)
{
Hardware_Init(); //初始化外围硬件
ESP8266_SendData((unsigned char *)("Ok\r\n"),4);
while(1){
char *s = (char *)ESP8266_GetIPD(300);
if(s != NULL){
UsartPrintf(USART_DEBUG, s);
LED_Control(s[0]);
}
}
}
不断的等待从串口去读取数据,每次只是选取首字节进行相应。