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 |
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include <SparkFun_OWire_Arduino_Library.h>
#include "setup.h"
#include "remote.h"
/*
MPlaty's BLE Light Poles.
Make sure to change things in the setup.h file! (DO NOT MODIFY ANYTHING IN THIS FILE)
*/
// The BLE Server
BLEServer* Server = NULL;
// The BLE Server Characteristics
BLECharacteristic* cPower = NULL;
BLECharacteristic* cColour = NULL;
BLECharacteristic* cMode = NULL;
/* Classes */
// sets up the status led
OWIRE oStatus;
// sets up the ir remote handler
Remote irRemote(R20KEYSPLIT);
// Sets up the IRRecv class
IRrecv irRecv(IR_PIN);
// Not sure if this is required, further tests needed.
bool deviceConnected = false;
bool oldDeviceConnected = false;
// Storage for the clients, unsure if storing them is necessary, but could be for individually controlling them.
BLE2902* clientConfigDescriptors[4];
// the following 6 variables are all for the button. will try and shrink these, and label them
bool buttonPressed = false;
int buttonState = LOW;
int lastButtonState = LOW;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
// the current brightness
int brightness = DEFAULT_BRIGHTNESS;
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* Server) {
deviceConnected = true;
BLEDevice::startAdvertising();
}
void onDisconnect(BLEServer* Server) {
deviceConnected = false;
}
};
void load_ble_server() {
// Add a service to the server
BLEService *sMain = Server->createService(S_MAIN_UUID);
// Add the Power characteristic to the server
cPower = sMain->createCharacteristic(
C_POWER_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// Add the Colour characteristic to the server
cColour = sMain->createCharacteristic(
C_COLOUR_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// Add the Mode characteristic to the server
cMode = sMain->createCharacteristic(
C_MODE_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
cPower->addDescriptor(new BLE2902());
cColour->addDescriptor(new BLE2902());
cMode->addDescriptor(new BLE2902());
sMain->start();
}
void setup() {
// Begin the Serial Communication
Serial.begin(SERIAL_SPEED);
// Setup the Status LED
oStatus.begin(STATUS_LED_PIN, false);
// Set the Colour of the status LED
oStatus.setModeAndColor(OW_SOLID, OW_RED);
// Set the power buttons' pinMode.
pinMode(POWER_BUTTON_PIN, INPUT_PULLUP);
// begin the IR reciever
irRecv.enableIRIn();
Serial.println("Booting up BLE Server...");
// Create the BLE Device and name it
BLEDevice::init("Light Pole Server");
// Allow for multiple connections
BLEDevice::setMTU(500);
// Create and set the BLE Server variable
Server = BLEDevice::createServer();
// Set the BLE Server callback
Server->setCallbacks(new MyServerCallbacks());
// Creates, and attaches the Service and its characteristics to the Server.
//load_ble_server();
// Add a service to the server
BLEService *sMain = Server->createService(S_MAIN_UUID);
// Add the Power characteristic to the server
cPower = sMain->createCharacteristic(
C_POWER_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// Add the Colour characteristic to the server
cColour = sMain->createCharacteristic(
C_COLOUR_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
// Add the Mode characteristic to the server
cMode = sMain->createCharacteristic(
C_MODE_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE |
BLECharacteristic::PROPERTY_NOTIFY |
BLECharacteristic::PROPERTY_INDICATE
);
cPower->addDescriptor(new BLE2902());
cColour->addDescriptor(new BLE2902());
cMode->addDescriptor(new BLE2902());
sMain->start();
// Start advertising
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(S_MAIN_UUID);
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x0);
delay(1000);
BLEDevice::startAdvertising();
}
decode_results results;
void ir_loop() {
// checks if there is IR Data
if (irRecv.decode(&results)) {
Serial.println("IR RECIEVED");
serialPrintUint64(results.value, HEX);
serialPrintUint64(results.value, HEX);
Serial.println("");
// sets the raw decoded data to the data variable.
buttonData button = irRemote.call(results.value);
if (button.type != R_EMPTY && button.button != RB_ERROR) {
if (button.type == R_POWER) {
if (button.button == RB_ON) {
Serial.println("Power ON");
uint8_t data = (uint8_t)brightness;
cPower->setValue(&data, 1);
cPower->notify();
} else if (button.button == RB_OFF) {
Serial.println("Power OFF");
uint8_t data = 0x00;
cPower->setValue(&data, 1);
cPower->notify();
}
}
}
irRecv.resume();
}
}
void power_button_loop() {
int reading = digitalRead(POWER_BUTTON_PIN);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
Serial.println("Button pressed");
if (deviceConnected) {
uint8_t data = 0xFF;
//pCharacteristic->setValue(&data, 1); // Set the value as a byte array
//pCharacteristic->notify();
Serial.println("Data updated!");
}
buttonPressed = true;
} else {
Serial.println("Button released");
if (deviceConnected) {
uint8_t data = 0x00;
//pCharacteristic->setValue(&data, 1); // Set the value as a byte array
//pCharacteristic->notify();
Serial.println("Data updated!");
}
buttonPressed = false;
}
}
}
lastButtonState = reading;
}
void loop() {
ir_loop();
if (!deviceConnected && oldDeviceConnected) {
Server->startAdvertising();
Serial.println("Start advertising");
oldDeviceConnected = deviceConnected;
}
if (deviceConnected && !oldDeviceConnected) {
// Actions to perform on connecting
oldDeviceConnected = deviceConnected;
}
}
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 |
#ifndef Setup_h
#define Setup_h
/*
The setup file for the Light Pole!
*/
/* Server Only */
/* PINS */
// IR_PIN - The pin the IR Reciever is connected too.
#define IR_PIN 3 // 34, 3
// REMOTE_TYPE - The type of IR remote that you will use.
#define REMOTE_TYPE 1
/* SETTINGS */
// DEFAULT_BRIGHTNESS - The brightness that the server will use on startup. (must be 0 to 255)
#define DEFAULT_BRIGHTNESS 127
/* Client Only */
// STRIP_LENGTH - how many leds are in the strips.
#define STRIP_LENGTH 36
// STRIP_TYPE - how many strips you have, 1 (STRIP_PIN_1), 2 (STRIP_PIN_1, STRIP_PIN_2) or 4 (all STRIP_PIN numbers). makes the effects look better.
#define STRIP_TYPE 4
// STRIP_PIN_X - the strip light pins.
#define STRIP_PIN_1 4
#define STRIP_PIN_2 5
#define STRIP_PIN_3 6
#define STRIP_PIN_4 7
/* Both */
/* PINS */
// STATUS_LED_PIN - The pin the status led is connected too.
#define STATUS_LED_PIN 4 // 13, 4
// POWER_BUTTON_PIN - The pin the power button is attached too.
#define POWER_BUTTON_PIN 5 // 27, 5
/* BLE - UUID'S */
// S_MAIN_UUID - The services' main UUID
#define S_MAIN_UUID "00c6273c-70d9-11ee-b962-0242ac120002"
// C_POWER_UUID - The power UUID, where 00 is off, and 01, to FF is the brightness
#define C_POWER_UUID "068ed628-70d9-11ee-b962-0242ac120002"
// C_COLOUR_UUID - The colour UUID, which sets the colour of the lights, or the mode.
#define C_COLOUR_UUID "09e45eba-70d9-11ee-b962-0242ac120002"
// C_MODE_UUID - The mode UUID, which sets the mode of the lights. If its 00, then it just shows the default colour.
#define C_MODE_UUID "09e45eba-70d9-11ee-b962-0242ac120002"
/* DEBUG */
// SERIAL_SPEED - The speed at which the serial data is transmitted.
#define SERIAL_SPEED 115200
// ENABLE_DEBUG - If true, debug messages will be sent. If disabled, only serious errors will be sent.
#define ENABLE_DEBUG true
#endif
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 |
#ifndef Remote_h
#define Remote_h
#include <Arduino.h>
enum RemoteType {
R20KEYSPLIT,
R24KEYWHITE,
R44KEYWHITE
};
enum remoteButtonType {
RB_ERROR,
RB_OFF,
RB_ON,
RB_RED,
RB_GREEN,
RB_BLUE,
RB_ORANGE,
RB_YELLOW,
RB_LIME,
RB_DARK_GREEN,
RB_CYAN,
RB_AQUA,
RB_DARK_BLUE,
RB_PURPLE,
RB_PINK,
RB_WHITE,
RB_FADE,
RB_JUMP,
RB_FIRE,
RB_RESET,
RB_BRIGHTNESS_DOWN,
RB_BRIGHTNESS_UP
};
enum remoteResponseType {
R_EMPTY,
R_POWER,
R_COLOUR,
R_MODE,
R_SETTING
};
struct buttonData {
String name;
remoteButtonType button;
remoteResponseType type;
};
class Remote {
public:
Remote(RemoteType type);
buttonData call(long type);
private:
RemoteType type;
};
#endif
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 |
#include "Remote.h"
buttonData twentyKeySplit(long key_data) {
buttonData data;
switch (key_data) {
case 0xFFA25D: // on
data.name = "On";
data.button = RB_ON;
data.type = R_POWER;
break;
case 0xFFE21D: // off
data.name = "Off";
data.button = RB_OFF;
data.type = R_POWER;
break;
case 0xBB44FF00: // red
data.name = "Red";
data.button = RB_RED;
data.type = R_COLOUR;
break;
case 0xBF40FF00: // green
data.name = "Green";
data.button = RB_GREEN;
data.type = R_COLOUR;
break;
case 0xBC43FF00: // blue
data.name = "Blue";
data.button = RB_BLUE;
data.type = R_COLOUR;
break;
case 0xF807FF00: // orange
data.name = "Orange";
data.button = RB_ORANGE;
data.type = R_COLOUR;
break;
case 0xEA15FF00: // yellow
data.name = "Yellow";
data.button = RB_YELLOW;
data.type = R_COLOUR;
break;
case 0xF609FF00: // lime
data.name = "Lime";
data.button = RB_LIME;
data.type = R_COLOUR;
break;
case 0xE916FF00: // dark green
data.name = "Dark Green";
data.button = RB_DARK_GREEN;
data.type = R_COLOUR;
break;
case 0xE619FF00: // cyan
data.name = "Cyan";
data.button = RB_CYAN;
data.type = R_COLOUR;
break;
case 0xF20DFF00: // aqua
data.name = "Aqua";
data.button = RB_AQUA;
data.type = R_COLOUR;
break;
case 0xF30CFF00: // dark blue
data.name = "Dark Blue";
data.button = RB_DARK_BLUE;
data.type = R_COLOUR;
break;
case 0xE718FF00: // purple
data.name = "Purple";
data.button = RB_PURPLE;
data.type = R_COLOUR;
break;
case 0xA15EFF00: // pink
data.name = "Pink";
data.button = RB_PINK;
data.type = R_COLOUR;
break;
case 0xF708FF00: // white
data.name = "White";
data.button = RB_WHITE;
data.type = R_COLOUR;
break;
case 0xE31CFF00: // fade
data.name = "Fade";
data.button = RB_FADE;
data.type = R_MODE;
break;
case 0xA55AFF00: // jump
data.name = "Jump";
data.button = RB_JUMP;
data.type = R_MODE;
break;
case 0xBD42FF00: // reset
data.name = "Reset";
data.button = RB_RESET;
data.type = R_SETTING;
break;
case 0xAD52FF00: // down
data.name = "Brightness Down";
data.button = RB_BRIGHTNESS_DOWN;
data.type = R_SETTING;
break;
case 0xB54AFF00: // up
data.name = "Brightness Up";
data.button = RB_BRIGHTNESS_UP;
data.type = R_SETTING;
break;
default:
data.name = "Unknown";
data.button = RB_ERROR;
data.type = R_EMPTY;
break;
}
return data;
}
/*
buttonData twentyFourKeyWhite(int type) {
buttonData data;
switch (type) {
case 0xF609FF00: // up
data.name = "brightness_up";
data.type = SETTING
break;
case 0xE21DFF00: // down
data.name = "brightness_down";
data.type = SETTING
break;
case 0xE01FFF00: // off
data.name = "off";
data.type = POWER
break;
case 0xF20DFF00: // on
data.name = "on";
data.type = POWER
break;
case 0xE619FF00: // red
data.name = "red";
data.type = COLOUR
break;
case 0xE41BFF00: // green
data.name = "green";
data.type = COLOUR;
break;
case 0xEE11FF00: // blue
data.name = "blue";
data.type = COLOUR;
break;
case 0xEA15FF00: // white
data.name = "white";
data.type = COLOUR;
break;
case 0xF807FF00: // orange
data.name = "orange";
data.type = COLOUR;
break;
case 0xF609FF00: // lime
data.name = "lime";
data.type = COLOUR;
break;
case 0xE916FF00: // light blue
data.name = "light_blue";
data.type = COLOUR;
break;
case 0xEA15FF00: // flash
data.name = "jump";
data.type = MODE
break;
case 0xE619FF00: // cyan
data.name = "cyan";
data.type = COLOUR;
break;
case 0xF20DFF00: // aqua
data.name = "aqua";
data.type = COLOUR
break;
case 0xF30CFF00: // dark blue
data.name = "dark_blue";
data.type = COLOUR
break;
case 0xE718FF00: // purple
data.name = "purple";
data.type = COLOUR
break;
case 0xA15EFF00: // pink
data.name = "pink";
data.type = COLOUR
break;
case 0xE31CFF00: // fade
data.name = "fade";
data.type = MODE
break;
case 0xA55AFF00: // jump
data.name = "jump";
data.type = MODE
break;
case 0xBD42FF00: // reset
data.name = "reset";
data.type = SETTING
break;
}
return data;
}*/
Remote::Remote(RemoteType type) {
this->type = type;
}
buttonData Remote::call(long key_data) {
// Initialize the LED strip based on the type
buttonData return_data;
switch (type) {
case R20KEYSPLIT:
return_data = twentyKeySplit(key_data);
break;
case R24KEYWHITE:
// return_data = twentyFourKeyWhite(type);
break;
case R44KEYWHITE:
// Initialize SK6812 strip
// Your initialization code here
break;
}
return return_data;
}