-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathESP8266-433Mhz-and-IR-Bridge-MQTT.ino
333 lines (256 loc) · 10.8 KB
/
ESP8266-433Mhz-and-IR-Bridge-MQTT.ino
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
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
//Pin defs
#include <ESP8266WiFi.h> //https://github.com/esp8266/Arduino
//#include <DNSServer.h>
//#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <PubSubClient.h>
//#include <ESP8266Ping.h>
#define redPin D1 //pin of red led
#define grnPin D4 //pin of blue led
#define bluPin D3 //pin of green led
#define IRsendPin D2 //pin of IR led
#define IRrecvPin D5 //pin of IR reciever
#define RFsendPin D6 //Pin for 433 transmit, active high.
#define RFrecvPin D7 //Pin for 433 recv, active low.
uint8_t MAC_array[6]; //To store mac address of device
char MAC_char[18];
long reEnableIR;
int MQTTConAttempts; //Max attempts to connect to MQTT server
int MQTTConAttemptsMax = 5; //Max connection attempts before giving up
#define RFdataDecodedSize 512 //size of RF buffer to hold data to send
#define IRdataDecodedSize 512 //size of IR buffer to hold data to send
#define RFsendBuffSize 512 //size of RF buffer to hold data to send
#define IRsendBuffSize 512 //size of IR buffer to hold data to send
//////////////////Telnet//////////////////////
/// Telnet Debug Interface - not yet implimented
#define MAX_SRV_CLIENTS 1 //max telnet clients
byte TelnetBuff[1024]; //telnet buff
/////////////////////MQTT///////////////////
//get mac address so we can have unique clientid for username in MQTT server
String getMacAddress() {
byte mac[6];
WiFi.macAddress(mac);
String cMac = "";
for (int i = 0; i < 6; ++i) {
cMac += String(mac[i], HEX);
if (i < 5)
cMac += "-";
}
cMac.toUpperCase();
Serial.print("Mac Addr:");
Serial.println(cMac);
return cMac;
}
const char* mqtt_server = "192.168.1.103";
//const char* mqtt_clientid = getMacAddress().c_str();
const char* mqtt_username = "openhab";
//const char* mqtt_password = "";
long lastReconnectAttempt = 0;
String mqttbuff;
char mqttmsg[1024];
//////////////////////////////////////////
/////////Non Blocking Delay Func/////////
// not implimented
///////////////Led States////////////////////////////////////////////
int redVal = 0;
int grnVal = 0;
int bluVal = 0;
bool FlashonSend = true; //pulses LED pin when packet is being sent
bool FlashonRecv = true; //pulses Led pin when packet is being recv
bool InvertLedPol = true; //Invert led polarity, IE high = OFF low = ON
byte pulsecolour[3] = {255, 255, 255};
//////////////////////////////////////////////////////////////////////
long minDelta = 500000;
int minDeltaCycles = 152;
//////////////////////RF Buffers and Structs/////////////////////////////
#define RFrecvPinBuffSize 200 //size of RF buffer to hold sampled data
#define AntiCollisionDelay 100 //won't transmit a packet within x number of milliseconds of recieving a packet, basic packet collision avoidance. Maybe Do Something better later?
byte rfDataIn[RFrecvPinBuffSize]; //define sample arrays and allocate memory, this is RAW pin data, 0/1 stored per bit format: 0000011111110000001111111
byte rfDataDecoded[RFdataDecodedSize]; //Array to hold decoded RF data, first byte defines length of data, each byte is timer0/4 count before state transistion.
byte rfDataOut[RFsendBuffSize]; //define sample arrays and allocate memory, first byte defines length of data to send
bool RFaddtoQue = false; //When flagged as true the main loop will detect this and send the RF packet as long as the anti-collision delay has passed
unsigned long lastRFrecv = 0; //Timestamp (ms) when the last RF packet was detected at the reciever
int RFsendIndex; //used in send function to track current index
int RFsendSubIndex; //used in send function to track current index
////////////////////////////////////////////////////////////////////////
/////////////////////IR Bufffers and Structs/////////////////////////////
#define IRrecvPinBuffSize 512 //size of IR buffer to hold sampled data, some remotes have very long transmit sequences //Still having issues with this one
byte IRpacketRepeats = 0; //number of times to repeat transmitted IR packet.
byte irDataIn[IRrecvPinBuffSize]; //define sample arrays and allocate memory, this is RAW pin data, 0/1 stored per bit format
byte irDataDecoded[IRdataDecodedSize]; //Array to hold decoded IR data, first byte defines length of data
byte irDataOut[IRsendBuffSize]; //define sample arrays and allocate memory, first byte defines length of data to send
int IRsendIndex; //used in send function to track current index
int IRsendSubIndex; //used in send function to track current index
byte IRpacketCounter = 0; //Counter for number of times to repeat IR packet
byte RFpacketRepeats = 10; //number of times to repeat transmitted IR packet.
byte RFpacketCounter = 0; //Counter for number of times to repeat IR packet
bool rfDelayTime = true;
int rfDelayCounter = 0;
int rfDelayCycles = 50; //Number of cycles of delay
bool firstpacket = true;
int IRindex; //current byte of irDataIn array, used in data sampling function
byte bitIRindex; //current bit of irDataIn array, used in data sampling function
int RFindex; //current byte of rfDataIn array, used in data sampling function
byte bitRFindex; //current bit of rfDataIn array, used in data sampling function
bool samplePins = true; //if true this function will sample the pins in the timer0 loop, during IR sending or important functions we turn this off.
bool IRsendPin_state = false; //holds IR pin state for bitbanging
bool IR_on = false; //true if there needs to be an RF carrier active
bool RF_on = false;
//// Flow Control and State Machine Variables ////
bool IR_NeedtoSend = false; //true where there needs to be a IR packet sent, this will run the subroutine to bitbang the packet out.
bool RF_NeedtoSend = false; //true where there needs to be a IR packet sent, this will run the subroutine to bitbang the packet out.
bool IRin_detected = false; //has a falling pulse been detected on IR reciever pin?, this optimisation stops unnessesary sampling of the pins where there no data.
byte timer0_count = 0; //gobal 32bit timer
////Variables to detect the start of RF packets//////
boolean rfTriggerCondition = false;
unsigned long lastLowRFsampleTime = 0;
boolean RFtrigger1 = false;
boolean RFtrigger2 = false;
/////////////////////////////////////////////////////////////////////
void clipData(byte* inputArray) {
int inputSize = sizeof(inputArray);
Serial.println(inputSize);
}
//////////////////////////////////////////////////////////////////////
void timer0_ISR (void) {
//main system timer that bitbangs the RF and IR pins.
//This timer ticks at 38khz, these fast ticks generate the intertupts to pulse the IR led at 38khz.
//The ticks are further devided by 4, this runs the routines to sample the RF and IR data pins, sample rate is around 21.5khz.
timer0_count = timer0_count + 1; //incr. count
if (timer0_count == 4) { //run this every 4 ticks of the timer function
timer0_count = 0; //reset timer
if (samplePins == true) { //if its time to sample the data pins run the subroutines
IR_sample();
RF_sample();
}
if (IR_NeedtoSend == true) { //if there is an IR packet waiting in the buffer
IR_SendFuncPWM();
}
if (RF_NeedtoSend == true) { //if there is an RF packet waiting in the buffer
RF_SendPacket();
}
}
if (IR_NeedtoSend == true) {
IRsend_ISR(); // this is called to generate the RF carrier pulses
}
timer0_write(ESP.getCycleCount() + 1860); // = ~76khz @ 160mhz system clock, needs to be twice carrier freq of 38khz.
//ESP.wdtFeed(); //reset watchdog // Sets the next tick of the timer callback function.
}
////////////////////////////////////////////////////////////////////////
void sendIRpuls() {
//(10);
LedAllOff();
samplePins = false;
IR_NeedtoSend = true;
//digitalWrite(D4, HIGH);
while (IR_NeedtoSend == true) {
//digitalWrite(D4, LOW);
digitalWrite(redPin, HIGH);
//delay(1);
}
digitalWrite(redPin, LOW);
digitalWrite(D4, LOW);
LedSet();
samplePins = true;
}
void sendRFpuls() {
//(10);
LedAllOff();
samplePins = false;
RF_NeedtoSend = true;
analogWrite(grnPin, 1024);
while (RF_NeedtoSend == true) {
analogWrite(grnPin, 0);
//delay(10);
// __asm__ __volatile__ ("nop"); // shortest possible delayM
}
analogWrite(grnPin, 1024);
// digitalWrite(D4, HIGH);
LedSet();
samplePins = true;
}
WiFiClient espClient;
PubSubClient client(espClient);
//WiFiServer server(23);
//WiFiClient serverClients[MAX_SRV_CLIENTS];
void setup() {
///////////Set Variables////////////////////////////////////////////////
IRindex = 0;
bitIRindex = 0;
IRsendIndex = 0;
IRsendSubIndex = 0;
IRpacketCounter = 0;
//////////Setup Pins//////////////////////////////////////////////////
pinMode(redPin, OUTPUT);
pinMode(bluPin, OUTPUT);
pinMode(grnPin, OUTPUT);
pinMode(IRsendPin, OUTPUT);
pinMode(RFsendPin, OUTPUT);
digitalWrite(redPin, HIGH);
delay(500);
digitalWrite(redPin, LOW);
delay(500);
digitalWrite(grnPin, HIGH);
delay(500);
//digitalWrite(grnPin, LOW);
//delay(500);
digitalWrite(bluPin, HIGH);
delay(500);
digitalWrite(bluPin, LOW);
delay(500);
pinMode(RFrecvPin, INPUT);
pinMode(IRrecvPin, INPUT);
////////////////////////////////////////////////////////////////////
Serial.begin(115200);
////////////////////////////////////////////////////////////////////
///////////Setup Timer0 for Sampling////////////////////////////////
WiFiManager wifiManager;
//wifiManager.resetSettings();
wifiManager.autoConnect("ESP Network Bridge");
// client.setCallback(MQTTcallback);
// client.setServer(mqtt_server, 1883);
// client.connect(getMacAddress().c_str(), mqtt_username, mqtt_password);
// client.subscribe("ESP/RFtoSend");
// client.subscribe("ESP/IRtoSend");
// client.subscribe("ESP/RLED");
// client.subscribe("ESP/GLED");
// client.subscribe("ESP/BLED");
noInterrupts();
timer0_isr_init();
timer0_attachInterrupt(timer0_ISR);
interrupts();
//ESP.wdtDisable();
//attachInterrupt(D5, IRin_ISR, FALLING);
Serial.println("Connected to Wifi and ready....");
timer0_write(ESP.getCycleCount() + 160000000L); // Adds a small delay to the first timer0 call.
/////////////////////////////////////////////////////////////////
mqttbuff.reserve(1000); // reserve some space for the MQTT input buffer
}
void HandleRFtransmit() {
if (RFaddtoQue == true) {
if ((millis() - lastRFrecv) > AntiCollisionDelay) {
sendRFpuls();
RFaddtoQue = false;
}
}
}
void HandlereEnableIR() {
//Serial.println((millis() - 1000) > reEnableIR);
if ((millis() - 2000) > reEnableIR) {
if ((millis() - reEnableIR) < 3000) {
attachInterrupt(D5, IRin_ISR, FALLING);
// Serial.println("RE IR");
}
}
}
void loop() {
//HandlereEnableIR();
//delay(1);
//sendIRpuls();
//sendRFpuls();
//HandleTelnet(); //See Telnet.ino
if (RFaddtoQue == false) {
HandleMQTT();
}
HandleRFtransmit();
}