概要
MachinechatのJEDI v3.0ソフトウェアリリースに伴い、シリアルデータコレクタが追加されました。シリアルデータコレクタは、JEDIが稼働しているマシンのシリアルインターフェースを介して、CSV(comma separated values)形式のデータをJEDIに送信することができます。このプロジェクトでは、ArduinoとSeeedのGrove Beginner Kitを使用し、シリアルデータコレクタを利用してJEDI Proにセンサデータを送信するデモを行います。シリアルデータコレクタのフォーマット要件、JEDIでのコレクタセットアップ、およびデバッグ機能について説明します。Ubuntuが動作するSeeedのミニPC Odyssey Blueに、MachinechatのIoTプラットフォームJEDI Proがインストールされています。
ハードウェア
-
Seeed Odyssey Blue x86 Mini PC
QuadコアのCeleron J4105 Mini PC、128GB外部SSD付き -
Seeed Grove Beginner Kit
Arduino Uno R3 Arduino(を含む) センサ付きGrove Starter Kit
ソフトウェア
-
JEDI Pro or JEDI Pro SSE
IoTデータの収集、可視化、モニタリング、データストレージのための適応型ソフトウェアで、IoTソリューションに組み込むことができます。
・センサ、デバイス、マシンからのデータ収集
・直感的なリアルタイムおよび履歴データ、システムビューダッシュボードの構築
・データ状態を自動的に監視し対応するためのルール作成
・メールやSMSによるアラート通知の受信
などの機能を備えています。
JEDI Pro SSEは、JEDI ProにSeeedのSenseCAP LoRaWANセンサ用のData Collectorを追加したSeeed Studio Editionバージョンです。 -
Arduino
Arduinoは、使いやすいハードウェアとソフトウェアをベースにしたオープンソースの電子機器プラットフォームです。
シリアルデータコレクタの詳細
シリアルデータコレクタは、繰り返し送信されるシリアルメッセージで最大15個のデータフィールドを受信することができます。各データフィールドはコンマで区切る必要があり、数値、文字列、ブール値、またはブランク(そのメッセージではヌルまたは「値なし」)を含むことができます。シリアルメッセージのレコードデリミタを設定する必要があり、「New Line」または「Carriage Return」に設定することができます。メッセージのデータフィールド数は、データコレクタで設定されたフィールド数と一致する必要があります。シリアルメッセージ内のデータの位置は、データコレクタの構成でフィールドに関連付けられた番号に対応します。
例えば、シリアルデータのメッセージには、「light(光)」、「sound(音)」、「temperature(温度)」の値が含まれることがあります。メッセージは以下のようなものになります。
124,33,72.1
値124を「光」、33を「音」、72.1を「温度」に関連付けるには、対応する3つのデータコレクタのフィールドを次の例のように設定する必要があります。
JEDIシリアルデータコレクタのセットアップは、5つのステップで構成されます。
1 - モニタするシリアルポートを選択します。
2 - データストリームの一意のTargetID名を選択します。
3 - シリアルポートのパラメータ(ボーレート、ストップビット、データビット、およびパリティ)を設定します。
4 - レコードデリミタを設定します。
5 - CSVフィールドを追加します。
オプションで、タイムスタンプが存在する場合はシリアルデータから抽出することができますが、デフォルトではデータが入力された時点でスタンプが押されます。
シリアルデータコレクタをデバッグします。
シリアルデータの取り込みや表示に問題がある場合、デバッガを有効にしてログファイルを作成することができます。シリアルデータコレクタの設定画面の左下に「Enable Debug」スライダがあります。有効にすると、コレクタが動作しているときに発生したアクティビティとエラーをキャプチャします。このキャプチャの出力は、JEDIがインストールされている「debug/datacollectors」サブディレクトリの「debug.log」ファイルで確認できます。
シリアルデータコレクタの詳しい情報は、Machinechatの記事Using the Serial Data Collectorに記載されています。
実装
Grove Beginner Kit上で動作するArduinoアプリケーションは、搭載された5つのセンサ(光、音、温度/湿度、圧力、加速度)を読み取り、センサデータをOLED(有機EL)ディスプレイに表示し、シリアルインターフェースを介してセンサデータをシリアルデータコレクタ専用のフォーマットでJEDIが動作するOdyssey Blue Mini-PCに送信します。Arduinoのコードは、Grove Beginner Kitのサンプルコードを修正したもので、10秒ごとに各センサをループして繰り返します。ハードウェアの実装は簡単で、Odyssey BlueとGrove Beginner Kitの間にUSBケーブルを接続するだけです。下図はその接続を示したものです(Scheme-itのOdysseyGrove Project and BOMを参照)。
SeeedのGrove Beginner Kitのセットアップ
1 - Grove Beginner Kit上で Arduino をセットアップします。Grove Beginner Kit for Arduinoのリンクを参照してください。 Arduino IDEで「Board」を選択する際に「Arduino Uno」を選択します。
2 - アプリケーションに必要なライブラリをインストールします。 Arduino のLibrary Managerを通じてこれらのライブラリを追加します。
- U8g2 Monochrome LCD, OLED and eInk Library
- DHT Sensor Library
- Grove_BMP280 Library
- Seeed_Arduino_LIS3DHTR Library
- SafeString library V3+ Library
3 - コードのウォークスルー(ファイル名:UNO_GroveBeginnerKitJediProSerialLoop.ino)
初期設定
//
// Seeed Grove Beginner Kit for Arduino - default code
// Modified to send CSV information over serial (USB) port
// For use as input to Machinechat JEDI software
// v0.1 DRM 07-04-2022
//
// CSV is as follows: "Light, Sound, Temoperature, Humidity, Air Pressure,
// Acceleration X, Acceleration Y, Acceleration Z"
//
// Only one parameter is sent at a time based on selection displayed on OLED
// Display
// SBR modification to remove selection capability and just loop thru the sensors send & display data on OLED
//
#include <U8g2lib.h>
#include <Wire.h>
//#include <MsTimer2.h>
#include "DHT.h"
#include "Seeed_BMP280.h"
#include "LIS3DHTR.h"
#include "millisDelay.h" //part of SafeString library for non-blocking timer use
#define WIRE Wire
millisDelay loopDelay;
//20*20
const unsigned char sound_bmp[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x3e, 0x00, 0x80, 0x3f, 0x0c, 0xc0, 0x3b, 0x0c, 0xfe, 0xb8, 0x0d, 0x7f, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0x03, 0xb8, 0x0d, 0xff, 0xb8, 0x0d, 0xc0, 0x39, 0x0c, 0x80, 0x3f, 0x0c, 0x00, 0x3e, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00};
//20*30
const unsigned char temp_bmp[] U8X8_PROGMEM = {0x00, 0x06, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x00, 0x09, 0x00, 0x80, 0x19, 0x00, 0x80, 0x19, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x39, 0x00, 0xc0, 0x3f, 0x00, 0x80, 0x1f, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x06, 0x00};
//20*20
const unsigned char hum_bmp[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x80,0x10,0x00,0x00,0x00,0x00,0x40,0x20,0x00,0x20,0x40,0x00,0x20,0x40,0x00,0x10,0x80,0x00,0x10,0x80,0x00,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x01,0x10,0x80,0x00,0x00,0x00,0x00,0x40,0x20,0x00,0x80,0x10,0x00};
//20*20
const unsigned char pressure_bmp1[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0x80,0x96,0x01,0x80,0x1f,0x03,0x00,0x0f,0x06,0x18,0x06,0x04,0x1c,0x04,0x04,0x06,0x00,0x06,0xc6,0xff,0x03,0xc6,0xff,0x01,0x04,0x00,0x00,0xfc,0xff,0x03,0xf8,0xff,0x03,0x00,0x00,0x00,0xfe,0xff,0x07,0xfe,0xff,0x07,0x00,0x00,0x00};
//30*30
const unsigned char pressure_bmp[] U8X8_PROGMEM= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc0,0x00,0x00,0x00,0xc8,0xc4,0x01,0x00,0xf8,0x87,0x07,0x00,0xf8,0x87,0x07,0x60,0xf0,0x03,0x04,0x60,0xf0,0x03,0x04,0xf0,0xc0,0x00,0x04,0xf0,0xc0,0x00,0x04,0x18,0x00,0x00,0x06,0x18,0x00,0x00,0x06,0x08,0xfc,0xff,0x03,0x08,0xfc,0xff,0x03,0x18,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0xf0,0xff,0xff,0x03,0xf0,0xff,0xff,0x03,0xe0,0xff,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x1f,0xfe,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//30*30
const unsigned char light_tmp[] U8X8_PROGMEM = {0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x80, 0xc1, 0x60, 0x00, 0x80, 0xc3, 0x70, 0x00, 0x00, 0xc3, 0x30, 0x00, 0x00, 0xc7, 0x38, 0x00, 0x00, 0x06, 0x18, 0x00, 0x0c, 0xf0, 0x03, 0x0c, 0x3c, 0xfc, 0x0f, 0x0f, 0x78, 0x1e, 0x9e, 0x07, 0x60, 0x07, 0xb8, 0x01, 0x00, 0x03, 0x30, 0x00, 0x80, 0x03, 0x70, 0x00, 0x80, 0x01, 0x60, 0x00, 0xbf, 0x01, 0x60, 0x3f, 0xbf, 0x01, 0x60, 0x3f, 0x80, 0x01, 0x60, 0x00, 0x80, 0x03, 0x70, 0x00, 0x00, 0x03, 0x30, 0x00, 0x60, 0x07, 0xb8, 0x01, 0x78, 0x1e, 0x9e, 0x07, 0x3c, 0xfc, 0x0f, 0x0f, 0x0c, 0xf0, 0x03, 0x0c, 0x00, 0x06, 0x18, 0x00, 0x00, 0xc7, 0x38, 0x00, 0x00, 0xc3, 0x30, 0x00, 0x80, 0xc3, 0x70, 0x00, 0x80, 0xc1, 0x60, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00};
//30*30
const unsigned char sound_bmp1[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0x00, 0x00, 0x70, 0xc0, 0x00, 0x00, 0x48, 0x80, 0x01, 0x00, 0x4c, 0x18, 0x03, 0x00, 0x46, 0x30, 0x02, 0x00, 0x43, 0x60, 0x04, 0x80, 0x41, 0x43, 0x04, 0xfc, 0x40, 0x84, 0x08, 0x46, 0x40, 0x8c, 0x08, 0x46, 0x40, 0x88, 0x08, 0x46, 0x40, 0x10, 0x09, 0x06, 0x40, 0x10, 0x09, 0x06, 0x40, 0x10, 0x19, 0x06, 0x40, 0x10, 0x09, 0x06, 0x40, 0x10, 0x09, 0x46, 0x40, 0x18, 0x09, 0x46, 0x40, 0x88, 0x08, 0x46, 0x40, 0x8c, 0x08, 0xfc, 0x40, 0x86, 0x0c, 0x80, 0x41, 0x43, 0x04, 0x00, 0x43, 0x20, 0x04, 0x00, 0x42, 0x30, 0x02, 0x00, 0x44, 0x0c, 0x03, 0x00, 0x48, 0x80, 0x01, 0x00, 0x50, 0xc0, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//30*30
const unsigned char acel_bmp[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x80, 0x01, 0x60, 0x00, 0x60, 0x00, 0x80, 0x00, 0x30, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x04, 0x04, 0x20, 0x01, 0x08, 0x04, 0x10, 0x02, 0x08, 0x02, 0xf8, 0x03, 0x08, 0x02, 0x0c, 0x0e, 0x10, 0x02, 0x0a, 0x10, 0x10, 0x02, 0x0a, 0x10, 0x10, 0x02, 0x02, 0x0a, 0x10, 0x02, 0x18, 0x06, 0x18, 0x06, 0x10, 0x02, 0x08, 0x04, 0x20, 0x01, 0x08, 0x04, 0xc0, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x04, 0x18, 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, 0x03, 0x60, 0x00, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//30*30
const unsigned char temp_bmp1[] U8X8_PROGMEM = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x1f, 0x8f, 0xff, 0xff, 0x3f, 0x0f, 0x00, 0x00, 0x3e, 0x0f, 0x00, 0x00, 0x3e, 0x8f, 0xff, 0xff, 0x3f, 0xfe, 0xff, 0xff, 0x1f, 0xfe, 0xff, 0xff, 0x07, 0xfc, 0x01, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#define BoardVersion 2
#if BoardVersion == 1
char led = 5;
char buzzer = 6;
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2, /* reset=*/U8X8_PIN_NONE);
char button = 2;
char rotary = A1;
char light = A2;
char sound = A0;
DHT dht(4,DHT11);
BMP280 bmp280;
// LIS3DHTR<TwoWire> accelemeter(I2C_MODE);
LIS3DHTR<TwoWire> accelemeter; //IIC
#elif BoardVersion == 2
char led = 4;
char buzzer = 5;
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R2, /* reset=*/U8X8_PIN_NONE);
char button = 6;
char rotary = A0;
char light = A6;
char sound = A2;
DHT dht(3,DHT11);
BMP280 bmp280;
//LIS3DHTR<TwoWire> accelemeter(I2C_MODE);
LIS3DHTR<TwoWire> accelemeter; //IIC
#endif
#define CLICKS 100
int BuzzerFrequency = 300;
char MODE = 1;
char LongPress = false;
int x = 50, y = 13;
char PressCounter = 0;
char BlinkEnable = true;
#define BLINK 10
#define SQueueLEN 10
int SQueue[SQueueLEN] = {0};
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
if(!bmp280.init()){
Serial.println("bmp280 init error!");
}
//accelemeter.begin(Wire);
accelemeter.begin(WIRE, LIS3DHTR_ADDRESS_UPDATED); //IIC init
delay(100);
//accelemeter.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
accelemeter.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
if (!accelemeter) {
Serial.println("LIS3DHTR didn't connect.");
}
for (int Index = 0 ; Index < SQueueLEN ; Index ++)
{
SQueue[Index] = analogRead(sound);
}
u8g2.begin();
//SBR mod
MODE = 1;
loopDelay.start(10000); // start a 10sec delay
}
メインループ - センササブルーチンを呼び出し、センサの読み取り、OLEDへのセンサデータの表示、およびシリアルインターフェースでのデータ送信を行います。
void loop() {
if (loopDelay.justFinished()) {
MODE = MODE + 1; // increment mode
loopDelay.start(10000); // start a 10sec delay
}
//reset mode loop
if (MODE == 6) {
MODE = 1;
}
if (MODE == 1) {
Light_show();
} else if (MODE == 2) {
Sound_show();
} else if (MODE == 3) {
Temp_show();
} else if (MODE == 4) {
Pressure_show();
} else if (MODE == 5) {
Acele_show();
}
}
光、音、温湿度、圧力、および加速度の各センサ用のセンササブルーチン(センサの読み込み、センサデータをシリアルメッセージで特定の位置に送信、およびキットのオンボードOLEDディスプレイにセンサデータを表示)
void Light_show()
{
int l = analogRead(light);
Serial.println(String(l) + ",,,,,,,");
Serial.flush();
delay(500);
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.drawCircle(8, 8, 8, U8G2_DRAW_ALL);
if (l >= 50 && l < 100) {
u8g2.drawDisc(8, 8, 8, U8G2_DRAW_UPPER_LEFT);
}
if (l >= 100 & l < 200) {
u8g2.drawDisc(8, 8, 8, U8G2_DRAW_UPPER_RIGHT | U8G2_DRAW_UPPER_LEFT);
}
if (l >= 200 && l < 350) {
u8g2.drawDisc(8, 8, 8, U8G2_DRAW_LOWER_LEFT | U8G2_DRAW_UPPER_RIGHT | U8G2_DRAW_UPPER_LEFT);
}
if (l >= 350) {
u8g2.drawDisc(8, 8, 8, U8G2_DRAW_ALL);
}
u8g2.setCursor(26, 32);
u8g2.print(F("Light:"));
u8g2.setCursor(80, 32);
u8g2.print(l);
//SBR mod
u8g2.setCursor(0, 64);
u8g2.print(F("JEDI Serial data"));
} while (u8g2.nextPage());
}
int filter1(int NEW_DATA,int QUEUE[],char n)
{
int max;
int min;
int sum;
char i;
QUEUE[0]=NEW_DATA;
if (QUEUE[0] < 0)
QUEUE[0] = 0;
max=QUEUE[0];
min=QUEUE[0];
sum=QUEUE[0];
for(i=n-1;i!=0;i--){
if(QUEUE[i]>max)max=QUEUE[i];
else if (QUEUE[i]<min)min=QUEUE[i];
sum=sum+QUEUE[i];
QUEUE[i]=QUEUE[i-1];
}
i=n-2;
sum=sum-max-min+i/2;
sum=sum/i;
return ((int)sum);
}
void Sound_show()
{
int s = analogRead(sound);
s = filter1(s,SQueue,SQueueLEN);
delay(500);
Serial.println("," + String(s) + ",,,,,,");
Serial.flush();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.setCursor(28, 32);
u8g2.print(F("Sound:"));
u8g2.setCursor(76, 32);
u8g2.drawXBMP(0, 0, 20, 20, sound_bmp);
u8g2.print(s);
//SBR mods
u8g2.setCursor(0, 64);
u8g2.print(F("JEDI Serial data"));
} while (u8g2.nextPage());
}
void Temp_show()
{
int tempC = 0, humid = 0;
float tempF = 0.0;
do{
humid = dht.readHumidity();
tempC = dht.readTemperature();
tempF = (float(tempC) * 1.8) + 32.0F;
} while ((humid == 0) && (tempC == 0));
delay(500);
Serial.println(",," + String(int(tempF)) + ",,,,,");
Serial.flush();
Serial.println(",,," + String(humid) + ",,,,");
Serial.flush();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.setCursor(32, 16);
u8g2.print(F("Temp:"));
u8g2.setCursor(72, 16);
u8g2.print(int(tempF));
u8g2.setCursor(88, 16);
u8g2.print("F");
u8g2.setCursor(32, 40);
u8g2.print(F("Humid:"));
u8g2.setCursor(80, 40);
u8g2.print(humid);
u8g2.drawXBMP(0, 0, 20, 30, temp_bmp);
u8g2.setCursor(0, 64);
u8g2.print(F("JEDI Serial data"));
} while (u8g2.nextPage());
}
void Pressure_show()
{
float pressure = (bmp280.getPressure() * 0.000295300586F);
delay(500);
Serial.println(",,,," + String(pressure, 2) + ",,,");
Serial.flush();
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.firstPage();
do {
u8g2.setCursor(76, 32);
u8g2.drawXBMP(0, 0, 20, 20, pressure_bmp1);
u8g2.setCursor(30, 25);
u8g2.print("Pressure:");
u8g2.setCursor(30, 40);
u8g2.print(pressure);
u8g2.print("inHg");
u8g2.setCursor(0, 64);
u8g2.print(F("JEDI Serial data"));
} while (u8g2.nextPage());
}
void Acele_show()
{
float ax, ay, az;
ax = accelemeter.getAccelerationX();
ay = -accelemeter.getAccelerationY();
az = accelemeter.getAccelerationZ();
delay(500);
Serial.println(",,,,," + String(ax, 2) + ",,");
Serial.flush();
Serial.println(",,,,,," + String(ay, 2) + ",");
Serial.flush();
Serial.println(",,,,,,," + String(az, 2));
Serial.flush();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.setCursor(0, 16);
u8g2.print(F("Accel:"));
u8g2.setFont(u8g2_font_t0_12b_mr);
u8g2.setCursor(55, 16);
u8g2.print(F("X:"));
u8g2.setCursor(71, 16);
u8g2.print(ax);
u8g2.setCursor(55, 32);
u8g2.print(F("Y:"));
u8g2.setCursor(71, 32);
u8g2.print(ay);
u8g2.setCursor(55, 48);
u8g2.print(F("Z:"));
u8g2.setCursor(71, 48);
u8g2.print(az);
u8g2.setFont(u8g2_font_t0_16b_mr);
u8g2.setCursor(0, 64);
u8g2.print(F("JEDI Serial data"));
} while (u8g2.nextPage());
}
UNO_GroveBeginnerKitJediProSerialLoop.inoアプリケーションの最新のソースコードは、以下のリンク先のgithubにあります。
JEDIシリアルデータコレクタとデータダッシュボードのセットアップ
JEDIで「Settings(設定)」タブを選択し、「Data Collectors(データコレクタ)」を選択し、「Add Collector(コレクタを追加)」を選択します。
Collectorを以下のように設定します。データコレクタの名前を「SerialGroveBeginner」(またはお好みのもの)、コレクタのタイプを「Serial」、シリアルポートをGrove Beginner Kitのシリアルポート(私の設定では/dev/ttyUSB0でした)、ターゲットIDを「GroveKit」(またはお好みのもの)、データ速度を「115200」、データビットを「8 Bit」、パリティは「No Parity」、レコードデリミタを「New Line」に選択します。以下の8つのセンサパラメータフィールド(Light、 Sound、Temperature、Humidity、Pressure、 AccelX、AccelY、AccelZ)のData Fieldsを追加します。
JEDI Proで「Data Dashboards」を選択し、「+」を選択して新しいチャートを追加します。
データチャートを設定し、「Add」を選択すると、データダッシュボードに表示されます(以下の例を参照)。
まとめ
MachinechatのJEDI IoTアプリケーションソフトウェア用シリアルデータコレクタは、開発ボード、プラットフォーム、またはCSV形式でシリアルデータを送信できるあらゆるデバイスから、センサやその他のタイプのデータを迅速かつ簡単に取り込む手段を提供します。JEDIソフトウェアが動作するハードウェアに接続されたUSB、RS-232、RS-485、その他のシリアルインターフェース機器から、CSV形式で送信されるデータであれば、どのようなものでも構いません。
参考資料
- Seeed - Odyssey Blue J4105 Mini PC
- Seeed - Grove Starter Kit
- Seeed - Grove Starter Kit Wiki
- Machinechat - Using the Serial Data Collector