Safety confirmation program for the elderly persons. (LPC1768)

Dependencies:   EthernetInterface HTTPClient mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 * Copyright (C) 2015 KLab Inc.
00003 *
00004 * Licensed under the Apache License, Version 2.0 (the "License");
00005 * you may not use this file except in compliance with the License.
00006 * You may obtain a copy of the License at
00007 *
00008 * http://www.apache.org/licenses/LICENSE-2.0
00009 *
00010 * Unless required by applicable law or agreed to in writing, software
00011 * distributed under the License is distributed on an "AS IS" BASIS,
00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 * See the License for the specific language governing permissions and
00014 * limitations under the License.
00015 */
00016 
00017 #include "mbed.h"
00018 #include "EthernetInterface.h"
00019 #include "HTTPClient.h"
00020 
00021 #define DEVELOP
00022 #ifdef DEVELOP
00023 #define dbg(...) printf(__VA_ARGS__)
00024 #else
00025 #define dbg(...)
00026 #endif
00027 
00028 // Parse.com に設置ずみのの対向アプリの ID と RESTAPIKEY
00029 #define PARSE_COM_APPID       "** YOUR PARSE APP ID **"
00030 #define PARSE_COM_RESTAPIKEY  "** YOUR PARSE APP REST API KEY **"
00031 
00032 #define REQUEST_HEADER_FOR_PARSE_COM \
00033     "X-Parse-Application-Id: " PARSE_COM_APPID      "\r\n" \
00034     "X-Parse-REST-API-Key: "   PARSE_COM_RESTAPIKEY "\r\n" \
00035     "Content-Type: "           "application/json"   "\r\n"
00036 
00037 #define URL_POSTDATA  "https://api.parse.com/1/functions/detected"
00038 #define URL_SENDMAIL  "https://api.parse.com/1/functions/sendmail"
00039 
00040 // for LM61BIZ
00041 #define GAP_DIGREE_ZERO  (600.0/3300.0)
00042 #define DIGREE_PER_VALUE (10.0/3300.0)
00043 
00044 #define SW_ON 0
00045 #define LED_MAX 5
00046 #define HTTPS_REQUEST_INTERVAL 1800 // 30分
00047 
00048 EthernetInterface eth;
00049 HTTPClient http;
00050 LocalFileSystem local("local");
00051 
00052 #define DEVICEID_FILENAME  "/local/id.txt"
00053 #define DEVICEID_MAXLENGTH 16
00054 
00055 DigitalOut LEDS[LED_MAX] = {p21, LED1, LED2, LED3, LED4};
00056 DigitalOut buzzer(p5);     // 電子ブザー
00057 AnalogIn sensorTEMP(p15);  // 温度センサ
00058 DigitalIn sensorPIR(p20);  // 赤外線センサ
00059 DigitalIn switchPUSH(p24); // 外付けプッシュボタン
00060 Ticker timer;
00061 char deviceId[DEVICEID_MAXLENGTH];
00062 
00063 // すべてのLEDをON/OFF
00064 void LedsShow(int OnOrOff)
00065 {
00066     for (int i = 0; i < LED_MAX; i++) {
00067         LEDS[i] = OnOrOff;
00068     }
00069 }
00070 
00071 // すべてのLEDを順次点灯
00072 void LedsRotate(float interval)
00073 {
00074     LedsShow(0);
00075     for (int i = 0; i < LED_MAX; i++) {
00076         LEDS[i] = 1;
00077         wait(interval);
00078     }
00079     LedsShow(0);
00080 }
00081 
00082 // time() 用にダミー日時をセット
00083 void setTime()
00084 {
00085     struct tm t;
00086     t.tm_sec  = 1;
00087     t.tm_min  = 1;
00088     t.tm_hour = 1;
00089     t.tm_mday = 1;
00090     t.tm_mon  = 1;
00091     t.tm_year = 100;
00092     time_t seconds = mktime(&t);
00093     set_time(seconds);
00094 }
00095 
00096 void handlerLedsRotate()
00097 {
00098     LedsRotate(0.1);
00099 }
00100 
00101 void handlerLed1Blink()
00102 {
00103     LEDS[1] = !LEDS[1];
00104 }
00105 
00106 // 初期化
00107 int init()
00108 {
00109     int sts;
00110 
00111     // 押しボタン接続ポートの DigitalIn をプルアップ
00112     switchPUSH.mode(PullUp);
00113 
00114     setTime();
00115     timer.attach(&handlerLedsRotate, 1);
00116 
00117     // イーサネットの初期化
00118     dbg("- start eth.init\r\n" );
00119     sts = eth.init(); //Use DHCP
00120     if (sts != 0) {
00121         dbg("- ech.init error!\r\n" );
00122         timer.detach();
00123         return -1;
00124     }
00125 
00126     dbg("- start eth.connect\r\n" );
00127     sts = eth.connect();
00128     if (sts != 0) {
00129         dbg("- eth.connect error!\r\n" );
00130         timer.detach();
00131         return -2;
00132     }
00133     dbg("- my IP Address = %s\r\n", eth.getIPAddress());
00134 
00135     // 自デバイス名を id.txt から読み込む
00136     strncpy(deviceId, eth.getIPAddress(), 15);
00137     deviceId[15] = '\0';
00138     FILE *fp = fopen(DEVICEID_FILENAME, "r");
00139     if (!fp) {
00140         // id.txt が存在しなければ新規作成し IP アドレスを書き込む
00141         fp = fopen(DEVICEID_FILENAME, "w");
00142         if (fp) {
00143             fprintf(fp, "%s", deviceId);
00144         }
00145     } else {
00146         fgets(deviceId, DEVICEID_MAXLENGTH, fp);
00147         for (int i = 0; i < DEVICEID_MAXLENGTH; i++) {
00148             if (deviceId[i] == '\r' || deviceId[i] == '\n') {
00149                 deviceId[i] = '\0';
00150                 break;
00151             }
00152         }
00153     }
00154     if (fp) {
00155         fclose(fp);
00156     }
00157     dbg("- my DeviceId = %s\r\n", deviceId);
00158 
00159     // センサ安定化待ち
00160     wait(4.0);
00161     timer.detach();
00162     return 0;
00163 }
00164 
00165 // Parse.com への POST
00166 int postToParseCom(const char *ApiUrl, char *postData)
00167 {
00168     int sts;
00169     char buf[256];
00170     HTTPText dataToPost(postData);
00171     HTTPText resData(buf, sizeof(buf));
00172     http.setHeader(REQUEST_HEADER_FOR_PARSE_COM);
00173     dbg("- start HTTPS request\r\n");
00174     sts = http.post(ApiUrl, dataToPost, &resData, HTTP_CLIENT_DEFAULT_TIMEOUT);
00175     if (sts == HTTP_OK) {
00176         dbg("- received HTTPS response\r\n");
00177         dbg("- head of data [%s]\r\n", buf);
00178         dbg("- done\r\n\r\n");
00179     } else {
00180         dbg("- HTTPS request error=%d, status=%d\r\n", sts, http.getHTTPResponseCode());
00181         dbg("- head of data [%s]\r\n", buf);
00182         return sts;
00183     }
00184     return HTTP_OK;
00185 }
00186 
00187 // エントリーポイント
00188 int main()
00189 {
00190     time_t lastRequestTime = 0;
00191     char reqData[128];
00192     int sts = init();
00193     if (sts != 0) {
00194         // 初期化エラー時は LED 全点灯で終了
00195         LedsShow(1);
00196         return -1;
00197     }
00198     while(1) {
00199         int buttonPressedMsecs = 0;
00200         // 緊急ボタン押下状態
00201         while (switchPUSH == SW_ON) {
00202             LEDS[2] = 1;
00203             // 長押し2秒でメール送信
00204             if (buttonPressedMsecs >= 2000) {
00205                 LEDS[1] = 1;
00206                 buzzer = 1; // ブザーを鳴らす
00207                 dbg("- long-pressed\r\n");
00208                 // デバイス名
00209                 sprintf(reqData, "{\"devid\" : \"%s\"}", deviceId);
00210                 sts = postToParseCom(URL_SENDMAIL, reqData);
00211                 if (sts != HTTP_OK) {
00212                     // あとで考える
00213                 }
00214                 break;
00215             }
00216             wait(0.2);
00217             buttonPressedMsecs += 200;
00218         }
00219         LEDS[1] = LEDS[2] = 0;
00220         buzzer = 0;
00221 
00222         // 赤外線センサ反応状態
00223         int detected = sensorPIR;
00224         if (!detected) {
00225             LEDS[0] = 0;
00226         } else {
00227             if (LEDS[0] == 0) {
00228                 LEDS[0] = 1;
00229                 dbg("- detected!\r\n");
00230                 // 温度センサの出力電圧値を摂氏値に
00231                 float valueTemp = (sensorTEMP - GAP_DIGREE_ZERO) / DIGREE_PER_VALUE;
00232                 dbg("- temperature = %2.1f C\r\n", valueTemp);
00233 
00234                 // 前回の送信から所定時間が経過していれば再び送信
00235                 int elapsed = time(NULL) - lastRequestTime;
00236                 if (elapsed > HTTPS_REQUEST_INTERVAL) {
00237                     // 温度情報・デバイス名・ローカル IP アドレス
00238                     sprintf(reqData, "{\"temp\" : \"%2.1f\", \"devid\" : \"%s\", \"ip\" : \"%s\"}",
00239                             valueTemp, deviceId, eth.getIPAddress());
00240                     timer.detach();
00241                     LEDS[1] = 1;
00242 
00243                     sts = postToParseCom(URL_POSTDATA, reqData);
00244                     if (sts == HTTP_OK) {
00245                         lastRequestTime = time(NULL);
00246                         LEDS[1] = 0;
00247                     } else {
00248                         // エラー時は LED1 を点滅状態に
00249                         timer.attach(&handlerLed1Blink, 1.0);
00250                     }
00251                 } else {
00252                     dbg("- HTTPS request is pending.. [%d/%d sec]\r\n", elapsed, HTTPS_REQUEST_INTERVAL);
00253                 }
00254             }
00255         }
00256         wait(0.2);
00257     }
00258     eth.disconnect(); // unreachable
00259 }
00260