IM920地温観測システム CQ 2017ARMセミナー用サンプルプログラム
Dependencies: C027_Support_ForIM920
Fork of C027_SupportTest by
Diff: main.cpp
- Revision:
- 34:1cbf923d4ca7
- Parent:
- 33:e27f40fada64
- Child:
- 35:7838543282c2
--- a/main.cpp Thu Aug 11 07:12:02 2016 +0000 +++ b/main.cpp Sun Jul 09 11:35:56 2017 +0000 @@ -15,24 +15,176 @@ */ #include "GPS.h" #include "MDM.h" +#include "DebugPrint.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 "1922" +#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 NULL +#define APN "soracom.io" //! Set the user name for your APN, or NULL if not needed -#define USERNAME NULL +#define USERNAME "sora" //! Set the password for your APN, or NULL if not needed -#define PASSWORD NULL +#define PASSWORD "sora" //------------------------------------------------------------------------------------ //#define CELLOCATE +#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" + + +/* +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 + // ERR retryは呼び出し元でしている + // 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, int sn, int *ad) +{ + char http_data[512]; + char data[128]; +// char buf[128]; + +#if 0 + data[0] = 0; + strncat(data, "{\"values\": {\r\n", sizeof(data)); + sprintf(buf, "\"%s\": [\r\n", M2X_CHID_TEMP0); + strncat(data, buf, sizeof(data)); + + sprintf(buf, "{ \"value\":%6.1f}", (ad[0]*MV_LSB-500)*DEGC_MV); + strncat(data, buf, sizeof(data)); + strncat(data, "],\r\n", sizeof(data)); + strncat(data, "}}", sizeof(data)); +#endif + sprintf(data, "{ \"value\": \"%6.1f\" }", (ad[0]*MV_LSB-500)*DEGC_MV); + + // HTTP PUTデータ作る + snprintf(http_data, sizeof(http_data), "PUT /v2/devices/%s/streams/%04d-temp0/value 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, sn, M2X_API_KEY, M2X_SERVER, + strlen(data), data); + TRACE(http_data); + // HTTP PUTする + return cloud_http_socket_send(mdm, http_data, M2X_SERVER); +} + int main(void) { int ret; @@ -41,12 +193,18 @@ #else char buf[512] = ""; #endif + const int wait = 100; + int ad[AD_NUM]; + int sn; + + im920.baud(19200); + im920.format(8, Serial::None, 1); // Create the GPS object #if 1 // use GPSI2C class - GPSI2C gps; +// GPSI2C gps; #else // or GPSSerial class - GPSSerial gps; +// GPSSerial gps; #endif // Create the modem object MDMSerial mdm; // use mdm(D1,D0) if you connect the cellular shield to a C027 @@ -57,21 +215,6 @@ bool mdmOk = mdm.init(SIMPIN, &devStatus); mdm.dumpDevStatus(&devStatus); if (mdmOk) { -#if 0 - // file system API - const char* filename = "File"; - char buf[] = "Hello World"; - printf("writeFile \"%s\"\r\n", buf); - if (mdm.writeFile(filename, buf, sizeof(buf))) - { - memset(buf, 0, sizeof(buf)); - int len = mdm.readFile(filename, buf, sizeof(buf)); - if (len >= 0) - printf("readFile %d \"%.*s\"\r\n", len, len, buf); - mdm.delFile(filename); - } -#endif - // wait until we are connected mdmOk = mdm.registerNet(&netStatus); mdm.dumpNetStatus(&netStatus); @@ -85,210 +228,21 @@ else { mdm.dumpIp(ip); - printf("Make a Http Post Request\r\n"); - int socket = mdm.socketSocket(MDMParser::IPPROTO_TCP); - if (socket >= 0) - { - mdm.socketSetBlocking(socket, 10000); - if (mdm.socketConnect(socket, "mbed.org", 80)) - { - const char http[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\r\n\r\n"; - mdm.socketSend(socket, http, sizeof(http)-1); - - ret = mdm.socketRecv(socket, buf, sizeof(buf)-1); - if (ret > 0) - printf("Socket Recv \"%*s\"\r\n", ret, buf); - mdm.socketClose(socket); - } - mdm.socketFree(socket); - } - - int port = 7; - const char* host = "echo.u-blox.com"; - MDMParser::IP ip = mdm.gethostbyname(host); - char data[] = "\r\nxxx Socket Hello World\r\n" -#ifdef LARGE_DATA - "00 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "01 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "02 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "03 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "04 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - - "05 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "06 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "07 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "08 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "09 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - - "10 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "11 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "12 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "13 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "14 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - - "15 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "16 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "17 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "18 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" - "19 0123456789 0123456789 0123456789 0123456789 0123456789 \r\n" -#endif - "End\r\n"; - - printf("Testing TCP sockets with ECHO server\r\n"); - socket = mdm.socketSocket(MDMParser::IPPROTO_TCP); - if (socket >= 0) - { - mdm.socketSetBlocking(socket, 10000); - if (mdm.socketConnect(socket, host, port)) { - memcpy(data, "\r\nTCP", 5); - ret = mdm.socketSend(socket, data, sizeof(data)-1); - if (ret == sizeof(data)-1) { - printf("Socket Send %d \"%s\"\r\n", ret, data); - } - ret = mdm.socketRecv(socket, buf, sizeof(buf)-1); - if (ret >= 0) { - printf("Socket Recv %d \"%.*s\"\r\n", ret, ret, buf); - } - mdm.socketClose(socket); - } - mdm.socketFree(socket); - } - - printf("Testing UDP sockets with ECHO server\r\n"); - socket = mdm.socketSocket(MDMParser::IPPROTO_UDP, port); - if (socket >= 0) - { - mdm.socketSetBlocking(socket, 10000); - memcpy(data, "\r\nUDP", 5); - ret = mdm.socketSendTo(socket, ip, port, data, sizeof(data)-1); - if (ret == sizeof(data)-1) { - printf("Socket SendTo %s:%d " IPSTR " %d \"%s\"\r\n", host, port, IPNUM(ip), ret, data); - } - ret = mdm.socketRecvFrom(socket, &ip, &port, buf, sizeof(buf)-1); - if (ret >= 0) { - printf("Socket RecvFrom " IPSTR ":%d %d \"%.*s\" \r\n", IPNUM(ip),port, ret, ret,buf); - } - mdm.socketFree(socket); - } - - // disconnect - mdm.disconnect(); } - - // http://www.geckobeach.com/cellular/secrets/gsmcodes.php - // http://de.wikipedia.org/wiki/USSD-Codes - const char* ussd = "*130#"; // You may get answer "UNKNOWN APPLICATION" - printf("Ussd Send Command %s\r\n", ussd); - ret = mdm.ussdCommand(ussd, buf); - if (ret > 0) - printf("Ussd Got Answer: \"%s\"\r\n", buf); + } else { + goto ErrOut; } - - printf("SMS and GPS Loop\r\n"); - char link[128] = ""; - unsigned int i = 0xFFFFFFFF; - const int wait = 100; - bool abort = false; -#ifdef CELLOCATE - const int sensorMask = 3; // Hybrid: GNSS + CellLocate - const int timeoutMargin = 5; // seconds - const int submitPeriod = 60; // 1 minutes in seconds - const int targetAccuracy = 1; // meters - unsigned int j = submitPeriod * 1000/wait; - bool cellLocWait = false; - MDMParser::CellLocData loc; - - //Token can be released from u-blox site, when you got one replace "TOKEN" below - if (!mdm.cellLocSrvHttp("TOKEN")) - mdm.cellLocSrvUdp(); - mdm.cellLocConfigSensor(1); // Deep scan mode - //mdm.cellUnsolIndication(1); -#endif - //DigitalOut led(LED1); - while (!abort) { - // led = !led; -#ifndef CELLOCATE - while ((ret = gps.getMessage(buf, sizeof(buf))) > 0) - { - int len = LENGTH(ret); - //printf("NMEA: %.*s\r\n", len-2, msg); - if ((PROTOCOL(ret) == GPSParser::NMEA) && (len > 6)) - { - // talker is $GA=Galileo $GB=Beidou $GL=Glonass $GN=Combined $GP=GPS - if ((buf[0] == '$') || buf[1] == 'G') { - #define _CHECK_TALKER(s) ((buf[3] == s[0]) && (buf[4] == s[1]) && (buf[5] == s[2])) - if (_CHECK_TALKER("GLL")) { - double la = 0, lo = 0; - char ch; - if (gps.getNmeaAngle(1,buf,len,la) && - gps.getNmeaAngle(3,buf,len,lo) && - gps.getNmeaItem(6,buf,len,ch) && ch == 'A') - { - printf("GPS Location: %.5f %.5f\r\n", la, lo); - sprintf(link, "I am here!\n" - "https://maps.google.com/?q=%.5f,%.5f", la, lo); - } - } else if (_CHECK_TALKER("GGA") || _CHECK_TALKER("GNS") ) { - double a = 0; - if (gps.getNmeaItem(9,buf,len,a)) // altitude msl [m] - printf("GPS Altitude: %.1f\r\n", a); - } else if (_CHECK_TALKER("VTG")) { - double s = 0; - if (gps.getNmeaItem(7,buf,len,s)) // speed [km/h] - printf("GPS Speed: %.1f\r\n", s); - } - } - } - } -#endif -#ifdef CELLOCATE - if (mdmOk && (j++ == submitPeriod * 1000/wait)) { - j=0; - printf("CellLocate Request\r\n"); - mdm.cellLocRequest(sensorMask, submitPeriod-timeoutMargin, targetAccuracy); - cellLocWait = true; - } - if (cellLocWait && mdm.cellLocGet(&loc)){ - cellLocWait = false; - printf("CellLocate position received, sensor_used: %d, \r\n", loc.sensorUsed ); - printf(" latitude: %0.5f, longitude: %0.5f, altitute: %d\r\n", loc.latitue, loc.longitude, loc.altitutude); - if (loc.sensorUsed == 1) - printf(" uncertainty: %d, speed: %d, direction: %d, vertical_acc: %d, satellite used: %d \r\n", loc.uncertainty,loc.speed,loc.direction,loc.verticalAcc,loc.svUsed); - if (loc.sensorUsed == 1 || loc.sensorUsed == 2) - sprintf(link, "I am here!\n" - "https://maps.google.com/?q=%.5f,%.5f", loc.latitue, loc.longitude); - } - if (cellLocWait && (j%100 == 0 )) - printf("Waiting for CellLocate...\r\n"); -#endif - if (mdmOk && (i++ == 5000/wait)) { - i = 0; - // check the network status - if (mdm.checkNetStatus(&netStatus)) { - mdm.dumpNetStatus(&netStatus, fprintf, stdout); - } - - // checking unread sms - int ix[8]; - int n = mdm.smsList("REC UNREAD", ix, 8); - if (8 < n) n = 8; - while (0 < n--) - { - char num[32]; - printf("Unread SMS at index %d\r\n", ix[n]); - if (mdm.smsRead(ix[n], num, buf, sizeof(buf))) { - printf("Got SMS from \"%s\" with text \"%s\"\r\n", num, buf); - printf("Delete SMS at index %d\r\n", ix[n]); - mdm.smsDelete(ix[n]); - // provide a reply - const char* reply = "Hello my friend"; - if (strstr(buf, /*w*/"here are you")) - reply = *link ? link : "I don't know"; // reply wil location link - else if (strstr(buf, /*s*/"hutdown")) - abort = true, reply = "bye bye"; - printf("Send SMS reply \"%s\" to \"%s\"\r\n", reply, num); - mdm.smsSend(num, reply); - } + /* + 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); + m2x_http_send(&mdm, sn, ad); } } #ifdef RTOS_H @@ -297,7 +251,8 @@ ::wait_ms(wait); #endif } - gps.powerOff(); +ErrOut: +// gps.powerOff(); mdm.powerOff(); return 0; }