IM920地温観測システム CQ 2017ARMセミナー用サンプルプログラム
Dependencies: C027_Support_ForIM920
Fork of C027_SupportTest by
main.cpp
00001 #include "mbed.h" 00002 #include "rtos.h" 00003 00004 //------------------------------------------------------------------------------------ 00005 /* 00006 地中温度観測システム親機プログラム 00007 C027_SupportTestをベースにしているがmain.cのコードはほとんで入れ替え 00008 (c) NT System Design 00009 */ 00010 #include "MDM.h" 00011 #include "DebugPrint.h" 00012 #include "RingBuf.h" 00013 00014 //------------------------------------------------------------------------------------ 00015 // You need to configure these cellular modem / SIM parameters. 00016 // These parameters are ignored for LISA-C200 variants and can be left NULL. 00017 //------------------------------------------------------------------------------------ 00018 //! Set your secret SIM pin here (e.g. "1234"). Check your SIM manual. 00019 #define SIMPIN "0000" 00020 /*! The APN of your network operator SIM, sometimes it is "internet" check your 00021 contract with the network operator. You can also try to look-up your settings in 00022 google: https://www.google.de/search?q=APN+list */ 00023 #define APN "soracom.io" 00024 //! Set the user name for your APN, or NULL if not needed 00025 #define USERNAME "sora" 00026 //! Set the password for your APN, or NULL if not needed 00027 #define PASSWORD "sora" 00028 //------------------------------------------------------------------------------------ 00029 00030 #define IM920_TX P4_28 00031 #define IM920_RX P4_29 00032 Serial im920(IM920_TX, IM920_RX); 00033 00034 #define AD_NUM 3 00035 #define MV_LSB (1500/1024.) 00036 #define DEGC_MV (1/10.) 00037 #define PV_LSB (2*1.5/1024) 00038 00039 #define M2X_SERVER "api-m2x.att.com" 00040 #define M2X_DEVICE_ID "964d05b1a6f4a8bb02c2a5aaf6e7e268" 00041 #define M2X_API_KEY "602d38e9e8dfcf62e7f87a59c80784ec" 00042 #define M2X_CHID_TEMP0 "temp0" 00043 00044 DigitalOut led(LED1); 00045 00046 // リングバッファサイズ 00047 #define RINGBUF_SIZE 60 // 毎分データで1時間ぶん 00048 // リングバッファ 00049 RingBuf ring(RINGBUF_SIZE); 00050 00051 /* 00052 IM920から受信したADデータをデコードする 00053 sn: IM920 SN 00054 *ad: ADデータ配列 LSB 00055 ret: 0=OK -1=ERR 00056 */ 00057 int im920_conv(char *in, int *sn, int *ad) 00058 { 00059 char *p; 00060 char *endptr; 00061 int l, h; 00062 int i; 00063 00064 p = strtok(in, ","); 00065 // SN 00066 p = strtok(NULL, ","); 00067 *sn = strtol(p, &endptr, 16); 00068 // SUM 00069 p = strtok(NULL, ":"); 00070 // printf("%s ", p); 00071 // AD0-2 00072 for(i = 0; i < AD_NUM; i++) { 00073 p = strtok(NULL, ","); 00074 // printf("%s ", p); 00075 l = strtol(p, &endptr, 16); 00076 p = strtok(NULL, ","); 00077 // printf("%s ", p); 00078 h = strtol(p, &endptr, 16); 00079 ad[i] = l + h*256; 00080 } 00081 00082 return 0; 00083 } 00084 00085 /** 00086 * M2X HTTP送信 00087 * @param http HTTP送信する文字列 00088 * @param hostname 00089 * @return 0=OK -1=ERR 00090 */ 00091 int cloud_http_socket_send(MDMSerial *mdm, char *http, const char *hostname) 00092 { 00093 int socket; 00094 char data[512]; // receive 00095 char *strtokptr; 00096 char *ptr; 00097 00098 socket = mdm->socketSocket(MDMParser::IPPROTO_TCP); 00099 if (socket >= 0) { 00100 mdm->socketSetBlocking(socket, 60*1000); // timeout im msec 00101 // 指定されたhostにSocket Connect 00102 if (!mdm->socketConnect(socket, hostname, 80)) { 00103 ERROR("ERROR socket connect\r\n"); 00104 ERROR("hostname=%s\r\n", hostname); 00105 return -1; 00106 } 00107 TRACE("socketConnect() OK\r\n"); 00108 } else { 00109 ERROR("sockeSocket() < 0\r\n"); 00110 ERROR("hostname=%s\r\n", hostname); 00111 return -1; 00112 } 00113 int ret = mdm->socketSend(socket, http, strlen(http)); 00114 TRACE("socketSend()=%d\r\n", ret); 00115 // Recv responce 十分な大きさの変数を渡す必要あり 00116 ret = mdm->socketRecv(socket, data, sizeof(data)-1); 00117 TRACE("socketRecv()=%d\r\n", ret); 00118 // 毎回Socket Closeが必要みたい 00119 mdm->socketClose(socket); 00120 mdm->socketFree(socket); 00121 // HTTPレスポンス受信出来た 00122 if (ret > 0) { 00123 TRACE("Socket Recv \"%s\"\r\n", data); 00124 // HTTPレスポンスcheck 00125 // 1行目抽出 00126 ptr = strtok_r(data, "\r\n", &strtokptr); 00127 // Status Code抽出 00128 ptr = strtok_r(ptr, " ", &strtokptr); 00129 ptr = strtok_r(NULL, " ", &strtokptr); 00130 int code = atoi(ptr); 00131 // ログにレスポンスコードout 00132 INFO("HTTP Res=%d\r\n", code); 00133 // Code=200番台以外ならばエラー 00134 // m2x 202(Accepted) 00135 if (code < 200 || code >= 300) { 00136 ERROR("HTTP Response ERR code=%d\r\n", code); 00137 return -1; 00138 } 00139 } else { 00140 // レスポンス受信できず 00141 ERROR("HTTP Response rcv ERR ret=%d\r\n", ret); 00142 return -1; 00143 } 00144 return 0; 00145 } 00146 /** 00147 * M2X にHTTP PUT送信する 00148 * HTTPデータを作って送信する 00149 * API V2 POST 00150 * @param *data JSONデータ (mag+powerv data) 00151 * @return 0=OK -1=ERR 00152 */ 00153 static char m2x_http_send(MDMSerial *mdm, RingBufType *rd) 00154 { 00155 char http_data[512]; 00156 char json[128]; 00157 // JSONデータ作る 00158 // sprintf(json, "{ \"value\": \"%6.1f\" }", (rd->ad[0]*MV_LSB-500)*DEGC_MV); 00159 sprintf(json, "{ \"values\": {\"%04d-temp0\": %6.2f,\"%04d-temp1\": %6.2f,\"%04d-power\": %6.2f}}", 00160 rd->sn, (rd->ad[0]*MV_LSB-500)*DEGC_MV, 00161 rd->sn, (rd->ad[1]*MV_LSB-500)*DEGC_MV, 00162 rd->sn, rd->ad[2]*PV_LSB); 00163 00164 // HTTP PUTデータ作る 00165 // snprintf(http_data, sizeof(http_data), "PUT /v2/devices/%s/streams/%04d-temp0/value HTTP/1.0\r\n" 00166 snprintf(http_data, sizeof(http_data), "POST /v2/devices/%s/update HTTP/1.0\r\n" 00167 "X-M2X-KEY: %s\r\n" 00168 "Host: %s\r\n" 00169 "Content-Type: application/json\r\n" 00170 "Content-Length: %d\r\n\r\n%s\r\n", 00171 M2X_DEVICE_ID, M2X_API_KEY, M2X_SERVER, 00172 strlen(json), json); 00173 TRACE(http_data); 00174 // HTTP PUTする 00175 return cloud_http_socket_send(mdm, http_data, M2X_SERVER); 00176 } 00177 /* 00178 M2Xへの送信スレッド 00179 */ 00180 void m2x_post_thread(void const *args) { 00181 RingBufType *rd; 00182 MDMSerial *mdm = (MDMSerial*)args; // 3Gモデムのインスタンス 00183 00184 while (true) { 00185 // リングバッファにデータあれば送信 00186 if (ring.len_get() > 0) { 00187 led = 1; 00188 rd = ring.pop(); // リングバッファからPOP 00189 m2x_http_send(mdm, rd); // M2Xへデータ送信 00190 led = 0; 00191 } 00192 Thread::wait(1000); // 1sec 00193 } 00194 } 00195 00196 int main(void) 00197 { 00198 int ret; 00199 char buf[512] = ""; 00200 const int wait = 100; 00201 int ad[AD_NUM]; 00202 int sn; 00203 RingBufType data_im920; 00204 00205 led = 1; 00206 printf("start\r\n"); 00207 im920.baud(19200); 00208 im920.format(8, Serial::None, 1); 00209 00210 // modem object 00211 MDMSerial mdm; 00212 //mdm.setDebug(4); // enable this for debugging issues 00213 // initialize the modem 00214 MDMParser::DevStatus devStatus = {}; 00215 MDMParser::NetStatus netStatus = {}; 00216 bool mdmOk = mdm.init(SIMPIN, &devStatus); 00217 mdm.dumpDevStatus(&devStatus); 00218 if (mdmOk) { 00219 // wait until we are connected 00220 mdmOk = mdm.registerNet(&netStatus); 00221 mdm.dumpNetStatus(&netStatus); 00222 } 00223 if (mdmOk) 00224 { 00225 // join the internet connection 00226 MDMParser::IP ip = mdm.join(APN,USERNAME,PASSWORD); 00227 if (ip == NOIP) 00228 printf("Not able to join network"); 00229 else 00230 { 00231 mdm.dumpIp(ip); 00232 } 00233 } else { 00234 printf("Modem init ERROR!"); 00235 return 0; 00236 } 00237 led = 0; 00238 // M2X送信スレッド 00239 Thread thread(m2x_post_thread,&mdm); 00240 /* 00241 MAIN LOOP 00242 */ 00243 printf("LOOP START\r\n"); 00244 while(true) { 00245 if (im920.gets(buf, 128) > 0) { 00246 printf("%s", buf); 00247 if (!im920_conv(buf, &sn, ad)) { 00248 printf ("IM920: %06d, %04d, %04d, %04d\r\n", sn, ad[0], ad[1], ad[2]); 00249 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); 00250 // リングバッファに保存 00251 data_im920.sn = sn; 00252 for(int i = 0; i < AD_NUM; i++) { 00253 data_im920.ad[i] = ad[i]; 00254 } 00255 ring.push(&data_im920); 00256 } 00257 } 00258 Thread::wait(wait); 00259 } 00260 mdm.powerOff(); 00261 return 0; 00262 }
Generated on Wed Jul 13 2022 01:06:47 by 1.7.2