io card support

This commit is contained in:
Siwat Sirichai 2023-12-27 23:15:11 +07:00
parent 75967bf1b3
commit 1f8ad10609
16 changed files with 999 additions and 0 deletions

View file

@ -0,0 +1,38 @@
#include <ESPMegaPRO.h>
#include <AnalogCard.hpp>
void AnalogCard::dacWrite(uint8_t pin, uint16_t value) {
switch(pin) {
case 0:
this->dac0.writeDAC(value);
break;
case 1:
this->dac1.writeDAC(value);
break;
case 2:
this->dac2.writeDAC(value);
break;
case 3:
this->dac3.writeDAC(value);
break;
}
}
uint16_t AnalogCard::analogRead(uint8_t pin) {
if (pin >= 0 && pin <= 3) {
return this->analogInputBankA.readADC_SingleEnded(pin);
} else if (pin >= 4 && pin <= 7) {
return this->analogInputBankB.readADC_SingleEnded(pin - 4);
}
}
void AnalogCard::begin() {
this->dac0 = MCP4725(DAC0_ADDRESS);
this->dac1 = MCP4725(DAC1_ADDRESS);
this->dac2 = MCP4725(DAC2_ADDRESS);
this->dac3 = MCP4725(DAC3_ADDRESS);
this->dac0.begin();
this->dac1.begin();
this->dac2.begin();
this->dac3.begin();
this->analogInputBankA.begin(ANALOG_INPUT_BANK_A_ADDRESS);
this->analogInputBankB.begin(ANALOG_INPUT_BANK_B_ADDRESS);
}

View file

@ -0,0 +1,26 @@
#pragma once
#include <ESPMegaPRO.h>
#include <Adafruit_ADS1X15.h>
#include <MCP4725.h>
#define ANALOG_INPUT_BANK_A_ADDRESS 0x48
#define ANALOG_INPUT_BANK_B_ADDRESS 0x49
#define DAC0_ADDRESS 0x60
#define DAC1_ADDRESS 0x61
#define DAC2_ADDRESS 0x62
#define DAC3_ADDRESS 0x63
class AnalogCard {
public:
AnalogCard();
void dacWrite(uint8_t pin, uint16_t value);
uint16_t analogRead(uint8_t pin);
void begin();
private:
MCP4725 dac0;
MCP4725 dac1;
MCP4725 dac2;
MCP4725 dac3;
Adafruit_ADS1115 analogInputBankA;
Adafruit_ADS1115 analogInputBankB;
};

View file

@ -0,0 +1,96 @@
#pragma once
#include <ESPMegaPRO.h>
#include <DigitalInputCard.hpp>
// Instantiate the card with the specified address
DigitalInputCard::DigitalInputCard(uint8_t address_a, uint8_t address_b) {
this->address_a = address_a;
this->address_b = address_b;
}
// Instantiate the card with the specified position on the dip switch
// Bit 0,1,2 are for bank A
// Bit 3,4,5 are for bank B
DigitalInputCard::DigitalInputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4, bool bit5) {
this->address_a = 0x20;
this->address_b = 0x20;
if (bit0) this->address_a += 1;
if (bit1) this->address_a += 2;
if (bit2) this->address_a += 4;
if (bit3) this->address_b += 1;
if (bit4) this->address_b += 2;
if (bit5) this->address_b += 4;
}
// Initialize the card
void DigitalInputCard::begin() {
this->inputBankA = PCF8574(this->address_a);
this->inputBankB = PCF8574(this->address_b);
this->inputBankA.begin();
this->inputBankB.begin();
}
// Refresh and Read the input from the specified pin, always refresh the input buffers
uint8_t DigitalInputCard::digitalRead(uint8_t pin) {
digitalRead(pin, true);
}
// Read the input from the specified pin, also refresh the input buffers if refresh is true
uint8_t DigitalInputCard::digitalRead(uint8_t pin, bool refresh) {
// First check if the pin is in bank A or B
if (pin >= 0 && pin <= 7) {
// Refresh the input buffers if refresh is true
if (refresh) refreshInputBankA();
// Extract the bit from the buffer
return ((inputBufferA >> (7 - pin)) & 1);
} else if (pin >= 8 && pin <= 15) {
// Refresh the input buffers if refresh is true
if (refresh) refreshInputBankB();
// Extract the bit from the buffer
return ((inputBufferB >> (15 - pin)) & 1);
}
}
// Preform a loop to refresh the input buffers
void DigitalInputCard::loop() {
// Store the current input buffers
uint8_t inputBufferA_old = inputBufferA;
uint8_t inputBufferB_old = inputBufferB;
// Refresh the input buffers
refreshInputBankA();
refreshInputBankB();
// Iterate over all pins and check if they changed
for (int i = 0; i < 16; i++) {
// Check which bank the pin is in
if (i<8) {
// Check if the pin changed
if (((inputBufferA_old >> (7 - i)) & 1) != ((inputBufferA >> (7 - i)) & 1)) {
// Call the callback function if it is not null and pass the pin and the new value
if (callback != NULL) callback(i, ((inputBufferA >> (7 - i)) & 1));
}
} else {
// Check if the pin changed
if (((inputBufferB_old >> (15 - i)) & 1) != ((inputBufferB >> (15 - i)) & 1)) {
// Call the callback function if it is not null and pass the pin and the new value
if (callback != NULL) callback(i, ((inputBufferB >> (15 - i)) & 1));
}
}
}
}
// Get the input buffer for bank A
uint8_t DigitalInputCard::getInputBufferA() {
return inputBufferA;
}
// Get the input buffer for bank B
uint8_t DigitalInputCard::getInputBufferB() {
return inputBufferB;
}
// Register a callback function to be called when a pin changes
void DigitalInputCard::registerCallback(void (*callback)(int, bool)) {
this->callback = callback;
}
// Refresh the input buffer for bank A
void DigitalInputCard::refreshInputBankA() {
inputBufferA = inputBankA.read8();
}
// Refresh the input buffer for bank B
void DigitalInputCard::refreshInputBankB() {
inputBufferB = inputBankB.read8();
}

View file

@ -0,0 +1,35 @@
#pragma once
#include <ESPMegaPRO.h>
#include <PCF8574.h>
class DigitalInputCard {
public:
// Instantiate the card with the specified address
DigitalInputCard(uint8_t address_a, uint8_t address_b);
// Instantiate the card with the specified position on the dip switch
DigitalInputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4, bool bit5);
// Initialize the card
void begin();
// Refresh and Read the input from the specified pin, always refresh the input buffers
uint8_t digitalRead(uint8_t pin);
// Read the input from the specified pin, also refresh the input buffers if refresh is true
uint8_t digitalRead(uint8_t pin, bool refresh);
// Preform a loop to refresh the input buffers
void loop();
// Get the input buffer for bank A
uint8_t getInputBufferA();
// Get the input buffer for bank B
uint8_t getInputBufferB();
// Register a callback function to be called when a pin changes
void registerCallback(void (*callback)(int, bool));
private:
PCF8574 inputBankA;
PCF8574 inputBankB;
uint8_t address_a;
uint8_t address_b;
uint8_t inputBufferA;
uint8_t inputBufferB;
void (*callback)(int, bool);
void refreshInputBankA();
void refreshInputBankB();
};

View file

@ -0,0 +1,32 @@
#include <DigitalOutputCard.hpp>
DigitalOutputCard::DigitalOutputCard(uint8_t address) {
this->address = address;
}
// Instantiate the card with the specified position on the dip switch
DigitalOutputCard::DigitalOutputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4) {
this->address = 0x20;
if (bit0) this->address += 1;
if (bit1) this->address += 2;
if (bit2) this->address += 4;
if (bit3) this->address += 8;
if (bit4) this->address += 16;
}
// Initialize the card
void DigitalOutputCard::begin() {
this->pwm = Adafruit_PWMServoDriver(this->address);
this->pwm.begin();
}
// Set the output to the specified state
void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) {
this->pwm.setPin(pin, state ? 4095 : 0);
}
// Set the output to the specified pwm value
void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) {
// If value is greater than 4095, set it to 4095
if (value > 4095) value = 4095;
// Set the pwm value
this->pwm.setPin(pin, value);
}

View file

@ -0,0 +1,20 @@
#pragma once
#include <ESPMegaPRO.h>
#include <Adafruit_PWMServoDriver.h>
class DigitalOutputCard
{
public:
// Instantiate the card with the specified address
DigitalOutputCard(uint8_t address);
// Instantiate the card with the specified position on the dip switch
DigitalOutputCard(bool bit0, bool bit1, bool bit2, bool bit3, bool bit4);
// Initialize the card
void begin();
// Set the output to the specified state
void digitalWrite(uint8_t pin, bool state);
// Set the output to the specified pwm value
void analogWrite(uint8_t pin, uint16_t value);
private:
Adafruit_PWMServoDriver pwm;
uint8_t address;
};