概述
在本 wiki 中,我们将介绍如何将更多 Grove 模块添加到 SenseCAP S2110 传感器构建器中,并列出所有支持的模块。
将 Grove - ±5A DC/AC 电流传感器 (ACS70331) 添加到构建器并应用
1. 使用 GitHub 源代码构建新库
这里的内容位于我们维护代码的 GitHub 上。
-
步骤 1: 在
src\sensor
文件夹中为新传感器添加一个sensorNew.hpp
文件。 -
步骤 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();
}
新传感器的 Modbus 寄存器地址将从 0x0034
开始,每个测量值的寄存器位宽为 32,因此两个相邻测量值之间的寄存器地址偏移量为 2。
2. Modbus 寄存器表知识
Modbus 寄存器地址 0x0000 到 0x0003 保留用于存储模块系统信息,其中 0x0000 是 modbus 地址,默认值为 1,最大值为 247,0x0001 是串口波特率,默认值为 96(对应 9600),0x0002 到 0x0003 用于软件版本。
Grove 传感器名称 | 寄存器名称 | 寄存器地址 (十六进制) | 寄存器地址 (十进制) |
---|---|---|---|
Grove - CO2 & Temperature & Humidity Sensor (SCD41) | 温度 | 0x0004 | 04 |
湿度 | 0x0006 | 06 | |
CO2 | 0x0008 | 08 | |
Grove - Light Sensor v1.2 | 光照 | 0x000A | 10 |
Grove - Flame Sensor | 火焰 | 0x000C | 12 |
Grove - Oxygen Sensor (MIX8410) | 氧气 | 0x000E | 14 |
Grove - Sunlight sensor (SI1151) | 光照强度 | 0x0010 | 16 |
可见光 | 0x0012 | 18 | |
紫外线 | 0x0014 | 20 | |
Grove Temperature and Barometer Sensor (BMP280) | 气压温度 | 0x0016 | 22 |
大气压力 | 0x0018 | 24 | |
高度 | 0x001A | 26 | |
Grove - Temperature Humidity Pressure Gas Sensor(BME680) | 温度 | 0x001C | 28 |
大气压力 | 0x001E | 30 | |
湿度 | 0x0020 | 32 | |
空气质量(VOC) | 0x0022 | 34 | |
Grove - Gas Sensor V2(Multichannel) | N02 | 0x0024 | 36 |
C2H50H | 0x0026 | 38 | |
VOC | 0x0028 | 40 | |
CO | 0x002A | 42 | |
Grove - UV Sensor | 紫外线强度 | 0x002C | 44 |
Grove - Turbidity Sensor Meter V1.0 | 浊度 | 0x002E | 46 |
Grove - TDS Sensor | TDS | 0x0030 | 48 |
Grove - Ultrasonic Ranger | 距离 | 0x0032 | 50 |
3. 硬件连接知识
将传感器的 SIG(信号)引脚连接到任何微控制器的模拟引脚之一,为 VCC 提供 5V-3.3V 电源,将 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; //要测量的交流周期数
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 值,因为交流电压因国家而异,有时甚至因插座而异。
程序将传感器值输出到串行监视器。您也可以打开串行绘图仪查看电压与时间的图表。
- 步骤 1:使用万用表测量交流电压并记录下来。
- 步骤 2:同样记录串行监视器中显示的电压。
在我的情况下,万用表的读数是 220V RMS 电压,而传感器在串行监视器上显示 718.87V,为了获得准确的校准值,我们需要进行简单的数学计算,使用以下公式。
- 步骤 3:找到 x 的值,并在程序中用它替换 Calibration_Value,然后将程序刷写到微控制器。
您可以根据您的配置更改其他参数,如 Phase_Shift、交流周期数和超时,或保持默认值。
参考
- 您可以参考 Grove AC-Voltage Sensor Library 获取更多信息。
- 有关计算的更多详细信息可以在这里找到
SenseCAP S2110 Sensor Builder 支持的 Grove 模块列表
目前,SenseCAP S2110 Sensor Builder 开箱即用地支持以下 Grove 模块,可与 SenseCAP Data Logger 通信并通过 LoRa 将传感器数据发送到 SenseCAP 平台。
- Grove - Temperature and Barometer Sensor (BMP280)
- Grove - Oxygen Sensor (MIX8410)
- Grove - CO2 & Temperature & Humidity Sensor - SCD41
- Grove - Sunlight Sensor - SI1151
- Grove - Light Sensor v1.2 - LS06-S phototransistor
- Grove - Flame Sensor
- Grove - Gas Sensor(BME680)
- Grove - Multichannel Gas Sensor v2
- Grove - TDS Sensor/Meter For Water Quality (Total Dissolved Solids)
- Grove - UV Sensor
- Grove - Ultrasonic Distance Sensor
- Grove - Turbidity Sensor
- Grove - Lightning Sensor
- Grove - ±5A DC/AC Current Sensor (ACS70331)
✨ 贡献者项目
- 此项目由 Seeed Studio 贡献者项目支持。
- 感谢 Mohammed Adnan Khan 的努力,您的工作将被展示。
技术支持与产品讨论
感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。