-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcontolKnob.ino
278 lines (221 loc) · 8.71 KB
/
contolKnob.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
/*
A rotary encoder publishes MQTT values for:
- brightness (between 0 and 255)
- RGB values (r,g,b format)
for more detail check:
https://github.com/marcoprovolo/Home-Automation-Devices
Copyright (C) 2017-2018 by Marco Provolo
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
See also the list of [contributors](https://github.com/your/project/contributors) who participated in this project.
*/
#include <FastLED.h> // http://fastled.io/ https://github.com/FastLED/FastLED
#include <ESP8266WiFi.h>
#include <PubSubClient.h> // https://github.com/knolleary/pubsubclient
/************ WIFI and MQTT INFORMATION ******************/
const char* wifi_ssid = ""; //
const char* wifi_password = ""; // YOUR PARAMETERS HERE
const char* mqtt_server = ""; //
const char* mqtt_usr = ""; // <- can be left empty if not used
const char* mqtt_psw = ""; // <- can be left empty if not used
/************ PIN DEFINITION ******************/
#define encoderPin1 D7
#define encoderPin2 D5
#define encoderButton D8
#define MAXBrightValue 255
#define MINBrightValue 0
#define MAXColorValue 255
#define MINColorValue 0
static unsigned long debouncingTime = 50; //debouncing time in milliseconds for the knob push
/*********** MQTT TOPICS **********************/
#define BrightnessPub "knob/brightness"
#define ColorPub "knob/color"
WiFiClient espClient; //initialise a wifi client
PubSubClient client(espClient); //creates a partially initialised client instance
char msg[50];
/*************FASTLED******************/
#define DATA_PIN D1
#define NUM_LEDS 2 // feedback led on device
#define COLOR_ORDER GRB
#define LED_TYPE WS2812B
CRGB leds[NUM_LEDS];
/********INTERRUPT VALUES for ROTARY ENCODER********/
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
volatile int Mode = 0;
volatile unsigned long lastMillis = 0; //debouce the button
volatile int BrightValue = 255; //this is full bright
volatile int ColorValue = 30;
unsigned long StartEncoding = 0; //slow down mqtt publish
static unsigned long PubSlowDown = 150; // publish every X milliseconds
long lastencoderValue = 0;
int lastMSB = 0;
int lastLSB = 0;
int BrightOLD = 0;
int ColorOLD = 30;
/************ SETUP WIFI CONNECT and PRINT IP SERIAL ******************/
void setup_wifi() {
bool toggle = true;
fill_solid(leds, NUM_LEDS, CRGB::Aqua); FastLED.show();
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifi_ssid);
WiFi.begin(wifi_ssid, wifi_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
if (toggle == false) fill_solid(leds, NUM_LEDS, CRGB::Black);
else fill_solid(leds, NUM_LEDS, CRGB::Aqua);
FastLED.show();
toggle = !toggle;
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
fill_solid(leds, NUM_LEDS, CRGB::White);
FastLED.show();
FastLED.delay(1000);
}
/* CALLBACK has to exist BTW it's useless because we are not subscribed to any topic */
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
msg[i] = payload[i];
Serial.print((char)payload[i]);
}
}
void setup() {
Serial.begin(115200);
Serial.println("lest's begin");
pinMode(encoderPin1, INPUT_PULLUP);
pinMode(encoderPin2, INPUT_PULLUP);
pinMode(encoderButton, INPUT_PULLUP);
attachInterrupt(encoderPin1, updateEncoder, CHANGE);
attachInterrupt(encoderPin2, updateEncoder, CHANGE);
attachInterrupt(encoderButton, ModeButton, RISING);
FastLED.addLeds<LED_TYPE, DATA_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setDither(0);
setup_wifi();
client.setServer(mqtt_server, 1883); //client is now ready for use
client.setCallback(callback);
}
void loop() {
char buf[50];
if (!client.connected()) {
reconnect();
}
client.loop();
// HSV (Rainbow) to RGB color conversion
CHSV hsv(ColorValue, 255, 255);
CRGB rgb;
hsv2rgb_rainbow( hsv, rgb);
// rgb will now be (0, 0, 255) -- pure blue as RGB
if (ColorValue != ColorOLD && (StartEncoding < millis() - PubSlowDown)) { //print if COLOR has CHANGED
Serial.print("COLOR encoder value [HSV]: ");
Serial.println(ColorValue);
Serial.print("COLOR encoder value [RGB]: ");
Serial.print("R: ");
Serial.print(rgb[0]);
Serial.print(" G: ");
Serial.print(rgb[1]);
Serial.print(" B: ");
Serial.println(rgb[2]);
Serial.println("publishing RGB value");
String RGBColor = String(rgb[0]) + "," + String(rgb[1]) + "," + String(rgb[2]);
RGBColor.toCharArray(buf, 14);
client.publish(ColorPub, buf);
ColorOLD = ColorValue;
}
if (BrightValue != BrightOLD && (StartEncoding < millis() - PubSlowDown)) { //print if BRIGHTNESS has CHANGED
Serial.print("BRIGHTNESS value: ");
Serial.println(BrightValue);
String(BrightValue).toCharArray(buf, 4);
Serial.println("publishing brightness");
client.publish(BrightnessPub, buf);
BrightOLD = BrightValue;
}
}
void reconnect() {
// Loop until we're reconnected
//bool toggle = 1;
while (!client.connected()) {
fill_solid(leds, NUM_LEDS, CRGB::Orange);
FastLED.show();
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "imaknob";
clientId += String(random(0xff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str, mqtt_usr, mqtt_psw)) {
Serial.println("connected");
fill_solid(leds, NUM_LEDS, CRGB::Green); FastLED.show();
delay(2000);
fill_solid(leds, NUM_LEDS, CHSV(0, 0, BrightValue)); FastLED.show();
} else {
fill_solid(leds, NUM_LEDS, CRGB::Orange); FastLED.show();
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void updateEncoder() {
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
StartEncoding = millis();
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
switch (Mode) {
case 0: //Brightness
if ((sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) && BrightValue < MAXBrightValue) BrightValue ++;
if ((sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) && BrightValue > MINBrightValue) BrightValue --;
break;
case 1: //Color
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) ColorValue ++;
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) ColorValue --;
if (ColorValue > MAXColorValue) ColorValue = MINColorValue;
if (ColorValue < MINColorValue) ColorValue = MAXColorValue;
break;
default:
// if nothing else matches, do the default
Serial.println("out of cases... something went wrong");
// default is optional
break;
}
displayLEDS();
lastEncoded = encoded; //store this value for next time
}
void ModeButton() {
while (digitalRead(encoderButton) == HIGH) {
//do nothing while button is pressed
Serial.println("please... relese the button!");
}
if (lastMillis < millis() - debouncingTime) {
Mode++;
lastMillis = millis();
}
if (Mode == 2) Mode = 0;
Serial.print("Setting mode: ");
Serial.println(Mode);
displayLEDS();
}
void displayLEDS() {
switch (Mode) {
case 0:
for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(0, 0, BrightValue);
break;
case 1:
for (int i = 0; i < NUM_LEDS; i++) leds[i] = CHSV(ColorValue, 255, 255);
break;
}
FastLED.show();
}
/***** END OF FILE *****/