From 346aa9796eb53c0198dcd1ac3138c24cc42bd2cf Mon Sep 17 00:00:00 2001 From: Siwat Sirichai Date: Sat, 26 Aug 2023 15:22:59 +0700 Subject: [PATCH] initial prototype --- .vscode/settings.json | 5 +- src/main.cpp | 134 +++++++++++++++++++++++++++++++++--------- 2 files changed, 111 insertions(+), 28 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index fc4c15b..4bf8df2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,6 @@ { - "C_Cpp.errorSquiggles": "enabled" + "C_Cpp.errorSquiggles": "enabled", + "files.associations": { + "string": "cpp" + } } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 8972a1b..12146af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ const IPAddress GATEWAY(192, 168, 0, 1); const IPAddress DNS(10, 192, 1, 1); const IPAddress MQTT_SERVER(192, 168, 0, 26); const int MQTT_PORT = 1883; +#define MQTT_BASE_TOPIC "/espmega/ProR3" // #define MQTT_USE_AUTH #ifdef MQTT_USE_AUTH const char MQTT_USERNAME[] = "username"; @@ -21,10 +22,11 @@ const char MQTT_PASSWORD[] = "password"; #endif // Inputs +#define VINT_COUNT 16 const int DEBOUNCE_TIME_MS = 50; -const int virtual_interrupt_pins[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; -int virtual_interupt_state[16]; -unsigned long virtual_interupt_timer[16]; +const int virtual_interrupt_pins[VINT_COUNT] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +int virtual_interupt_state[VINT_COUNT]; +unsigned long virtual_interupt_timer[VINT_COUNT]; // Outputs #define PWM_COUNT 16 @@ -43,7 +45,9 @@ void network_begin(); void mqtt_connect(); void mqtt_subscribe(); void thread_initialization(); -void mqtt_callback(String topic, String message); +void pwm_state_callback(String topic, String message); +void pwm_value_callback(String topic, String message); +void state_request_callback(String topic, String message); void io_begin(); void publish_pwm_states(); @@ -55,6 +59,14 @@ void pwm_toggle(int id1, int id2); void pwm_cycle_value(int id); boolean pwm_group_state(int id1, int id2); +void publish_input_states(); +void publish_input_state(int id); +void publish_input_state(int id, int state); + +char PWM_STATE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/state"; +char PWM_VALUE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/value"; +char INPUTS_TOPIC[75] = MQTT_BASE_TOPIC "/input/00"; + WiFiClient eth; PubSubClient mqtt_client(MQTT_SERVER, 1883, eth); PubSubClientTools mqtt(mqtt_client); @@ -71,6 +83,8 @@ void setup() Serial.println("Initializing MQTT . . ."); mqtt_connect(); thread_initialization(); + Serial.println("Initialization Completed."); + Serial.println("Jumping to User Code."); } void loop() @@ -116,6 +130,8 @@ void mqtt_connect() { mqtt_subscribe(); Serial.print("MQTT connected\n"); + publish_pwm_states(); + publish_input_states(); } else { @@ -126,7 +142,19 @@ void mqtt_connect() void mqtt_subscribe() { - mqtt.subscribe("/espmega", mqtt_callback); + char PWM_SET_STATE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/set/state"; + char PWM_SET_VALUE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/set/value"; + char STATE_REQUEST_TOPIC[75] = MQTT_BASE_TOPIC "/requeststate"; + for (int i = 0; i < PWM_COUNT; i++) + { + PWM_SET_VALUE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 4] = ((i - i % 10) / 10) + '0'; + PWM_SET_VALUE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 5] = (i % 10) + '0'; + PWM_SET_STATE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 4] = ((i - i % 10) / 10) + '0'; + PWM_SET_STATE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 5] = (i % 10) + '0'; + mqtt.subscribe(PWM_SET_STATE_TOPIC, pwm_state_callback); + mqtt.subscribe(PWM_SET_VALUE_TOPIC, pwm_value_callback); + } + mqtt.subscribe(STATE_REQUEST_TOPIC, state_request_callback); } void thread_initialization() @@ -137,12 +165,41 @@ void thread_initialization() mqtt_reconnector.setInterval(30000); } -void mqtt_callback(String topic, String message) +void pwm_state_callback(String topic, String message) { + Serial.println("Recieved PWM State Message"); + Serial.println(topic); + Serial.println(message); + int a = topic.charAt(sizeof(MQTT_BASE_TOPIC)+4) - '0'; + int b = topic.charAt(sizeof(MQTT_BASE_TOPIC)+5) - '0'; + int id = 10 * a + b; + if (message.compareTo("on")==0) + { + Serial.printf("Setting pwm %d to on\n", id); + pwm_set_state(id, true); + } + else if (message.compareTo("off")==0) + { + Serial.printf("Setting pwm %d to off\n", id); + pwm_set_state(id, false); + } +} + +void pwm_value_callback(String topic, String message) +{ + Serial.println("Recieved PWM Value Message"); + Serial.println(topic); + Serial.println(message); + int a = topic.charAt(sizeof(MQTT_BASE_TOPIC)+4) - '0'; + int b = topic.charAt(sizeof(MQTT_BASE_TOPIC)+5) - '0'; + int id = 10 * a + b; + int value = message.toInt(); + pwm_set_value(id, value); } void virtual_interrupt_callback(int pin, int state) { + publish_input_state(pin,state); Serial.printf("Pin %d changed to %d\n", pin, state); } @@ -177,47 +234,43 @@ void publish_pwm_states() void publish_pwm_state(int id) { - int state = pwm_states[id - 1]; - int value = pwm_values[id - 1]; - String topic = "/iotplc/pwm"; - topic += (id); - topic += "/state"; + int state = pwm_states[id]; + int value = pwm_values[id]; + PWM_STATE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 4] = ((id - id % 10) / 10) + '0'; + PWM_STATE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 5] = (id % 10) + '0'; if (state == 1) { - mqtt_client.publish((char *)topic.c_str(), "on"); + mqtt_client.publish(PWM_STATE_TOPIC, "on"); } else if (state == 0) { - mqtt_client.publish((char *)topic.c_str(), "off"); + mqtt_client.publish(PWM_STATE_TOPIC, "off"); } - topic = "/iotplc/pwm"; - topic += (id); - topic += "/value"; - mqtt_client.publish((char *)topic.c_str(), (char *)String(value).c_str()); + mqtt.publish(String(PWM_VALUE_TOPIC), String(value)); } void pwm_set_state(int id, int state) { - if (state != pwm_states[id - 1]) + if (state != pwm_states[id]) { - pwm_states[id - 1] = state; - int pwm_value = pwm_values[id - 1]; - analogWrite(pwm_pins[id - 1], state * (int)(pwm_linear_scaling_m[id - 1] * pwm_value + pwm_linear_scaling_c[id - 1])); + pwm_states[id] = state; + int pwm_value = pwm_values[id]; + ESPMega_analogWrite(pwm_pins[id], state * (int)(pwm_linear_scaling_m[id] * pwm_value + pwm_linear_scaling_c[id])); publish_pwm_state(id); } } void pwm_set_value(int id, int value) { - pwm_values[id - 1] = value; - int pwm_state = pwm_states[id - 1]; - analogWrite(pwm_pins[id - 1], pwm_state * (int)(pwm_linear_scaling_m[id - 1] * value + pwm_linear_scaling_c[id - 1])); + pwm_values[id] = value; + int pwm_state = pwm_states[id]; + ESPMega_analogWrite(pwm_pins[id], pwm_state * (int)(pwm_linear_scaling_m[id] * value + pwm_linear_scaling_c[id])); publish_pwm_state(id); } void pwm_toggle(int id) { - int state = !pwm_states[id - 1]; + int state = !pwm_states[id]; pwm_set_state(id, state); } @@ -246,8 +299,8 @@ boolean pwm_group_state(int id1, int id2) void pwm_cycle_value(int id) { - int state = pwm_states[id - 1]; - int value = pwm_values[id - 1]; + int state = pwm_states[id]; + int value = pwm_values[id]; if (state == 1) for (int i = 0; i < PWM_CYCLE_VALUES_COUNT; i++) { @@ -267,4 +320,31 @@ void pwm_cycle_value(int id) } pwm_set_state(id, 1); pwm_set_value(id, PWM_CYCLE_VALUES[PWM_CYCLE_VALUES_COUNT - 1]); +} + +void publish_input_states() +{ + for (int i = 0; i < VINT_COUNT; i++) + { + publish_input_state(i); + } +} +void publish_input_state(int id) +{ + int state = ESPMega_digitalRead(virtual_interrupt_pins[id]); + publish_input_state(id, state); +} + +void publish_input_state(int id, int state) +{ + char INPUTS_TOPIC[75] = MQTT_BASE_TOPIC "/input/00"; + INPUTS_TOPIC[sizeof(MQTT_BASE_TOPIC) + 6] = ((id - id % 10) / 10) + '0'; + INPUTS_TOPIC[sizeof(MQTT_BASE_TOPIC) + 7] = (id % 10) + '0'; + mqtt.publish(String(INPUTS_TOPIC), state ? "1" : "0"); +} + +void state_request_callback(String topic, String message) +{ + publish_input_states(); + publish_pwm_states(); } \ No newline at end of file