Categories

CMIS-1 Test Code DC Current with OLED Display

WIKI:

CMIS (Current Monitor IoT Sensors), SDK Kit is based on an Espressif ESP32 WROOM and the board has four AC/DC ACS758 100A (ACS758LCB-100B-PFF-T), Hall Effect based, Linear Current Sensors.

These bi-directional current sensors will read +/- 100A and have a sensitivity of typically 20mV/A.

 

The example code below will measure a low voltage DC Current, typically relating to solar storage batteries charge and discharging.  The ACS725 will in turn output a DC voltage, with resultant output to the OLED Display.  Each loop the RED LED will flash.

You may need to initially calibrate the SensorZeroVoltage for each Current Sensor.  Some example code can be found here.

As the sensor can read +/- current, but the output remain DC positive for zero current, the output will sit centre around 50% of VCC which is 5V, so the expected zero current voltage will be 2.5V.  As we are using the ESP32 ADC, we need to reduce 5V to a maximum of 3.3V and to do this a simple potential divider (10K and 18K), is included on the sensor output.  Our Zero current voltage will now be based on around 3.3V / 2 = 1.65V.

The reason for 3.2V and not 3.3V, is that the ESP32 ADC is reported not to be quite linear at the top end.  This means that the ESP32 is not able to distinguish 3.2 V from 3.3 V and you may get the same ADC value for both voltages.  Our input voltage range is based on 0 to 3.2V and using the ESP32 12 bit ADC, this will output a value of  0 – 4095.

Remember, you must power the SDK from an external DC power source, when measuring current.

Other useful advanced ESP32 ADC functions are listed here

Should you wish to expand the code for AC Current measurement, the critical parameter is the peak value as this results in peak current and therefore RMS current (average current).  An interesting article can be found on AC from TronicsBench. Please BEWARE of the danger of HIGH VOLTAGES!  However, our main interest here is low voltage (typically up to around 60V), DC current, so we will concentrate on this basic measurement, with no multi-sampling and filtering, as proof of concept for test purposes.

 

Example Arduino code below.

/*
Dave Williams, DitroniX 2019-2022 (ditronix.net)
CMIS-1 Current Monitor IoT Sensors v1.0
Features include ESP32 MODBUS EEPROM CT Clamp Multi-Current Voltage
PCA v1.00 – Test Code Firmware v1 – 2nd September 2022

Simplified Board Bring Up Test – AC/DC Current Sensors (Output sent to the OLED Display)
.
Remember!
– Set the BOARD to ESP32 DEV Module (or similar).
– You can also set the BAUD rate up to 921600 to speed up flashing.
– The SDK does NOT need external power to flash. It will take Power from the USB 5V.
– You MUST power the SDK from an external DC power source, when measuring current.
– You can have the USB and external DC power connected at the same time.
.
Note that in the default state, upon first power up and during reset, the Green LED will be partially lit. Once programmed and the GPIO defined, the Green LED will go off after power up.
.
The purpose of this test code is to cycle through the various main functions of the board as part of bring up testing.
.
This test code is OPEN SOURCE and although is is not intended for real world use, it may be freely used, or modified as needed.
It is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/

// Libraries
#include <driver/adc.h>
#include <GyverOLED.h>

// **************** VARIABLES / DEFINES / STATIC ****************

// Constants
const int LoopDelay = 2; // Loop Delay in Seconds
const float SensorRatioFactor = 0.0132; // Sensor Sensitivity 20mV/A @ 5V x 0.66
const float SensorQuiescent = 0.5; // Minimum Measurement
const float SensorCutOffPositive = 1.0;
const float SensorCutOffNegative = -1.0;
const float Sensor1ZeroVoltage = 1.484; // Calibration value based on 0 Amp reading
const float Sensor2ZeroVoltage = 1.480; // Calibration value based on 0 Amp reading
const float Sensor3ZeroVoltage = 1.480; // Calibration value based on 0 Amp reading
const float Sensor4ZeroVoltage = 1.470; // Calibration value based on 0 Amp reading
const float ADCFactorVoltage = 3.3 / 4095.0; // 0.0008058

// Variables
float SensorVoltage;
float SensorCalculatedCurrent;

// **************** OUTPUTS ****************
#define LED_Red 2 // Red LED
#define LED_Green 4 // Green LED

// **************** INPUTS ****************
#define Current_1 35 //GPIO 35 (Analog ADC1_CH7)
#define Current_2 32 //GPIO 32 (Analog ADC1_CH4)
#define Current_3 33 //GPIO 33 (Analog ADC1_CH5)
#define Current_4 27 //GPIO 27 (Analog ADC2_CH7)

// OLED Instance. You will need to select your OLED Display.
// Uncomment/Comment as needed.
//GyverOLED<SSD1306_128x32, OLED_BUFFER> oled;
//GyverOLED<SSD1306_128x32, OLED_NO_BUFFER> oled;
GyverOLED<SSD1306_128x64, OLED_BUFFER> oled;
//GyverOLED<SSD1306_128x64, OLED_NO_BUFFER> oled;
//GyverOLED<SSH1106_128x64> oled;

void setup() {

// Stabalise
delay(250);

// LEDs
pinMode(LED_Red, OUTPUT);
pinMode(LED_Green, OUTPUT);

// LEDs Default Off State
digitalWrite(LED_Red, HIGH);
digitalWrite(LED_Green, HIGH);

// OLED
oled.init();
oled.clear();
oled.setCursor(18, 0);
oled.setScale(5);
oled.print(“CMIS”);
oled.setCursor(8, 5);
oled.setScale(1);
oled.print(“DitroniX.net / wiki”);
oled.update();
delay(2000);
}

void loop() {

// Loop through the four channels and display on the OLED.

// Basic Reading of Current 1
SensorVoltage = ADCFactorVoltage * analogRead(Current_1);
SensorVoltage = SensorVoltage – Sensor1ZeroVoltage;
SensorCalculatedCurrent = SensorVoltage / SensorRatioFactor;

// Display Basic Current
if (SensorCalculatedCurrent >= SensorCutOffPositive || SensorCalculatedCurrent <= SensorCutOffNegative) {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor1″);
oled.setCursor(0, 5);
oled.print(SensorCalculatedCurrent, 1);
oled.println(” A”);
oled.update();

} else {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor1”);
oled.setCursor(8, 5);
oled.println(“-Zero-“);
oled.update();
}

// Loop Delay
delay(LoopDelay * 1000);

// Basic Reading of Current 2
SensorVoltage = ADCFactorVoltage * analogRead(Current_2);
SensorVoltage = SensorVoltage – Sensor2ZeroVoltage;
SensorCalculatedCurrent = SensorVoltage / SensorRatioFactor;

// Display Basic Current
if (SensorCalculatedCurrent >= SensorCutOffPositive || SensorCalculatedCurrent <= SensorCutOffNegative) {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor2″);
oled.setCursor(0, 5);
oled.print(SensorCalculatedCurrent, 1);
oled.println(” A”);
oled.update();

} else {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor2”);
oled.setCursor(8, 5);
oled.println(“-Zero-“);
oled.update();
}

// Loop Delay
delay(LoopDelay * 1000);

// Basic Reading of Current 3
SensorVoltage = ADCFactorVoltage * analogRead(Current_3);
SensorVoltage = SensorVoltage – Sensor3ZeroVoltage;
SensorCalculatedCurrent = SensorVoltage / SensorRatioFactor;

// Display Basic Current
if (SensorCalculatedCurrent >= SensorCutOffPositive || SensorCalculatedCurrent <= SensorCutOffNegative) {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor3″);
oled.setCursor(0, 5);
oled.print(SensorCalculatedCurrent, 1);
oled.println(” A”);
oled.update();

} else {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor3”);
oled.setCursor(8, 5);
oled.println(“-Zero-“);
oled.update();
}

// Loop Delay
delay(LoopDelay * 1000);

// Basic Reading of Current 4
SensorVoltage = ADCFactorVoltage * analogRead(Current_4);
SensorVoltage = SensorVoltage – Sensor4ZeroVoltage;
SensorCalculatedCurrent = SensorVoltage / SensorRatioFactor;

// Display Basic Current
if (SensorCalculatedCurrent >= SensorCutOffPositive || SensorCalculatedCurrent <= SensorCutOffNegative) {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor4″);
oled.setCursor(0, 5);
oled.print(SensorCalculatedCurrent, 1);
oled.println(” A”);
oled.update();

} else {
oled.clear();
oled.setScale(3);
oled.setCursor(0, 1);
oled.print(“Sensor4”);
oled.setCursor(8, 5);
oled.println(“-Zero-“);
oled.update();
}

// Heatbeat LED
digitalWrite(LED_Red, LOW);
delay(50);
digitalWrite(LED_Red, HIGH);

// Loop Delay
delay(LoopDelay * 1000);

}

Leave a Reply

This site uses User Verification plugin to reduce spam. See how your comment data is processed.