Introduction: Industrial ESP32 Controller for (4-20mA) Current Measurement | Norvi-IIOT-AE02-I Device

About: ESP32 & STM32 based Industrial Controllers

Norvi systems are ESP32 embedded commercial controllers. These devices come with several features with different models that make them suitable for IoT solutions and industrial automation.

Check out our previous Instructables to know more about the Norvi devices.

Getting started with Norvi Devices

Working with Built-in display and push buttons of the Norvi devices

Norvi-IIOT-AE02-V Device - an Industrial ESP32 Controller for (0-10V) Voltage Measurement

The Norvi-IIOT-AE02-I model is capable of measuring 4-20 mA industrial level current. We’ll be looking at how to read analog values (current value between 4-20 mA) with this model in this instructable.

The features of Norvi-IIOT-AE02-I are,

  • 8 Digital Inputs, 24V
  • 6 Analog inputs (4-20mA)
  • 2 Transistor outputs, PWM compatible (36VDC max with 360mW collector power dissipation)
  • RS-485 Communication
  • WIFI & Bluetooth
  • Built-in OLED Display with 3 buttons
  • Expansion port with I2C, UART and GPIO

Check out more about the product - Norvi-IIOT-AE02-I

So what do you need to get started?

  • The Norvi IIOT-AE02-I Device
  • USB cable(Type A to Type B mini)
  • PC/Laptop
  • A 2kΩ resistor
  • Wires
  • Power supply, 24V DC

Step 1: Understanding More About the Display

  • The device has a built-in 0.96 OLED SSD1306 display of 128 x 64 resolution. Its address is 03xC.
  • The GPIOs 16(SDA) and 17(SCL)of ESP32 in the device are used for I2C communication with this display.

Step 2: Understanding More About the Analog Inputs.

  • The device has two ADS1115 modules of addresses 0x48 & 0x49 respectively.
  • ADS1115 is a 16-bit analog to digital converter (ADC) that consists of four analog channels. Here in the device, the entire 4 channels of the first ADS1115 module and the first two channels of the next module are used as analog inputs.
  • The same GPIOs, 16(SDA) and 17(SCL) of ESP32 are used for I2C communication with the ADCs.
  • Each ADC module is capable of measuring a maximum voltage of 4.0V. So considering this into account and to achieve a measurement of 4-20mA the above arrangement is made inside the device using an amplifier and resistor.
  • Hence, the value read by the analog channels of the ADC is 20 times smaller than the actual analog input reading at the analog input pins A0-A5.
  • Here for measurement of 40mV (V1) at the analog input, the current value of 4mA gets mapped(40mV/10Ω). This value gets 20 times multiplied by an amplifier and read as 800mV at the analog channel of the ADC modules. Hence the measurement of 4mA is ensured. Similarly, the measurement of 20mA is achieved.

Step 3: GPIO Pins of Digital Inputs

  • GPIO pins detail of Digital Inputs are as follows,
I.0 = 18    I.1 = 39   I.2 = 34    I.3 = 35
I.4 = 19    I.5 = 21   I.6 = 22    I.7 = 23
  • Here the digital inputs are normally kept on/high (digital logic state "1") by using pull-up resistors inside the device. So when the connection is made the state changes to off/low(digital logic state "0").

To know more about how to work with the digital input side check this instructable - Getting Started With Norvi Devices

Step 4: Analog Inputs and GPIO Pins of Transistor Outputs

  • There are 6 analog input pins starting from A0-A5 which are capable of measuring 4-20mA industrial level current. The first four inputs(A0-A3) are connected to the four channels of the first ADS1115 module of address 0x48 and the final two inputs (A5 & A6) are connected to the first two channels of the second ADS1115 module.
  • The GPIO pins of the transistors are as follows,
T.0 = 26   T.1 = 27

Step 5: Programming the Device

  • Install the Adafruit SSD1306, Adafruit GFX and Adafruit ADS1015 libraries in your Arduino IDE and upload the below sketch.

(For installing ESP32 board and booting up the device, check the steps 1 and 2 of our previous instructable - Getting Started With Norvi Devices)

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_ADS1015.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)

Adafruit_ADS1115 ads1(0x48);
Adafruit_ADS1115 ads2(0x49);

float Voltage = 0.0;
void setup()
{
  Wire.begin(16, 17);
  Serial.begin(115200);
  ads1.begin();
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //starting the display
  display.display();
  delay(2000);
  display.clearDisplay();
}

void loop()
{
  float adc1;

  adc1 = ads1.readADC_SingleEnded(1);
  Voltage = (adc1 * 0.1875) ;

  Serial.print("AIN0: ");
  Serial.print(adc1);
  Serial.print("\tVoltage: ");
  Serial.println(Voltage /20, 3);
  Serial.print("\tCurrent: ");
  Serial.println(Voltage /200, 3);
  delay(1000);
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(15, 0);
  display.println("Voltage Value");
  display.setCursor(45, 15);
  display.println(Voltage/20,3);
  display.setCursor(15, 30);
  display.println("Current Value");
  display.setCursor(45, 45);
  display.println(Voltage/200,3);
  display.display();
  delay(1000);
  display.clearDisplay();

}<br>

Step 6: Understanding the Code

  • The necessary libraries are imported to use I2C (Wire library), to write the display (Adafruit_SSD1306 and Adafruit_GFX libraries) and to read the analog value by the ADCs. (Adafruit_ADS1015 library.)
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_ADS1015.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
  • Then, the width and height of our OLED display are defined.

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
  • Next, with I2C communication protocol (&Wire), a display object with the width and height defined earlier is initialized.

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // Declaration for an SSD1306 display connected to I2C (SDA, SCL pins);
  • The below lines define the addresses of the ADCs.

Adafruit_ADS1115 ads1(0x48);
Adafruit_ADS1115 ads2(0x49);
  • A float variable is defined to store the voltage value.

float Voltage = 0.0;
  • Next, in setup(), we initialize the Serial Monitor at a baud rate of 115200.

 Serial.begin(115200);
  • In the following line, you initialize I2C by setting the sda and scl GPIOs to communicate with the display.

 Wire.begin(16, 17);
  • Then the first ADS1115 module is initialized to begin its operation.

 ads1.begin();
  • Next, the display is initialized using its address.

 display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //starting the display
  • Using the below lines, we can ensure whether our display is working correctly. Here the display check is done for 2s (2000ms) and this can be varied.

display.display();
delay(2000);
display.clearDisplay();
  • Inside the loop() function, the float variable adc0 is initialized which is used to store the output of the analog channel of the first ADC module ads1.

float adc0;
  • The below function reads the first analog channel value of the first ADC module ads1 and stores this value in the “adc0” float variable.
adc0 = ads1.readADC_SingleEnded(0);
  • This statement converts ADC value into a voltage value, (in mV) where 0.1875mV is the resolution of ADS1115.
 Voltage = (adc0 * 0.1875);
  • The below lines prints the value of ADC, voltage read at the analog input of the Norvi device, and current on the serial monitor with a delay of one second after every reading.

Serial.print("AIN0: ");
Serial.print(adc0);
Serial.print("\tVoltage: ");
Serial.println(Voltage/20, 3); //the actual analog input reading is 20 times the value read by the ADC.
Serial.print("\tCurrent: ");
Serial.println(Voltage/200, 3); // And to measure the current we have to divide the  voltage value by (considering the 10Ω resistor)200 as explained in the second step.
Serial.print("\tCurrent: ");
Serial.println(Voltage /200, 3);
delay(1000);
  • The text size, text color and text position are defined. The voltage & the current values read are displayed on the OLED screen.

display.setTextSize(1);
display.setTextColor(WHITE); 
display.setCursor(15, 0);
display.println("Voltage Value");
display.setCursor(45, 15);
display.println(Voltage/20,3);
display.setCursor(15, 30);
display.println("Current Value");
display.setCursor(45, 45);
display.println(Voltage/200,3);
display.display();
delay(1000);
display.clearDisplay();

Step 7: Making the Circuit Connection and Explanation

  • Complete the circuit as shown in the diagram to get the read value. As per our circuit connection the voltage,

V1 = (10/2010)*24 = 0.1194V (Theoretically)

The current flowing through the 10Ω resistor,

I = 0.119/10=0.0119A = 11.9mA (Theoretically)

  • This can be verified by checking the voltage difference and the current flow between the analog input of the device (A0)& the common terminal, using a multimeter.

    **It is to be noted that Norvi-IIOT-AE02-I is capable of reading 4-20mA industrial level current.

Step 8: Code Verification

  • Once you upload the sketch and boot up the device, the device displays “Voltage Value” and “Current Value”.
  • The ADC value read using the serial monitor in Arduino IDE should be near to a value of 13050. This implies that the voltage value V2 read by the analog channel of the ADC module is equal to 2.446875V (13050 * 0.1875/1000) {code ---> Voltage = (adc0 * 0.1875)/1000)
  • Hence the actual voltage value read at the analog input A0 of our device will be, V1=0.122V (2.446875/20) which is almost equal to the same value (0.119V) that we obtained in our theoretical calculation.

Check more about the Norvi lineup - www.norvi.lk