4-20 mA signal measurement with Arduino
In this video I show you how to measure the output signal of a 4-20 mA-type sensor and convert it into some values using an Arduino. You will learn how to build a "current to voltage" circuit with a simple protection (Zener diode) and you will also learn how you can customize my source code to convert the signal of any sensor into a human-readable format.
Drawings and schematics
Arduino source code
//Arduino Nano; SDA = A4, SCL = A5 #include <Wire.h> //--Display--------------------------------------------- #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 #define OLED_RESET 4 // Reset pin Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); float Current = 0; //4-20 mA (mapped) float rawADCValue = 0; //0-1023 float ADCVoltage = 0; //0-5 V float pressure = 0; //0-250 bar (mapped) int ADC_Pin = A1; void setup() { Serial.begin(115200); if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { Serial.println(F("SSD1306 allocation failed")); for (;;); // Don't proceed, loop forever } display.display(); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.setTextSize(2); display.clearDisplay(); // Clear display display.setCursor(0, 0); // Start at top-left corner display.print("0.00"); display.display(); display.clearDisplay(); } void loop() { readADC(); printLCD(); } void readADC() { rawADCValue = 0; //Reset the value before summation for (int i = 0; i < 100; i++) //Do 100 readings { rawADCValue += analogRead(ADC_Pin); delay(5); //"settling time" for the ADC //Sum the results 100 times } ADCVoltage = (float)(rawADCValue / 100.0) * (4630 / 1023.0); //The average is converted into voltage (5000 mV = 5 V) //measure the real 5 V of your board and substitute the result (mine was 4630 mV) Serial.print("RAW: "); Serial.println((rawADCValue / 100.0)); Serial.print("Voltage: "); Serial.println(ADCVoltage); //For 220 Ohm: 4 mA * 220 Ohm = 880 mV, 20 mA * 220 Ohm = 4400 mV //For 250 Ohm: 4 mA * 250 Ohm = 1000 mV, 20 mA * 250 Ohm = 5000 mV //Note: measure the 220 (or 250) resistor, and calculate the actual voltages Current = mapfloat(ADCVoltage, 880, 4400, 4, 20); // Voltage between 880-4400 mV is distributed as current 4-20 mA //2640 mV should be 12 mA equivalent Serial.print("Current: "); Serial.println(Current); pressure = mapfloat(Current, 4, 20, 0, 250); Serial.print("Pressure: "); Serial.println(pressure); //Current between 4-20 mA is distributed as pressure between 0-250 bar. //12 mA should be 125 bar equivalent } void printLCD() { display.clearDisplay(); display.setTextSize(3); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println(ADCVoltage); //Print the voltage (in mV) display.setCursor(0, 40); display.println(Current); //Print the corresponding current display.display(); } float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }