Modular ESP Firmware - Modularization - source code

From The TinkerNet Wiki
Jump to navigation Jump to search

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 }