-
Notifications
You must be signed in to change notification settings - Fork 0
/
periphery.cpp
234 lines (210 loc) · 6.42 KB
/
periphery.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
Vladimir Kirievskiy (C) 2019
********************************************************************************************
* @brief MQTT client software for esp8266 platform (tested on Wemos D1 mini)
* @license MIT
* SDK: Arduino IDE 1.8.5 with plugin for esp8266
*
********************************************************************************************
* @author V. Kirievskiy aka vlakir
* vladimir@kirievskiy.ru
* https://github.com/vlakir
* This software is furnished "as is", without technical support, and with no
* warranty, express or implied, as to its usefulness for any purpose.
*/
#include "periphery.h"
/*
* @brief
* GPIO initialization routine
*
*/
void initPeripheral (void) {
//set suitable mode for your device
pinMode(0, MODE_PIN_0);
pinMode(2, MODE_PIN_2);
pinMode(4, MODE_PIN_4);
pinMode(5, MODE_PIN_5);
pinMode(12, MODE_PIN_12);
pinMode(13, MODE_PIN_13);
pinMode(14, MODE_PIN_14);
pinMode(15, MODE_PIN_15);
pinMode(16, MODE_PIN_16);
}
/*
* @brief
* Post current ADC value to MQTT broker.
*
* @param context - PubSubClient object
*/
void vPostADC(void* vContext) {
static unsigned int uiOld;
static VirtualDelay singleDelay;
PubSubClient *pxPsClient = (PubSubClient *)vContext;
DO_ONCE(
uiOld = 1025; // initial unreal value for 10-bit ADC
);
singleDelay.start(FORCE_ADC_PUBLISH_PERIOD_MS);
if (singleDelay.elapsed()) {
uiOld = 1025; // to remind of itself even if nothing has changed
}
unsigned int uiADC = analogRead(A0);
if (uiADC != uiOld) {
uiOld = uiADC;
char acMessage[33];
char acTopic[80];
sprintf(acMessage, "%d", uiADC);
sprintf(acTopic, "%s%s%s", xGlobalSettings.acDeviceID, "/state", "/ADC");
(*pxPsClient).publish(acTopic, acMessage);
}
}
/*
* @brief
* Post current GPIO state to MQTT broker.
*
* @param context - PubSubClient object
*/
void vPostGPIO(void* vContext) {
static unsigned int uiOld;
static VirtualDelay singleDelay;
PubSubClient *pxPsClient = (PubSubClient *)vContext;
DO_ONCE(
uiOld = 513; // initial unreal value
);
singleDelay.start(FORCE_GPIO_PUBLISH_PERIOD_MS);
if (singleDelay.elapsed()) {
uiOld = 513; // to remind of itself even if nothing has changed
}
bool bit0 = digitalRead(0);
bool bit1 = digitalRead(2);
bool bit2 = digitalRead(4);
bool bit3 = digitalRead(5);
bool bit4 = digitalRead(12);
bool bit5 = digitalRead(13);
bool bit6 = digitalRead(14);
bool bit7 = digitalRead(15);
bool bit8 = digitalRead(16);
unsigned int uiValue = bit0 + 2 * bit1 + 4 * bit2 + 8 * bit3 + 16 * bit4 +
32 * bit5 + 64 * bit6 + 128 * bit7 + 256 * bit8;
if (uiValue != uiOld) {
uiOld = uiValue;
_vStateBit(bit0, "GPIO0", pxPsClient);
_vStateBit(bit1, "GPIO2", pxPsClient);
_vStateBit(bit2, "GPIO4", pxPsClient);
_vStateBit(bit3, "GPIO5", pxPsClient);
_vStateBit(bit4, "GPIO12", pxPsClient);
_vStateBit(bit5, "GPIO13", pxPsClient);
_vStateBit(bit6, "GPIO14", pxPsClient);
_vStateBit(bit7, "GPIO15", pxPsClient);
_vStateBit(bit8, "GPIO16", pxPsClient);
_vStateBit(uiValue, "GPIOALL", pxPsClient);
}
}
/*
* @brief
* Callback function for recieving command message from MQTT broker and set GPIO
*
* @param acTopic - command message
* @param abPayload - value of command message ("0" or "1")
* @param uiLength - length of byte array
*/
void vRecieveCallback(char* acTopic, byte* abPayload, unsigned int uiLength) {
char acToken[20];
strcpy(acToken, _acGetToken(acTopic, 2));
char * acMessage = _acPayload2string(abPayload, uiLength);
if (strcmp(acToken, "GPIO0") == 0) {
_vSetOut(acMessage, 0);
} else if (strcmp(acToken, "GPIO2") == 0) {
_vSetOut(acMessage, 2); // BUILTIN_LED for WEMOS D1 mini
} else if (strcmp(acToken, "GPIO4") == 0) {
_vSetOut(acMessage, 4);
} else if (strcmp(acToken, "GPIO5") == 0) {
_vSetOut(acMessage, 5);
} else if (strcmp(acToken, "GPIO12") == 0) {
_vSetOut(acMessage, 12);
} else if (strcmp(acToken, "GPIO13") == 0) {
_vSetOut(acMessage, 13);
} else if (strcmp(acToken, "GPIO14") == 0) {
_vSetOut(acMessage, 14);
} else if (strcmp(acToken, "GPIO15") == 0) {
_vSetOut(acMessage, 15);
} else if (strcmp(acToken, "GPIO16") == 0) {
_vSetOut(acMessage, 16);
} else if (strcmp(acToken, "GPIOALL") == 0) {
_vSetOut(acMessage, 0);
_vSetOut(acMessage, 2); // BUILTIN_LED for WEMOS D1 mini
_vSetOut(acMessage, 4);
_vSetOut(acMessage, 5);
_vSetOut(acMessage, 12);
_vSetOut(acMessage, 13);
_vSetOut(acMessage, 14);
_vSetOut(acMessage, 15);
_vSetOut(acMessage, 16);
}
}
/*
* @brief
* Tokenize topic message from MQTT broker and return uiNumber member of it
*
* @param acTopicStr - topic message
* @param uiNumber - number of returned member
* @return - selected member of topic message
*/
static char* _acGetToken(char* acTopicStr, unsigned int uiNumber) {
char acTopic[80];
strcpy(acTopic, acTopicStr);
char* aacTokens[20];
aacTokens[0] = strtok(acTopic, "/");
int i = 0;
while (aacTokens[i] != NULL) {
i++;
aacTokens[i] = strtok(NULL, "/");
}
return aacTokens[uiNumber];
}
/*
* @brief
* Set bOutNumber GPIO to state defined cMessage value
*
* @param cMessage - message ("0" of "1")
* @param bOutNumber - GPIO number
*/
static void _vSetOut(char * cMessage, byte bOutNumber) {
if (strcmp(cMessage, "1") == 0) {
digitalWrite(bOutNumber, HIGH);
}
else if (strcmp(cMessage, "0") == 0) {
digitalWrite(bOutNumber, LOW);
}
}
/*
* @brief
* Prepare topic string and send it to MQTT broker
*
* @param uiValue - value of sending parameter
* @param acId - name of parameter (e.g. "ADC" or "GPIO1")
* @param pxPsClient - PubSubClient object
*/
static void _vStateBit(unsigned int uiValue, char* acId, PubSubClient *pxPsClient) {
char acMessage[33];
char acTopic[80];
sprintf(acMessage, "%d", uiValue);
sprintf(acTopic, "%s%s%s", xGlobalSettings.acDeviceID, "/state/", acId);
(*pxPsClient).publish(acTopic, acMessage);
}
/*
* @brief
* Convert byte array to string
*
* @param abPayload - byte array
* @param uiLength - length of byte array
* @return - converted string
*/
static char* _acPayload2string(byte* abPayload, unsigned int uiLength) {
char* acMessageBuffer = new char[uiLength+1];
int i;
for (i = 0; i < uiLength; i++) {
acMessageBuffer[i] = abPayload[i];
}
acMessageBuffer[uiLength] = '\0';
return acMessageBuffer;
}