点击下方查看效果 Click Here
背景 不满足于在页面上显示单独的温湿度数据,我决定添加光线感应以及——每15分钟添加一次实时数据并更新页面。
资源准备
实现原理 服务端某进程每隔一段时间获取一次本地数据,并将数据添加到index.html
。
具体操作 本地端 首先,修改Arduino的部分代码,这个时候,我们就不需要返回一个html页面了,只需要一串表明物理量的数字即可。另外,顺便加上光敏数据,光敏模块使用3号数字引脚。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <SPI.h> #include <Ethernet.h> #include <dht11.h> #define SENSORPIN 2 #define LIGHTSENSORPIN 3 byte mac[] = { 0xDE , 0xAD , 0xBE , 0xE8 , 0xDE , 0xED }; IPAddress ip (192 , 168 , 1 , 30 ) ; dht11 sensor; EthernetServer server (80 ) ; void setup () { Serial.begin(115200 ); Ethernet.begin(mac, ip); server.begin(); } void loop () { EthernetClient client = server.available(); if (client) { Serial.println("Incoming...\n" ); if (client.connected()) { int count = 0 ; while (!client.available()) { count++; delay(100 ); if (count >= 10 ) { count = 0 ; break ; } } while (client.available()) { char charget = client.read(); Serial.write(charget); } sensor.read(SENSORPIN); client.println((float )sensor.humidity, 2 ); client.println(sensor.temperature); client.println(digitalRead(LIGHTSENSORPIN)); } delay(1 ); if (client.connected()) { client.stop(); Serial.println("client disonnected" ); } } }
frp客户端几乎不用动。
云端 我使用C++和shell,利用curl命令获取数据,然后把数据加到index.html
头部。
比较懒,没注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 #include <iostream> #include <fstream> #include <unistd.h> #include <ctime> #include <string> using namespace std;string nowtime () ;void getdata () ;void work () ;void deploy () ;int main () { while (1 ) { work (); sleep (900 ); } return 0 ; } void getdata () { system ("curl frp.vvzero.com:21321 > newdata.dat" ); } string nowtime () { string value ("" ) ; time_t now = time (0 ); tm *ltm = localtime (&now); value = to_string (ltm->tm_hour) + ':' + to_string (ltm->tm_min); if (value.length ()==4 ) { if (value[1 ] == ':' ) value.insert (0 ,1 ,'0' ); else if (value[2 ] == ':' ) value.insert (3 ,1 ,'0' ); } else if (value.length ()==3 ) { value.insert (0 ,1 ,'0' ); value.insert (3 ,1 ,'0' ); } return value; } void work () { ofstream output; ifstream index, data; getdata (); output.open ("tmp_data.dat" ,ios::out); index.open ("index.html" ,ios::in); data.open ("newdata.dat" ,ios::in); string row; for (int i=0 ;i<10 ;i++) { getline (index, row); output << row << endl; } float humidity=0.0 ; int temperature=0 ; int light=0 ; data >> humidity; data >> temperature; data >> light; output << nowtime () << " " << (int )humidity << " " << temperature << " " << (light == 0 ? "Yes" : "No" ) << endl; int count=0 ; getline (index, row); while (row[0 ]!='<' && count<99 ) { output << row << endl; getline (index, row); count++; } while (row[0 ]!='<' ) getline (index, row); output << row << endl; while (!index.eof ()) { getline (index, row); if (row.length () >= 5 ) output << row << endl; } output.close (); index.close (); data.close (); deploy (); } void deploy () { system ("rm index.html" ); system ("rm newdata.dat" ); system ("mv tmp_data.dat index.html" ); }
这里实现了每隔15分钟获取一次数据。
然后$g++ -o GET get_data.cpp -std=c++11
注意这里使用的是C++11标准,所以需要加上-std=c++11
。
在Nginx的根目录下,先新建一个如下格式的index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 <html > <head > <title > VVIOT</title > </head > <body > Here is Villivateur Von's laboratory!</br > <a href ="https://www.vvzero.com" > Click to enter my blog</a > <pre > Time Humidity(%) Temperature(C) Light_Detected ------------------------------------------------------------ </pre > </body > </html >
然后配置好合适的权限,在该目录下运行$sudo nohup ./GET &
。
大功告成!