IM920地温観測システム CQ 2017ARMセミナー用サンプルプログラム

Dependencies:   C027_Support_ForIM920

Fork of C027_SupportTest by u-blox

Committer:
ntaka206
Date:
Thu Jul 13 00:49:14 2017 +0000
Revision:
36:b89a6e114339
Parent:
35:7838543282c2
IM920????????; CQ 2017ARM??????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lawliet 0:4e3cb26f6019 1 #include "mbed.h"
ntaka206 35:7838543282c2 2 #include "rtos.h"
mazgch 9:26f694bc31b4 3
mazgch 19:f022ff746eb8 4 //------------------------------------------------------------------------------------
ntaka206 35:7838543282c2 5 /*
ntaka206 35:7838543282c2 6 地中温度観測システム親機プログラム
ntaka206 35:7838543282c2 7 C027_SupportTestをベースにしているがmain.cのコードはほとんで入れ替え
ntaka206 35:7838543282c2 8 (c) NT System Design
mazgch 11:b8505cbbd55c 9 */
mazgch 19:f022ff746eb8 10 #include "MDM.h"
ntaka206 34:1cbf923d4ca7 11 #include "DebugPrint.h"
ntaka206 35:7838543282c2 12 #include "RingBuf.h"
ntaka206 34:1cbf923d4ca7 13
mazgch 19:f022ff746eb8 14 //------------------------------------------------------------------------------------
mazgch 19:f022ff746eb8 15 // You need to configure these cellular modem / SIM parameters.
mazgch 19:f022ff746eb8 16 // These parameters are ignored for LISA-C200 variants and can be left NULL.
mazgch 19:f022ff746eb8 17 //------------------------------------------------------------------------------------
mazgch 19:f022ff746eb8 18 //! Set your secret SIM pin here (e.g. "1234"). Check your SIM manual.
ntaka206 34:1cbf923d4ca7 19 #define SIMPIN "0000"
mazgch 19:f022ff746eb8 20 /*! The APN of your network operator SIM, sometimes it is "internet" check your
mazgch 19:f022ff746eb8 21 contract with the network operator. You can also try to look-up your settings in
mazgch 19:f022ff746eb8 22 google: https://www.google.de/search?q=APN+list */
ntaka206 34:1cbf923d4ca7 23 #define APN "soracom.io"
mazgch 19:f022ff746eb8 24 //! Set the user name for your APN, or NULL if not needed
ntaka206 34:1cbf923d4ca7 25 #define USERNAME "sora"
mazgch 19:f022ff746eb8 26 //! Set the password for your APN, or NULL if not needed
ntaka206 34:1cbf923d4ca7 27 #define PASSWORD "sora"
mazgch 19:f022ff746eb8 28 //------------------------------------------------------------------------------------
lawliet 0:4e3cb26f6019 29
ntaka206 34:1cbf923d4ca7 30 #define IM920_TX P4_28
ntaka206 34:1cbf923d4ca7 31 #define IM920_RX P4_29
ntaka206 34:1cbf923d4ca7 32 Serial im920(IM920_TX, IM920_RX);
ntaka206 34:1cbf923d4ca7 33
ntaka206 34:1cbf923d4ca7 34 #define AD_NUM 3
ntaka206 34:1cbf923d4ca7 35 #define MV_LSB (1500/1024.)
ntaka206 34:1cbf923d4ca7 36 #define DEGC_MV (1/10.)
ntaka206 34:1cbf923d4ca7 37 #define PV_LSB (2*1.5/1024)
ntaka206 34:1cbf923d4ca7 38
ntaka206 34:1cbf923d4ca7 39 #define M2X_SERVER "api-m2x.att.com"
ntaka206 34:1cbf923d4ca7 40 #define M2X_DEVICE_ID "964d05b1a6f4a8bb02c2a5aaf6e7e268"
ntaka206 34:1cbf923d4ca7 41 #define M2X_API_KEY "602d38e9e8dfcf62e7f87a59c80784ec"
ntaka206 34:1cbf923d4ca7 42 #define M2X_CHID_TEMP0 "temp0"
ntaka206 34:1cbf923d4ca7 43
ntaka206 35:7838543282c2 44 DigitalOut led(LED1);
ntaka206 35:7838543282c2 45
ntaka206 35:7838543282c2 46 // リングバッファサイズ
ntaka206 35:7838543282c2 47 #define RINGBUF_SIZE 60 // 毎分データで1時間ぶん
ntaka206 35:7838543282c2 48 // リングバッファ
ntaka206 35:7838543282c2 49 RingBuf ring(RINGBUF_SIZE);
ntaka206 34:1cbf923d4ca7 50
ntaka206 34:1cbf923d4ca7 51 /*
ntaka206 34:1cbf923d4ca7 52 IM920から受信したADデータをデコードする
ntaka206 34:1cbf923d4ca7 53 sn: IM920 SN
ntaka206 34:1cbf923d4ca7 54 *ad: ADデータ配列 LSB
ntaka206 34:1cbf923d4ca7 55 ret: 0=OK -1=ERR
ntaka206 34:1cbf923d4ca7 56 */
ntaka206 34:1cbf923d4ca7 57 int im920_conv(char *in, int *sn, int *ad)
ntaka206 34:1cbf923d4ca7 58 {
ntaka206 34:1cbf923d4ca7 59 char *p;
ntaka206 34:1cbf923d4ca7 60 char *endptr;
ntaka206 34:1cbf923d4ca7 61 int l, h;
ntaka206 34:1cbf923d4ca7 62 int i;
ntaka206 34:1cbf923d4ca7 63
ntaka206 34:1cbf923d4ca7 64 p = strtok(in, ",");
ntaka206 34:1cbf923d4ca7 65 // SN
ntaka206 34:1cbf923d4ca7 66 p = strtok(NULL, ",");
ntaka206 34:1cbf923d4ca7 67 *sn = strtol(p, &endptr, 16);
ntaka206 34:1cbf923d4ca7 68 // SUM
ntaka206 34:1cbf923d4ca7 69 p = strtok(NULL, ":");
ntaka206 34:1cbf923d4ca7 70 // printf("%s ", p);
ntaka206 34:1cbf923d4ca7 71 // AD0-2
ntaka206 34:1cbf923d4ca7 72 for(i = 0; i < AD_NUM; i++) {
ntaka206 34:1cbf923d4ca7 73 p = strtok(NULL, ",");
ntaka206 34:1cbf923d4ca7 74 // printf("%s ", p);
ntaka206 34:1cbf923d4ca7 75 l = strtol(p, &endptr, 16);
ntaka206 34:1cbf923d4ca7 76 p = strtok(NULL, ",");
ntaka206 34:1cbf923d4ca7 77 // printf("%s ", p);
ntaka206 34:1cbf923d4ca7 78 h = strtol(p, &endptr, 16);
ntaka206 34:1cbf923d4ca7 79 ad[i] = l + h*256;
ntaka206 34:1cbf923d4ca7 80 }
ntaka206 34:1cbf923d4ca7 81
ntaka206 34:1cbf923d4ca7 82 return 0;
ntaka206 34:1cbf923d4ca7 83 }
ntaka206 34:1cbf923d4ca7 84
ntaka206 34:1cbf923d4ca7 85 /**
ntaka206 34:1cbf923d4ca7 86 * M2X HTTP送信
ntaka206 34:1cbf923d4ca7 87 * @param http HTTP送信する文字列
ntaka206 34:1cbf923d4ca7 88 * @param hostname
ntaka206 34:1cbf923d4ca7 89 * @return 0=OK -1=ERR
ntaka206 34:1cbf923d4ca7 90 */
ntaka206 34:1cbf923d4ca7 91 int cloud_http_socket_send(MDMSerial *mdm, char *http, const char *hostname)
ntaka206 34:1cbf923d4ca7 92 {
ntaka206 34:1cbf923d4ca7 93 int socket;
ntaka206 34:1cbf923d4ca7 94 char data[512]; // receive
ntaka206 34:1cbf923d4ca7 95 char *strtokptr;
ntaka206 34:1cbf923d4ca7 96 char *ptr;
ntaka206 34:1cbf923d4ca7 97
ntaka206 34:1cbf923d4ca7 98 socket = mdm->socketSocket(MDMParser::IPPROTO_TCP);
ntaka206 34:1cbf923d4ca7 99 if (socket >= 0) {
ntaka206 34:1cbf923d4ca7 100 mdm->socketSetBlocking(socket, 60*1000); // timeout im msec
ntaka206 34:1cbf923d4ca7 101 // 指定されたhostにSocket Connect
ntaka206 34:1cbf923d4ca7 102 if (!mdm->socketConnect(socket, hostname, 80)) {
ntaka206 34:1cbf923d4ca7 103 ERROR("ERROR socket connect\r\n");
ntaka206 34:1cbf923d4ca7 104 ERROR("hostname=%s\r\n", hostname);
ntaka206 34:1cbf923d4ca7 105 return -1;
ntaka206 34:1cbf923d4ca7 106 }
ntaka206 34:1cbf923d4ca7 107 TRACE("socketConnect() OK\r\n");
ntaka206 34:1cbf923d4ca7 108 } else {
ntaka206 34:1cbf923d4ca7 109 ERROR("sockeSocket() < 0\r\n");
ntaka206 34:1cbf923d4ca7 110 ERROR("hostname=%s\r\n", hostname);
ntaka206 34:1cbf923d4ca7 111 return -1;
ntaka206 34:1cbf923d4ca7 112 }
ntaka206 34:1cbf923d4ca7 113 int ret = mdm->socketSend(socket, http, strlen(http));
ntaka206 34:1cbf923d4ca7 114 TRACE("socketSend()=%d\r\n", ret);
ntaka206 34:1cbf923d4ca7 115 // Recv responce 十分な大きさの変数を渡す必要あり
ntaka206 34:1cbf923d4ca7 116 ret = mdm->socketRecv(socket, data, sizeof(data)-1);
ntaka206 34:1cbf923d4ca7 117 TRACE("socketRecv()=%d\r\n", ret);
ntaka206 34:1cbf923d4ca7 118 // 毎回Socket Closeが必要みたい
ntaka206 34:1cbf923d4ca7 119 mdm->socketClose(socket);
ntaka206 34:1cbf923d4ca7 120 mdm->socketFree(socket);
ntaka206 34:1cbf923d4ca7 121 // HTTPレスポンス受信出来た
ntaka206 34:1cbf923d4ca7 122 if (ret > 0) {
ntaka206 34:1cbf923d4ca7 123 TRACE("Socket Recv \"%s\"\r\n", data);
ntaka206 34:1cbf923d4ca7 124 // HTTPレスポンスcheck
ntaka206 34:1cbf923d4ca7 125 // 1行目抽出
ntaka206 34:1cbf923d4ca7 126 ptr = strtok_r(data, "\r\n", &strtokptr);
ntaka206 34:1cbf923d4ca7 127 // Status Code抽出
ntaka206 34:1cbf923d4ca7 128 ptr = strtok_r(ptr, " ", &strtokptr);
ntaka206 34:1cbf923d4ca7 129 ptr = strtok_r(NULL, " ", &strtokptr);
ntaka206 34:1cbf923d4ca7 130 int code = atoi(ptr);
ntaka206 34:1cbf923d4ca7 131 // ログにレスポンスコードout
ntaka206 34:1cbf923d4ca7 132 INFO("HTTP Res=%d\r\n", code);
ntaka206 34:1cbf923d4ca7 133 // Code=200番台以外ならばエラー
ntaka206 34:1cbf923d4ca7 134 // m2x 202(Accepted)
ntaka206 34:1cbf923d4ca7 135 if (code < 200 || code >= 300) {
ntaka206 34:1cbf923d4ca7 136 ERROR("HTTP Response ERR code=%d\r\n", code);
ntaka206 34:1cbf923d4ca7 137 return -1;
ntaka206 34:1cbf923d4ca7 138 }
ntaka206 34:1cbf923d4ca7 139 } else {
ntaka206 34:1cbf923d4ca7 140 // レスポンス受信できず
ntaka206 34:1cbf923d4ca7 141 ERROR("HTTP Response rcv ERR ret=%d\r\n", ret);
ntaka206 34:1cbf923d4ca7 142 return -1;
ntaka206 34:1cbf923d4ca7 143 }
ntaka206 34:1cbf923d4ca7 144 return 0;
ntaka206 34:1cbf923d4ca7 145 }
ntaka206 34:1cbf923d4ca7 146 /**
ntaka206 34:1cbf923d4ca7 147 * M2X にHTTP PUT送信する
ntaka206 34:1cbf923d4ca7 148 * HTTPデータを作って送信する
ntaka206 34:1cbf923d4ca7 149 * API V2 POST
ntaka206 34:1cbf923d4ca7 150 * @param *data JSONデータ (mag+powerv data)
ntaka206 34:1cbf923d4ca7 151 * @return 0=OK -1=ERR
ntaka206 34:1cbf923d4ca7 152 */
ntaka206 35:7838543282c2 153 static char m2x_http_send(MDMSerial *mdm, RingBufType *rd)
ntaka206 34:1cbf923d4ca7 154 {
ntaka206 34:1cbf923d4ca7 155 char http_data[512];
ntaka206 35:7838543282c2 156 char json[128];
ntaka206 35:7838543282c2 157 // JSONデータ作る
ntaka206 35:7838543282c2 158 // sprintf(json, "{ \"value\": \"%6.1f\" }", (rd->ad[0]*MV_LSB-500)*DEGC_MV);
ntaka206 35:7838543282c2 159 sprintf(json, "{ \"values\": {\"%04d-temp0\": %6.2f,\"%04d-temp1\": %6.2f,\"%04d-power\": %6.2f}}",
ntaka206 35:7838543282c2 160 rd->sn, (rd->ad[0]*MV_LSB-500)*DEGC_MV,
ntaka206 35:7838543282c2 161 rd->sn, (rd->ad[1]*MV_LSB-500)*DEGC_MV,
ntaka206 35:7838543282c2 162 rd->sn, rd->ad[2]*PV_LSB);
ntaka206 34:1cbf923d4ca7 163
ntaka206 34:1cbf923d4ca7 164 // HTTP PUTデータ作る
ntaka206 35:7838543282c2 165 // snprintf(http_data, sizeof(http_data), "PUT /v2/devices/%s/streams/%04d-temp0/value HTTP/1.0\r\n"
ntaka206 35:7838543282c2 166 snprintf(http_data, sizeof(http_data), "POST /v2/devices/%s/update HTTP/1.0\r\n"
ntaka206 34:1cbf923d4ca7 167 "X-M2X-KEY: %s\r\n"
ntaka206 34:1cbf923d4ca7 168 "Host: %s\r\n"
ntaka206 34:1cbf923d4ca7 169 "Content-Type: application/json\r\n"
ntaka206 34:1cbf923d4ca7 170 "Content-Length: %d\r\n\r\n%s\r\n",
ntaka206 35:7838543282c2 171 M2X_DEVICE_ID, M2X_API_KEY, M2X_SERVER,
ntaka206 35:7838543282c2 172 strlen(json), json);
ntaka206 34:1cbf923d4ca7 173 TRACE(http_data);
ntaka206 34:1cbf923d4ca7 174 // HTTP PUTする
ntaka206 34:1cbf923d4ca7 175 return cloud_http_socket_send(mdm, http_data, M2X_SERVER);
ntaka206 34:1cbf923d4ca7 176 }
ntaka206 35:7838543282c2 177 /*
ntaka206 35:7838543282c2 178 M2Xへの送信スレッド
ntaka206 35:7838543282c2 179 */
ntaka206 35:7838543282c2 180 void m2x_post_thread(void const *args) {
ntaka206 35:7838543282c2 181 RingBufType *rd;
ntaka206 35:7838543282c2 182 MDMSerial *mdm = (MDMSerial*)args; // 3Gモデムのインスタンス
ntaka206 35:7838543282c2 183
ntaka206 35:7838543282c2 184 while (true) {
ntaka206 35:7838543282c2 185 // リングバッファにデータあれば送信
ntaka206 35:7838543282c2 186 if (ring.len_get() > 0) {
ntaka206 35:7838543282c2 187 led = 1;
ntaka206 35:7838543282c2 188 rd = ring.pop(); // リングバッファからPOP
ntaka206 35:7838543282c2 189 m2x_http_send(mdm, rd); // M2Xへデータ送信
ntaka206 35:7838543282c2 190 led = 0;
ntaka206 35:7838543282c2 191 }
ntaka206 35:7838543282c2 192 Thread::wait(1000); // 1sec
ntaka206 35:7838543282c2 193 }
ntaka206 35:7838543282c2 194 }
ntaka206 34:1cbf923d4ca7 195
lawliet 0:4e3cb26f6019 196 int main(void)
lawliet 0:4e3cb26f6019 197 {
mazgch 2:b77151f111a9 198 int ret;
mazgch 17:c293780a40ac 199 char buf[512] = "";
ntaka206 34:1cbf923d4ca7 200 const int wait = 100;
ntaka206 34:1cbf923d4ca7 201 int ad[AD_NUM];
ntaka206 34:1cbf923d4ca7 202 int sn;
ntaka206 35:7838543282c2 203 RingBufType data_im920;
ntaka206 34:1cbf923d4ca7 204
ntaka206 35:7838543282c2 205 led = 1;
ntaka206 35:7838543282c2 206 printf("start\r\n");
ntaka206 34:1cbf923d4ca7 207 im920.baud(19200);
ntaka206 34:1cbf923d4ca7 208 im920.format(8, Serial::None, 1);
lawliet 0:4e3cb26f6019 209
ntaka206 35:7838543282c2 210 // modem object
ntaka206 35:7838543282c2 211 MDMSerial mdm;
mazgch 28:334263983fcd 212 //mdm.setDebug(4); // enable this for debugging issues
mazgch 2:b77151f111a9 213 // initialize the modem
mazgch 19:f022ff746eb8 214 MDMParser::DevStatus devStatus = {};
mazgch 19:f022ff746eb8 215 MDMParser::NetStatus netStatus = {};
mazgch 10:d2da2028a233 216 bool mdmOk = mdm.init(SIMPIN, &devStatus);
mazgch 19:f022ff746eb8 217 mdm.dumpDevStatus(&devStatus);
mazgch 19:f022ff746eb8 218 if (mdmOk) {
mazgch 20:52f0e5de8c3d 219 // wait until we are connected
mazgch 20:52f0e5de8c3d 220 mdmOk = mdm.registerNet(&netStatus);
mazgch 20:52f0e5de8c3d 221 mdm.dumpNetStatus(&netStatus);
mazgch 20:52f0e5de8c3d 222 }
mazgch 20:52f0e5de8c3d 223 if (mdmOk)
mazgch 20:52f0e5de8c3d 224 {
mazgch 4:90ab1ec64b0e 225 // join the internet connection
mazgch 19:f022ff746eb8 226 MDMParser::IP ip = mdm.join(APN,USERNAME,PASSWORD);
mazgch 32:b838fcaba45e 227 if (ip == NOIP)
mazgch 32:b838fcaba45e 228 printf("Not able to join network");
mazgch 32:b838fcaba45e 229 else
mazgch 2:b77151f111a9 230 {
mazgch 19:f022ff746eb8 231 mdm.dumpIp(ip);
mazgch 2:b77151f111a9 232 }
ntaka206 34:1cbf923d4ca7 233 } else {
ntaka206 35:7838543282c2 234 printf("Modem init ERROR!");
ntaka206 35:7838543282c2 235 return 0;
mazgch 10:d2da2028a233 236 }
ntaka206 35:7838543282c2 237 led = 0;
ntaka206 35:7838543282c2 238 // M2X送信スレッド
ntaka206 35:7838543282c2 239 Thread thread(m2x_post_thread,&mdm);
ntaka206 34:1cbf923d4ca7 240 /*
ntaka206 34:1cbf923d4ca7 241 MAIN LOOP
ntaka206 34:1cbf923d4ca7 242 */
ntaka206 34:1cbf923d4ca7 243 printf("LOOP START\r\n");
ntaka206 34:1cbf923d4ca7 244 while(true) {
ntaka206 34:1cbf923d4ca7 245 if (im920.gets(buf, 128) > 0) {
ntaka206 34:1cbf923d4ca7 246 printf("%s", buf);
ntaka206 34:1cbf923d4ca7 247 if (!im920_conv(buf, &sn, ad)) {
ntaka206 34:1cbf923d4ca7 248 printf ("IM920: %06d, %04d, %04d, %04d\r\n", sn, ad[0], ad[1], ad[2]);
ntaka206 34:1cbf923d4ca7 249 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);
ntaka206 35:7838543282c2 250 // リングバッファに保存
ntaka206 35:7838543282c2 251 data_im920.sn = sn;
ntaka206 35:7838543282c2 252 for(int i = 0; i < AD_NUM; i++) {
ntaka206 35:7838543282c2 253 data_im920.ad[i] = ad[i];
ntaka206 35:7838543282c2 254 }
ntaka206 35:7838543282c2 255 ring.push(&data_im920);
mazgch 4:90ab1ec64b0e 256 }
mazgch 9:26f694bc31b4 257 }
mazgch 31:a07d0f76dc81 258 Thread::wait(wait);
lawliet 0:4e3cb26f6019 259 }
mazgch 10:d2da2028a233 260 mdm.powerOff();
lawliet 0:4e3cb26f6019 261 return 0;
lawliet 0:4e3cb26f6019 262 }