聚丰项目 > 家庭网关模拟
所谓的网关,其实也可以叫中央控制器(IOT HUB),主要是收集各离散节点的信息,在终端上显示;另外就是通过手持终端来发出各种指令控制,控制各离散节点设备的运行。
netlhx
分享netlhx
团队成员
刘红新 老师
温度传感器连接到扩展板的A1
光照传感器连接到扩展板的A2
PWM输出连接到扩展板的D5
舵机连接到扩展板的D3
LCD连接到I2C接口
整体连接效果如图
在原来的计划中,舵机控制是准备实现的。只是可惜在实验中,舵机被烧坏了。
烧坏的舵机,估计是在试验的时候,正反转设置的时候参数有问题,可惜!
实现关键代码
程序代码使用NODE.JS来实现,调用底层的MRAA及UPM库来实现相关操作。
完整控制代码如下
var http = require('http');
var query = require('querystring');
var mraa = require('mraa');
var grove = require('jsupm_grove');
var LCD = require('jsupm_i2clcd');
var SERVO = require('jsupm_servo');
var os = require('os');
var lcd = new LCD.Jhd1313m1(6, 0x3E, 0x62);
var hostname = os.hostname().toString();
var ipaddr = os.networkInterfaces()['wlan0'][0]['address'].toString();
var light = new grove.GroveLight(2);
var temp = new grove.GroveTemp(1);
var lightValue = light.value();
var tempValue = temp.value();
//var servo = new SERVO.ES08A(3);
var led_pwm = new mraa.Pwm(6);
led_pwm.enable(true); //must enable
var ds2 = new mraa.Gpio(13);
ds2.dir(mraa.DIR_OUT);
ds2.write(1);
led_pwm.write(0);
//servo.setAngle(90);
lcd.clear();
lcd.setCursor(0, 0);
lcd.write('Intel Edison IoT');
var status = {};
status['host'] = hostname;
status['ipaddr'] = ipaddr;
status['title'] = 'Intel Edison IoT';
setInterval(function() {
status['temp'] = temp.value().toString();
status['light'] = light.value().toString();
}, 2000);
var server = http.createServer(function(req, res) {
switch(req.method) {
case 'GET':
//res.writeHead(200, {'Content-Type': 'application/json'});
//res.end(JSON.stringify(status));
break;
case 'POST':
var content = "";
req.setEncoding('utf8');
req.on('data', function(chunk) {
content += chunk;
});
req.on('end', function() {
console.log(content);
status['title'] = JSON.parse(content)['title'];
status['pwm'] = JSON.parse(content)['pwm'];
status['ds2'] = JSON.parse(content)['ds2'];
console.log(status);
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(status['title'].toString());
led_pwm.write(Number(status['pwm']) / 100);
ds2.write(Number(status['ds2']));
});
break;
default:
break;
}
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(status));
});
server.listen(8000);
复制代码
目前代码测试正常,不过不排除潜在的BUG,希望各位有时间的话测试。
客户端使用ANDROID,编写一个简单APP来显示及控制节点。部分关键代码如下
host = (TextView)findViewById(R.id.host);
ipAddr = (TextView)findViewById(R.id.ipAddr);
light = (TextView)findViewById(R.id.light);
temp = (TextView)findViewById(R.id.temp);
pwm = (SeekBar)findViewById(R.id.pwmSeekBar);
lcd = (EditText)findViewById(R.id.lcd);
ds2 = (Button)findViewById(R.id.switchButton);
postButton = (Button)findViewById(R.id.postButton);
info = new JSONObject();
postButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
info.put("pwm", "" + pwm.getProgress());
info.put("title", lcd.getText().toString());
//info.put("ds2", String.valueOf(0));
} catch (JSONException e) {
e.printStackTrace();
}
new SendJsonTask().execute(info);
}
});
ds2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if(ds2.getText() == "关") {
info.put("ds2", "0");
ds2.setText("开");
}
else {
info.put("ds2", "1");
ds2.setText("关");
}
} catch (JSONException e) {
e.printStackTrace();
}
ds2.setEnabled(false);
}
});
}
class SendJsonTask extends AsyncTask<JSONObject, Void, String>
{
@Override
protected String doInBackground(JSONObject... params) {
StringBuilder sb = new StringBuilder();
String http = "http://192.168.99.221:8000/";
HttpURLConnection urlConnection=null;
try {
URL url = new URL(http);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setConnectTimeout(10000);
urlConnection.setReadTimeout(10000);
urlConnection.setRequestProperty("Content-Type","application/json");
urlConnection.connect();
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
Log.d("JSON", params[0].toString());
out.write(params[0].toString());
out.close();
int HttpResult =urlConnection.getResponseCode();
if(HttpResult == HttpURLConnection.HTTP_OK){
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(),"utf-8"));
String line = null;
while ((line = br.readLine()) != null) {
sb.append(line );
}
br.close();
Log.d("JSON", sb.toString());
return sb.toString();
}else{
System.out.println(urlConnection.getResponseMessage());
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally{
if(urlConnection!=null)
urlConnection.disconnect();
}
return null;
}
@Override
protected void onPostExecute(String data)
{
super.onPostExecute(data);
try {
JSONObject receivedInfo = new JSONObject(data.toString());
host.setText(receivedInfo.get("host").toString());
ipAddr.setText(receivedInfo.get("ipaddr").toString());
light.setText(receivedInfo.get("light").toString());
temp.setText(receivedInfo.get("temp").toString());
lcd.setText(receivedInfo.get("title").toString());
//if(Integer.parseInt(receivedInfo.get("ds2").toString()) == 1)
//ds2.setText("关");
//else
//ds2.setText("开");
ds2.setEnabled(true);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
复制代码
网络访问部分使用了异步任务,在接收到JSON数据之后,刷新APP界面元素。
功能概括
INTEL EDISON作为中央控制节点,收集及接收来自终端节点的信息,并执行相应的控制指令
温度传感器收集温度信息
光照传感器收集光照强度,光照强度值可以用来控制灯光的强弱
无级调光,通过PWM来控制灯的亮度(通过LED灯来模拟)
舵机控制,比如调整自动浇花器的位置
开关控制,打开或关闭指定位置的照明灯(通过LED灯来模拟)
LCD显示,模拟家中的LED显示屏
设计思路
程序设计语言使用NODE.JS做为服务端控制语言,这也是INTEL主推的一个物联网应用中的开发语言。NODE.JS调用底层的MRAA及UPM库来控制硬件。硬件控制GROVE的实验请参考http://bbs.elecfans.com/forum.ph ... d&tid=919288&extra=。
INTEL官方提供的诸多IDE中,XDK实在太臃肿,加上使用NODE.JS只需要一个VIM即可实现编程、调试。另外C/C++类编程语言在调试过程中需要反复修改、编译、调试,步骤略显繁琐。所以这里使用轻便的NODE.JS来实现服务端功能。
服务器端使用比较原生的HTTP模块搭建了一个简单的WEB服务器,客户端可以使用HTTP请求来获取或者上传相应控制指令。
数据通信格式
服务器与客户端之前使用JSON来进行通信,一次典型的通信数据如下
{"ds2":"1","title":"Hello, world","pwm":"51"}
复制代码
上述JSON数据中,第一部分是客户端通过HTTP POST方法上传的要求服务器执行的信息
"ds2":"1" 请求EDISON打开板载的DS2指示灯,起到模拟开灯/关灯的效果
"title":"Hello, world" 请求将LCD的显示内容设置为HELLO, WORLD
"pwm":"51" 请求将连接在D5上的LED灯亮度值设置为51%
下面一部分JSON数据是将EDISON上的一些信息反馈给客户端,用户可以使用HTTP来显示这些内容,如下图
简易的客户端APP实现
除了可以使用浏览器之外,专门设计了一个简单的ANDROID客户端程序,界面很简单,如下图
APP上面是显示区域,显示从服务器端获取的数据信息;中间为控制区域,只设计了控制EDISON的部分接口;最下面是刷新按钮,用来刷新数据。
效果及简单总结
本贴实现了一个典型的C/S通信控制。
服务端SERVER使用了大名鼎鼎的NODE.JS,主要提供两方面的内容:基于RESTFULL的服务;结合MRAA及UPM提供硬件访问控制
客户端实现了WEB/APP双访问机制,不过出于安全考虑,WEB访问只提供了只读式的访问方式。要想控制设备,需要通过APP来实现
本项目虽然功能还比较简单,但是通信/控制的基本框架已基本具备,添加新的功能已非常简单
基于C/S通信架构的调试,比单机设备调试需要考虑的因素更多,过程也更复杂
附:
部分运行效果图
LCD显示效果,可以通过APP来实时改变显示内容
舵机调试
外接的WIFI天线,以增强远距离通信效果
动心忍性1234: 您好我是无线电杂志的编辑,我们对您的项目十分感兴趣,请问您有兴趣投稿吗?成为我们的作者除稿费外还有其他优厚条件。敬请参与。投稿请联系QQ260534978.
回复