IM920地温観測システム CQ 2017ARMセミナー用サンプルプログラム
Dependencies: C027_Support_ForIM920
Fork of C027_SupportTest by
main.cpp
- Committer:
- ntaka206
- Date:
- 2017-07-13
- Revision:
- 36:b89a6e114339
- Parent:
- 35:7838543282c2
File content as of revision 36:b89a6e114339:
#include "mbed.h" #include "rtos.h" //------------------------------------------------------------------------------------ /* 地中温度観測システム親機プログラム C027_SupportTestをベースにしているがmain.cのコードはほとんで入れ替え (c) NT System Design */ #include "MDM.h" #include "DebugPrint.h" #include "RingBuf.h" //------------------------------------------------------------------------------------ // You need to configure these cellular modem / SIM parameters. // These parameters are ignored for LISA-C200 variants and can be left NULL. //------------------------------------------------------------------------------------ //! Set your secret SIM pin here (e.g. "1234"). Check your SIM manual. #define SIMPIN "0000" /*! The APN of your network operator SIM, sometimes it is "internet" check your contract with the network operator. You can also try to look-up your settings in google: https://www.google.de/search?q=APN+list */ #define APN "soracom.io" //! Set the user name for your APN, or NULL if not needed #define USERNAME "sora" //! Set the password for your APN, or NULL if not needed #define PASSWORD "sora" //------------------------------------------------------------------------------------ #define IM920_TX P4_28 #define IM920_RX P4_29 Serial im920(IM920_TX, IM920_RX); #define AD_NUM 3 #define MV_LSB (1500/1024.) #define DEGC_MV (1/10.) #define PV_LSB (2*1.5/1024) #define M2X_SERVER "api-m2x.att.com" #define M2X_DEVICE_ID "964d05b1a6f4a8bb02c2a5aaf6e7e268" #define M2X_API_KEY "602d38e9e8dfcf62e7f87a59c80784ec" #define M2X_CHID_TEMP0 "temp0" DigitalOut led(LED1); // リングバッファサイズ #define RINGBUF_SIZE 60 // 毎分データで1時間ぶん // リングバッファ RingBuf ring(RINGBUF_SIZE); /* IM920から受信したADデータをデコードする sn: IM920 SN *ad: ADデータ配列 LSB ret: 0=OK -1=ERR */ int im920_conv(char *in, int *sn, int *ad) { char *p; char *endptr; int l, h; int i; p = strtok(in, ","); // SN p = strtok(NULL, ","); *sn = strtol(p, &endptr, 16); // SUM p = strtok(NULL, ":"); // printf("%s ", p); // AD0-2 for(i = 0; i < AD_NUM; i++) { p = strtok(NULL, ","); // printf("%s ", p); l = strtol(p, &endptr, 16); p = strtok(NULL, ","); // printf("%s ", p); h = strtol(p, &endptr, 16); ad[i] = l + h*256; } return 0; } /** * M2X HTTP送信 * @param http HTTP送信する文字列 * @param hostname * @return 0=OK -1=ERR */ int cloud_http_socket_send(MDMSerial *mdm, char *http, const char *hostname) { int socket; char data[512]; // receive char *strtokptr; char *ptr; socket = mdm->socketSocket(MDMParser::IPPROTO_TCP); if (socket >= 0) { mdm->socketSetBlocking(socket, 60*1000); // timeout im msec // 指定されたhostにSocket Connect if (!mdm->socketConnect(socket, hostname, 80)) { ERROR("ERROR socket connect\r\n"); ERROR("hostname=%s\r\n", hostname); return -1; } TRACE("socketConnect() OK\r\n"); } else { ERROR("sockeSocket() < 0\r\n"); ERROR("hostname=%s\r\n", hostname); return -1; } int ret = mdm->socketSend(socket, http, strlen(http)); TRACE("socketSend()=%d\r\n", ret); // Recv responce 十分な大きさの変数を渡す必要あり ret = mdm->socketRecv(socket, data, sizeof(data)-1); TRACE("socketRecv()=%d\r\n", ret); // 毎回Socket Closeが必要みたい mdm->socketClose(socket); mdm->socketFree(socket); // HTTPレスポンス受信出来た if (ret > 0) { TRACE("Socket Recv \"%s\"\r\n", data); // HTTPレスポンスcheck // 1行目抽出 ptr = strtok_r(data, "\r\n", &strtokptr); // Status Code抽出 ptr = strtok_r(ptr, " ", &strtokptr); ptr = strtok_r(NULL, " ", &strtokptr); int code = atoi(ptr); // ログにレスポンスコードout INFO("HTTP Res=%d\r\n", code); // Code=200番台以外ならばエラー // m2x 202(Accepted) if (code < 200 || code >= 300) { ERROR("HTTP Response ERR code=%d\r\n", code); return -1; } } else { // レスポンス受信できず ERROR("HTTP Response rcv ERR ret=%d\r\n", ret); return -1; } return 0; } /** * M2X にHTTP PUT送信する * HTTPデータを作って送信する * API V2 POST * @param *data JSONデータ (mag+powerv data) * @return 0=OK -1=ERR */ static char m2x_http_send(MDMSerial *mdm, RingBufType *rd) { char http_data[512]; char json[128]; // JSONデータ作る // sprintf(json, "{ \"value\": \"%6.1f\" }", (rd->ad[0]*MV_LSB-500)*DEGC_MV); sprintf(json, "{ \"values\": {\"%04d-temp0\": %6.2f,\"%04d-temp1\": %6.2f,\"%04d-power\": %6.2f}}", rd->sn, (rd->ad[0]*MV_LSB-500)*DEGC_MV, rd->sn, (rd->ad[1]*MV_LSB-500)*DEGC_MV, rd->sn, rd->ad[2]*PV_LSB); // HTTP PUTデータ作る // snprintf(http_data, sizeof(http_data), "PUT /v2/devices/%s/streams/%04d-temp0/value HTTP/1.0\r\n" snprintf(http_data, sizeof(http_data), "POST /v2/devices/%s/update HTTP/1.0\r\n" "X-M2X-KEY: %s\r\n" "Host: %s\r\n" "Content-Type: application/json\r\n" "Content-Length: %d\r\n\r\n%s\r\n", M2X_DEVICE_ID, M2X_API_KEY, M2X_SERVER, strlen(json), json); TRACE(http_data); // HTTP PUTする return cloud_http_socket_send(mdm, http_data, M2X_SERVER); } /* M2Xへの送信スレッド */ void m2x_post_thread(void const *args) { RingBufType *rd; MDMSerial *mdm = (MDMSerial*)args; // 3Gモデムのインスタンス while (true) { // リングバッファにデータあれば送信 if (ring.len_get() > 0) { led = 1; rd = ring.pop(); // リングバッファからPOP m2x_http_send(mdm, rd); // M2Xへデータ送信 led = 0; } Thread::wait(1000); // 1sec } } int main(void) { int ret; char buf[512] = ""; const int wait = 100; int ad[AD_NUM]; int sn; RingBufType data_im920; led = 1; printf("start\r\n"); im920.baud(19200); im920.format(8, Serial::None, 1); // modem object MDMSerial mdm; //mdm.setDebug(4); // enable this for debugging issues // initialize the modem MDMParser::DevStatus devStatus = {}; MDMParser::NetStatus netStatus = {}; bool mdmOk = mdm.init(SIMPIN, &devStatus); mdm.dumpDevStatus(&devStatus); if (mdmOk) { // wait until we are connected mdmOk = mdm.registerNet(&netStatus); mdm.dumpNetStatus(&netStatus); } if (mdmOk) { // join the internet connection MDMParser::IP ip = mdm.join(APN,USERNAME,PASSWORD); if (ip == NOIP) printf("Not able to join network"); else { mdm.dumpIp(ip); } } else { printf("Modem init ERROR!"); return 0; } led = 0; // M2X送信スレッド Thread thread(m2x_post_thread,&mdm); /* MAIN LOOP */ printf("LOOP START\r\n"); while(true) { if (im920.gets(buf, 128) > 0) { printf("%s", buf); if (!im920_conv(buf, &sn, ad)) { printf ("IM920: %06d, %04d, %04d, %04d\r\n", sn, ad[0], ad[1], ad[2]); printf ("IM920: %06d, %f, %f, %f\r\n", sn, (ad[0]*MV_LSB-500)*DEGC_MV, (ad[1]*MV_LSB-500)*DEGC_MV, ad[2]*PV_LSB); // リングバッファに保存 data_im920.sn = sn; for(int i = 0; i < AD_NUM; i++) { data_im920.ad[i] = ad[i]; } ring.push(&data_im920); } } Thread::wait(wait); } mdm.powerOff(); return 0; }