レンタルサーバーと連携したsakura.ioの運用例
Dependencies: mbed SakuraIO MPU9250_SPI BME280 gps AQM0802A
main.cpp
00001 #include <mbed.h> 00002 #include <AQM0802A.h> 00003 #include <BME280.h> 00004 #include <MPU9250.h> 00005 #include <SakuraIO.h> 00006 #include "SakuraPinNames.h" 00007 #include "sensors.h" 00008 #include "gps.h" 00009 00010 //LED制御メッセージのタイプ種別の定数 00011 #define MESG_NORMAL 0 00012 #define MESG_INIT 1 00013 00014 00015 // Serial over CMSIS_DAP 00016 Serial pc(DAP_UART_TX, DAP_UART_RX, 9600); 00017 00018 // GPS 00019 Serial gps(GPS_TX, GPS_RX, 9600); 00020 DigitalOut gps_en(GPS_EN); 00021 00022 // LED 00023 DigitalOut led_1(LED1); 00024 DigitalOut led_2(LED2); 00025 DigitalOut led_3(LED3); 00026 DigitalOut led_4(LED4); 00027 00028 // LCD backlight 00029 DigitalOut lcd_led(LED_LCD); 00030 00031 // Switch 00032 DigitalIn sw_1(SW1); 00033 DigitalIn sw_2(SW2); 00034 DigitalIn sw_3(SW3); 00035 DigitalIn sw_4(SW4); 00036 DigitalIn sw_5(SW5); 00037 DigitalIn sw_6(SW6); 00038 00039 // Internal I2C 00040 I2C internal_i2c(I2C_INTERNAL_SDA, I2C_INTERNAL_SCL); 00041 AQM0802A lcd(internal_i2c); 00042 BME280 bme280(internal_i2c); 00043 00044 // SPI 00045 SPI internal_mpu9250_spi(SPI_MPU_MOSI, SPI_MPU_MISO, SPI_MPU_SCK); 00046 mpu9250_spi mpu9250(internal_mpu9250_spi, SPI_MPU_CS); 00047 00048 // sakura.io 00049 //SakuraIO_I2C sakuraio(I2C_SDA, I2C_SCL); 00050 #define SPI_FREQ (350000) 00051 SPI sakuraio_spi(PB_15, PB_14, PB_13); 00052 DigitalOut sakuraio_cs(PB_12); 00053 SakuraIO_SPI sakuraio(sakuraio_spi, sakuraio_cs); 00054 00055 SensorData sensor_data; 00056 00057 // GPS UART buffer 00058 char uart_buffer[128] = {0}; 00059 int uart_buffer_index = 0; 00060 00061 //LED応対s申告の為のLTE接続した直後を検出するためのフラグ 00062 // 0:切断、1:接続直後でLED情報送信中、2:LED状態到達確認済み 00063 int connected_now = 0; 00064 00065 // NMEA Decoder 00066 GPSDecoder gps_decoder; 00067 00068 void gps_uart_buffering_handler(); 00069 00070 const int SEND_INTERVAL_TICKS_PAR_COUNT = 1500; 00071 00072 const int RETRY_INTERVAL_TICKS_PAR_COUNT = 50; 00073 00074 void setup() 00075 { 00076 lcd_led = 1; 00077 pc.printf("Hello World !\r\n"); 00078 lcd.cls(); 00079 lcd.printf("Hello"); 00080 connected_now = 0; 00081 00082 // Initialize sensors 00083 bme280.initialize(); 00084 pc.printf("BME280 ok.\r\n"); 00085 mpu9250.init(1, BITS_DLPF_CFG_188HZ); 00086 pc.printf("MPU9250 ok. WHOAMI=%02x\r\n", mpu9250.whoami()); 00087 if (mpu9250.whoami() != 0x71) { 00088 pc.printf("[ERROR] MPU9250 init fail.\r\n"); 00089 } 00090 00091 mpu9250.set_gyro_scale(BITS_FS_2000DPS); //Set full scale range for gyros 00092 mpu9250.set_acc_scale(BITS_FS_16G); //Set full scale range for accs 00093 mpu9250.calib_acc(); 00094 mpu9250.AK8963_calib_Magnetometer(); 00095 00096 // active high 00097 gps_en = 1; 00098 gps.attach(&gps_uart_buffering_handler, Serial::RxIrq); 00099 00100 led_1 = 1; 00101 led_2 = 0; 00102 00103 pc.printf("Send par %d seconds.\r\n", (SEND_INTERVAL_TICKS_PAR_COUNT * 200) / 1000); 00104 } 00105 00106 void read_sensor_data() 00107 { 00108 sensor_data.bme280.temperature = bme280.getTemperature(); 00109 sensor_data.bme280.pressure = bme280.getPressure(); 00110 sensor_data.bme280.humidity = bme280.getHumidity(); 00111 00112 mpu9250.read_all(); 00113 sensor_data.mpu9250.temperature = mpu9250.Temperature; 00114 for (int cnt_send = 0; cnt_send < 3; cnt_send++) { 00115 sensor_data.mpu9250.accelerometer[cnt_send] = mpu9250.accelerometer_data[cnt_send]; 00116 sensor_data.mpu9250.gyroscope[cnt_send] = mpu9250.gyroscope_data[cnt_send]; 00117 sensor_data.mpu9250.magnetometer[cnt_send] = mpu9250.Magnetometer[cnt_send]; 00118 } 00119 } 00120 00121 void enqueue_sensor_data(int counter) 00122 { 00123 sakuraio.enqueueTx(0, (int32_t)counter); 00124 sakuraio.enqueueTx(1, sensor_data.bme280.temperature); 00125 sakuraio.enqueueTx(2, sensor_data.bme280.pressure); 00126 sakuraio.enqueueTx(3, sensor_data.bme280.humidity); 00127 sakuraio.enqueueTx(4, sensor_data.mpu9250.accelerometer[0]); 00128 sakuraio.enqueueTx(5, sensor_data.mpu9250.accelerometer[1]); 00129 sakuraio.enqueueTx(6, sensor_data.mpu9250.accelerometer[2]); 00130 sakuraio.enqueueTx(7, sensor_data.mpu9250.gyroscope[0]); 00131 sakuraio.enqueueTx(8, sensor_data.mpu9250.gyroscope[1]); 00132 sakuraio.enqueueTx(9, sensor_data.mpu9250.gyroscope[2]); 00133 sakuraio.enqueueTx(10, sensor_data.mpu9250.magnetometer[0]); 00134 sakuraio.enqueueTx(11, sensor_data.mpu9250.magnetometer[1]); 00135 sakuraio.enqueueTx(12, sensor_data.mpu9250.magnetometer[2]); 00136 sakuraio.enqueueTx(13, gps_decoder.get_longitude()); 00137 sakuraio.enqueueTx(14, gps_decoder.get_latitude()); 00138 sakuraio.enqueueTx(15, gps_decoder.get_unixtime()); 00139 } 00140 00141 void gps_uart_buffering_handler() 00142 { 00143 while (gps.readable() == 1) { 00144 char c = gps.getc(); 00145 if (c == '\r') { 00146 continue; 00147 } 00148 uart_buffer[uart_buffer_index] = c; 00149 uart_buffer_index++; 00150 if (c == '\n') { 00151 uart_buffer[uart_buffer_index - 1] = '\0'; 00152 gps_decoder.set_nmea_message(uart_buffer); 00153 gps_decoder.decode(); 00154 uart_buffer_index = 0; 00155 } 00156 } 00157 } 00158 00159 00160 void loop() 00161 { 00162 static int cnt_send = 1; 00163 static int tick_by_200ms = 0; 00164 static int stat_sw5 = -1; 00165 uint8_t rx_available = 0; 00166 uint8_t rx_queued = 0; 00167 uint8_t rx_ch=0; 00168 uint8_t rx_type=0; 00169 uint8_t rx_value[8]; 00170 int64_t rx_offset=0; 00171 int64_t rx_val; 00172 uint32_t tx_tmp; 00173 uint8_t ch20_ctrl; 00174 uint32_t ch20_id; 00175 uint8_t ch20_mesg; 00176 00177 if((sakuraio.getConnectionStatus() & 0x80) == 0x00) { 00178 //Offline 00179 lcd.cls(); 00180 lcd.printf("Offline"); 00181 pc.printf("Network is offline.\r\n(After 1 sec to running retry.)\r\n"); 00182 wait(1); 00183 connected_now = 0; 00184 return; 00185 } 00186 else { 00187 //ON_LINEだったとき 00188 if(0 == connected_now){ 00189 //接続直後(直前までオフラインだった)時 00190 00191 //現在のLED状態を申告する送信 00192 tx_tmp = (MESG_INIT << 8) | (lcd_led & 0xFF); 00193 sakuraio.enqueueTx(20, tx_tmp); 00194 sakuraio.send(); 00195 00196 //接続直後でLED情報送信中 00197 connected_now = 1; 00198 00199 //過去の送信カウント数クリアと、Offlineになってしまった液晶のsend再表示の為 00200 stat_sw5 = -1; 00201 } 00202 if(1 == connected_now){ 00203 //現在のLED状態を申告に対する応答がプラットフォームから帰ってきてない時 00204 if((tick_by_200ms % RETRY_INTERVAL_TICKS_PAR_COUNT) == 0){ 00205 //一定時間経過していたら再度LED状態を申告 00206 tx_tmp = (MESG_INIT<<8) | (lcd_led & 0xFF); 00207 sakuraio.enqueueTx(20, tx_tmp); 00208 sakuraio.send(); 00209 } 00210 } 00211 } 00212 00213 00214 00215 //スイッチ状態が切り替わった時、もしくは、LTE接続が一旦切れて復帰した時 00216 if (stat_sw5 != sw_5) { 00217 stat_sw5 = sw_5; 00218 led_3 = stat_sw5; //State: `Send Enable' 00219 if (stat_sw5 == 0) { 00220 lcd.cls(); 00221 lcd.printf("Send:OFF"); 00222 } else { 00223 cnt_send = 1; 00224 tick_by_200ms = 0; 00225 lcd.cls(); 00226 lcd.printf("Send:ON"); 00227 } 00228 } 00229 00230 if (stat_sw5 == 1) { 00231 //送信スイッチONの時。送信処理開始 00232 if ((tick_by_200ms % SEND_INTERVAL_TICKS_PAR_COUNT) == 0) { //Send data intarval is 5 minutes. 00233 pc.printf("\r\n\r\n--------------------\r\n"); 00234 read_sensor_data(); 00235 pc.printf("BME280\r\n"); 00236 pc.printf("\tTemp: %.2fC\r\n", sensor_data.bme280.temperature); 00237 pc.printf("\tPres: %.2fhPa\r\n", sensor_data.bme280.pressure); 00238 pc.printf("\tHum: %.2f%%\r\n", sensor_data.bme280.humidity); 00239 pc.printf("MPU9250\r\n"); 00240 pc.printf("\tTemp: %.2fC\r\n", sensor_data.mpu9250.temperature); 00241 for (int j = 0; j < 3; j++) { 00242 pc.printf("\tacc[%d]: %.2f\r\n", j, sensor_data.mpu9250.accelerometer[j]); 00243 pc.printf("\tgyro[%d]: %.2f\r\n", j, sensor_data.mpu9250.gyroscope[j]); 00244 pc.printf("\tmag[%d]: %.2f\r\n", j, sensor_data.mpu9250.magnetometer[j]); 00245 } 00246 pc.printf("GPS\r\n"); 00247 pc.printf("\tlat: %f%c\r\n", 00248 gps_decoder.get_latitude(), 00249 gps_decoder.get_latitude() >= 0 ? 'N' : 'S'); 00250 pc.printf("\tlon: %f%c\r\n", 00251 gps_decoder.get_longitude(), 00252 gps_decoder.get_longitude() >= 0 ? 'E' : 'W'); 00253 pc.printf("\tspeed: %fkm/h\r\n", gps_decoder.get_speed()); 00254 pc.printf("\tmove_direction: %f\r\n", gps_decoder.get_move_direction()); 00255 pc.printf("\tdate: %d/%02d/%02d %02d:%02d:%02d (UTC)\r\n", 00256 gps_decoder.get_year(), gps_decoder.get_month(), gps_decoder.get_day(), 00257 gps_decoder.get_hour(), gps_decoder.get_min(), gps_decoder.get_sec()); 00258 pc.printf("\tUNIX time: %d\r\n", gps_decoder.get_unixtime()); 00259 led_2 = 1; 00260 pc.printf("Send:%d\r\n", cnt_send); 00261 lcd.setCursor(0, 1); 00262 lcd.printf("%d", cnt_send); 00263 enqueue_sensor_data(cnt_send); 00264 sakuraio.send(); 00265 cnt_send++; 00266 led_2 = 0; 00267 pc.printf("After %d sec to send.\r\n", (int)(SEND_INTERVAL_TICKS_PAR_COUNT * 0.2)); 00268 } 00269 } 00270 00271 //受信確認処理 00272 do { 00273 rx_available = 0; 00274 if ( CMD_ERROR_NONE == sakuraio.getRxQueueLength(&rx_available, &rx_queued)) { 00275 //getRxQueueLengthが成功したとき 00276 if (0 < rx_queued) { 00277 //sakura.ioモジュールの受信キューにデータが入っているとき 00278 //キューからひとつデータを取り出す 00279 if ( CMD_ERROR_NONE == sakuraio.dequeueRx(&rx_ch, &rx_type, rx_value, &rx_offset)) { 00280 //正常に受信キューからデータを取り出せたとき 00281 if ( (20 == rx_ch) && (0x49 == rx_type) ) { 00282 //LED状態の要求、もしくは、LED状態申告の回答のとき 00283 00284 //受信した32bit整数値が、8bit値が4つの配列になって届くので、ひとつの整数値に整形 00285 rx_val = ( (int64_t)rx_value[3] << 24) + ( (int64_t)rx_value[2] << 16) + ( (int64_t)rx_value[1] << 8) + ( (int64_t)rx_value[0] << 0); 00286 00287 //受信した32bit値からbitmapに従ってそれぞれの情報の切り出し 00288 ch20_ctrl = rx_val & 0xFF; 00289 ch20_mesg = (rx_val>>8) & 0xFF; 00290 ch20_id = (rx_val>>16) & 0xFFFF; 00291 00292 00293 if ( (1 == ch20_ctrl) && (MESG_NORMAL == ch20_mesg)) { 00294 //LED状態の要求だったとき 00295 tx_tmp = (ch20_id<<16) | (MESG_NORMAL<<8) | (lcd_led & 0xFF); 00296 sakuraio.enqueueTx(20, tx_tmp); 00297 sakuraio.send(); 00298 } 00299 if ( (1 == ch20_ctrl) && (MESG_INIT == ch20_mesg)) { 00300 //LED状態申告の回答だったとき 00301 //フラグを進めて、LED状態到達確認済みとし、再送処理を止める 00302 connected_now = 2; 00303 } 00304 } 00305 if ( (21 == rx_ch) && (0x49 == rx_type) ) { 00306 //LED設定のとき 00307 00308 //受信した32bit整数値が、8bit値が4つの配列になって届くので、ひとつの整数値に整形 00309 rx_val = ( (int64_t)rx_value[3] << 24) + ( (int64_t)rx_value[2] << 16) + ( (int64_t)rx_value[1] << 8) + ( (int64_t)rx_value[0] << 0); 00310 00311 //受信した32bit値からbitmapに従ってそれぞれの情報の切り出し 00312 ch20_ctrl = rx_val & 0xFF; 00313 ch20_mesg = (rx_val>>8) & 0xFF; 00314 ch20_id = (rx_val>>16) & 0xFFFF; 00315 00316 00317 if ( 1 == ch20_ctrl || 0 == ch20_ctrl ) { 00318 //LED制御値が、0(OFF) or 1(ON)だったとき 00319 00320 //LEDに制御値を設定 00321 lcd_led = ch20_ctrl; 00322 00323 //設定後の値をプラットフォームへ返送 00324 tx_tmp = (ch20_id<<16) | (MESG_NORMAL<<8) | (lcd_led & 0xFF); 00325 sakuraio.enqueueTx(20, tx_tmp); 00326 sakuraio.send(); 00327 } 00328 } 00329 } 00330 } 00331 } 00332 }while(0 < rx_queued); //受信キューが空になるまで回す 00333 00334 00335 00336 led_1 = !led_1; 00337 led_4 = !sw_4; 00338 tick_by_200ms++; 00339 wait(0.2); 00340 } 00341 00342 00343 int main() 00344 { 00345 setup(); 00346 while(1) { 00347 loop(); 00348 } 00349 }
Generated on Fri Jul 15 2022 13:55:31 by
1.7.2
SAKURA Internet