Merge branch 'analog'
This commit is contained in:
commit
1e08039a1e
|
@ -92,6 +92,23 @@ char AC_ROOM_TEMPERATURE_TOPIC[75];
|
|||
char AC_HUMIDITY_TOPIC[75];
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
#define DAC_COUNT 4
|
||||
#define ADC_COUNT 8
|
||||
bool dac_states[DAC_COUNT];
|
||||
uint16_t dac_values[DAC_COUNT];
|
||||
uint16_t adc_values[ADC_COUNT];
|
||||
bool adc_report_enable[ADC_COUNT];
|
||||
|
||||
char ADC_COMMAND_TOPIC[75];
|
||||
char ADC_STATE_TOPIC[75];
|
||||
char ADC_REPORT_TOPIC[75];
|
||||
char DAC_SET_STATE_TOPIC[75];
|
||||
char DAC_SET_VALUE_TOPIC[75];
|
||||
char DAC_STATE_TOPIC[75];
|
||||
char DAC_VALUE_TOPIC[75];
|
||||
#endif
|
||||
|
||||
// EEPROM ADDRESS
|
||||
#define EEPROM_ADDRESS_AC_MODE 0 // 01bytes
|
||||
#define EEPROM_ADDRESS_AC_TEMPERATURE 1 // 01bytes
|
||||
|
@ -109,6 +126,9 @@ char AC_HUMIDITY_TOPIC[75];
|
|||
#define EEPROM_ADDRESS_MQTT_USERNAME 122 // 32bytes, thru 153
|
||||
#define EEPROM_ADDRESS_MQTT_PASSWORD 154 // 32bytes, thru 185
|
||||
#define EEPROM_ADDRESS_MQTT_USEAUTH 186 // 1bytes
|
||||
#define EEPROM_ADDRESS_ADC_REPORT_STATE 187 // 8bytes, thru 194
|
||||
#define EEPROM_ADDRESS_DAC_STATE 195 // 4bytes, thru 198
|
||||
#define EEPROM_ADDRESS_DAC_VALUE 199 // 8bytes, thru 206
|
||||
|
||||
char PWM_STATE_TOPIC[75];
|
||||
char PWM_VALUE_TOPIC[75];
|
||||
|
@ -125,7 +145,8 @@ Thread mqtt_reconnector = Thread();
|
|||
Thread environment_reporter = Thread();
|
||||
Thread eeprom_pwm_updater = Thread();
|
||||
Thread user_timer_tick = Thread();
|
||||
StaticThreadController<4> thread_controller(&mqtt_reconnector, &environment_reporter, &eeprom_pwm_updater, &user_timer_tick);
|
||||
Thread analog_handler = Thread();
|
||||
StaticThreadController<5> thread_controller(&mqtt_reconnector, &environment_reporter, &eeprom_pwm_updater, &user_timer_tick, &analog_handler);
|
||||
|
||||
#ifdef ENABLE_INTERNAL_LCD
|
||||
Thread top_bar_updater = Thread();
|
||||
|
@ -297,6 +318,30 @@ void eeprom_retrieve_init()
|
|||
strcat(PWM_VALUE_TOPIC, "/pwm/00/value");
|
||||
memcpy(INPUTS_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(INPUTS_TOPIC, "/input/00");
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
memcpy(ADC_COMMAND_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(ADC_COMMAND_TOPIC, "/adc/00/set/state");
|
||||
memcpy(ADC_STATE_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(ADC_STATE_TOPIC, "/adc/00/state");
|
||||
memcpy(ADC_REPORT_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(ADC_REPORT_TOPIC, "/adc/00/report");
|
||||
memcpy(DAC_SET_STATE_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(DAC_SET_STATE_TOPIC, "/dac/00/set/state");
|
||||
memcpy(DAC_SET_VALUE_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(DAC_SET_VALUE_TOPIC, "/dac/00/set/value");
|
||||
memcpy(DAC_STATE_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(DAC_STATE_TOPIC, "/dac/00/state");
|
||||
memcpy(DAC_VALUE_TOPIC, MQTT_BASE_TOPIC, 20);
|
||||
strcat(DAC_VALUE_TOPIC, "/dac/00/value");
|
||||
ESPMega_FRAM.read(EEPROM_ADDRESS_ADC_REPORT_STATE, (uint8_t *)adc_report_enable, 8);
|
||||
ESPMega_FRAM.read(EEPROM_ADDRESS_DAC_STATE, (uint8_t *)dac_states, 4);
|
||||
ESPMega_FRAM.read(EEPROM_ADDRESS_DAC_VALUE, (uint8_t *)dac_values, 8);
|
||||
for (int i = 0; i < DAC_COUNT; i++)
|
||||
{
|
||||
dac_set_state(i, dac_states[i]);
|
||||
dac_set_value(i, dac_values[i]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WEBUI
|
||||
|
@ -534,6 +579,12 @@ void mqtt_connect()
|
|||
publish_ac_state();
|
||||
#endif
|
||||
mqtt_connected_user_callback();
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
publish_dac_states();
|
||||
publish_dac_values();
|
||||
publish_adc_values();
|
||||
publish_adc_states();
|
||||
#endif
|
||||
standalone = false;
|
||||
ESPMega_updateTimeFromNTP();
|
||||
}
|
||||
|
@ -572,6 +623,23 @@ void mqtt_subscribe()
|
|||
mqtt.subscribe(AC_SET_MODE_TOPIC);
|
||||
#endif
|
||||
mqtt.subscribe(STATE_REQUEST_TOPIC);
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
for (int i = 0; i < ADC_COUNT; i++)
|
||||
{
|
||||
ADC_COMMAND_TOPIC[base_topic_length + 4] = ((i - i % 10) / 10) + '0';
|
||||
ADC_COMMAND_TOPIC[base_topic_length + 5] = (i % 10) + '0';
|
||||
mqtt.subscribe(ADC_COMMAND_TOPIC);
|
||||
}
|
||||
for (int i = 0; i < DAC_COUNT; i++)
|
||||
{
|
||||
DAC_SET_STATE_TOPIC[base_topic_length + 4] = ((i - i % 10) / 10) + '0';
|
||||
DAC_SET_STATE_TOPIC[base_topic_length + 5] = (i % 10) + '0';
|
||||
DAC_SET_VALUE_TOPIC[base_topic_length + 4] = ((i - i % 10) / 10) + '0';
|
||||
DAC_SET_VALUE_TOPIC[base_topic_length + 5] = (i % 10) + '0';
|
||||
mqtt.subscribe(DAC_SET_STATE_TOPIC);
|
||||
mqtt.subscribe(DAC_SET_VALUE_TOPIC);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -597,6 +665,20 @@ void mqtt_callback(char *topic, byte *payload, unsigned int length)
|
|||
{
|
||||
pwm_value_callback(topic_trim, topic_length, payload_nt, length);
|
||||
}
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
else if ((!strncmp(topic_trim, "/adc/", 5)) && !strncmp(topic_trim + 7, "/set/state", 10))
|
||||
{
|
||||
adc_set_state_callback(topic_trim, topic_length, payload_nt, length);
|
||||
}
|
||||
else if ((!strncmp(topic_trim, "/dac/", 5)) && !strncmp(topic_trim + 7, "/set/state", 10))
|
||||
{
|
||||
dac_set_state_callback(topic_trim, topic_length, payload_nt, length);
|
||||
}
|
||||
else if ((!strncmp(topic_trim, "/dac/", 5)) && !strncmp(topic_trim + 7, "/set/value", 10))
|
||||
{
|
||||
dac_set_value_callback(topic_trim, topic_length, payload_nt, length);
|
||||
}
|
||||
#endif
|
||||
else if (!strcmp(topic, STATE_REQUEST_TOPIC))
|
||||
{
|
||||
state_request_callback();
|
||||
|
@ -628,6 +710,10 @@ void thread_initialization()
|
|||
eeprom_pwm_updater.setInterval(1000);
|
||||
user_timer_tick.onRun(timer_tick_callback);
|
||||
user_timer_tick.setInterval(15000);
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
analog_handler.onRun(adc_loop);
|
||||
analog_handler.setInterval(ANALOG_REPORTING_INTERVAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -924,6 +1010,12 @@ void state_request_callback()
|
|||
publish_env_state();
|
||||
#endif
|
||||
user_state_request_callback();
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
publish_adc_states();
|
||||
publish_adc_values();
|
||||
publish_dac_states();
|
||||
publish_dac_values();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_IR_MODULE
|
||||
|
@ -1748,3 +1840,274 @@ void check_boot_reset()
|
|||
factory_reset();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ANALOG_MODULE
|
||||
/**
|
||||
* Enables the ADC reporting for the specified ID.
|
||||
*
|
||||
* @param id The ID of the ADC to enable reporting for.
|
||||
*/
|
||||
void enable_adc(int id)
|
||||
{
|
||||
adc_report_enable[id] = true;
|
||||
ESPMega_FRAM.write8(EEPROM_ADDRESS_ADC_REPORT_STATE + id, 1);
|
||||
publish_adc_state(id);
|
||||
}
|
||||
/**
|
||||
* @brief Disables the ADC reporting for the specified ID.
|
||||
*
|
||||
* This function sets the adc_report_enable flag to false for the specified ID and writes the state to the EEPROM.
|
||||
*
|
||||
* @param id The ID of the ADC to disable reporting for.
|
||||
*/
|
||||
void disable_adc(int id)
|
||||
{
|
||||
adc_report_enable[id] = false;
|
||||
ESPMega_FRAM.write8(EEPROM_ADDRESS_ADC_REPORT_STATE + id, 0);
|
||||
publish_adc_state(id);
|
||||
}
|
||||
|
||||
void publish_adc_state(int id)
|
||||
{
|
||||
ADC_STATE_TOPIC[base_topic_length + 4] = ((id - id % 10) / 10) + '0';
|
||||
ADC_STATE_TOPIC[base_topic_length + 5] = (id % 10) + '0';
|
||||
mqtt.publish(ADC_STATE_TOPIC, adc_report_enable[id] ? "on" : "off");
|
||||
}
|
||||
|
||||
void publish_adc_states()
|
||||
{
|
||||
for (int i = 0; i < ADC_COUNT; i++)
|
||||
{
|
||||
publish_adc_state(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the ADC value for the specified ID if ADC reporting is enabled.
|
||||
*
|
||||
* @param id The ID of the ADC channel.
|
||||
*/
|
||||
void adc_update(int id)
|
||||
{
|
||||
if (adc_report_enable[id])
|
||||
{
|
||||
adc_values[id] = ESPMega_analogRead(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the ADC value for the specified ID, do so even if reporting is disabled..
|
||||
*
|
||||
* @param id The ID of the ADC pin.
|
||||
*/
|
||||
void adc_update_force(int id)
|
||||
{
|
||||
adc_values[id] = ESPMega_analogRead(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates all ADC channels.
|
||||
*
|
||||
* This function updates all ADC channels by calling the `adc_update` function for each channel.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void adc_update_all()
|
||||
{
|
||||
for (int i = 0; i < ADC_COUNT; i++)
|
||||
{
|
||||
adc_update(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Performs ADC loop operations.
|
||||
*
|
||||
* This function updates all ADC values and publishes them.
|
||||
*/
|
||||
void adc_loop()
|
||||
{
|
||||
adc_update_all();
|
||||
publish_adc_values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes the ADC value to the MQTT broker.
|
||||
*
|
||||
* @param id The ID of the ADC channel.
|
||||
*/
|
||||
void publish_adc_value(int id)
|
||||
{
|
||||
ADC_REPORT_TOPIC[base_topic_length + 4] = ((id - id % 10) / 10) + '0';
|
||||
ADC_REPORT_TOPIC[base_topic_length + 5] = (id % 10) + '0';
|
||||
char temp[8];
|
||||
itoa(adc_values[id], temp, DEC);
|
||||
mqtt.publish(ADC_REPORT_TOPIC, temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes the values of all enabled ADC channels.
|
||||
* This function iterates through all ADC channels and publishes the values
|
||||
* of the enabled channels using the publish_adc() function.
|
||||
*/
|
||||
void publish_adc_values()
|
||||
{
|
||||
for (int i = 0; i < ADC_COUNT; i++)
|
||||
{
|
||||
if (adc_report_enable[i])
|
||||
publish_adc_value(i);
|
||||
}
|
||||
}
|
||||
|
||||
void publish_dac_state(int id)
|
||||
{
|
||||
DAC_STATE_TOPIC[base_topic_length + 4] = ((id - id % 10) / 10) + '0';
|
||||
DAC_STATE_TOPIC[base_topic_length + 5] = (id % 10) + '0';
|
||||
mqtt.publish(DAC_STATE_TOPIC, dac_states[id] ? "on" : "off");
|
||||
}
|
||||
|
||||
void publish_dac_value(int id)
|
||||
{
|
||||
DAC_VALUE_TOPIC[base_topic_length + 4] = ((id - id % 10) / 10) + '0';
|
||||
DAC_VALUE_TOPIC[base_topic_length + 5] = (id % 10) + '0';
|
||||
char temp[6];
|
||||
itoa(dac_values[id], temp, DEC);
|
||||
mqtt.publish(DAC_VALUE_TOPIC, temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Retrieves the ADC value for the specified ID.
|
||||
*
|
||||
* This function checks if the ADC report is enabled for the given ID. If not, it forces an update.
|
||||
* It then returns the ADC value for the specified ID.
|
||||
*
|
||||
* @param id The ID of the ADC channel.
|
||||
* @return The ADC value for the specified ID.
|
||||
*/
|
||||
uint16_t get_adc_value(int id)
|
||||
{
|
||||
if (!adc_report_enable[id])
|
||||
adc_update_force(id);
|
||||
return adc_values[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the state of an ADC based on the received MQTT message.
|
||||
*
|
||||
* This function is called when an MQTT message is received to set the state of an ADC (Analog-to-Digital Converter).
|
||||
* The function extracts the ADC ID from the topic and enables or disables the ADC based on the payload value.
|
||||
*
|
||||
* @param topic The topic of the MQTT message.
|
||||
* @param topic_length The length of the topic.
|
||||
* @param payload The payload of the MQTT message.
|
||||
* @param payload_length The length of the payload.
|
||||
*/
|
||||
void adc_set_state_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length)
|
||||
{
|
||||
int a = topic[5] - '0';
|
||||
int b = topic[6] - '0';
|
||||
int id = 10 * a + b;
|
||||
if (!strcmp(payload, "on"))
|
||||
{
|
||||
enable_adc(id);
|
||||
}
|
||||
else if (!strcmp(payload, "off"))
|
||||
{
|
||||
disable_adc(id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the value of a DAC channel.
|
||||
*
|
||||
* This function sets the value of a DAC channel specified by the `id` parameter.
|
||||
* The `value` parameter represents the desired value for the DAC channel.
|
||||
* The function updates the internal DAC value array, writes the value to the DAC,
|
||||
* and also stores the value in the FRAM memory.
|
||||
*
|
||||
* @param id The ID of the DAC channel.
|
||||
* @param value The desired value for the DAC channel.
|
||||
*/
|
||||
void dac_set_value(int id, int value)
|
||||
{
|
||||
dac_values[id] = value;
|
||||
ESPMega_dacWrite(id, dac_values[id] * dac_states[id]);
|
||||
ESPMega_FRAM.write16(EEPROM_ADDRESS_DAC_VALUE + id * 2, dac_values[id]);
|
||||
publish_dac_value(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the state of a DAC channel.
|
||||
*
|
||||
* This function updates the state of a DAC channel and writes the new state to the DAC output.
|
||||
* It also saves the state to the EEPROM for persistence across power cycles.
|
||||
*
|
||||
* @param id The ID of the DAC channel.
|
||||
* @param state The new state of the DAC channel.
|
||||
*/
|
||||
void dac_set_state(int id, bool state)
|
||||
{
|
||||
dac_states[id] = state;
|
||||
ESPMega_dacWrite(id, dac_values[id] * dac_states[id]);
|
||||
ESPMega_FRAM.write8(EEPROM_ADDRESS_DAC_STATE + id, dac_states[id]);
|
||||
publish_dac_state(id);
|
||||
}
|
||||
|
||||
void publish_dac_states()
|
||||
{
|
||||
for (int i = 0; i < DAC_COUNT; i++)
|
||||
{
|
||||
publish_dac_state(i);
|
||||
}
|
||||
}
|
||||
|
||||
void publish_dac_values()
|
||||
{
|
||||
for (int i = 0; i < DAC_COUNT; i++)
|
||||
{
|
||||
publish_dac_value(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the value of the DAC with a callback function.
|
||||
*
|
||||
* @param topic The topic of the message.
|
||||
* @param topic_length The length of the topic string.
|
||||
* @param payload The payload of the message.
|
||||
* @param payload_length The length of the payload string.
|
||||
*/
|
||||
void dac_set_value_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length)
|
||||
{
|
||||
int a = topic[5] - '0';
|
||||
int b = topic[6] - '0';
|
||||
int id = 10 * a + b;
|
||||
int value = atoi(payload);
|
||||
dac_set_value(id, value);
|
||||
}
|
||||
/**
|
||||
* @brief Callback function for setting the state of the DAC.
|
||||
*
|
||||
* This function is called when a message is received on the specified topic.
|
||||
* It takes the topic, topic length, payload, and payload length as parameters.
|
||||
*
|
||||
* @param topic The topic of the received message.
|
||||
* @param topic_length The length of the topic string.
|
||||
* @param payload The payload of the received message.
|
||||
* @param payload_length The length of the payload string.
|
||||
*/
|
||||
void dac_set_state_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length)
|
||||
{
|
||||
int a = topic[5] - '0';
|
||||
int b = topic[6] - '0';
|
||||
int id = 10 * a + b;
|
||||
if (!strcmp(payload, "on"))
|
||||
{
|
||||
dac_set_state(id, true);
|
||||
}
|
||||
else if (!strcmp(payload, "off"))
|
||||
{
|
||||
dac_set_state(id, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -132,3 +132,24 @@ void set_mqtt_useauth(bool use_auth);
|
|||
|
||||
void factory_reset();
|
||||
void check_boot_reset();
|
||||
|
||||
void enable_adc(int id);
|
||||
void disable_adc(int id);
|
||||
void adc_update(int id);
|
||||
void adc_update_force(int id);
|
||||
void adc_update_all();
|
||||
void adc_loop();
|
||||
void publish_adc_value(int id);
|
||||
void publish_adc_values();
|
||||
uint16_t get_adc_value(int id);
|
||||
void adc_set_state_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length);
|
||||
void dac_set_value(int id, int value);
|
||||
void dac_set_state(int id, bool state);
|
||||
void dac_set_value_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length);
|
||||
void dac_set_state_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length);
|
||||
void publish_dac_value(int id);
|
||||
void publish_dac_state(int id);
|
||||
void publish_dac_values();
|
||||
void publish_dac_states();
|
||||
void publish_adc_state(int id);
|
||||
void publish_adc_states();
|
|
@ -16,6 +16,7 @@
|
|||
#define ENABLE_INTERNAL_LCD
|
||||
#define ENABLE_IR_MODULE
|
||||
#define ENABLE_CLIMATE_MODULE // Require IR Module
|
||||
#define ENABLE_ANALOG_MODULE
|
||||
#define ENABLE_WEBUI
|
||||
|
||||
// Infrared Transciever
|
||||
|
@ -35,6 +36,9 @@
|
|||
#define ESPMega_EXTLCD Serial2
|
||||
#endif
|
||||
|
||||
// Analog Module Configuration
|
||||
#define ANALOG_REPORTING_INTERVAL 500
|
||||
|
||||
// User Defined Functions
|
||||
void user_pre_init();
|
||||
void user_init();
|
||||
|
|
Loading…
Reference in New Issue