/*
Analog Input wiht Fault
RAW: 0-1024
MA: 0-21mA
EU: -25.0 - 100.00 %
*/
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
#define ZERO_RANGE 0.0F
#define FULL_RANGE 20.0F
#define BLINK_TIME_DELAY 500UL
#define LCD_TIME_DELAY 100UL
#define zeroRangePin 2
#define fullRangePin 3
#define analogInputPin A0
typedef struct {
private:
unsigned long startTime;
bool enable;
public:
bool state;
bool timerOn(unsigned long dt, bool en = true);
} timer_t;
bool timer_t::timerOn(unsigned long delayTime, bool en) {
if (en) {
if (!state) {
unsigned long currTime = millis();
if (!enable) startTime = currTime;
unsigned long elapsedTime = currTime - startTime;
if (elapsedTime >= delayTime) {
state = true;
}
}
} else {
state = false;
}
enable = en;
return state;
}
timer_t blinkTimer;
timer_t lcdPrintTimer;
int raw;
float voltageInput;
float currentInput;
float percentage;
bool fullRange;
bool zeroRange;
bool toggle;
void setup() {
lcd.init();
lcd.backlight();
lcd.setCursor(4, 0);
lcd.print("ANALOG INPUT");
pinMode(zeroRangePin, OUTPUT);
pinMode(fullRangePin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
Blink();
AnalogCondition();
LCDPrint();
}
void AnalogCondition() {
raw = analogRead(analogInputPin);
voltageInput = Scale(raw, 0, 1023, 0, 5); // Voltage: 0.0 - 5.0 V
currentInput = Scale(raw, 0, 1023, 0, 20); // Current: 0.0 - 20.0 mA
percentage = Scale(currentInput, 4, 20, 0, 100); // Percent: 0.0 - 100.0 % @4-20mA
zeroRange = currentInput <= ZERO_RANGE;
fullRange = currentInput >= FULL_RANGE;
digitalWrite(zeroRangePin, zeroRange);
digitalWrite(fullRangePin, fullRange);
}
void Blink() {
if (!blinkTimer.timerOn(BLINK_TIME_DELAY, !blinkTimer.state)) return;
toggle = !toggle;
digitalWrite(LED_BUILTIN, toggle);
}
float Scale(float value, int rawMin, int rawMax, int euMin, int euMax) {
return (value - rawMin) * (euMax - euMin) / (rawMax - rawMin) + euMin;
}
void LCDPrint() {
if (!lcdPrintTimer.timerOn(LCD_TIME_DELAY, !lcdPrintTimer.state)) {
lcd.setCursor(0, 1);
lcd.print("Votage:");
lcd.print(PadLeft(String(voltageInput, 2), 7, ' '));
lcd.setCursor(0, 2);
lcd.print("Current:");
lcd.print(PadLeft(String(currentInput, 2), 6, ' '));
lcd.setCursor(0, 3);
lcd.print("Percent:");
lcd.print(PadLeft(String(percentage, 2), 6, ' '));
}
}
String PadLeft(String message, int length, char paddingChar) {
int lenPad = length - message.length();
for (int index = 0; index < lenPad; index++) {
message = paddingChar + message;
}
return message.substring(0, length);
}
100.0%
EU MAX
|
4.0mA
0.0%
|
0.0
EU MIN
|
50.0
|
0.0mA
-25.0%
|
20.0mA
ZERO
FULL
An example of the signal level for the failure