Skip to main content

Grove モジュールを Builder に追加する方法

note

この文書は AI によって翻訳されています。内容に不正確な点や改善すべき点がございましたら、文書下部のコメント欄または以下の Issue ページにてご報告ください。
https://github.com/Seeed-Studio/wiki-documents/issues

概要

この Wiki では、SenseCAP S2110 Sensor Builder にさらに多くの Grove モジュールを追加する方法と、サポートされているモジュールの一覧を紹介します。

Grove - ±5A DC/AC Current Sensor (ACS70331) を Builder に追加して適用する方法

1. GitHub ソースコードを使用して新しいライブラリを構築する

内容は GitHub にあります。ここでコードを管理しています。

  • ステップ 1: 新しいセンサー用に sensorNew.hpp ファイルを src\sensor フォルダーに追加します。

  • ステップ 2: センサークラスを定義し、init() および sample() 関数を実装します。

    センサークラスは sensorClass クラスを継承し、init() および sample() 関数を実装する必要があります。 init() 関数はセンサーを初期化し、Modbus 通信のためのレジスターオフセット値を返します。 sample() 関数はセンサーデータを読み取り、データが有効な場合は true を返し、無効な場合は false を返します。

  • ステップ 3: sensorNEW.hpp ファイルをインクルードして呼び出します。

    src\sensor\sensorBuilder.hpp ファイルに #include "sensorNew.hpp" 行を追加します。 sensorBuilder.ino ファイルの setup() 関数で、新しいセンサークラスオブジェクトを作成し、それを引数として SensorBuilder.addSensor() 関数を呼び出します。

以下のコードを参照してください:

void setup()
{
Serial.begin(9600);
SensorBuilder.check_grove();

/* センサーリスト */
sensorUltrasonic *ultrasonic = new sensorUltrasonic();
SensorBuilder.addSensor(ultrasonic);

// 新しいセンサーをセンサーリストに追加
sensorNew *newSensor = new sensorNew();
SensorBuilder.addSensor(newSensor);

SensorBuilder.begin();
}
note

新しいセンサーの Modbus レジスターアドレスは 0x0034 から始まります。各測定値のレジスタービット幅は 32 であるため、隣接する測定値間のレジスターアドレスオフセットは 2 です。

2. Modbus レジスターテーブルの知識

Modbus レジスターアドレス 0x0000 から 0x0003 はモジュールシステム情報を格納するために予約されています。0x0000 はデフォルト値が 1、最大値が 247 の Modbus アドレスであり、0x0001 はデフォルト値が 96(9600 に対応)のシリアルポートボーレートです。0x0002 から 0x0003 はソフトウェアバージョン用です。

Grove センサー名レジスター名レジスターアドレス
(16進数)
レジスターアドレス
(10進数)
Grove - CO2 & Temperature & Humidity Sensor (SCD41)温度0x000404
湿度0x000606
CO20x000808
Grove - Light Sensor v1.20x000A10
Grove - Flame Sensor0x000C12
Grove - Oxygen Sensor (MIX8410)酸素0x000E14
Grove - Sunlight sensor (SI1151)光強度0x001016
可視光0x001218
UV0x001420
Grove Temperature and Barometer Sensor (BMP280)気圧温度0x001622
大気圧0x001824
高度0x001A26
Grove - Temperature Humidity Pressure Gas Sensor(BME680)温度0x001C28
大気圧0x001E30
湿度0x002032
空気質(VOC)0x002234
Grove - Gas Sensor V2(Multichannel)N020x002436
C2H50H0x002638
VOC0x002840
CO0x002A42
Grove - UV SensorUV 強度0x002C44
Grove - Turbidity Sensor Meter V1.0濁度0x002E46
Grove - TDS SensorTDS0x003048
Grove - Ultrasonic Ranger距離0x003250

3. ハードウェア接続の知識

センサーの SIG(信号)ピンを任意のマイクロコントローラーのアナログピンのいずれかに接続し、5V-3.3V を VCC に供給し、GND をマイクロコントローラーのグランドに接続します。

Grove センサーにはポテンショメーターが取り付けられており、ゲインを微調整することで異なる入力電圧に適応させることができます。これによりセンサーの感度を変更することができます。

4. 上記の手順に従って Grove AC センサー用のライブラリを作成する

上記の手順に従って、Grove AC センサーを適用するためのライブラリを作成します。

#ifndef _SENSOR_AC_H
#define _SENSOR_AC_H

#include "sensorClass.hpp"

#define AC_ADC_PIN A2
#define ADC_BITS 12
#define ADC_COUNTS (1<<ADC_BITS)

class sensorAC : public sensorClass
{
public:
sensorAC(): sensorClass("AC"){};
~sensorAC(){};

uint16_t init(uint16_t reg, bool i2c_available);
bool connected();
bool sample();

enum
{
AC = 0,
MAX
};
private:
double voltCal = 523.56;
double phaseCal = 1.7;
unsigned int cycles = 20;
unsigned int timeout = 2000;
int SupplyVoltage = 3300;
int sampleV;
double lastFilteredV,filteredV;
double offsetV = ADC_COUNTS >> 1;
double phaseShiftedV;
double sqV,sumV;
int startV;
boolean lastVCross,checkVCross;
};

uint16_t sensorAC::init(uint16_t reg, bool i2c_available){
uint16_t t_reg = reg;

for (uint16_t i = 0; i < sensorAC::MAX; i++)
{
sensorClass::reg_t value;
value.addr = t_reg;
value.type = sensorClass::regType_t::REG_TYPE_S32_ABCD;
value.value.s32 = 0;
t_reg += sensorClass::valueLength(value.type);
m_valueVector.emplace_back(value);
}

_connected = i2c_available ? false : true;
//_connected = true;
return t_reg - reg;
}

bool sensorAC::sample()
{

GROVE_SWITCH_ADC;
pinMode(AC_ADC_PIN, INPUT);

unsigned int crossCount = 0;
unsigned int numberOfSamples = 0;

unsigned long start = millis();

while(1){
int startV = analogRead(AC_ADC_PIN);
if((startV<(ADC_COUNTS*0.51)) && (startV>(ADC_COUNTS*0.49)))
break;
if((millis()-start)>timeout)
break;
}

start = millis();

while((crossCount<cycles) && ((millis()-start)<timeout))
{
numberOfSamples++;
lastFilteredV = filteredV;

sampleV = analogRead(AC_ADC_PIN);
offsetV = offsetV + ((sampleV - offsetV)/ADC_COUNTS);
filteredV = sampleV - offsetV;

sqV = filteredV * filteredV;
sumV += sqV;

phaseShiftedV = lastFilteredV + phaseCal * (filteredV - lastFilteredV);

lastVCross = checkVCross;
if(sampleV>startV)
checkVCross = true;
else
checkVCross = false;
if(numberOfSamples == 1)
lastVCross = checkVCross;
if(lastVCross !=checkVCross)
crossCount++;
}

double V_RATIO = voltCal * ((SupplyVoltage/1000.0)/(ADC_COUNTS));
float value = V_RATIO * sqrt(sumV/numberOfSamples);
m_valueVector[AC].value.s32 = value * SCALE;
//Serial.println(value);
sumV = 0;

return true;
}

bool sensorAC::connected()
{
return _connected;
}

#endif

5. Arduinoを使用して最初のテストをプログラムする

このプログラムはいくつかのパラメータを受け取り、プログラムを実行する前に初期化する必要があります。これにより、センサーと正確な値を得るためにプログラムが正しく動作することが保証されます。

まず、プログラムをマイクロコントローラーにフラッシュし、その後、読み取り値に合わせてパラメータをキャリブレーションします。

#define AC_ADC_PIN A2               //ここではピンA2を使用
#define ADC_BITS 12 //マイクロコントローラーによって異なる
#define Calibration_Value 523.56 //キャリブレーション結果に依存
#define Phase_Shift 1.7 //キャリブレーション結果に依存

void setup() {
Serial.begin(115200);
pinMode(AC_ADC_PIN, INPUT);
}

int ADC_COUNTS = (1<<ADC_BITS);
double voltCal = Calibration_Value;
double phaseCal = Phase_Shift;
unsigned int cycles = 10; //測定したいACサイクルの数
unsigned int timeout = 500; //タイムアウト
int SupplyVoltage = 3300;
int sampleV;
double lastFilteredV,filteredV;
double offsetV = ADC_COUNTS >> 1;
double phaseShiftedV;
double sqV,sumV;
int startV;
boolean lastVCross,checkVCross;

void loop() {
unsigned int crossCount = 0;
unsigned int numberOfSamples = 0;

unsigned long start = millis();

while(1){
int startV = analogRead(AC_ADC_PIN);
if((startV<(ADC_COUNTS*0.51)) && (startV>(ADC_COUNTS*0.49)))
break;
if((millis()-start)>timeout)
break;
}

start = millis();

while((crossCount<cycles) && ((millis()-start)<timeout))
{
numberOfSamples++;
lastFilteredV = filteredV;

sampleV = analogRead(AC_ADC_PIN);
offsetV = offsetV + ((sampleV - offsetV)/ADC_COUNTS);
filteredV = sampleV - offsetV;

sqV = filteredV * filteredV;
sumV += sqV;

phaseShiftedV = lastFilteredV + phaseCal * (filteredV - lastFilteredV);

lastVCross = checkVCross;
if(sampleV>startV)
checkVCross = true;
else
checkVCross = false;
if(numberOfSamples == 1)
lastVCross = checkVCross;
if(lastVCross !=checkVCross)
crossCount++;
}

double V_RATIO = voltCal * ((SupplyVoltage/1000.0)/(ADC_COUNTS));
float value = V_RATIO * sqrt(sumV/numberOfSamples);
Serial.println(value);
sumV = 0;

}

6. キャリブレーション値を取得する

初期設定では、アナログピンはA2ピンに設定されていますが、必要に応じてAC_ADC_PINパラメータを使用して変更できます。
キャリブレーション値(Calibration_Value)と位相シフト値(Phase_Shift)は、電圧源を変更するたびに変更する必要があります。これは、AC電圧が国や場合によってはコンセントごとに異なるためです。

プログラムはセンサー値をシリアルモニターに出力します。また、シリアルプロッターを開いて電圧と時間のグラフを表示することもできます。

  • ステップ1: マルチメーターを使用してAC電圧を測定し、その値を記録します。
  • ステップ2: 同様に、シリアルモニターに表示される電圧を記録します。

ここでは、マルチメーターの読み取り値が220V RMS電圧であり、センサーがシリアルモニターに718.87Vを表示している場合、正確なキャリブレーション値を得るために以下の式を使用して簡単な計算を行う必要があります。

 \dfrac{Mains Voltage}{x} = \dfrac{Sensor voltage}{Initail Calibration}

  • ステップ3: xの値を求め、プログラム内のCalibration_Valueに置き換え、プログラムをマイクロコントローラーにフラッシュします。

 x = \dfrac{mains voltage \times initial calibration}{Sensor voltage}

Phase_Shift、ACサイクル数、タイムアウトなどの他のパラメータは、設定に応じて変更するか、デフォルトのままにしておくことができます。

参考文献

SenseCAP S2110 Sensor Builderで対応しているGroveモジュールの一覧

現在、SenseCAP S2110 Sensor Builderは以下のGroveモジュールを標準でサポートしており、SenseCAP Data Loggerと通信し、センサーデータをLoRa経由でSenseCAPプラットフォームに送信することができます。

✨ コントリビュータープロジェクト

技術サポートと製品ディスカッション

弊社製品をお選びいただきありがとうございます!製品の使用体験をスムーズにするために、さまざまなサポートを提供しています。異なる好みやニーズに対応するため、複数のコミュニケーションチャネルをご用意しています。

Loading Comments...