見出し画像

Mbed Connect Cloudの再利用 (各種センサー、WiFi 評価ボード かな?)


ODIN-W2(技適付きWiFiモジュール)の載ったこのIoTボードを昔、入手してました。それをPlatformIOで動作させてみました。いやーいろいろなセンサーが載ってました。

ボード自体は、2018年の下記のイベントでいただきました。楽しかったなぁ~。

この時のイベントの様子は下記で詳しく語っていただいてます。

今回は下記のコンテンツを活用させていただいています。

内容は、【1】LCDに表示、 【2】LED点滅、 【3】温湿度センサーの測定値をLCDに表示、【4】 空気センサーの測定値をLCDに表示、 【5】光度センサーの測定値をLCDに表示、 【6】加速度センサーの測定値をLCDに表示、 【7】距離センサーの測定値をLCDに表示

1.  Mbed Connect Cloudとは?

Mbed Connect Cloudとは、センサなどの載ったプログラム可能WiFIボードです。載っているデバイスは下記です。

・ODIN-W2:WiFiモジュール(技適付き)

・LPC11U35:DAP Link = デバッガーインターフェース。

C12832:LCDディスプレイ

SHT31:温湿度センサー

CSS811:空気センサー

TSL2561:光度センサー

MMA7660:加速度センサー

・vl53l0x:距離センサー

設計資料は下記で公開されています。

2.開発環境の準備

 基本的な環境構築は下記と同様です。

Boardは [u-blox ODIN-W2] を選択して初期環境を立ち上げます。

画像1

platformio.iniを下記のように書き換えます。mbed_connect_odin が用意されているので楽でした。デバッガーも,cmsis-dapが接続できました。

[env:mbed_connect_odin]
platform = ststm32
board = mbed_connect_odin
framework = mbed
debug_tool = cmsis-dap
upload_protocol = cmsis-dap
build_flags = -D PIO_FRAMEWORK_MBED_RTOS_PRESENT

3. ライブラリーの入手先

zipで添付するので、そちらを使うほうが最初は楽かもしれません。

C12832のライブラリは、下記から入手します。

SHT31のライブラリを下記から入手します。

CSS811のライブラリを下記から入手します。

TSL2561のライブラリを下記から入手します。

MMA7660のライブラリを下記から入手します。

4. C21832ライブラリの修正

ライブラリが古いmbedのバージョン対応なので、最新の環境に適応させると、エラーが発生します。下記の修正が必要です。

C21832.cpp の修正(misoの設定のNCのままにするとエラーが出る。)

修正箇所[修正前]

C12832::C12832(PinName mosi,  PinName sck, PinName reset, PinName a0, PinName ncs, const char* name)
   : _spi(mosi,NC,sck),_reset(reset),_A0(a0),_CS(ncs),GraphicsDisplay(name)

修正箇所[修正後]

C12832::C12832(PinName mosi, PinName miso, PinName sck, PinName reset, PinName a0, PinName ncs, const char* name)
   : _spi(mosi,miso,sck),_reset(reset),_A0(a0),_CS(ncs),GraphicsDisplay(name)

C21832.h の修正

修正箇所[修正前]

    C12832(PinName mosi, PinName sck, PinName reset, PinName a0, PinName ncs, const char* name = "LCD");

修正箇所[修正後]

    C12832(PinName mosi, PinName miso, PinName sck, PinName reset, PinName a0, PinName ncs, const char* name = "LCD");

こんなエラー、実行に出るので、修正が必要でした。あせった。

++ MbedOS Error Info ++
Error Status: 0x80FF0144 Code: 324 Module: 255
Error Message: Assertion failed: pin != (PinName)NC
Location: 0x80020E9
File: C:\Users\hiroa\.platformio\packages\framework-mbed@6.51506.201227\targets\TARGET_STM\pinmap.c+62
Error Value: 0x0
Current Thread: main Id: 0x20005290 Entry: 0x8003047 StackSize: 0x1000 StackMem: 0x20006038 SP: 0x20006EE4
For more info, visit: https://mbed.com/s/error?error=0x80FF0144&tgt=MBED_CONNECT_ODIN
-- MbedOS Error Info --

5. 実際のコードと実行結果

5.0.ベースのコード

下記のベースのコードに、各機能のコードを追加していきます。

#include "mbed.h"
#include "C12832.h"
#include "CCS811.h"
#include "Sht31.h"
#include "TSL2561.h"
#include "MMA7660.h"
// GLOBAL VARIABLES HERE

// FUNCTION DEFINTIONS HERE

int main() {
   // MAIN CODE HERE

}

5.1. LCD実行コード

ベースコードにC12832の表示に必要なコードを下記のように追記して実行します。

#include "mbed.h"
#include "C12832.h"

// GLOBAL VARIABLES HERE
C12832  lcd( PE_14 , PE_13 , PE_12 , PD_12  , PD_11 , PE_9 );

// FUNCTION DEFINTIONS HERE
void lcd_print(const char* message) {
   lcd.cls();
   lcd.locate(0, 3);
   lcd.printf(message);
}

int main() {
   // MAIN CODE HERE
   lcd_print("Hello World!");
}

実行結果はLCDに [ Helllo World ] が表示されます。

5.2. LEDトグル実行コード

ベースコードにLEDトグル実行コードに必要なコードを下記のように追記して実行します。

#include "mbed.h"

// GLOBAL VARIABLES HERE
DigitalOut  led(PB_8, 1);
InterruptIn button(PF_2);

// FUNCTION DEFINTIONS HERE
void toggle_led() {
   led = !led;
}

int main() {
   // MAIN CODE HERE
   button.rise(&toggle_led);
}

SW2を押すごとにLEDが点滅します。

5.3. 温湿度センサーの測定値をLCDに表示

ベースコードC12832の表示のコードに、温湿度センサー(SHT31)の測定値の表示に必要なコードを下記のように追記して実行します。

#include "mbed.h"
#include "C12832.h"
#include "Sht31.h"

// GLOBAL VARIABLES HERE
C12832  lcd( PE_14 , PE_13 , PE_12 , PD_12  , PD_11 , PE_9 );
Sht31   temp_sensor(PF_0, PF_1);

// FUNCTION DEFINTIONS HERE
void lcd_print(const char* message) {
  lcd.cls();
  lcd.locate(0, 3);
  lcd.printf(message);
}
void read_temp() {
   float t = temp_sensor.readTemperature();
   float h = temp_sensor.readHumidity();
   char val[32];
   sprintf(val, "TEMP: %3.2fC, HUM: %3.2f%%", t, h);
   lcd_print(val);
}

int main() {

   // MAIN CODE HERE
   while(1) {
       read_temp();
       thread_sleep_for(2000);
   }
}

実行結果はLCDに [ TEMP:  30.41C,  HUM:  55.57  ] のように表示されます。

5.4. 空気センサーの測定値をLCDに表示

ベースコードC12832の表示のコードに、空気センサー(CCS811)の測定値の表示に必要なコードを下記のように追記して実行します。

#include "mbed.h"
#include "C12832.h"
#include "CCS811.h"

// GLOBAL VARIABLES HERE
C12832  lcd( PE_14 , PE_13 , PE_12 , PD_12  , PD_11 , PE_9 );
CCS811  air_sensor(PF_0, PF_1);

// FUNCTION DEFINTIONS HERE
void lcd_print(const char* message) {
  lcd.cls();
  lcd.locate(0, 3);
  lcd.printf(message);
}
void read_air() {
   air_sensor.init();
   uint16_t eco2, tvoc;
   air_sensor.readData(&eco2, &tvoc);
   char val[32];
   sprintf(val, "eCO2: %dppm, TVOC: %dppb", eco2, tvoc);
   lcd_print(val);
}

int main() {
   
   // MAIN CODE HERE
   while(1) {
       read_air();
       thread_sleep_for(2000);
   }
}

実行結果はLCDに [ eCOS:  574ppm,  TVOC:  26ppb  ] のように表示されます。

5.5. 光度センサーの測定値をLCDに表示

ベースコードC12832の表示のコードに、光度センサー(TSL2561)の測定値の表示に必要なコードを下記のように追記して実行します。

#include "mbed.h"
#include "C12832.h"
#include "TSL2561.h"

// GLOBAL VARIABLES HERE
C12832  lcd( PE_14 , PE_13 , PE_12 , PD_12  , PD_11 , PE_9 );
TSL2561 light_sensor(PF_0, PF_1, TSL2561_ADDR_HIGH);

// FUNCTION DEFINTIONS HERE
void lcd_print(const char* message) {
  lcd.cls();
  lcd.locate(0, 3);
  lcd.printf(message);
}
void read_light() {
   int vis = light_sensor.getLuminosity(TSL2561_VISIBLE);
   int infr = light_sensor.getLuminosity(TSL2561_INFRARED);
   char val[32];
   sprintf(val, "VIS: %d, INFR: %d ", vis, infr);
   lcd_print(val);
}

int main() {

   // MAIN CODE HERE
   light_sensor.begin();
   light_sensor.setGain(TSL2561_GAIN_0X);
   light_sensor.setTiming(TSL2561_INTEGRATIONTIME_402MS);
   while(1) {
       // WHILE LOOP CODE HERE
       read_light();
       thread_sleep_for(2000);
   }
}

実行結果はLCDに [ VIS:  170,  INFR:  30 ] のように表示されます。

5.6. 加速度センサーの測定値をLCDに表示

ベースコードC12832の表示のコードに、加速度センサー(MMA7660)の測定値の表示に必要なコードを下記のように追記して実行します。

#include "mbed.h"
#include "C12832.h"
#include "MMA7660.h"
// GLOBAL VARIABLES HERE
C12832  lcd( PE_14 , PE_13 , PE_12 , PD_12  , PD_11 , PE_9 );
MMA7660 accel(PF_0, PF_1);
// FUNCTION DEFINTIONS HERE
void lcd_print(const char* message) {
 lcd.cls();
 lcd.locate(0, 3);
 lcd.printf(message);
}
void read_accel() {
   float x = accel.x();
   float y = accel.y();
   float z = accel.z();
   char val[32];
   sprintf(val, "x=%.2f y=%.2f z=%.2f", x, y, z);
   lcd_print(val);
}
int main() {
   printf("Mbed OS version %d.%d.%d\r\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
   while(1) {
       // MAIN CODE HERE
       read_accel();
       thread_sleep_for(2000);
   }
}

実行結果はLCDに [ x=-0.23 y=-0.09 z=0.98 ] のように表示されます。

5.7. 距離センサーの測定値をLCDに表示

ベースコードC12832の表示のコードに、距離センサー(vl53l0x)の測定値の表示に必要なコードを下記のように追記して実行します。

#include "mbed.h"
#include "C12832.h"
#include "vl53l0x_api.h"
#include "vl53l0x_platform.h"
#include "vl53l0x_i2c_platform.h"
#define USE_I2C_2V8
// GLOBAL VARIABLES HERE
/* Sets up LCD and prints sensor data value of Indoor Air Quality sensor to LCD */
C12832  lcd( PE_14 , PE_13 , PE_12 , PD_12  , PD_11 , PE_9 ); //LCD: MISO, MOSI, SCK, RESET, A0, nCS
// FUNCTION DEFINTIONS HERE
VL53L0X_Error WaitMeasurementDataReady(VL53L0X_DEV Dev) {
   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
   uint8_t NewDatReady=0;
   uint32_t LoopNb;
   
   if (Status == VL53L0X_ERROR_NONE) {
       LoopNb = 0;
       do {
           Status = VL53L0X_GetMeasurementDataReady(Dev, &NewDatReady);
           if ((NewDatReady == 0x01) || Status != VL53L0X_ERROR_NONE) {
               break;
           }
           LoopNb = LoopNb + 1;
           VL53L0X_PollingDelay(Dev);
       } while (LoopNb < VL53L0X_DEFAULT_MAX_LOOP);
       if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP) {
           Status = VL53L0X_ERROR_TIME_OUT;
       }
   }
   return Status;
}
VL53L0X_Error WaitStopCompleted(VL53L0X_DEV Dev) {
   VL53L0X_Error Status = VL53L0X_ERROR_NONE;
   uint32_t StopCompleted=0;
   uint32_t LoopNb;
   if (Status == VL53L0X_ERROR_NONE) {
       LoopNb = 0;
       do {
           Status = VL53L0X_GetStopCompletedStatus(Dev, &StopCompleted);
           if ((StopCompleted == 0x00) || Status != VL53L0X_ERROR_NONE) {
               break;
           }
           LoopNb = LoopNb + 1;
           VL53L0X_PollingDelay(Dev);
       } while (LoopNb < VL53L0X_DEFAULT_MAX_LOOP);
       if (LoopNb >= VL53L0X_DEFAULT_MAX_LOOP) {
           Status = VL53L0X_ERROR_TIME_OUT;
       }
   }
   return Status;
}
int main()
{
   lcd.cls();
   printf("Mbed OS version %d.%d.%d\r\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
   
   //Setup laser
   int var=1, measure=0;
   int ave=0, sum=0;
   VL53L0X_Dev_t MyDevice;
   VL53L0X_Dev_t *pMyDevice = &MyDevice;
   VL53L0X_RangingMeasurementData_t    RangingMeasurementData;
   VL53L0X_RangingMeasurementData_t   *pRangingMeasurementData    = &RangingMeasurementData;
   
   // Initialize Comms laster
   pMyDevice->I2cDevAddr      = 0x52;
   pMyDevice->comms_type      =  1;
   pMyDevice->comms_speed_khz =  400;
   
   
   VL53L0X_RdWord(&MyDevice, VL53L0X_REG_OSC_CALIBRATE_VAL,0);
   VL53L0X_DataInit(&MyDevice); 
   uint32_t refSpadCount;
   uint8_t isApertureSpads;
   uint8_t VhvSettings;
   uint8_t PhaseCal;
   
   VL53L0X_StaticInit(pMyDevice); 
   VL53L0X_PerformRefSpadManagement(pMyDevice, &refSpadCount, &isApertureSpads); // Device Initialization
   VL53L0X_PerformRefCalibration(pMyDevice, &VhvSettings, &PhaseCal); // Device Initialization
   VL53L0X_SetDeviceMode(pMyDevice, VL53L0X_DEVICEMODE_CONTINUOUS_RANGING); // Setup in single ranging mode
   VL53L0X_SetLimitCheckValue(pMyDevice, VL53L0X_CHECKENABLE_SIGNAL_RATE_FINAL_RANGE, (FixPoint1616_t)(0.25*65536)); //High Accuracy mode, see API PDF
   VL53L0X_SetLimitCheckValue(pMyDevice, VL53L0X_CHECKENABLE_SIGMA_FINAL_RANGE, (FixPoint1616_t)(18*65536)); //High Accuracy mode, see API PDF
   VL53L0X_SetMeasurementTimingBudgetMicroSeconds(pMyDevice, 200000); //High Accuracy mode, see API PDF
   VL53L0X_StartMeasurement(pMyDevice);
   
   // MAIN CODE HERE
   while(1) {
       lcd.cls();
       lcd.locate(0,3);
       lcd.printf("(DISTANCE)");
           while(var<=10){
               WaitMeasurementDataReady(pMyDevice);
               VL53L0X_GetRangingMeasurementData(pMyDevice, pRangingMeasurementData);
               measure=pRangingMeasurementData->RangeMilliMeter;
               sum=sum+measure;
               VL53L0X_ClearInterruptMask(pMyDevice, VL53L0X_REG_SYSTEM_INTERRUPT_GPIO_NEW_SAMPLE_READY);
               VL53L0X_PollingDelay(pMyDevice);
               var++;
               }
       ave=sum/var;
       var=1;
       sum=0; 
       lcd.locate(0,15);
       lcd.printf("%dmm", ave); // Print to LCD values
       wait(1);
   }
}

実行結果はLCDに [ (DISTANCE) 160mm ] のように表示されます。

6. ダウンロード

src と lib を下記に用意しましたが、解凍して適宜コピーしてください。

こんな感じに配置します。

画像2


この記事が気に入ったらサポートをしてみませんか?