|
|
|
@ -92,23 +92,43 @@ 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
|
|
|
|
|
#define EEPROM_ADDRESS_AC_FAN_SPEED 2 // 01bytes
|
|
|
|
|
#define EEPROM_ADDRESS_PWM_STATE 3 // 16bytes, thru 18
|
|
|
|
|
#define EEPROM_ADDRESS_PWM_VALUE 19 // 32bytes, thru 50
|
|
|
|
|
#define EEPROM_ADDRESS_HOSTNAME 65 // 15bytes, thru 79
|
|
|
|
|
#define EEPROM_ADDRESS_TOPIC 80 // 20bytes, thru 99
|
|
|
|
|
#define EEPROM_ADDRESS_IP 100 // 04bytes, thru 103
|
|
|
|
|
#define EEPROM_ADDRESS_SUBNET 104 // 04bytes, thru 107
|
|
|
|
|
#define EEPROM_ADDRESS_GATEWAY 108 // 04bytes, thru 111
|
|
|
|
|
#define EEPROM_ADDRESS_DNS 112 // 04bytes, thru 115
|
|
|
|
|
#define EEPROM_ADDRESS_MQTT_SERVER 116 // 04bytes, thru 119
|
|
|
|
|
#define EEPROM_ADDRESS_MQTT_PORT 120 // 02bytes, thru 121
|
|
|
|
|
#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_AC_MODE 0 // 01bytes
|
|
|
|
|
#define EEPROM_ADDRESS_AC_TEMPERATURE 1 // 01bytes
|
|
|
|
|
#define EEPROM_ADDRESS_AC_FAN_SPEED 2 // 01bytes
|
|
|
|
|
#define EEPROM_ADDRESS_PWM_STATE 3 // 16bytes, thru 18
|
|
|
|
|
#define EEPROM_ADDRESS_PWM_VALUE 19 // 32bytes, thru 50
|
|
|
|
|
#define EEPROM_ADDRESS_HOSTNAME 65 // 15bytes, thru 79
|
|
|
|
|
#define EEPROM_ADDRESS_TOPIC 80 // 20bytes, thru 99
|
|
|
|
|
#define EEPROM_ADDRESS_IP 100 // 04bytes, thru 103
|
|
|
|
|
#define EEPROM_ADDRESS_SUBNET 104 // 04bytes, thru 107
|
|
|
|
|
#define EEPROM_ADDRESS_GATEWAY 108 // 04bytes, thru 111
|
|
|
|
|
#define EEPROM_ADDRESS_DNS 112 // 04bytes, thru 115
|
|
|
|
|
#define EEPROM_ADDRESS_MQTT_SERVER 116 // 04bytes, thru 119
|
|
|
|
|
#define EEPROM_ADDRESS_MQTT_PORT 120 // 02bytes, thru 121
|
|
|
|
|
#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();
|
|
|
|
@ -144,12 +165,12 @@ void setup()
|
|
|
|
|
#endif
|
|
|
|
|
Serial.println("ESPMega R3 Initializing");
|
|
|
|
|
ESPMega_begin();
|
|
|
|
|
#ifdef OVERCLOCK_FM2
|
|
|
|
|
#ifdef OVERCLOCK_FM2
|
|
|
|
|
Wire.setClock(1000000);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef OVERCLOCK_FM
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef OVERCLOCK_FM
|
|
|
|
|
Wire.setClock(400000);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
io_begin();
|
|
|
|
|
eeprom_retrieve_init();
|
|
|
|
|
user_pre_init();
|
|
|
|
@ -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
|
|
|
|
@ -1747,4 +1839,275 @@ 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
|
|
|
|
|