Created
October 21, 2020 19:14
-
-
Save machinaut/142a4ea2a58f8f6c73b747ee7428babd to your computer and use it in GitHub Desktop.
air sensor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
BasicHTTPClient.ino | |
Created on: 24.05.2015 | |
*/ | |
#include <Arduino.h> | |
#include <ESP8266WiFi.h> | |
#include <ESP8266WiFiMulti.h> | |
#include <ESP8266HTTPClient.h> | |
#include <WiFiClient.h> | |
#include <Arduino_JSON.h> | |
ESP8266WiFiMulti WiFiMulti; | |
#include <FastLED.h> | |
#define LED_PIN 14 | |
#define BRIGHTNESS 96 | |
#define LED_TYPE WS2811 | |
#define COLOR_ORDER GRB | |
const uint8_t kMatrixWidth = 20; | |
const uint8_t kMatrixHeight = 1; | |
const bool kMatrixSerpentineLayout = true; | |
// This example combines two features of FastLED to produce a remarkable range of | |
// effects from a relatively small amount of code. This example combines FastLED's | |
// color palette lookup functions with FastLED's Perlin/simplex noise generator, and | |
// the combination is extremely powerful. | |
// | |
// You might want to look at the "ColorPalette" and "Noise" examples separately | |
// if this example code seems daunting. | |
// | |
// | |
// The basic setup here is that for each frame, we generate a new array of | |
// 'noise' data, and then map it onto the LED matrix through a color palette. | |
// | |
// Periodically, the color palette is changed, and new noise-generation parameters | |
// are chosen at the same time. In this example, specific noise-generation | |
// values have been selected to match the given color palettes; some are faster, | |
// or slower, or larger, or smaller than others, but there's no reason these | |
// parameters can't be freely mixed-and-matched. | |
// | |
// In addition, this example includes some fast automatic 'data smoothing' at | |
// lower noise speeds to help produce smoother animations in those cases. | |
// | |
// The FastLED built-in color palettes (Forest, Clouds, Lava, Ocean, Party) are | |
// used, as well as some 'hand-defined' ones, and some proceedurally generated | |
// palettes. | |
#define NUM_LEDS (kMatrixWidth * kMatrixHeight) | |
#define MAX_DIMENSION ((kMatrixWidth>kMatrixHeight) ? kMatrixWidth : kMatrixHeight) | |
// The leds | |
CRGB leds[kMatrixWidth * kMatrixHeight]; | |
// The 16 bit version of our coordinates | |
static uint16_t x; | |
static uint16_t y; | |
static uint16_t z; | |
// We're using the x/y dimensions to map to the x/y pixels on the matrix. We'll | |
// use the z-axis for "time". speed determines how fast time moves forward. Try | |
// 1 for a very slow moving effect, or 60 for something that ends up looking like | |
// water. | |
uint16_t speed = 1; // speed is set dynamically once we've started up | |
// Scale determines how far apart the pixels in our noise matrix are. Try | |
// changing these values around to see how it affects the motion of the display. The | |
// higher the value of scale, the more "zoomed out" the noise iwll be. A value | |
// of 1 will be so zoomed in, you'll mostly see solid colors. | |
uint16_t scale = 30; // scale is set dynamically once we've started up | |
// This is the array that we keep our computed noise values in | |
uint8_t noise[MAX_DIMENSION][MAX_DIMENSION]; | |
CRGBPalette16 currentPalette( PartyColors_p ); | |
uint8_t colorLoop = 1; | |
int level = 0; | |
//CRGBPalette16 qualityPalettes[6]; | |
// Fill the x/y array of 8-bit noise values using the inoise8 function. | |
void fillnoise8() { | |
// If we're runing at a low "speed", some 8-bit artifacts become visible | |
// from frame-to-frame. In order to reduce this, we can do some fast data-smoothing. | |
// The amount of data smoothing we're doing depends on "speed". | |
uint8_t dataSmoothing = 0; | |
if( speed < 50) { | |
dataSmoothing = 200 - (speed * 4); | |
} | |
for(int i = 0; i < MAX_DIMENSION; i++) { | |
int ioffset = scale * i; | |
for(int j = 0; j < MAX_DIMENSION; j++) { | |
int joffset = scale * j; | |
uint8_t data = inoise8(x + ioffset,y + joffset,z); | |
// The range of the inoise8 function is roughly 16-238. | |
// These two operations expand those values out to roughly 0..255 | |
// You can comment them out if you want the raw noise data. | |
data = qsub8(data,16); | |
data = qadd8(data,scale8(data,39)); | |
if( dataSmoothing ) { | |
uint8_t olddata = noise[i][j]; | |
uint8_t newdata = scale8( olddata, dataSmoothing) + scale8( data, 256 - dataSmoothing); | |
data = newdata; | |
} | |
noise[i][j] = data; | |
} | |
} | |
z += speed; | |
// apply slow drift to X and Y, just for visual variation. | |
x += speed / 8; | |
y -= speed / 16; | |
} | |
void mapNoiseToLEDsUsingPalette() | |
{ | |
static uint8_t ihue=0; | |
for(int i = 0; i < kMatrixWidth; i++) { | |
for(int j = 0; j < kMatrixHeight; j++) { | |
// We use the value at the (i,j) coordinate in the noise | |
// array for our brightness, and the flipped value from (j,i) | |
// for our pixel's index into the color palette. | |
uint8_t index = noise[j][i]; | |
uint8_t bri = noise[i][j]; | |
// if this palette is a 'loop', add a slowly-changing base value | |
if( colorLoop) { | |
index += ihue; | |
} | |
// brighten up, as the color palette itself often contains the | |
// light/dark dynamic range desired | |
if( bri > 127 ) { | |
bri = 255; | |
} else { | |
bri = dim8_raw( bri * 2); | |
} | |
CRGB color = ColorFromPalette( currentPalette, index, bri); | |
leds[XY(i,j)] = color; | |
} | |
} | |
ihue+=1; | |
} | |
void setup() { | |
LEDS.addLeds<LED_TYPE,LED_PIN,COLOR_ORDER>(leds,NUM_LEDS); | |
LEDS.setBrightness(BRIGHTNESS); | |
// Initialize our coordinates to some random values | |
x = random16(); | |
y = random16(); | |
z = random16(); | |
Serial.begin(115200); | |
// Serial.setDebugOutput(true); | |
Serial.println(); | |
Serial.println(); | |
Serial.println(); | |
for (uint8_t t = 4; t > 0; t--) { | |
Serial.printf("[SETUP] WAIT %d...\n", t); | |
Serial.flush(); | |
delay(1000); | |
} | |
WiFi.mode(WIFI_STA); | |
WiFiMulti.addAP("wifiname", "wifipass"); | |
} | |
void loop() { | |
// wait for WiFi connection | |
if ((WiFiMulti.run() == WL_CONNECTED)) { | |
WiFiClient client; | |
HTTPClient http; | |
Serial.print("[HTTP] begin...\n"); | |
if (http.begin(client, "http://www.purpleair.com/json?key=7AOUDHPV16Z14GP1&show=72789")) { // HTTP | |
Serial.print("[HTTP] GET...\n"); | |
// start connection and send HTTP header | |
int httpCode = http.GET(); | |
// httpCode will be negative on error | |
if (httpCode > 0) { | |
// HTTP header has been send and Server response header has been handled | |
Serial.printf("[HTTP] GET... code: %d\n", httpCode); | |
// file found at server | |
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) { | |
String payload = http.getString(); | |
Serial.println(payload); | |
// Process the payload into JSON? | |
JSONVar myObject = JSON.parse(payload); | |
// JSONVar cannot be cast directly to double | |
float PM2_5 = atof(myObject["results"][0]["PM2_5Value"]); | |
Serial.println("PM2.5"); | |
Serial.println(PM2_5); | |
int max_level[] = {12, 35, 55, 150, 250, 500}; | |
String labels[] = {"Good", "Moderate", "USG", "Unhealthy", "V Unhealthy", "Hazardous"}; | |
int color[] = {96, 64, 24, 250, 224, 192}; | |
for (int i = 0; i < 6; i++) { | |
if (PM2_5 <= max_level[i]) { | |
level = i; // XXX | |
break; | |
} | |
} | |
// level = (level + 1) % 6; | |
// Serial.println("overriding level:"); | |
// Serial.println(level); | |
currentPalette = CRGBPalette16( | |
CHSV( ((color[level] + 0) % 256), 255, 128), | |
CHSV( ((color[level] + 8) % 256), 255, 255), | |
CHSV( ((color[level] + 0) % 256), 192, 255), | |
CHSV( ((color[level] - 8) % 256), 255, 255)); | |
Serial.println("Air quality level:"); | |
Serial.println(labels[level]); | |
} | |
} else { | |
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); | |
} | |
http.end(); | |
} else { | |
Serial.printf("[HTTP} Unable to connect\n"); | |
} | |
} | |
// Now run the color for 100 iterations before reading wifi again | |
int iter; | |
for (iter = 0 ; iter < 100 ; iter ++) { | |
// generate noise data | |
fillnoise8(); | |
// convert the noise data to colors in the LED array | |
// using the current palette | |
mapNoiseToLEDsUsingPalette(); | |
LEDS.show(); | |
delay(100); | |
} | |
// delay(10000); // Accounted for in the loop above | |
} | |
// | |
// Mark's xy coordinate mapping code. See the XYMatrix for more information on it. | |
// | |
uint16_t XY( uint8_t x, uint8_t y) | |
{ | |
uint16_t i; | |
if( kMatrixSerpentineLayout == false) { | |
i = (y * kMatrixWidth) + x; | |
} | |
if( kMatrixSerpentineLayout == true) { | |
if( y & 0x01) { | |
// Odd rows run backwards | |
uint8_t reverseX = (kMatrixWidth - 1) - x; | |
i = (y * kMatrixWidth) + reverseX; | |
} else { | |
// Even rows run forwards | |
i = (y * kMatrixWidth) + x; | |
} | |
} | |
return i; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment