Modular ESP Firmware - Modularization - source code
Jump to navigation
Jump to search
Contents
functions.h
1 #ifndef FUNCTIONS_H
2 #define FUNCTIONS_H
3
4 #include <stdint.h>
5 #include <Arduino.h>
6
7 #include <ESP8266WiFi.h>
8
9 void setup_wifi();
10
11 #include <PubSubClient.h>
12
13 void setup_mqtt();
14
15 void MQTT_callback(char *topic, byte *payload, int length);
16 void MQTT_reconnect();
17 void MQTT_beacon();
18
19 void DOtheBloodyMQTT();
20
21 void setup();
22 void loop();
23
24 bool getTimer(unsigned long &timer, unsigned long interval);
25 void blinkLED(); // Just a little function to blink the LED for the beacon function.
26 void DoLights(char *WhatToDo); // Turn LED on/off
27 void DoAnswer(char *WhatToDo); // Send back text
28 void DoControl(char *WhatToDo); // Send MQTT to another device/topic
29
30 #endif // FUNCTIONS_H
TopSecret.h
1 #ifndef TOPSECRET_H
2 #define TOPSECRET_H
3
4 // WiFi
5 // Store your WiFi credentials here.
6 // Update these with values suitable for your network.
7
8 #define WAP 0
9 // Allow testing on the various networks at the lab...
10 #if WAP==0
11 const char* WiFi_ssid = "TinkerToys";
12 const char* WiFi_password = "password";
13 #elif WAP==1
14 const char* WiFi_ssid = "TinkerToysB";
15 const char* WiFi_password = "password";
16 #elif WAP==2
17 const char* WiFi_ssid = "vanneck";
18 const char* WiFi_password = "password";
19 #else
20 const char* WiFi_ssid = "VictoriaDrive2B";
21 const char* WiFi_password = "password";
22 #endif
23
24 const char* WiFi_ClientName = "GimmeAName";
25
26 // MQTT
27 // Store your MQTT credentials here.
28 // Update these with values suitable for your network.
29
30 // Set BrokerName OR BrokerIP, not both...
31 const char* MQTT_broker = "BROKER.DOMAIN.TLD";
32 // const int* MQTT_BrokerIP = { 192, 168, 0, 12 };
33
34 const char* MQTT_user = "";
35 const char* MQTT_pass = "";
36
37 const char* MQTT_ClientName = "GimmeAName";
38
39 #endif // TOPSECRET_H
BotSecret.h
1 #ifndef BOTSECRET_H
2 #define BOTSECRET_H
3
4 ////////////////////////////////////////////////////////////////
5 extern char* WiFi_ssid;
6 extern char* WiFi_password;
7 extern char* WiFi_ClientName;
8 ////////////////////////////////////////////////////////////////
9
10 ////////////////////////////////////////////////////////////////
11 extern char* MQTT_broker;
12 extern char* MQTT_user;
13 extern char* MQTT_pass;
14 extern char* MQTT_ClientName;
15 ////////////////////////////////////////////////////////////////
16
17 #endif // BOTSECRET_H
MQTT.h
1 #ifndef MQTT_H
2 #define MQTT_H
3
4 #define MQTT_BUFFER_SIZE (50) // This number is arbitrary
5
6 char MQTT_outTopic[MQTT_BUFFER_SIZE];
7 char MQTT_inTopic[MQTT_BUFFER_SIZE];
8 char MQTT_teleTopic[MQTT_BUFFER_SIZE];
9 char MQTT_statTopic[MQTT_BUFFER_SIZE];
10
11 char MQTT_msg_out[MQTT_BUFFER_SIZE];
12
13 unsigned long beacon_timer = 0;
14 #define BEACON_INTERVAL 30000 // Timer interval for the "keep-alive" status beacon
15
16 #endif // MQTT_H
main.cpp
1 #include "TopSecret.h"
2 #include "functions.h"
3
4 ////////////////////////////////////////////////////////////////
5 //
6 // This version roughly based on principles from:
7 // https://community.platformio.org/t/tutorial-for-creating-multi-cpp-file-arduino-project/5830/43
8 //
9 // Need to look further into "extern"
10 // https://stackoverflow.com/questions/10422034/when-to-use-extern-in-c
11 //
12 ////////////////////////////////////////////////////////////////
13
14 void setup()
15 {
16 Serial.begin(115200);
17 delay(50); // Delay to let the ESP get booted before sending out serial data
18 Serial.printf("\n+---------------------------------------+\n");
19 Serial.printf("| ESP MQTT Testing |\n");
20 Serial.printf("+---------------------------------------+\n");
21
22 setup_wifi();
23
24 setup_mqtt();
25
26 pinMode(LED_BUILTIN, OUTPUT);
27 digitalWrite(LED_BUILTIN, HIGH);
28
29 }
30
31 void loop()
32 {
33 // put your main code here, to run repeatedly:
34 DOtheBloodyMQTT();
35 }
Wifi.cpp
1 #include "functions.h"
2 #include "BotSecret.h"
3
4 ////////////////////////////////////////////////////////////////
5 // WiFi Functions
6 ////////////////////////////////////////////////////////////////
7
8 void setup_wifi()
9 {
10
11 // We start by connecting to a WiFi network
12 Serial.printf("| |\n");
13 Serial.printf("| Connecting to: %-22s |\n", WiFi_ssid);
14 Serial.printf("| ");
15
16 WiFi.mode(WIFI_STA); // Connecting as a STATION
17 WiFi.begin(WiFi_ssid, WiFi_password);
18
19 int dotcount = 0;
20 while (WiFi.status() != WL_CONNECTED) // Give it a bit of time to establish the WiFi connection...
21 {
22 dotcount++;
23 delay(500);
24 Serial.printf(".");
25 }
26
27 for (int i = 0; i < (38 - dotcount); i++)
28 {
29 Serial.printf(" ");
30 }
31 Serial.printf("|\n");
32
33 Serial.printf("| WiFi connected on Channel %-2d |\n", WiFi.channel());
34 // Serial.printf("|Channel: %d\n", WiFi.channel());
35 Serial.printf("| IP address: %-15s |\n", WiFi.localIP().toString().c_str());
36 Serial.printf("+---------------------------------------+\n");
37
38 #ifdef DEBUG0
39 WiFi.printDiag(Serial);
40 #endif
41 }
MQTT.cpp
1 #include "functions.h"
2 #include "BotSecret.h"
3
4 #include "MQTT.h"
5
6 WiFiClient espClient;
7 PubSubClient MQTT_client(espClient);
8
9 void DOtheBloodyMQTT()
10 {
11 if (!MQTT_client.connected())
12 {
13 MQTT_reconnect();
14 }
15 MQTT_client.loop();
16 MQTT_beacon();
17 }
18
19 ////////////////////////////////////////////////////////////////
20 // MQTT Functions
21 ////////////////////////////////////////////////////////////////
22
23 void setup_mqtt()
24 {
25 MQTT_client.setServer(MQTT_broker, 1883);
26 MQTT_client.setCallback(MQTT_callback);
27
28 // Build the topic names
29 strcpy(MQTT_inTopic, "cmnd/"); // in - Commands
30 strcat(MQTT_inTopic, MQTT_ClientName);
31 strcat(MQTT_inTopic, "/#");
32 strcpy(MQTT_teleTopic, "tele/"); // out - Telemetry
33 strcat(MQTT_teleTopic, MQTT_ClientName);
34 strcpy(MQTT_statTopic, "stat/"); // out - Status
35 strcat(MQTT_statTopic, MQTT_ClientName);
36 strcpy(MQTT_outTopic, "noti/"); // out - Notifications
37 strcat(MQTT_outTopic, MQTT_ClientName);
38
39 MQTT_reconnect();
40 Serial.printf("+---------------------------------------+\n");
41 }
42
43 void MQTT_callback(char *topic, byte *payload, int length)
44 {
45
46 char MQTT_msg_in[MQTT_BUFFER_SIZE];
47 char *MQTT_command = strrchr(topic, '/');
48
49 #ifdef DEBUG
50 Serial.printf("| |\n");
51 Serial.printf("| Message arrived |\n");
52 Serial.printf("| Command: %28s |\n", MQTT_command);
53 #endif
54
55 if (length < MQTT_BUFFER_SIZE)
56 {
57 for (int i = 0; i < length; i++)
58 {
59 MQTT_msg_in[i] = (char)payload[i];
60 MQTT_msg_in[i + 1] = '\0';
61 }
62
63 #ifdef DEBUG
64 Serial.printf("| Message: %28s |\n", MQTT_msg_in);
65 #endif
66 /////////////////////////////////////////////////////
67 // Message handling goes here...
68 /////////////////////////////////////////////////////
69 if (strcmp(MQTT_command, "/lights") == 0)
70 {
71 DoLights(MQTT_msg_in);
72 }
73 else if (strcmp(MQTT_command, "/respond") == 0)
74 {
75 DoAnswer(MQTT_msg_in);
76 }
77 else if (strcmp(MQTT_command, "/control") == 0)
78 {
79 DoControl(MQTT_msg_in);
80 }
81 else
82 {
83 #ifdef DEBUG
84 Serial.printf("| Dunno Whatcha want... |\n");
85 #endif
86 }
87 }
88 else
89 {
90 #ifdef DEBUG
91 Serial.printf("| But, it's TOO Bloody Big! |\n");
92 #endif
93 }
94 }
95
96 void MQTT_reconnect()
97 {
98 // Loop until we're reconnected
99 while (!MQTT_client.connected())
100 {
101 Serial.printf("| |\n");
102 Serial.printf("| Attempting MQTT connection... |\n");
103 // Create a random client ID
104 String clientId = MQTT_ClientName;
105 clientId += String(random(0xffff), HEX);
106 // Attempt to connect
107 if (MQTT_client.connect(clientId.c_str()))
108 {
109 Serial.printf("| connected to %-24s |\n", MQTT_broker);
110 Serial.printf("| My Name: %-27s |\n", MQTT_ClientName);
111 // Once connected, publish an announcement...
112 MQTT_client.publish(MQTT_statTopic, "hello world");
113 // ... and resubscribe
114 MQTT_client.subscribe(MQTT_inTopic);
115 }
116 else
117 {
118 Serial.printf("| |\n");
119 Serial.printf("| failed, rc=%d |\n", MQTT_client.state());
120 Serial.printf("| trying again in 5 seconds |\n");
121 // Wait 5 seconds before retrying
122 delay(5000);
123 }
124 }
125 }
126
127 void MQTT_beacon()
128 {
129 /* Beacon signal published at set interval to indicate the device
130 * is still powered up and actively connected to MQTT...
131 * A keepalive of sorts
132 * also updates state within MQTT so it can be captured for
133 * indicator light elsewhere
134 */
135 if (getTimer(beacon_timer, BEACON_INTERVAL))
136 {
137 MQTT_client.publish(MQTT_teleTopic, "boop");
138 blinkLED();
139 }
140 }
141
142 ////////////////////////////////////////////////////////////////
143 // Random cmnd handlers for testing...
144 ////////////////////////////////////////////////////////////////
145
146 void DoLights(char *WhatToDo) // Turn LED on/off
147 {
148 Serial.printf("[- Lights - %3s -]\n", WhatToDo);
149 if (strcmp(WhatToDo, "ON") == 0)
150 digitalWrite(LED_BUILTIN, LOW);
151 if (strcmp(WhatToDo, "OFF") == 0)
152 digitalWrite(LED_BUILTIN, HIGH);
153 }
154
155 void DoAnswer(char *WhatToDo) // Send back text
156 {
157 Serial.printf("[- Responding: %-23s -]\n", WhatToDo);
158 MQTT_client.publish(MQTT_outTopic, WhatToDo);
159 }
160
161 void DoControl(char *WhatToDo) // Send MQTT to another device/topic
162 {
163 /*
164 Should be something along the lines of,
165
166 MQTT_client.publish(TopicFromMessage, MessageFromMessage);
167
168 Where
169 TopicFromMessage
170 is an MQTT topic for sending to another device
171 and
172 MessageFromMessage
173 is the message to publish to that topic...
174 */
175 }
Supplimentary.cpp
1 #include "functions.h"
2
3 ////////////////////////////////////////////////////////////////
4 // Supplimentary Functions
5 ////////////////////////////////////////////////////////////////
6
7 bool getTimer(unsigned long &timer, unsigned long interval)
8 /* Global timer function, used a lot
9 *
10 * @param unsigned long time - The current timer
11 * @param unsigned long interval - Length of time to run timer
12 *
13 * @return bool True when timer is complete
14 * @return bool False when timer is counting
15 */
16 {
17
18 if (timer < 1)
19 {
20 timer = millis();
21 }
22
23 if (millis() - timer >= interval)
24 {
25 timer = 0;
26 return true;
27 }
28
29 return false;
30 }
31
32 void blinkLED() // Just a little function to blink the on-board LED for the beacon function.
33 {
34 digitalWrite(LED_BUILTIN, LOW);
35 delay(10);
36 digitalWrite(LED_BUILTIN, HIGH);
37 delay(10);
38 digitalWrite(LED_BUILTIN, LOW);
39 delay(10);
40 digitalWrite(LED_BUILTIN, HIGH);
41 }