刚开始学习arduino,接触到了yeelink。这个当前在开发爱好者中比较火的物联网云平台。试着了解了下,真的还不错。当然你也可以把你的应用部署到其他云平台中,只是这个平台给初学者提供了很多简单好用的控件和操作。
因此我就开始在例程中招了个比较简单的来尝试---室内温度监控。但是例程中需要w5100模块,由于只是买了个arduino初学套件,没有这些板子,怎么办了?还好这个难不倒我。我用电脑读取arduino的串口信息,并使用最简单的sockets结合yeelink的api实现了数据的上传。
下面是对整个过程的一个描述,经验有限,还请见谅。
1.电路的搭建
2.代码
// labtemperature.ino
int potPin = 0;//将A0作为LM35的输入
void setup() {
Serial.begin(9600);
}
void loop() {
long val;
float dat;
val = analogRead(potPin); //读取LM35值
dat = 5.0*val*100.0/1024;//计算室温
Serial.print(dat);//向串口输出室温
delay(1000*30);//30秒获取一次实验室温度
}
3.由于是在windows下开发,所以使用java的rxtx包来读取串口信息,并将它保存为json格式
public class Temperature {
private static String portname = "your arduino portname";
private static CommPortIdentifier portID;
private static SerialPort serialPort;
private static DataInputStream inputStream;
public static void main(String[] args) throws Exception {
portID = CommPortIdentifier.getPortIdentifier(portname);
serialPort = (SerialPort) portID.open("yourapp", 2000);
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
inputStream = new DataInputStream(serialPort.getInputStream());
serialPort.notifyOnDataAvailable(true);
serialPort.addEventListener(new SerialPortEventListener() {
@Override
public void serialEvent(SerialPortEvent ev) {
// TODO Auto-generated method stub
switch (ev.getEventType()) {
case SerialPortEvent.DATA_AVAILABLE:
try {
Json json = new Json(inputStream);
json.saveTemperature();
new PostThread().start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
break;
}
}
});
}
}
class PostThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
Http datapost = new Http();
datapost.doDataPost();
}
}
在该实现中,实现了serial的监听方法,主要是监听SerialPortEvent.DATA_AVAILABLE。
其中Json类是用来读取串口输入流数据并将它按yeelink api要求写入到json文件中
public class Json {
DataInputStream inputstream;
public Json(DataInputStream inputstream){
File file = new File("data.json");
if(file.isFile()&&file.exists()){
file.delete();
System.out.println("删除json成功!");
}
this.inputstream = inputstream;
}
public void saveTemperature() throws Exception {
FileWriter writer = new FileWriter("data.json", false);
writer.write("{\r\n");
writer.write("\"timestamp\":\"" + getTime() + "\",\r\n");
writer.write("\"value\":" + readComm() + "\r\n");
writer.write("}");
writer.flush();
writer.close();
}
public String readComm() {
int ch;
StringBuffer temper = new StringBuffer();
try {
while ((ch = inputstream.read()) > 0) {
temper.append((char) ch);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return temper.toString();
}
public String getTime() {
SimpleDateFormat sdf1 = new SimpleDateFormat("",
Locale.SIMPLIFIED_CHINESE);
SimpleDateFormat sdf2 = new SimpleDateFormat("",
Locale.SIMPLIFIED_CHINESE);
sdf1.applyPattern("yyyy-MM-dd");
sdf2.applyPattern("HH:mm:ss");
return sdf1.format(new Date()) + "T" + sdf2.format(new Date());
}
}
Http类是使用socket向yeelink云发送post请求,上传温度数据,比较简单。
public class Http {
private BufferedWriter httpPostWriter = null;
private BufferedReader httpResponse = null;
private Socket socket;
public void doDataPost() {
try {
// form域的数据.form域的数据以二进制形式发送
StringBuffer formDataItems = new StringBuffer();
readToBuffer(formDataItems, "data.json");
String hostname = "api.yeelink.net";// 主机,可以是域名,也可以是ip地址
String ApiKey = "your api key";
int port = 80;// 端口
InetAddress addr = InetAddress.getByName(hostname);
socket = new Socket(addr, port);
// 创建数据提交数据流
httpPostWriter = new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream(), "GBK"));
//填入你的device number 和 sensor number
String httpSubmitPath = "/v1.0/device/deviceNumber/sensor/sensorNumber/datapoints";
// 发送数据头
httpPostWriter.write("POST " + httpSubmitPath + " HTTP/1.1\r\n");
httpPostWriter
.write("User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:9.0.1) Gecko/20100101 Firefox/9.0.1\r\n");
httpPostWriter.write("Host: " + hostname + "\r\n");
httpPostWriter.write("Accept: */*\r\n");
httpPostWriter.write("U-ApiKey: " + ApiKey + "\r\n");
httpPostWriter.write("Content-Length: " + formDataItems.length()
+ "\r\n");
httpPostWriter
.write("Content-Type: application/x-www-form-urlencoded\r\n");
httpPostWriter.write("\r\n"); // 以空行作为分割
// 发送数据
httpPostWriter.write(formDataItems.toString());
httpPostWriter.flush();
// 创建web服务器响应的数据流
httpResponse = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "GBK"));
String lineStr = "";
while ((lineStr = httpResponse.readLine()) != null) {
System.out.println(lineStr);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (httpPostWriter != null) {
httpPostWriter.close();
}
if (httpResponse != null) {
httpResponse.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void readToBuffer(StringBuffer buffer, String filePath)
throws IOException {
InputStream is = new FileInputStream(filePath);
String line; // 用来保存每行读取的内容
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
line = reader.readLine(); // 读取第一行
while (line != null) { // 如果 line 为空说明读完了
buffer.append(line); // 将读到的内容添加到 buffer 中
buffer.append("\n"); // 添加换行符
line = reader.readLine(); // 读取下一行
}
reader.close();
is.close();
}
}
最后来张yeelink手机客户端的温度计截图