Pular para o conteúdo principal

Visão geral

Neste wiki, apresentamos como adicionar mais módulos Grove ao SenseCAP S2110 Sensor Builder e listamos todos os módulos compatíveis.

Adicionar Grove - Sensor de Corrente CC/CA ±5A (ACS70331) ao builder e aplicar

1. Criar novas bibliotecas usando o código-fonte do GitHub

O conteúdo aqui está no GitHub, onde mantemos o código.

  • Passo 1: Adicione um arquivo sensorNew.hpp à pasta src\sensor para o novo sensor.

  • Passo 2: Defina a classe do sensor e implemente as funções init() e sample().

A classe do sensor deve herdar da classe sensorClass e implementar as funções init() e sample(). A função init() é usada para inicializar o sensor e então retorna um valor de deslocamento de registro para comunicação Modbus. A função sample() é usada para ler os dados do sensor, retornando true quando os dados são válidos e false quando os dados são inválidos.

  • Passo 3: Inclua o arquivo sensorNEW.hpp e chame-o.

Adicione a linha #include "sensorNew.hpp" ao arquivo src\sensor\sensorBuilder.hpp. Na função setup() do arquivo sensorBuilder.ino, crie o novo objeto de classe de sensor e chame a função SensorBuilder.addSensor() com ele como argumento.

Consulte o código a seguir:

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

O endereço de registro Modbus para o novo sensor começará em 0x0034; a largura de bits de registro para cada valor de medição é 32, portanto o deslocamento de endereço de registro entre dois valores de medição adjacentes é 2.

2. Conhecimento da Tabela de Registros Modbus

Os endereços de registro Modbus de 0x0000 a 0x0003 são reservados para armazenar informações do sistema do módulo, onde 0x0000 é o endereço Modbus com um valor padrão de 1 e valor máximo de 247, 0x0001 é a taxa de baud da porta serial com valor padrão de 96 (correspondente a 9600) e 0x0002 a 0x0003 são para a versão do software.

Nome do Sensor GroveNome do RegistroEndereço de Registro
(Hexadecimal)
Endereço de Registro
(Decimal)
Grove - Sensor de CO2 & Temperatura & Umidade (SCD41)Temperatura0x000404
Umidade0x000606
CO20x000808
Grove - Sensor de Luz v1.2Luz0x000A10
Grove - Sensor de ChamaChama0x000C12
Grove - Sensor de Oxigênio (MIX8410)Oxigênio0x000E14
Grove - Sensor de Luz Solar (SI1151)Intensidade de Luz0x001016
Luz Visível0x001218
UV0x001420
Grove Sensor de Temperatura e Barômetro (BMP280)Temperatura Barométrica0x001622
Pressão Atmosférica0x001824
Altura0x001A26
Grove - Sensor de Temperatura Umidade Pressão Gás (BME680)Temperatura0x001C28
Pressão Atmosférica0x001E30
Umidade0x002032
Qualidade do Ar (VOC)0x002234
Grove - Sensor de Gás V2 (Multicanal)N020x002436
C2H50H0x002638
VOC0x002840
CO0x002A42
Grove - Sensor UVIntensidade UV0x002C44
Grove - Medidor de Turbidez V1.0Turbidez0x002E46
Grove - Sensor TDSTDS0x003048
Grove - Sensor UltrassônicoDistância0x003250

3. Conhecimento da Conexão de Hardware

Conecte o pino SIG (sinal) do sensor a um dos pinos analógicos de qualquer microcontrolador, forneça 5V–3,3V para VCC e GND para o terra do microcontrolador.

O sensor Grove vem com um potenciômetro montado nele, que permite ao usuário ajustar finamente o ganho, tornando-o ajustável para se adequar a diferentes tensões de entrada. Isso ajuda a alterar a sensibilidade do sensor.

4. A partir dos passos acima, podemos ter a biblioteca para o sensor AC Grove:

Seguindo os passos acima, temos a biblioteca para aplicar o sensor AC Grove.

#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. Usar o Arduino para programar e testar primeiro

O programa recebe alguns parâmetros que precisam ser inicializados antes de executar o programa. Isso garante que o programa esteja rodando corretamente com o sensor e obtenha valores precisos.

Primeiro grave o programa no microcontrolador e depois calibre os parâmetros para ajustar às leituras.

#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. Obter valor de calibração

Inicialmente, o pino Analógico é definido como o pino A2, podendo ser alterado de acordo com sua necessidade, usando o parâmetro AC_ADC_PIN. Os valores de Calibration_Value e Phase_Shift precisam ser alterados sempre que você mudar a fonte de tensão, pois a tensão AC varia de país para país ou, às vezes, até de tomada para tomada.

O programa envia o valor do sensor para o monitor serial. Também é possível abrir o serial plotter para visualizar o gráfico de tensão vs tempo.

  • Etapa 1: Pegue o multímetro, meça a tensão AC e anote o valor.
  • Etapa 2: Da mesma forma, anote a tensão mostrada no monitor serial.

No meu caso, a leitura do multímetro é 220 V de tensão RMS, enquanto o sensor mostra 718,87 V no monitor serial. Para obter um valor de calibração preciso, precisamos fazer um cálculo simples, usando a seguinte fórmula.

Mains Voltage / x = Sensor voltage / Initial Calibration

  • Etapa 3: Encontre o valor de x e substitua-o por Calibration_Value no programa e grave o programa no microcontrolador.

x = (mains voltage × initial calibration) / Sensor voltage Você pode alterar outros parâmetros como Phase_Shift, número de ciclos de AC e timeout de acordo com sua configuração ou mantê-los como padrão.

Referência

A lista de módulos Grove suportados para SenseCAP S2110 Sensor Builder

Atualmente, SenseCAP S2110 Sensor Builder oferece suporte aos seguintes módulos Grove prontos para uso para se comunicar com o SenseCAP Data Logger e enviar os dados do sensor para a plataforma SenseCAP via LoRa.

✨ Projeto de Contribuidores

Suporte Técnico & Discussão de Produto

Obrigado por escolher nossos produtos! Estamos aqui para fornecer diferentes tipos de suporte para garantir que sua experiência com nossos produtos seja a mais tranquila possível. Oferecemos vários canais de comunicação para atender a diferentes preferências e necessidades.

Loading Comments...