sakura.io Evalution board's example.
Dependencies: AQM0802A BME280 MPU9250_SPI SakuraIO gps mbed
Fork of SakuraIO_Evaluation_Board_Standard by
sakura.io Evalution board's sample program. Collecting the onboard sensors(GPS, 9axis motion sensor, Environment sensor), send to sakura.io service.
main.cpp@11:b7ad0fe7ce64, 2018-08-07 (annotated)
- Committer:
- Fuminori OKUHARA
- Date:
- Tue Aug 07 12:18:37 2018 +0900
- Revision:
- 11:b7ad0fe7ce64
- Parent:
- 8:e92264bc120e
FIX: Removed useless connection check.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Fuminori OKUHARA |
8:e92264bc120e | 1 | #include <mbed.h> |
Fuminori OKUHARA |
8:e92264bc120e | 2 | #include <AQM0802A.h> |
Fuminori OKUHARA |
8:e92264bc120e | 3 | #include <BME280.h> |
Fuminori OKUHARA |
8:e92264bc120e | 4 | #include <MPU9250.h> |
Fuminori OKUHARA |
8:e92264bc120e | 5 | #include <SakuraIO.h> |
Fuminori OKUHARA |
8:e92264bc120e | 6 | #include "SakuraPinNames.h" |
Fuminori OKUHARA |
8:e92264bc120e | 7 | #include "sensors.h" |
Fuminori OKUHARA |
8:e92264bc120e | 8 | #include "gps.h" |
Fuminori OKUHARA |
8:e92264bc120e | 9 | |
Fuminori OKUHARA |
8:e92264bc120e | 10 | // Serial over CMSIS_DAP |
Fuminori OKUHARA |
8:e92264bc120e | 11 | Serial pc(DAP_UART_TX, DAP_UART_RX, 9600); |
Fuminori OKUHARA |
8:e92264bc120e | 12 | |
Fuminori OKUHARA |
8:e92264bc120e | 13 | // GPS |
Fuminori OKUHARA |
8:e92264bc120e | 14 | Serial gps(GPS_TX, GPS_RX, 9600); |
Fuminori OKUHARA |
8:e92264bc120e | 15 | DigitalOut gps_en(GPS_EN); |
Fuminori OKUHARA |
8:e92264bc120e | 16 | |
Fuminori OKUHARA |
8:e92264bc120e | 17 | // LED |
Fuminori OKUHARA |
8:e92264bc120e | 18 | DigitalOut led_1(LED1); |
Fuminori OKUHARA |
8:e92264bc120e | 19 | DigitalOut led_2(LED2); |
Fuminori OKUHARA |
8:e92264bc120e | 20 | DigitalOut led_3(LED3); |
Fuminori OKUHARA |
8:e92264bc120e | 21 | DigitalOut led_4(LED4); |
Fuminori OKUHARA |
8:e92264bc120e | 22 | |
Fuminori OKUHARA |
8:e92264bc120e | 23 | // LCD backlight |
Fuminori OKUHARA |
8:e92264bc120e | 24 | DigitalOut lcd_led(LED_LCD); |
Fuminori OKUHARA |
8:e92264bc120e | 25 | |
Fuminori OKUHARA |
8:e92264bc120e | 26 | // Switch |
Fuminori OKUHARA |
8:e92264bc120e | 27 | DigitalIn sw_1(SW1); |
Fuminori OKUHARA |
8:e92264bc120e | 28 | DigitalIn sw_2(SW2); |
Fuminori OKUHARA |
8:e92264bc120e | 29 | DigitalIn sw_3(SW3); |
Fuminori OKUHARA |
8:e92264bc120e | 30 | DigitalIn sw_4(SW4); |
Fuminori OKUHARA |
8:e92264bc120e | 31 | DigitalIn sw_5(SW5); |
Fuminori OKUHARA |
8:e92264bc120e | 32 | DigitalIn sw_6(SW6); |
Fuminori OKUHARA |
8:e92264bc120e | 33 | |
Fuminori OKUHARA |
8:e92264bc120e | 34 | // Internal I2C |
Fuminori OKUHARA |
8:e92264bc120e | 35 | I2C internal_i2c(I2C_INTERNAL_SDA, I2C_INTERNAL_SCL); |
Fuminori OKUHARA |
8:e92264bc120e | 36 | AQM0802A lcd(internal_i2c); |
Fuminori OKUHARA |
8:e92264bc120e | 37 | BME280 bme280(internal_i2c); |
Fuminori OKUHARA |
8:e92264bc120e | 38 | |
Fuminori OKUHARA |
8:e92264bc120e | 39 | // SPI |
Fuminori OKUHARA |
8:e92264bc120e | 40 | SPI internal_mpu9250_spi(SPI_MPU_MOSI, SPI_MPU_MISO, SPI_MPU_SCK); |
Fuminori OKUHARA |
8:e92264bc120e | 41 | mpu9250_spi mpu9250(internal_mpu9250_spi, SPI_MPU_CS); |
Fuminori OKUHARA |
8:e92264bc120e | 42 | |
Fuminori OKUHARA |
8:e92264bc120e | 43 | // sakura.io |
Fuminori OKUHARA |
8:e92264bc120e | 44 | SakuraIO_I2C sakuraio(I2C_SDA, I2C_SCL); |
Fuminori OKUHARA |
8:e92264bc120e | 45 | |
Fuminori OKUHARA |
8:e92264bc120e | 46 | SensorData sensor_data; |
Fuminori OKUHARA |
8:e92264bc120e | 47 | |
Fuminori OKUHARA |
8:e92264bc120e | 48 | // GPS UART buffer |
Fuminori OKUHARA |
8:e92264bc120e | 49 | char uart_buffer[128] = {0}; |
Fuminori OKUHARA |
8:e92264bc120e | 50 | int uart_buffer_index = 0; |
Fuminori OKUHARA |
8:e92264bc120e | 51 | |
Fuminori OKUHARA |
8:e92264bc120e | 52 | // NMEA Decoder |
Fuminori OKUHARA |
8:e92264bc120e | 53 | GPSDecoder gps_decoder; |
Fuminori OKUHARA |
8:e92264bc120e | 54 | |
Fuminori OKUHARA |
8:e92264bc120e | 55 | void gps_uart_buffering_handler(); |
Fuminori OKUHARA |
8:e92264bc120e | 56 | |
Fuminori OKUHARA |
8:e92264bc120e | 57 | const int SEND_INTERVAL_TICKS_PAR_COUNT = 1500; |
Fuminori OKUHARA |
8:e92264bc120e | 58 | |
Fuminori OKUHARA |
8:e92264bc120e | 59 | void setup() |
Fuminori OKUHARA |
8:e92264bc120e | 60 | { |
Fuminori OKUHARA |
8:e92264bc120e | 61 | lcd_led = 1; |
Fuminori OKUHARA |
8:e92264bc120e | 62 | pc.printf("Hello World !\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 63 | lcd.cls(); |
Fuminori OKUHARA |
8:e92264bc120e | 64 | lcd.printf("Hello"); |
Fuminori OKUHARA |
8:e92264bc120e | 65 | |
Fuminori OKUHARA |
8:e92264bc120e | 66 | // Initialize sensors |
Fuminori OKUHARA |
8:e92264bc120e | 67 | bme280.initialize(); |
Fuminori OKUHARA |
8:e92264bc120e | 68 | pc.printf("BME280 ok.\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 69 | mpu9250.init(1, BITS_DLPF_CFG_188HZ); |
Fuminori OKUHARA |
8:e92264bc120e | 70 | pc.printf("MPU9250 ok. WHOAMI=%02x\r\n", mpu9250.whoami()); |
Fuminori OKUHARA |
8:e92264bc120e | 71 | if (mpu9250.whoami() != 0x71) { |
Fuminori OKUHARA |
8:e92264bc120e | 72 | pc.printf("[ERROR] MPU9250 init fail.\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 73 | } |
Fuminori OKUHARA |
8:e92264bc120e | 74 | |
Fuminori OKUHARA |
8:e92264bc120e | 75 | mpu9250.set_gyro_scale(BITS_FS_2000DPS); //Set full scale range for gyros |
Fuminori OKUHARA |
8:e92264bc120e | 76 | mpu9250.set_acc_scale(BITS_FS_16G); //Set full scale range for accs |
Fuminori OKUHARA |
8:e92264bc120e | 77 | mpu9250.calib_acc(); |
Fuminori OKUHARA |
8:e92264bc120e | 78 | mpu9250.AK8963_calib_Magnetometer(); |
Fuminori OKUHARA |
8:e92264bc120e | 79 | |
Fuminori OKUHARA |
8:e92264bc120e | 80 | // active high |
Fuminori OKUHARA |
8:e92264bc120e | 81 | gps_en = 1; |
Fuminori OKUHARA |
8:e92264bc120e | 82 | gps.attach(&gps_uart_buffering_handler, Serial::RxIrq); |
Fuminori OKUHARA |
8:e92264bc120e | 83 | |
Fuminori OKUHARA |
8:e92264bc120e | 84 | led_1 = 1; |
Fuminori OKUHARA |
8:e92264bc120e | 85 | led_2 = 0; |
Fuminori OKUHARA |
8:e92264bc120e | 86 | |
Fuminori OKUHARA |
8:e92264bc120e | 87 | pc.printf("Send par %d seconds.\r\n", (SEND_INTERVAL_TICKS_PAR_COUNT * 200) / 1000); |
Fuminori OKUHARA |
8:e92264bc120e | 88 | } |
Fuminori OKUHARA |
8:e92264bc120e | 89 | |
Fuminori OKUHARA |
8:e92264bc120e | 90 | void read_sensor_data() |
Fuminori OKUHARA |
8:e92264bc120e | 91 | { |
Fuminori OKUHARA |
8:e92264bc120e | 92 | sensor_data.bme280.temperature = bme280.getTemperature(); |
Fuminori OKUHARA |
8:e92264bc120e | 93 | sensor_data.bme280.pressure = bme280.getPressure(); |
Fuminori OKUHARA |
8:e92264bc120e | 94 | sensor_data.bme280.humidity = bme280.getHumidity(); |
Fuminori OKUHARA |
8:e92264bc120e | 95 | |
Fuminori OKUHARA |
8:e92264bc120e | 96 | mpu9250.read_all(); |
Fuminori OKUHARA |
8:e92264bc120e | 97 | sensor_data.mpu9250.temperature = mpu9250.Temperature; |
Fuminori OKUHARA |
8:e92264bc120e | 98 | for (int cnt_send = 0; cnt_send < 3; cnt_send++) { |
Fuminori OKUHARA |
8:e92264bc120e | 99 | sensor_data.mpu9250.accelerometer[cnt_send] = mpu9250.accelerometer_data[cnt_send]; |
Fuminori OKUHARA |
8:e92264bc120e | 100 | sensor_data.mpu9250.gyroscope[cnt_send] = mpu9250.gyroscope_data[cnt_send]; |
Fuminori OKUHARA |
8:e92264bc120e | 101 | sensor_data.mpu9250.magnetometer[cnt_send] = mpu9250.Magnetometer[cnt_send]; |
Fuminori OKUHARA |
8:e92264bc120e | 102 | } |
Fuminori OKUHARA |
8:e92264bc120e | 103 | } |
Fuminori OKUHARA |
8:e92264bc120e | 104 | |
Fuminori OKUHARA |
8:e92264bc120e | 105 | void enqueue_sensor_data(int counter) |
Fuminori OKUHARA |
8:e92264bc120e | 106 | { |
Fuminori OKUHARA |
8:e92264bc120e | 107 | sakuraio.enqueueTx(0, (int32_t)counter); |
Fuminori OKUHARA |
8:e92264bc120e | 108 | sakuraio.enqueueTx(1, sensor_data.bme280.temperature); |
Fuminori OKUHARA |
8:e92264bc120e | 109 | sakuraio.enqueueTx(2, sensor_data.bme280.pressure); |
Fuminori OKUHARA |
8:e92264bc120e | 110 | sakuraio.enqueueTx(3, sensor_data.bme280.humidity); |
Fuminori OKUHARA |
8:e92264bc120e | 111 | sakuraio.enqueueTx(4, sensor_data.mpu9250.accelerometer[0]); |
Fuminori OKUHARA |
8:e92264bc120e | 112 | sakuraio.enqueueTx(5, sensor_data.mpu9250.accelerometer[1]); |
Fuminori OKUHARA |
8:e92264bc120e | 113 | sakuraio.enqueueTx(6, sensor_data.mpu9250.accelerometer[2]); |
Fuminori OKUHARA |
8:e92264bc120e | 114 | sakuraio.enqueueTx(7, sensor_data.mpu9250.gyroscope[0]); |
Fuminori OKUHARA |
8:e92264bc120e | 115 | sakuraio.enqueueTx(8, sensor_data.mpu9250.gyroscope[1]); |
Fuminori OKUHARA |
8:e92264bc120e | 116 | sakuraio.enqueueTx(9, sensor_data.mpu9250.gyroscope[2]); |
Fuminori OKUHARA |
8:e92264bc120e | 117 | sakuraio.enqueueTx(10, sensor_data.mpu9250.magnetometer[0]); |
Fuminori OKUHARA |
8:e92264bc120e | 118 | sakuraio.enqueueTx(11, sensor_data.mpu9250.magnetometer[1]); |
Fuminori OKUHARA |
8:e92264bc120e | 119 | sakuraio.enqueueTx(12, sensor_data.mpu9250.magnetometer[2]); |
Fuminori OKUHARA |
8:e92264bc120e | 120 | sakuraio.enqueueTx(13, gps_decoder.get_longitude()); |
Fuminori OKUHARA |
8:e92264bc120e | 121 | sakuraio.enqueueTx(14, gps_decoder.get_latitude()); |
Fuminori OKUHARA |
8:e92264bc120e | 122 | sakuraio.enqueueTx(15, gps_decoder.get_unixtime()); |
Fuminori OKUHARA |
8:e92264bc120e | 123 | } |
Fuminori OKUHARA |
8:e92264bc120e | 124 | |
Fuminori OKUHARA |
8:e92264bc120e | 125 | void gps_uart_buffering_handler() |
Fuminori OKUHARA |
8:e92264bc120e | 126 | { |
Fuminori OKUHARA |
8:e92264bc120e | 127 | while (gps.readable() == 1) { |
Fuminori OKUHARA |
8:e92264bc120e | 128 | char c = gps.getc(); |
Fuminori OKUHARA |
8:e92264bc120e | 129 | if (c == '\r') { |
Fuminori OKUHARA |
8:e92264bc120e | 130 | continue; |
Fuminori OKUHARA |
8:e92264bc120e | 131 | } |
Fuminori OKUHARA |
8:e92264bc120e | 132 | uart_buffer[uart_buffer_index] = c; |
Fuminori OKUHARA |
8:e92264bc120e | 133 | uart_buffer_index++; |
Fuminori OKUHARA |
8:e92264bc120e | 134 | if (c == '\n') { |
Fuminori OKUHARA |
8:e92264bc120e | 135 | uart_buffer[uart_buffer_index - 1] = '\0'; |
Fuminori OKUHARA |
8:e92264bc120e | 136 | gps_decoder.set_nmea_message(uart_buffer); |
Fuminori OKUHARA |
8:e92264bc120e | 137 | gps_decoder.decode(); |
Fuminori OKUHARA |
8:e92264bc120e | 138 | uart_buffer_index = 0; |
Fuminori OKUHARA |
8:e92264bc120e | 139 | } |
Fuminori OKUHARA |
8:e92264bc120e | 140 | } |
Fuminori OKUHARA |
8:e92264bc120e | 141 | } |
Fuminori OKUHARA |
8:e92264bc120e | 142 | |
Fuminori OKUHARA |
8:e92264bc120e | 143 | |
Fuminori OKUHARA |
8:e92264bc120e | 144 | void loop() |
Fuminori OKUHARA |
8:e92264bc120e | 145 | { |
Fuminori OKUHARA |
8:e92264bc120e | 146 | static int cnt_send = 1; |
Fuminori OKUHARA |
8:e92264bc120e | 147 | static int tick_by_200ms = 0; |
Fuminori OKUHARA |
8:e92264bc120e | 148 | static int stat_sw5 = -1; |
Fuminori OKUHARA |
8:e92264bc120e | 149 | |
Fuminori OKUHARA |
8:e92264bc120e | 150 | if((sakuraio.getConnectionStatus() & 0x80) == 0x00) { |
Fuminori OKUHARA |
8:e92264bc120e | 151 | //Offline |
Fuminori OKUHARA |
8:e92264bc120e | 152 | lcd.cls(); |
Fuminori OKUHARA |
8:e92264bc120e | 153 | lcd.printf("Offline"); |
Fuminori OKUHARA |
8:e92264bc120e | 154 | pc.printf("Network is offline.\r\n(After 1 sec to running retry.)\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 155 | wait(1); |
Fuminori OKUHARA |
8:e92264bc120e | 156 | return; |
Fuminori OKUHARA |
8:e92264bc120e | 157 | } |
Fuminori OKUHARA |
8:e92264bc120e | 158 | |
Fuminori OKUHARA |
8:e92264bc120e | 159 | if (stat_sw5 != sw_5) { |
Fuminori OKUHARA |
8:e92264bc120e | 160 | stat_sw5 = sw_5; |
Fuminori OKUHARA |
8:e92264bc120e | 161 | led_3 = stat_sw5; //State: `Send Enable' |
Fuminori OKUHARA |
8:e92264bc120e | 162 | if (stat_sw5 == 0) { |
Fuminori OKUHARA |
8:e92264bc120e | 163 | lcd.cls(); |
Fuminori OKUHARA |
8:e92264bc120e | 164 | lcd.printf("Send:OFF"); |
Fuminori OKUHARA |
8:e92264bc120e | 165 | } else { |
Fuminori OKUHARA |
8:e92264bc120e | 166 | cnt_send = 1; |
Fuminori OKUHARA |
8:e92264bc120e | 167 | tick_by_200ms = 0; |
Fuminori OKUHARA |
8:e92264bc120e | 168 | lcd.cls(); |
Fuminori OKUHARA |
8:e92264bc120e | 169 | lcd.printf("Send:ON"); |
Fuminori OKUHARA |
8:e92264bc120e | 170 | } |
Fuminori OKUHARA |
8:e92264bc120e | 171 | } |
Fuminori OKUHARA |
8:e92264bc120e | 172 | |
Fuminori OKUHARA |
8:e92264bc120e | 173 | if (stat_sw5 == 1) { |
Fuminori OKUHARA |
8:e92264bc120e | 174 | if ((tick_by_200ms % SEND_INTERVAL_TICKS_PAR_COUNT) == 0) { //Send data intarval is 5 minutes. |
Fuminori OKUHARA |
8:e92264bc120e | 175 | pc.printf("\r\n\r\n--------------------\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 176 | read_sensor_data(); |
Fuminori OKUHARA |
8:e92264bc120e | 177 | pc.printf("BME280\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 178 | pc.printf("\tTemp: %.2fC\r\n", sensor_data.bme280.temperature); |
Fuminori OKUHARA |
8:e92264bc120e | 179 | pc.printf("\tPres: %.2fhPa\r\n", sensor_data.bme280.pressure); |
Fuminori OKUHARA |
8:e92264bc120e | 180 | pc.printf("\tHum: %.2f%%\r\n", sensor_data.bme280.humidity); |
Fuminori OKUHARA |
8:e92264bc120e | 181 | pc.printf("MPU9250\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 182 | pc.printf("\tTemp: %.2fC\r\n", sensor_data.mpu9250.temperature); |
Fuminori OKUHARA |
8:e92264bc120e | 183 | for (int j = 0; j < 3; j++) { |
Fuminori OKUHARA |
8:e92264bc120e | 184 | pc.printf("\tacc[%d]: %.2f\r\n", j, sensor_data.mpu9250.accelerometer[j]); |
Fuminori OKUHARA |
8:e92264bc120e | 185 | pc.printf("\tgyro[%d]: %.2f\r\n", j, sensor_data.mpu9250.gyroscope[j]); |
Fuminori OKUHARA |
8:e92264bc120e | 186 | pc.printf("\tmag[%d]: %.2f\r\n", j, sensor_data.mpu9250.magnetometer[j]); |
Fuminori OKUHARA |
8:e92264bc120e | 187 | } |
Fuminori OKUHARA |
8:e92264bc120e | 188 | pc.printf("GPS\r\n"); |
Fuminori OKUHARA |
8:e92264bc120e | 189 | pc.printf("\tlat: %f%c\r\n", |
Fuminori OKUHARA |
8:e92264bc120e | 190 | gps_decoder.get_latitude(), |
Fuminori OKUHARA |
8:e92264bc120e | 191 | gps_decoder.get_latitude() >= 0 ? 'N' : 'S'); |
Fuminori OKUHARA |
8:e92264bc120e | 192 | pc.printf("\tlon: %f%c\r\n", |
Fuminori OKUHARA |
8:e92264bc120e | 193 | gps_decoder.get_longitude(), |
Fuminori OKUHARA |
8:e92264bc120e | 194 | gps_decoder.get_longitude() >= 0 ? 'E' : 'W'); |
Fuminori OKUHARA |
8:e92264bc120e | 195 | pc.printf("\tspeed: %fkm/h\r\n", gps_decoder.get_speed()); |
Fuminori OKUHARA |
8:e92264bc120e | 196 | pc.printf("\tmove_direction: %f\r\n", gps_decoder.get_move_direction()); |
Fuminori OKUHARA |
8:e92264bc120e | 197 | pc.printf("\tdate: %d/%02d/%02d %02d:%02d:%02d (UTC)\r\n", |
Fuminori OKUHARA |
8:e92264bc120e | 198 | gps_decoder.get_year(), gps_decoder.get_month(), gps_decoder.get_day(), |
Fuminori OKUHARA |
8:e92264bc120e | 199 | gps_decoder.get_hour(), gps_decoder.get_min(), gps_decoder.get_sec()); |
Fuminori OKUHARA |
8:e92264bc120e | 200 | pc.printf("\tUNIX time: %d\r\n", gps_decoder.get_unixtime()); |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 201 | led_2 = 1; |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 202 | pc.printf("Send:%d\r\n", cnt_send); |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 203 | lcd.setCursor(0, 1); |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 204 | lcd.printf("%d", cnt_send); |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 205 | enqueue_sensor_data(cnt_send); |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 206 | sakuraio.send(); |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 207 | cnt_send++; |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 208 | led_2 = 0; |
Fuminori OKUHARA |
11:b7ad0fe7ce64 | 209 | pc.printf("After %d sec to send.\r\n", (int)(SEND_INTERVAL_TICKS_PAR_COUNT * 0.2)); |
Fuminori OKUHARA |
8:e92264bc120e | 210 | } |
Fuminori OKUHARA |
8:e92264bc120e | 211 | } |
Fuminori OKUHARA |
8:e92264bc120e | 212 | led_1 = !led_1; |
Fuminori OKUHARA |
8:e92264bc120e | 213 | led_4 = !sw_4; |
Fuminori OKUHARA |
8:e92264bc120e | 214 | tick_by_200ms++; |
Fuminori OKUHARA |
8:e92264bc120e | 215 | wait(0.2); |
Fuminori OKUHARA |
8:e92264bc120e | 216 | } |
Fuminori OKUHARA |
8:e92264bc120e | 217 | |
Fuminori OKUHARA |
8:e92264bc120e | 218 | |
Fuminori OKUHARA |
8:e92264bc120e | 219 | int main() |
Fuminori OKUHARA |
8:e92264bc120e | 220 | { |
Fuminori OKUHARA |
8:e92264bc120e | 221 | setup(); |
Fuminori OKUHARA |
8:e92264bc120e | 222 | while(1) { |
Fuminori OKUHARA |
8:e92264bc120e | 223 | loop(); |
Fuminori OKUHARA |
8:e92264bc120e | 224 | } |
Fuminori OKUHARA |
8:e92264bc120e | 225 | } |