空間活動偵測 -1 arduino
我想做一個能夠及時通知家中發生異狀的系統
研究結果
用Arduino接收感測器資料,定時傳送資料人體紅外線資料,及即時傳送開關門資料,再用google apps script 做資料交換與分析,將arduino傳送過來的資料存入google試算表,由試算表做圖表繪製,再由apps script 定時推播圖表訊息,以及分析內容推播異常或警告訊息。研究過程
一開始想用自己架設的伺服器存資料,用raspberry pi安裝apache + mysql + phpMyAdmin,但因為網路IP位置是浮動的關係,資料無法從外部傳回進伺服器,只能做本地端的資料傳輸,如果單使用arduino上傳資料到google試算表,又因為arduino uno3無網路連線加密的問題無法傳輸資料。之後找到國外的伺服器能做資料交換,加上用google的試算表做簡單的資料庫儲存,所以最後是用arduino接收感測器資訊,傳輸到資料交換伺服器再到google,由apps script 接收資料及填入試算表,完成了資料接收的問題。
硬體:使用arduino uno3 + 乙太網路擴充板 + 自己做的電路板
連接的感測器:
- 人體紅外線感測器
- 門窗的磁簧開關


跟pushingbox連線的ID分別有這些
- #include <Dhcp.h>
- #include <Dns.h>
- #include <Ethernet.h>
- #include <EthernetClient.h>
- #include <EthernetServer.h>
- #include <EthernetUdp.h>
- //#include "net_function.cpp"
- #include "set_ID.h"
- #define PushingBox
- unsigned char hour = 0, minute = 0;
- boolean push_man_check;
- String URL_data;
- #define ReedS0_pin 2
- #define ReedS1_pin 3
- #define ReedS2_pin 4
- #define ReedS3_pin 5
- #define ReedS4_pin 6
- #define ReedS5_pin 7
- #define man0_pin 8
- #define man1_pin 9
- #define man2_pin A5
- #define man3_pin A4
- #define man4_pin A3
- #define man5_pin A2
- #define ReedS_number 5 //6個(0~5)
- #define man_number 5 //6個(0~1)
- #if defined( PushingBox )
- //byte mac[] = { 0x00, 0xAB, 0xBC, 0xCD, 0xDE, 0x00 };
- char server[] = "api.pushingbox.com";
- String strGet = "GET /pushingbox?devid=";
- String strHttp = " HTTP/1.1";
- String strHost = "Host: api.pushingbox.com"; //OK
- int serverPort = 80;
- char ReedS[] = { 0, 0, 0, 0, 0, 0};//ReedS = Reed Switch 磁簧開關
- char oReedS[] = { 0, 0, 0, 0, 0, 0};//oReedS 過去的狀態, ReedS 現在的狀態
- int man[] = { 0, 0, 0, 0, 0, 0};
- #endif
- EthernetClient client;
- boolean conn; // Connected
- //DeviceAddress insideThermometer;
- unsigned long startime = 0;
- //------------------------------------------------------------------------------------------
- //串接URL
- void getdata(String *data, String ID, String kind) {
- *data = strGet;
- *data += ID;
- *data += "&board=";
- *data += board;
- if (kind == gettime_ID) {
- *data += "&information=";
- *data += "時間";
- }
- if (kind == push_RS_ID || kind == push_human_ID || kind == pushnotif_ID) {
- *data += "&time=";
- *data += (int)hour;
- *data += ':';
- if(minute<=9){
- *data += "0";
- }
- *data += (int)minute;
- }
- if (kind == push_RS_ID) {
- *data += "&RS0=";
- *data += (int)ReedS[0];
- *data += "&RS1=";
- *data += (int)ReedS[1];
- *data += "&RS2=";
- *data += (int)ReedS[2];
- *data += "&RS3=";
- *data += (int)ReedS[3];
- *data += "&RS4=";
- *data += (int)ReedS[4];
- *data += "&RS5=";
- *data += (int)ReedS[5];
- }
- if (kind == push_human_ID) {
- *data += "&man0=";
- *data += man[0];
- *data += "&man1=";
- *data += man[1];
- *data += "&man2=";
- *data += man[2];
- *data += "&man3=";
- *data += man[3];
- *data += "&man4=";
- *data += man[4];
- *data += "&man5=";
- *data += man[5];
- }
- if (kind == pushnotif_ID) {
- *data += "&title=";
- *data += "活動情況";
- *data += "&message=";
- if (ReedS[0] == 1) {
- *data += "門_開啟";
- }
- else {
- *data += "門_關閉";
- }
- }
- *data += strHttp;
- Serial.print("URL: ");
- Serial.println(*data);
- }
- //push URL data to 網路
- bool connect_pushdata(String *push_URL, String *host) {
- Serial.println("connect server --->");
- if (client.connect(server, serverPort)) {
- Serial.println("Make a HTTP request ... ");
- conn = true;
- client.println(*push_URL);
- client.println(*host);
- client.println( "Connection: close" );
- client.println();
- return true;
- }
- else {
- Serial.println("Can not connect server ---X---");
- return false;
- }
- }
- //網路回復
- void netword_request() {
- int ln = 0;
- int count = 0;
- char date_str[40]=" ";
- while (conn) {
- if (client.available()) {
- char c = client.read(); // Save http header to c
- Serial.print(c); // Print http header to serial monitor
- if (c == '\n') {
- ln++;
- // Serial.print("ln count: ");
- // Serial.println(ln);
- }
- if (ln == 2) {
- date_str[count++] = c;
- }
- }
- if (!client.connected()) {
- Serial.println("disconnecting...");
- client.stop();
- URL_data = "";
- conn = false;
- ln = 0;
- count = 0;
- Serial.print("seriver date: ");
- for (char i = 1; i < 40; i++) {
- Serial.print(date_str[i]);
- }
- Serial.print("\n");
- if(((date_str[24] - '0') * 10 + (date_str[25] - '0')) >= 0 && ((date_str[24] - '0') * 10 + (date_str[25] - '0')) <= 23 &&
- ((date_str[27] - '0') * 10 + (date_str[28] - '0')) >= 0 && ((date_str[27] - '0') * 10 + (date_str[28] - '0')) <= 59)
- {
- hour = (date_str[24] - '0') * 10 + (date_str[25] - '0') + 8;
- if (hour >= 24) {
- hour -= 24;
- }
- minute = (date_str[27] - '0') * 10 + (date_str[28] - '0');
- }
- Serial.print("time ");
- Serial.print((int)hour);
- Serial.print(":");
- Serial.println((int)minute);
- }
- }
- }
- //網路設定
- void net_init() {
- char in = "";
- byte mac[] = { 0x00, 0xAB, 0xBC, 0xCD, 0xDE, 0x00 };
- //Init Net
- Serial.print("DHCP: ");
- //Ethernet.begin(mac, ip, mydns);
- if (Ethernet.begin(mac) == 0) {
- Serial.println("FAIL");
- while (Ethernet.begin(mac) == 0){
- if (Serial.available() > 0) {
- in=Serial.read();
- if(in == 's'){
- Serial.println("skip DHCP");
- break;
- }
- }
- }
- Serial.print("DHCP: ");
- }
- if(in != 's'){
- Serial.println("OK");
- Serial.print("Local IP : ");
- Serial.println(Ethernet.localIP());
- }
- }
- void dotime() {
- //add one minute 60000=60*1000ms=1m
- if ((millis() - startime) >= (60000) || (millis() - startime) < 0) {
- startime = millis();
- minute++;
- if (minute >= 60) {
- minute -= 60;
- hour++;
- if (hour >= 24) {
- hour -= 24;
- }
- }
- }
- }
- //需要先跑第一次的程式
- void first_run() {
- getdata(&URL_data, gettime_ID, gettime_ID);
- while(!connect_pushdata(&URL_data, &strHost));
- netword_request();//網路回復
- for (char i = 0; i <= ReedS_number; i++) {
- ReedS[i] = digitalRead(ReedS0_pin + i);
- oReedS[i] = ReedS[i];
- }
- }
- //===========================================================================================
- void setup(void)
- {
- // start serial port
- Serial.begin(9600);
- while (!Serial) {
- ; // wait for serial port to connect. Needed for Leonardo only
- }
- Serial.println(star_information);
- Serial.println("wait DHCP:FAIL input s to skip DHCP");
- Serial.println("test send to input r send Reed Switch, m send human, n send notification");
- pinMode(4, OUTPUT);
- digitalWrite(4,HIGH);
- pinMode(ReedS0_pin, INPUT);
- pinMode(ReedS1_pin, INPUT);
- //pinMode(ReedS2_pin, INPUT);
- pinMode(ReedS3_pin, INPUT);
- pinMode(ReedS4_pin, INPUT);
- pinMode(ReedS5_pin, INPUT);
- pinMode(man0_pin, INPUT);
- pinMode(man1_pin, INPUT);
- net_init();
- //delay(3000);
- /* dht.begin();
- Serial.println("DHTxx OK!");*/
- startime = millis();
- first_run();
- }
- void loop(void)
- {
- dotime();
- //讀ReedS
- for (char i = 0; i <= ReedS_number; i++) {
- ReedS[i] = digitalRead(ReedS0_pin + i);
- }
- //讀man
- //man[0]=digitalRead(man0_pin);
- if (digitalRead(man0_pin) == 1) {
- man[0] += 1;
- }
- if (digitalRead(man1_pin) == 1) {
- man[1] += 1;
- }
- if (digitalRead(man2_pin) == 1) {
- man[2] += 1;
- }
- if (digitalRead(man3_pin) == 1) {
- man[3] += 1;
- }
- if (digitalRead(man4_pin) == 1) {
- man[4] += 1;
- }
- if (digitalRead(man5_pin) == 1) {
- man[5] += 1;
- }
- Serial.print("ReedS: ");
- for (char i = 0; i <= ReedS_number; i++) {
- Serial.print((int)ReedS[i]);
- Serial.print(" ");
- }
- Serial.print("man: ");
- for (char i = 0; i <= man_number; i++) {
- Serial.print(man[i]);
- Serial.print(" ");
- }
- Serial.println();
- //手動push
- if (Serial.available() > 0) {
- char in=Serial.read();
- if(in=='r'){
- getdata(&URL_data, push_RS_ID, push_RS_ID);
- connect_pushdata(&URL_data, &strHost);
- netword_request();//網路回復
- }else if(in=='m'){
- getdata(&URL_data, push_human_ID, push_human_ID);
- connect_pushdata(&URL_data, &strHost);
- netword_request();//網路回復
- }else if(in=='n'){
- getdata(&URL_data, pushnotif_ID, pushnotif_ID);
- connect_pushdata(&URL_data, &strHost);
- netword_request();//網路回復
- }else{
- //in=Serial.read();
- }
- }
- //如果ReedS通知
- if (ReedS[0] != oReedS[0]) {
- getdata(&URL_data, pushnotif_ID, pushnotif_ID);
- if(!connect_pushdata(&URL_data, &strHost)){
- connect_pushdata(&URL_data, &strHost);
- }
- netword_request();//網路回復
- }
- //如果ReedS有變化 push data
- if ((ReedS[0] != oReedS[0]) || (ReedS[1] != oReedS[1]) || (ReedS[2] != oReedS[2]) || (ReedS[3] != oReedS[3]) || (ReedS[4] != oReedS[4]) || (ReedS[5] != oReedS[5])) {
- getdata(&URL_data, push_RS_ID, push_RS_ID);
- connect_pushdata(&URL_data, &strHost);
- netword_request();//網路回復
- for (char i = 0; i <= ReedS_number; i++) {
- oReedS[i] = ReedS[i];
- }
- }
- //每15分鐘push man
- if (minute == 0 || minute == 15 || minute == 30 || minute == 45) {
- if (!push_man_check) {
- getdata(&URL_data, push_human_ID, push_human_ID);
- connect_pushdata(&URL_data, &strHost);
- netword_request();//網路回復
- for (char i = 0; i <= man_number; i++) {
- man[i] = 0;
- }
- push_man_check = true;
- }
- }
- //清除每15分鐘已通知標籤
- if ((minute > 1 && minute < 14) || (minute > 16 && minute < 29) || (minute > 31 && minute < 44) || (minute > 46 && minute < 59)) {
- push_man_check = false;
- }
- //netword_request();//網路回復
- delay(2000);
- }
- #define star_information "test Model"
- #define push_RS_ID "vxxxxxxxxxxxxxxx"
- #define push_human_ID "vyyyyyyyyyyyyyyy"
- #define pushnotif_ID "vzzzzzzzzzzzzzzz"
- #define gettime_ID "vaaaaaaaaaaaaaaa" //m
- //#define gettime_ID "vbbbbbbbbbbbbbbb"
- #define board "1"
留言
張貼留言