Safety confirmation program for the elderly persons. (LPC1768)

Dependencies:   EthernetInterface HTTPClient mbed-rtos mbed

Committer:
mkttanabe
Date:
Fri Feb 13 11:36:45 2015 +0000
Revision:
0:928a824c31d7
first commit.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mkttanabe 0:928a824c31d7 1 /*
mkttanabe 0:928a824c31d7 2 * Copyright (C) 2015 KLab Inc.
mkttanabe 0:928a824c31d7 3 *
mkttanabe 0:928a824c31d7 4 * Licensed under the Apache License, Version 2.0 (the "License");
mkttanabe 0:928a824c31d7 5 * you may not use this file except in compliance with the License.
mkttanabe 0:928a824c31d7 6 * You may obtain a copy of the License at
mkttanabe 0:928a824c31d7 7 *
mkttanabe 0:928a824c31d7 8 * http://www.apache.org/licenses/LICENSE-2.0
mkttanabe 0:928a824c31d7 9 *
mkttanabe 0:928a824c31d7 10 * Unless required by applicable law or agreed to in writing, software
mkttanabe 0:928a824c31d7 11 * distributed under the License is distributed on an "AS IS" BASIS,
mkttanabe 0:928a824c31d7 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mkttanabe 0:928a824c31d7 13 * See the License for the specific language governing permissions and
mkttanabe 0:928a824c31d7 14 * limitations under the License.
mkttanabe 0:928a824c31d7 15 */
mkttanabe 0:928a824c31d7 16
mkttanabe 0:928a824c31d7 17 #include "mbed.h"
mkttanabe 0:928a824c31d7 18 #include "EthernetInterface.h"
mkttanabe 0:928a824c31d7 19 #include "HTTPClient.h"
mkttanabe 0:928a824c31d7 20
mkttanabe 0:928a824c31d7 21 #define DEVELOP
mkttanabe 0:928a824c31d7 22 #ifdef DEVELOP
mkttanabe 0:928a824c31d7 23 #define dbg(...) printf(__VA_ARGS__)
mkttanabe 0:928a824c31d7 24 #else
mkttanabe 0:928a824c31d7 25 #define dbg(...)
mkttanabe 0:928a824c31d7 26 #endif
mkttanabe 0:928a824c31d7 27
mkttanabe 0:928a824c31d7 28 // Parse.com に設置ずみのの対向アプリの ID と RESTAPIKEY
mkttanabe 0:928a824c31d7 29 #define PARSE_COM_APPID "** YOUR PARSE APP ID **"
mkttanabe 0:928a824c31d7 30 #define PARSE_COM_RESTAPIKEY "** YOUR PARSE APP REST API KEY **"
mkttanabe 0:928a824c31d7 31
mkttanabe 0:928a824c31d7 32 #define REQUEST_HEADER_FOR_PARSE_COM \
mkttanabe 0:928a824c31d7 33 "X-Parse-Application-Id: " PARSE_COM_APPID "\r\n" \
mkttanabe 0:928a824c31d7 34 "X-Parse-REST-API-Key: " PARSE_COM_RESTAPIKEY "\r\n" \
mkttanabe 0:928a824c31d7 35 "Content-Type: " "application/json" "\r\n"
mkttanabe 0:928a824c31d7 36
mkttanabe 0:928a824c31d7 37 #define URL_POSTDATA "https://api.parse.com/1/functions/detected"
mkttanabe 0:928a824c31d7 38 #define URL_SENDMAIL "https://api.parse.com/1/functions/sendmail"
mkttanabe 0:928a824c31d7 39
mkttanabe 0:928a824c31d7 40 // for LM61BIZ
mkttanabe 0:928a824c31d7 41 #define GAP_DIGREE_ZERO (600.0/3300.0)
mkttanabe 0:928a824c31d7 42 #define DIGREE_PER_VALUE (10.0/3300.0)
mkttanabe 0:928a824c31d7 43
mkttanabe 0:928a824c31d7 44 #define SW_ON 0
mkttanabe 0:928a824c31d7 45 #define LED_MAX 5
mkttanabe 0:928a824c31d7 46 #define HTTPS_REQUEST_INTERVAL 1800 // 30分
mkttanabe 0:928a824c31d7 47
mkttanabe 0:928a824c31d7 48 EthernetInterface eth;
mkttanabe 0:928a824c31d7 49 HTTPClient http;
mkttanabe 0:928a824c31d7 50 LocalFileSystem local("local");
mkttanabe 0:928a824c31d7 51
mkttanabe 0:928a824c31d7 52 #define DEVICEID_FILENAME "/local/id.txt"
mkttanabe 0:928a824c31d7 53 #define DEVICEID_MAXLENGTH 16
mkttanabe 0:928a824c31d7 54
mkttanabe 0:928a824c31d7 55 DigitalOut LEDS[LED_MAX] = {p21, LED1, LED2, LED3, LED4};
mkttanabe 0:928a824c31d7 56 DigitalOut buzzer(p5); // 電子ブザー
mkttanabe 0:928a824c31d7 57 AnalogIn sensorTEMP(p15); // 温度センサ
mkttanabe 0:928a824c31d7 58 DigitalIn sensorPIR(p20); // 赤外線センサ
mkttanabe 0:928a824c31d7 59 DigitalIn switchPUSH(p24); // 外付けプッシュボタン
mkttanabe 0:928a824c31d7 60 Ticker timer;
mkttanabe 0:928a824c31d7 61 char deviceId[DEVICEID_MAXLENGTH];
mkttanabe 0:928a824c31d7 62
mkttanabe 0:928a824c31d7 63 // すべてのLEDをON/OFF
mkttanabe 0:928a824c31d7 64 void LedsShow(int OnOrOff)
mkttanabe 0:928a824c31d7 65 {
mkttanabe 0:928a824c31d7 66 for (int i = 0; i < LED_MAX; i++) {
mkttanabe 0:928a824c31d7 67 LEDS[i] = OnOrOff;
mkttanabe 0:928a824c31d7 68 }
mkttanabe 0:928a824c31d7 69 }
mkttanabe 0:928a824c31d7 70
mkttanabe 0:928a824c31d7 71 // すべてのLEDを順次点灯
mkttanabe 0:928a824c31d7 72 void LedsRotate(float interval)
mkttanabe 0:928a824c31d7 73 {
mkttanabe 0:928a824c31d7 74 LedsShow(0);
mkttanabe 0:928a824c31d7 75 for (int i = 0; i < LED_MAX; i++) {
mkttanabe 0:928a824c31d7 76 LEDS[i] = 1;
mkttanabe 0:928a824c31d7 77 wait(interval);
mkttanabe 0:928a824c31d7 78 }
mkttanabe 0:928a824c31d7 79 LedsShow(0);
mkttanabe 0:928a824c31d7 80 }
mkttanabe 0:928a824c31d7 81
mkttanabe 0:928a824c31d7 82 // time() 用にダミー日時をセット
mkttanabe 0:928a824c31d7 83 void setTime()
mkttanabe 0:928a824c31d7 84 {
mkttanabe 0:928a824c31d7 85 struct tm t;
mkttanabe 0:928a824c31d7 86 t.tm_sec = 1;
mkttanabe 0:928a824c31d7 87 t.tm_min = 1;
mkttanabe 0:928a824c31d7 88 t.tm_hour = 1;
mkttanabe 0:928a824c31d7 89 t.tm_mday = 1;
mkttanabe 0:928a824c31d7 90 t.tm_mon = 1;
mkttanabe 0:928a824c31d7 91 t.tm_year = 100;
mkttanabe 0:928a824c31d7 92 time_t seconds = mktime(&t);
mkttanabe 0:928a824c31d7 93 set_time(seconds);
mkttanabe 0:928a824c31d7 94 }
mkttanabe 0:928a824c31d7 95
mkttanabe 0:928a824c31d7 96 void handlerLedsRotate()
mkttanabe 0:928a824c31d7 97 {
mkttanabe 0:928a824c31d7 98 LedsRotate(0.1);
mkttanabe 0:928a824c31d7 99 }
mkttanabe 0:928a824c31d7 100
mkttanabe 0:928a824c31d7 101 void handlerLed1Blink()
mkttanabe 0:928a824c31d7 102 {
mkttanabe 0:928a824c31d7 103 LEDS[1] = !LEDS[1];
mkttanabe 0:928a824c31d7 104 }
mkttanabe 0:928a824c31d7 105
mkttanabe 0:928a824c31d7 106 // 初期化
mkttanabe 0:928a824c31d7 107 int init()
mkttanabe 0:928a824c31d7 108 {
mkttanabe 0:928a824c31d7 109 int sts;
mkttanabe 0:928a824c31d7 110
mkttanabe 0:928a824c31d7 111 // 押しボタン接続ポートの DigitalIn をプルアップ
mkttanabe 0:928a824c31d7 112 switchPUSH.mode(PullUp);
mkttanabe 0:928a824c31d7 113
mkttanabe 0:928a824c31d7 114 setTime();
mkttanabe 0:928a824c31d7 115 timer.attach(&handlerLedsRotate, 1);
mkttanabe 0:928a824c31d7 116
mkttanabe 0:928a824c31d7 117 // イーサネットの初期化
mkttanabe 0:928a824c31d7 118 dbg("- start eth.init\r\n" );
mkttanabe 0:928a824c31d7 119 sts = eth.init(); //Use DHCP
mkttanabe 0:928a824c31d7 120 if (sts != 0) {
mkttanabe 0:928a824c31d7 121 dbg("- ech.init error!\r\n" );
mkttanabe 0:928a824c31d7 122 timer.detach();
mkttanabe 0:928a824c31d7 123 return -1;
mkttanabe 0:928a824c31d7 124 }
mkttanabe 0:928a824c31d7 125
mkttanabe 0:928a824c31d7 126 dbg("- start eth.connect\r\n" );
mkttanabe 0:928a824c31d7 127 sts = eth.connect();
mkttanabe 0:928a824c31d7 128 if (sts != 0) {
mkttanabe 0:928a824c31d7 129 dbg("- eth.connect error!\r\n" );
mkttanabe 0:928a824c31d7 130 timer.detach();
mkttanabe 0:928a824c31d7 131 return -2;
mkttanabe 0:928a824c31d7 132 }
mkttanabe 0:928a824c31d7 133 dbg("- my IP Address = %s\r\n", eth.getIPAddress());
mkttanabe 0:928a824c31d7 134
mkttanabe 0:928a824c31d7 135 // 自デバイス名を id.txt から読み込む
mkttanabe 0:928a824c31d7 136 strncpy(deviceId, eth.getIPAddress(), 15);
mkttanabe 0:928a824c31d7 137 deviceId[15] = '\0';
mkttanabe 0:928a824c31d7 138 FILE *fp = fopen(DEVICEID_FILENAME, "r");
mkttanabe 0:928a824c31d7 139 if (!fp) {
mkttanabe 0:928a824c31d7 140 // id.txt が存在しなければ新規作成し IP アドレスを書き込む
mkttanabe 0:928a824c31d7 141 fp = fopen(DEVICEID_FILENAME, "w");
mkttanabe 0:928a824c31d7 142 if (fp) {
mkttanabe 0:928a824c31d7 143 fprintf(fp, "%s", deviceId);
mkttanabe 0:928a824c31d7 144 }
mkttanabe 0:928a824c31d7 145 } else {
mkttanabe 0:928a824c31d7 146 fgets(deviceId, DEVICEID_MAXLENGTH, fp);
mkttanabe 0:928a824c31d7 147 for (int i = 0; i < DEVICEID_MAXLENGTH; i++) {
mkttanabe 0:928a824c31d7 148 if (deviceId[i] == '\r' || deviceId[i] == '\n') {
mkttanabe 0:928a824c31d7 149 deviceId[i] = '\0';
mkttanabe 0:928a824c31d7 150 break;
mkttanabe 0:928a824c31d7 151 }
mkttanabe 0:928a824c31d7 152 }
mkttanabe 0:928a824c31d7 153 }
mkttanabe 0:928a824c31d7 154 if (fp) {
mkttanabe 0:928a824c31d7 155 fclose(fp);
mkttanabe 0:928a824c31d7 156 }
mkttanabe 0:928a824c31d7 157 dbg("- my DeviceId = %s\r\n", deviceId);
mkttanabe 0:928a824c31d7 158
mkttanabe 0:928a824c31d7 159 // センサ安定化待ち
mkttanabe 0:928a824c31d7 160 wait(4.0);
mkttanabe 0:928a824c31d7 161 timer.detach();
mkttanabe 0:928a824c31d7 162 return 0;
mkttanabe 0:928a824c31d7 163 }
mkttanabe 0:928a824c31d7 164
mkttanabe 0:928a824c31d7 165 // Parse.com への POST
mkttanabe 0:928a824c31d7 166 int postToParseCom(const char *ApiUrl, char *postData)
mkttanabe 0:928a824c31d7 167 {
mkttanabe 0:928a824c31d7 168 int sts;
mkttanabe 0:928a824c31d7 169 char buf[256];
mkttanabe 0:928a824c31d7 170 HTTPText dataToPost(postData);
mkttanabe 0:928a824c31d7 171 HTTPText resData(buf, sizeof(buf));
mkttanabe 0:928a824c31d7 172 http.setHeader(REQUEST_HEADER_FOR_PARSE_COM);
mkttanabe 0:928a824c31d7 173 dbg("- start HTTPS request\r\n");
mkttanabe 0:928a824c31d7 174 sts = http.post(ApiUrl, dataToPost, &resData, HTTP_CLIENT_DEFAULT_TIMEOUT);
mkttanabe 0:928a824c31d7 175 if (sts == HTTP_OK) {
mkttanabe 0:928a824c31d7 176 dbg("- received HTTPS response\r\n");
mkttanabe 0:928a824c31d7 177 dbg("- head of data [%s]\r\n", buf);
mkttanabe 0:928a824c31d7 178 dbg("- done\r\n\r\n");
mkttanabe 0:928a824c31d7 179 } else {
mkttanabe 0:928a824c31d7 180 dbg("- HTTPS request error=%d, status=%d\r\n", sts, http.getHTTPResponseCode());
mkttanabe 0:928a824c31d7 181 dbg("- head of data [%s]\r\n", buf);
mkttanabe 0:928a824c31d7 182 return sts;
mkttanabe 0:928a824c31d7 183 }
mkttanabe 0:928a824c31d7 184 return HTTP_OK;
mkttanabe 0:928a824c31d7 185 }
mkttanabe 0:928a824c31d7 186
mkttanabe 0:928a824c31d7 187 // エントリーポイント
mkttanabe 0:928a824c31d7 188 int main()
mkttanabe 0:928a824c31d7 189 {
mkttanabe 0:928a824c31d7 190 time_t lastRequestTime = 0;
mkttanabe 0:928a824c31d7 191 char reqData[128];
mkttanabe 0:928a824c31d7 192 int sts = init();
mkttanabe 0:928a824c31d7 193 if (sts != 0) {
mkttanabe 0:928a824c31d7 194 // 初期化エラー時は LED 全点灯で終了
mkttanabe 0:928a824c31d7 195 LedsShow(1);
mkttanabe 0:928a824c31d7 196 return -1;
mkttanabe 0:928a824c31d7 197 }
mkttanabe 0:928a824c31d7 198 while(1) {
mkttanabe 0:928a824c31d7 199 int buttonPressedMsecs = 0;
mkttanabe 0:928a824c31d7 200 // 緊急ボタン押下状態
mkttanabe 0:928a824c31d7 201 while (switchPUSH == SW_ON) {
mkttanabe 0:928a824c31d7 202 LEDS[2] = 1;
mkttanabe 0:928a824c31d7 203 // 長押し2秒でメール送信
mkttanabe 0:928a824c31d7 204 if (buttonPressedMsecs >= 2000) {
mkttanabe 0:928a824c31d7 205 LEDS[1] = 1;
mkttanabe 0:928a824c31d7 206 buzzer = 1; // ブザーを鳴らす
mkttanabe 0:928a824c31d7 207 dbg("- long-pressed\r\n");
mkttanabe 0:928a824c31d7 208 // デバイス名
mkttanabe 0:928a824c31d7 209 sprintf(reqData, "{\"devid\" : \"%s\"}", deviceId);
mkttanabe 0:928a824c31d7 210 sts = postToParseCom(URL_SENDMAIL, reqData);
mkttanabe 0:928a824c31d7 211 if (sts != HTTP_OK) {
mkttanabe 0:928a824c31d7 212 // あとで考える
mkttanabe 0:928a824c31d7 213 }
mkttanabe 0:928a824c31d7 214 break;
mkttanabe 0:928a824c31d7 215 }
mkttanabe 0:928a824c31d7 216 wait(0.2);
mkttanabe 0:928a824c31d7 217 buttonPressedMsecs += 200;
mkttanabe 0:928a824c31d7 218 }
mkttanabe 0:928a824c31d7 219 LEDS[1] = LEDS[2] = 0;
mkttanabe 0:928a824c31d7 220 buzzer = 0;
mkttanabe 0:928a824c31d7 221
mkttanabe 0:928a824c31d7 222 // 赤外線センサ反応状態
mkttanabe 0:928a824c31d7 223 int detected = sensorPIR;
mkttanabe 0:928a824c31d7 224 if (!detected) {
mkttanabe 0:928a824c31d7 225 LEDS[0] = 0;
mkttanabe 0:928a824c31d7 226 } else {
mkttanabe 0:928a824c31d7 227 if (LEDS[0] == 0) {
mkttanabe 0:928a824c31d7 228 LEDS[0] = 1;
mkttanabe 0:928a824c31d7 229 dbg("- detected!\r\n");
mkttanabe 0:928a824c31d7 230 // 温度センサの出力電圧値を摂氏値に
mkttanabe 0:928a824c31d7 231 float valueTemp = (sensorTEMP - GAP_DIGREE_ZERO) / DIGREE_PER_VALUE;
mkttanabe 0:928a824c31d7 232 dbg("- temperature = %2.1f C\r\n", valueTemp);
mkttanabe 0:928a824c31d7 233
mkttanabe 0:928a824c31d7 234 // 前回の送信から所定時間が経過していれば再び送信
mkttanabe 0:928a824c31d7 235 int elapsed = time(NULL) - lastRequestTime;
mkttanabe 0:928a824c31d7 236 if (elapsed > HTTPS_REQUEST_INTERVAL) {
mkttanabe 0:928a824c31d7 237 // 温度情報・デバイス名・ローカル IP アドレス
mkttanabe 0:928a824c31d7 238 sprintf(reqData, "{\"temp\" : \"%2.1f\", \"devid\" : \"%s\", \"ip\" : \"%s\"}",
mkttanabe 0:928a824c31d7 239 valueTemp, deviceId, eth.getIPAddress());
mkttanabe 0:928a824c31d7 240 timer.detach();
mkttanabe 0:928a824c31d7 241 LEDS[1] = 1;
mkttanabe 0:928a824c31d7 242
mkttanabe 0:928a824c31d7 243 sts = postToParseCom(URL_POSTDATA, reqData);
mkttanabe 0:928a824c31d7 244 if (sts == HTTP_OK) {
mkttanabe 0:928a824c31d7 245 lastRequestTime = time(NULL);
mkttanabe 0:928a824c31d7 246 LEDS[1] = 0;
mkttanabe 0:928a824c31d7 247 } else {
mkttanabe 0:928a824c31d7 248 // エラー時は LED1 を点滅状態に
mkttanabe 0:928a824c31d7 249 timer.attach(&handlerLed1Blink, 1.0);
mkttanabe 0:928a824c31d7 250 }
mkttanabe 0:928a824c31d7 251 } else {
mkttanabe 0:928a824c31d7 252 dbg("- HTTPS request is pending.. [%d/%d sec]\r\n", elapsed, HTTPS_REQUEST_INTERVAL);
mkttanabe 0:928a824c31d7 253 }
mkttanabe 0:928a824c31d7 254 }
mkttanabe 0:928a824c31d7 255 }
mkttanabe 0:928a824c31d7 256 wait(0.2);
mkttanabe 0:928a824c31d7 257 }
mkttanabe 0:928a824c31d7 258 eth.disconnect(); // unreachable
mkttanabe 0:928a824c31d7 259 }
mkttanabe 0:928a824c31d7 260