Files
Library-ES32A08/ES32A08.cpp
2025-02-05 11:59:39 -05:00

300 lines
7.4 KiB
C++

#include "ES32A08.h"
// Initialize the board and reset it
void ES32A08::begin() {
// 74HC595D shift register config (Relay + 7-Seg disp.)
pinMode(DATA_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(OE_PIN, OUTPUT);
digitalWrite(DATA_PIN, LOW);
digitalWrite(LATCH_PIN, LOW);
digitalWrite(CLOCK_PIN, LOW);
digitalWrite(OE_PIN, LOW);
pinMode(PWR_LED_PIN, OUTPUT); // "PWR" board Led
pinMode(buttonPins[0], INPUT_PULLUP);
pinMode(buttonPins[1], INPUT_PULLUP);
pinMode(buttonPins[2], INPUT_PULLUP);
pinMode(buttonPins[3], INPUT_PULLUP);
// Digital inputs shift register config
pinMode(LOAD165_PIN, OUTPUT);
pinMode(CLK165_PIN, OUTPUT);
pinMode(DATA165_PIN, INPUT);
digitalWrite(LOAD165_PIN, HIGH);
reset();
xTaskCreatePinnedToCore(ES32A08::updateRegisters, "Update Registers",
2048, // Stack size
this, // Parameter
1, // Priority
NULL, // Task handle
1 // Core on which the task will run
);
}
// Open relays and clear display
void ES32A08::reset() {
setPWRLED(RESET_LED_ON);
currentRelays = RESET_RELAY_ON ? 0b11111111 : 0b00000000;
clearDisplay(); // it also calls sendToShiftRegister()
}
// Send relays and display settings to the s.r.
void ES32A08::sendToShiftRegister() {
digitalWrite(LATCH_PIN, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, currentRelays);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, currentDigits);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, currentSegments);
digitalWrite(LATCH_PIN, HIGH);
delayMicroseconds(DIGIT_PERS);
} // There are 3 shift registers for a total of 24 bits
// Clear entire 7-seg display
void ES32A08::clearDisplay() {
memset(displayBuffer, 0, sizeof(displayBuffer));
}
// Task to continuosly feed the registers
void ES32A08::updateRegisters(void *instance) {
ES32A08 *self = static_cast<ES32A08 *>(instance); // Cast del puntatore
for (;;) {
for (uint8_t pos = 0; pos < 4; pos++) {
self->currentDigits = self->digitNumber[1 + pos];
self->currentSegments = self->displayBuffer[pos];
self->sendToShiftRegister();
}
}
}
// Char to segment conversion by LUT
uint8_t ES32A08::charToSegments(char c) {
switch (c) {
case '0':
return 0b00111111; // 0
case '1':
return 0b00000110; // 1
case '2':
return 0b01011011; // 2
case '3':
return 0b01001111; // 3
case '4':
return 0b01100110; // 4
case '5':
return 0b01101101; // 5
case '6':
return 0b01111101; // 6
case '7':
return 0b00000111; // 7
case '8':
return 0b01111111; // 8
case '9':
return 0b01101111; // 9
case ' ':
return 0b00000000; // white space
case '.':
return 0b10000000; // decimal point
case '-':
return 0b01000000; // score
case '_':
return 0b00001000; // underscore
case 'A':
return 0b01110111; // A
case 'a':
return 0b01011111; // a
case 'B':
case 'b':
return 0b01111100; // B-b
case 'C':
return 0b00111001; // C
case 'c':
return 0b01011000; // c
case 'D':
case 'd':
return 0b01011110; // D-d
case 'E':
return 0b01111001; // E
case 'e':
return 0b01111011; // e
case 'F':
case 'f':
return 0b01110001; // F-f
case 'G':
case 'g':
return 0b01101111; // G-g
case 'H':
return 0b01110110; // H
case 'h':
return 0b01110100; // h
case 'I':
return 0b00000110; // I
case 'i':
return 0b00010000; // i
case 'J':
case 'j':
return 0b00011110; // J-j
case 'L':
return 0b00111000; // L
case 'l':
return 0b00011000; // l
case 'M':
case 'm':
return 0b00110111; // M-m
case 'N':
case 'n':
return 0b01010100; // N-n
case 'O':
case 'o':
return 0b01011100; // O-o
case 'P':
case 'p':
return 0b01110011; // P-p
case 'Q':
case 'q':
return 0b01100111; // Q-q
case 'R':
case 'r':
return 0b01010000; // R-r
case 'S':
case 's':
return 0b01101101; // S-s
case 'T':
case 't':
return 0b01111000; // T-t
case 'U':
return 0b00111110; // U
case 'u':
return 0b00011100; // u
case 'Y':
case 'y':
return 0b01100110; // Y-y
case 'Z':
case 'z':
return 0b01011011; // Z-z
default:
return 0b00000000; // Blank if not found
}
}
// Show a 4-char message on the display
void ES32A08::display(const char *message) {
memset(displayBuffer, 0, sizeof(displayBuffer));
for (int pos = 0; message[pos] != '\0' && pos < 4; pos++)
displayBuffer[pos] = charToSegments(message[pos]);
}
// Show a number on the 4-digit display
void ES32A08::display(int number) {
if (number > 9999 || number < -999)
display(" -- ");
else {
char buffer[5]; // Chars buffer + endl ('\0')
snprintf(buffer, sizeof(buffer), "%4d", number);
for (int i = 0; i < 4; i++)
displayBuffer[i] = charToSegments(buffer[i]);
}
}
// Show a float on the 4-digit display
void ES32A08::display(float number) {
memset(displayBuffer, 0, sizeof(displayBuffer));
if (number > 9999 || number < -999)
display(" -- ");
else {
char buffer[6]; // Chars buffer + endl ('\0')
snprintf(buffer, sizeof(buffer), "%.2f", number);
int i;
for (i = 0; i < 4 && buffer[i] != '.'; i++) {
displayBuffer[i] = charToSegments(buffer[i]);
}
if (i == 4)
return; // No decimal point found
if (buffer[i] == '.') {
displayBuffer[i - 1] |= 0b10000000; // Decimal point
for (i; i < 5; i++) {
displayBuffer[i] = charToSegments(buffer[i + 1]);
}
}
}
}
// Read single 4-20mA input
float ES32A08::readAnalogmA(int channel) {
if (channel < 0 || channel > 3)
return 0;
int adcValue = analogRead(mAInputPins[channel]);
float current = ((adcValue / 4095.0) * (20.0 - 4.0)) * 2.0692;
return current;
}
// Read single 0-10V input
float ES32A08::readAnalogVoltage(int channel) {
if (channel < 0 || channel > 3)
return 0;
int adcValue = analogRead(voltageInputPins[channel]);
float voltage = ((adcValue / 4095.0) * 10.0) * 2.0692;
return voltage;
}
// Raw read single 0-10V input
int ES32A08::rawReadAnalogVoltage(int channel) {
if (channel < 0 || channel > 3)
return 0;
return analogRead(voltageInputPins[channel]);
}
// Set single relay
void ES32A08::setRelay(int relay, bool state) {
bitWrite(currentRelays, relay, state);
sendToShiftRegister();
}
// Set all relays (0b00000000 - 0b11111111)
void ES32A08::setRelays(unsigned long relayStates) {
currentRelays = relayStates;
sendToShiftRegister();
}
// Read all digital inputs
uint8_t ES32A08::readDigitalInputs() {
uint8_t inputs = 0;
digitalWrite(LOAD165_PIN, LOW);
delayMicroseconds(5);
digitalWrite(LOAD165_PIN, HIGH);
// delayMicroseconds(5);
for (int i = 0; i < 8; i++) {
digitalWrite(CLK165_PIN, LOW); // Init clock cycle
delayMicroseconds(5);
bitWrite(inputs, 7 - i, digitalRead(DATA165_PIN));
digitalWrite(CLK165_PIN, HIGH);
// delayMicroseconds(5);
}
return inputs;
}
// Read single digital input
bool ES32A08::readDigitalInput(int inputNumber) {
if (inputNumber < 1 || inputNumber > 8)
return false;
uint8_t digitalInputs = readDigitalInputs();
return digitalInputs & (1 << (inputNumber - 1));
}
// Set "PWR" onboard LED
void ES32A08::setPWRLED(bool state) { digitalWrite(PWR_LED_PIN, !state); }
// Read single button state
bool ES32A08::readButton(int buttonNumber) {
return !digitalRead(buttonPins[buttonNumber - 1]);
}