-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathesp-hsmr-NeoPixelBus.ino
220 lines (179 loc) · 5.51 KB
/
esp-hsmr-NeoPixelBus.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
// NeoPixelCylon
// This example will move a Cylon Red Eye back and forth across the
// the full collection of pixels on the strip.
//
// This will demonstrate the use of the NeoEase animation ease methods; that provide
// simulated acceleration to the animations.
//
//
#include <NeoPixelBus.h>
#include <NeoPixelAnimator.h>
#include <WiFiClient.h>
#include <WiFiClientSecure.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
const char* wlan_ssid = "";
const char* wlan_password = "";
const uint16_t PixelCount = 3*49; // make sure to set this to the number of pixels in your strip
const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266
RgbColor CylonEyeColor = HtmlColor(0x7f0000);
NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount, PixelPin);
// for esp8266 omit the pin
//NeoPixelBus<NeoGrbFeature, Neo800KbpsMethod> strip(PixelCount);
NeoPixelAnimator animations(2); // only ever need 2 animations
uint16_t lastPixel = 0; // track the eye position
int8_t moveDir = 1; // track the direction of movement
int mil; // millisecond timer for scheduling the api query
// uncomment one of the lines below to see the effects of
// changing the ease function on the movement animation
AnimEaseFunction moveEase =
// NeoEase::Linear;
// NeoEase::QuadraticInOut;
// NeoEase::CubicInOut;
NeoEase::QuarticInOut;
// NeoEase::QuinticInOut;
// NeoEase::SinusoidalInOut;
// NeoEase::ExponentialInOut;
// NeoEase::CircularInOut;
void FadeAll(uint8_t darkenBy)
{
RgbColor color;
for (uint16_t indexPixel = 0; indexPixel < strip.PixelCount(); indexPixel++)
{
color = strip.GetPixelColor(indexPixel);
color.Darken(darkenBy);
strip.SetPixelColor(indexPixel, color);
}
}
void FadeAnimUpdate(const AnimationParam& param)
{
if (param.state == AnimationState_Completed)
{
FadeAll(10);
animations.RestartAnimation(param.index);
}
}
void MoveAnimUpdate(const AnimationParam& param)
{
// apply the movement animation curve
float progress = moveEase(param.progress);
// use the curved progress to calculate the pixel to effect
uint16_t nextPixel;
if (moveDir > 0)
{
nextPixel = progress * PixelCount;
}
else
{
nextPixel = (1.0f - progress) * PixelCount;
}
// if progress moves fast enough, we may move more than
// one pixel, so we update all between the calculated and
// the last
if (lastPixel != nextPixel)
{
for (uint16_t i = lastPixel + moveDir; i != nextPixel; i += moveDir)
{
strip.SetPixelColor(i, CylonEyeColor);
}
}
strip.SetPixelColor(nextPixel, CylonEyeColor);
lastPixel = nextPixel;
if (param.state == AnimationState_Completed){
// reverse direction of movement
moveDir *= -1;
// done, time to restart this position tracking animation/timer
animations.RestartAnimation(param.index);
}
}
void SetupAnimations() {
// fade all pixels providing a tail that is longer the faster
// the pixel moves.
animations.StartAnimation(0, 5, FadeAnimUpdate);
// take several seconds to move eye fron one side to the other
animations.StartAnimation(1, 2000, MoveAnimUpdate);
}
void setup() {
// fire up wifi and query space api
Serial.begin(115200);
strip.Begin();
strip.Show();
Serial.println();
Serial.println("Running...");
WiFi.begin(wlan_ssid, wlan_password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
SetupAnimations();
if(getSpaceApi()){
CylonEyeColor = HtmlColor(0x669900);
}else{
CylonEyeColor = HtmlColor(0xCC0033);
}
//WiFi.forceSleepBegin();
}
void loop(){
// this is all that is needed to keep it running
// and avoiding using delay() is always a good thing for
// any timing related routines
// query the server every minute
if(millis() - mil >= 1000 * 60){
//WiFi.forceSleepWake();
if(getSpaceApi()){
CylonEyeColor = HtmlColor(0x669900);
}else{
CylonEyeColor = HtmlColor(0xCC0033);
}
//WiFi.forceSleepBegin();
// query every minute
mil = millis();
}
if (millis() - mil < 0) {
// should overflow after 50 d
mil = millis();
}
animations.UpdateAnimations();
strip.Show();
}
bool getSpaceApi(){
StaticJsonBuffer<2000> jsonBuffer;
// set up client
WiFiClient client;
const int httpPort = 80;
const char* url = "hsmr.cc";
const char* file = "/spaceapi.json";
//connect to api
if (!client.connect(url, httpPort)) {
Serial.println("connection failed");
return false;
}
//download status
client.print(String("GET ") + file + " HTTP/1.1\r\n" +
"Host: " + url + "\r\n" +
"Connection: close\r\n\r\n");
// try until it exceeds 1 second
int started = millis();
while(!client.available()){
delay(1);
if(millis() - started > 1000){
return false;
}
}
// read the returned strings
while(client.available()){
String line = client.readStringUntil('\r');
Serial.println(line);
JsonObject& root = jsonBuffer.parseObject(line);
if (!root.success()){
Serial.println("parseObject() failed");
}else{
Serial.println(root["state"]["open"].asString());
return root["state"]["open"] == true;
}
}
}