Skip to main content

Descripción General

En esta wiki, te mostramos cómo añadir más módulos Grove al SenseCAP S2110 Sensor Builder y listamos todos los que son compatibles.

Añadir el Grove - Sensor de Corriente DC/AC ±5A (ACS70331) al Builder y su aplicación

1. Construir nuevas librerías usando el código fuente de GitHub

El contenido se encuentra en el repositorio GitHub, donde mantenemos el código.

  • Paso 1: Agrega un archivo sensorNew.hpp en la carpeta src\sensor para el nuevo sensor.

  • Paso 2: Define la clase del sensor e implementa las funciones init() y sample().

La clase del sensor debe heredar de la clase sensorClass e implementar las funciones init() y sample().
La función init() se usa para inicializar el sensor y debe retornar un valor de desplazamiento (offset) de registro para la comunicación Modbus.
La función sample() se usa para leer los datos del sensor. Retorna true cuando los datos son válidos, y false cuando son inválidos.

  • Paso 3: Incluye el archivo sensorNEW.hpp y haz la llamada correspondiente.

Agrega la línea #include "sensorNew.hpp" en el archivo src\sensor\sensorBuilder.hpp.
En la función setup() del archivo sensorBuilder.ino, crea un objeto de la clase del nuevo sensor y llama a la función SensorBuilder.addSensor() pasándole dicho objeto como argumento.

Consulta el siguiente ejemplo de código:

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

/* lista de sensores */
sensorUltrasonic *ultrasonic = new sensorUltrasonic();
SensorBuilder.addSensor(ultrasonic);

// añadir nuevo sensor a la lista
sensorNew *newSensor = new sensorNew();
SensorBuilder.addSensor(newSensor);

SensorBuilder.begin();
}
note

La dirección de registro Modbus para el nuevo sensor comenzará en 0x0034. El ancho de bit de cada valor de medición es de 32, por lo tanto, el desplazamiento entre dos registros adyacentes es de 2.

2. Conocimiento de la Tabla de Registros Modbus

Las direcciones de registro Modbus desde 0x0000 hasta 0x0003 están reservadas para almacenar información del sistema del módulo: 0x0000: Dirección Modbus, valor por defecto: 1, máximo: 247. 0x0001: Velocidad del puerto serie (baud rate), valor por defecto: 96 (corresponde a 9600 baudios). 0x0002 a 0x0003: Versión del software.

Nombre del Sensor GroveNombre del RegistroDirección del Registro
(Hexadecimal)
Dirección del Registro
(Decimal)
Grove - Sensor de CO2, Temperatura y Humedad (SCD41)Temperatura0x000404
Humedad0x000606
CO20x000808
Grove - Sensor de Luz v1.2Luz0x000A10
Grove - Sensor de LlamaLlama0x000C12
Grove - Sensor de Oxígeno (MIX8410)Oxígeno0x000E14
Grove - Sensor de Luz Solar (SI1151)Intensidad de Luz0x001016
Luz Visible0x001218
UV0x001420
Grove - Sensor de Temperatura y Barómetro (BMP280)Temperatura Barométrica0x001622
Presión Atmosférica0x001824
Altura0x001A26
Grove - Sensor de Temperatura, Humedad, Presión y Gas (BME680)Temperatura0x001C28
Presión Atmosférica0x001E30
Humedad0x002032
Calidad del Aire (VOC)0x002234
Grove - Sensor de Gas V2 (Multicanal)NO20x002436
C2H5OH0x002638
VOC0x002840
CO0x002A42
Grove - Sensor UVIntensidad UV0x002C44
Grove - Sensor de Turbidez V1.0Turbidez0x002E46
Grove - Sensor TDSTDS0x003048
Grove - Sensor de Distancia UltrasónicaDistancia0x003250

3. Conocimiento sobre la Conexión del Hardware

Conecta el pin SIG (señal) del sensor a uno de los pines analógicos del microcontrolador. Alimenta con 5 V–3.3 V al pin VCC y conecta GND a tierra del microcontrolador.

El sensor Grove incluye un potenciómetro que permite al usuario ajustar la ganancia, haciendo que se adapte a diferentes niveles de voltaje de entrada. Esto ayuda a modificar la sensibilidad del sensor.

4. A partir de los pasos anteriores, ya tenemos la librería para el sensor AC Grove:

Siguiendo los pasos anteriores, hemos creado la librería para implementar el sensor de corriente alterna 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 Arduino para hacer pruebas iniciales

El siguiente programa permite probar el sensor mediante una lectura básica de la señal de corriente alterna. Para obtener valores precisos, es necesario inicializar algunos parámetros antes de ejecutar el programa.

Primero, carga el programa al microcontrolador y luego calibra los parámetros para que se ajusten a las lecturas reales del sensor.

#define AC_ADC_PIN A2				// Se utiliza el pin A2
#define ADC_BITS 12 // Depende del microcontrolador
#define Calibration_Value 523.56 // Valor obtenido tras calibración
#define Phase_Shift 1.7 // Ajuste de fase según calibración

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; // Número de ciclos AC a medir
unsigned int timeout = 500; // Tiempo máximo de espera (ms)
int SupplyVoltage = 3300; // Voltaje de referencia (en mV)
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();

// Espera a un cruce por cero para iniciar la medición
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;
checkVCross = (sampleV > startV);

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. Obtener el valor de calibración

Inicialmente, el pin analógico está configurado en el pin A2, pero se puede cambiar según tus necesidades, utilizando el parámetro AC_ADC_PIN.
Los valores de Calibration_Value y Phase_Shift deben cambiarse cada vez que cambies la fuente de voltaje, ya que el voltaje de CA varía de un país a otro o incluso de un enchufe a otro.

El programa muestra el valor del sensor en el monitor serial. También se puede abrir el Serial Plotter para ver la gráfica de voltaje vs tiempo.

  • Paso 1: Toma el multímetro, mide el voltaje de CA y anótalo.
  • Paso 2: De forma similar, anota el voltaje mostrado en el monitor serial.

En mi caso, la lectura del multímetro es de 220 V RMS, mientras que el sensor muestra 718.87 V en el monitor serial. Para obtener un valor de calibración preciso, necesitamos hacer una simple operación matemática usando la siguiente fórmula.

Fórmula de voltaje del sensor

  • Paso 3: Encuentra el valor de x y reemplázalo por Calibration_Value en el programa, luego flashea el programa al microcontrolador.

Fórmula de voltaje del sensor

Puedes cambiar otros parámetros como Phase_Shift, el número de ciclos de CA y el tiempo de espera (timeout) de acuerdo con tu configuración o dejar los valores por defecto.

Referencia

Lista de módulos Grove compatibles con SenseCAP S2110 Sensor Builder

Actualmente, SenseCAP S2110 Sensor Builder es compatible de forma nativa con los siguientes módulos Grove para comunicarse con el registrador de datos SenseCAP y enviar los datos del sensor a la plataforma SenseCAP vía LoRa.

✨ Proyecto del Contribuyente

Soporte Técnico y Discusión del Producto

¡Gracias por elegir nuestros productos!
Estamos aquí para brindarte soporte técnico y asegurarnos de que tu experiencia sea lo más fluida posible.
Ofrecemos varios canales de comunicación para adaptarnos a diferentes preferencias y necesidades.

Loading Comments...