Skip to main content

概要

このwikiでは、SenseCAP S2110 Sensor Builderにより多くのGroveモジュールを追加する方法を紹介し、サポートされているすべてのモジュールをリストアップします。

Grove - ±5A DC/AC電流センサー(ACS70331)をビルダーに追加して適用する

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();

/* sensor list */
sensorUltrasonic *ultrasonic = new sensorUltrasonic();
SensorBuilder.addSensor(ultrasonic);

// add new sensor to sensor list
sensorNew *newSensor = new sensorNew();
SensorBuilder.addSensor(newSensor);

SensorBuilder.begin();
}
note

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

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

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

Groveセンサー名レジスタ名レジスタアドレス
(16進数)
レジスタアドレス
(10進数)
Grove - CO2 & Temperature & Humidity Sensor (SCD41)Temperature0x000404
Humidity0x000606
CO20x000808
Grove - Light Sensor v1.2Light0x000A10
Grove - Flame SensorFlame0x000C12
Grove - Oxygen Sensor (MIX8410)Oxygen0x000E14
Grove - Sunlight sensor (SI1151)Light Intensity0x001016
Visible Light0x001218
UV0x001420
Grove Temperature and Barometer Sensor (BMP280)Barometric Temperature0x001622
Atmospheric Pressure0x001824
Height0x001A26
Grove - Temperature Humidity Pressure Gas Sensor(BME680)Temperature0x001C28
Atmospheric Pressure0x001E30
Humidity0x002032
Air Quality(VOC)0x002234
Grove - Gas Sensor V2(Multichannel)N020x002436
C2H50H0x002638
VOC0x002840
CO0x002A42
Grove - UV SensorUV Intensity0x002C44
Grove - Turbidity Sensor Meter V1.0Turbidity0x002E46
Grove - TDS SensorTDS0x003048
Grove - Ultrasonic RangerDistance0x003250

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

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

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				//here pin A2 is used
#define ADC_BITS 12 //depends on microcontroller to microcontroller
#define Calibration_Value 523.56 //depends on the calibration result
#define Phase_Shift 1.7 //depends on the calibration result

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; //Number of AC Cycles you want to measure
unsigned int timeout = 500; //Timeout
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を示しています。正確なキャリブレーション値を得るために、以下の式を使用して簡単な計算を行う必要があります。

Mains Voltage / x = Sensor voltage / Initial Calibration

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

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

リファレンス

SenseCAP S2110 Sensor BuilderでサポートされているGroveモジュールのリスト

現在、SenseCAP S2110 Sensor Builderは、SenseCAP Data Loggerと通信し、LoRa経由でSenseCAPプラットフォームにセンサーデータを送信するために、以下のGroveモジュールをすぐに使用できるようサポートしています。

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

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

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

Loading Comments...