Vím, že je to spíš hračka než seriózní měřidlo, ale stejně bych ten graf rád viděl.
Problém je v tom že program jsem nepsal já, byl u stl souborů na krabičku.
Tyhle displeje jsou zatím pro mě jako začátečníka velká neznámá. Stjně tak v tom ostatním taky trochu plavu. Zvlášť tady, kde je plno zaremovaných příkazů.
Může se nějaká dobrá duše podívat, kde je chyba?
Kód: Vybrat vše
#include <ESP8266WiFi.h>
#include "SSD1306.h"
#define GAS_SENSOR_PIN A0
const boolean DEBUG = false;
SSD1306 display(0x3C, D2, D1);
long frame = 1; //1 instead of 0, to avoid all modulo checks from triggering on first frame
int sensorValue = 0;
float tempAveragedSensorValue = 0;
float averagedSensorValue = 0;
const int INTERVALS_PER_UI = 50;
bool showGraph = false;
const int UPDATE_INTERVAL = 100; //ms
const int AVERAGING_SAMPLES = 10;
const int GRAPH_SAMPLES_PER_PIXEL = DEBUG ? 5 : (5*60*1000 / UPDATE_INTERVAL); //each vertical line on the graph represents 5 minutes
const int GRAPH_MARKER_SPACING = 12; //show a marker in the graph for every hour
const int X_RES = 128;
const int Y_RES = 64;
const int LOWEST_OBSERVED_READING = 198;
const int HIGHEST_OBSERVED_READING = 330 + 20;
int graphValues[128];
int currentGraphSampleCount = 0;
void setup() {
disableWifi();
Serial.begin(9600);
display.init();
display.flipScreenVertically();
if(!DEBUG)
{
showHeatupMessage();
}
}
void loop(){
readSensor();
displayUi();
delay(UPDATE_INTERVAL);
frame++;
}
void displayUi()
{
display.clear();
if(showGraph)
{
displayGraph();
} else {
displayReading();
}
if(frame % INTERVALS_PER_UI == 0)
{
showGraph = !showGraph;
}
display.display();
}
void displayGraph()
{
display.drawRect(0, 0, X_RES, Y_RES);
for(int x = 0; x < X_RES; x++)
{
int actualX = X_RES - x-1;
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
int loggedValue = graphValues[x];
int actualY = int(normalizeSensorValue(float(loggedValue)) * float(Y_RES));
if(loggedValue == 0.0)
{
actualY = Y_RES;
}
// display.drawString(0, x*10, String(actualY));
// display.setPixel(actualX, actualY);
//display.drawString(0, x*10, String(int(float(loggedValue)*float(Y_RES)/float(1023))));
display.setPixel(actualX, int(float(loggedValue)*float(Y_RES)/float(1023)));
if((x+1) % GRAPH_MARKER_SPACING == 0)
{
//render marker
// display.drawRect(actualX, 0, 1, actualY);
} else {
display.drawRect(actualX, actualY, 1, Y_RES - actualY);
display.drawVerticalLine(actualX, actualY, Y_RES - actualY);
}
}
}
void displayReading()
{
float pollution = normalizeSensorValue(averagedSensorValue);
float quality = 1.0 - pollution;
display.setFont(ArialMT_Plain_16);
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(X_RES/2, 0, "Air Quality:");
display.setFont(ArialMT_Plain_24);
display.drawString(X_RES/2, 15, String(int(quality * 100)) + "%");
if(DEBUG || true) {
display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, Y_RES-11, String(sensorValue));
display.setTextAlignment(TEXT_ALIGN_RIGHT);
display.drawString(X_RES, Y_RES-11, String(sensorValue/1023.0*3.3) + "v");
}
}
void readSensor()
{
sensorValue = analogRead(GAS_SENSOR_PIN);
if(tempAveragedSensorValue == 0)
{
tempAveragedSensorValue = sensorValue;
} else {
tempAveragedSensorValue = (averagedSensorValue * float(AVERAGING_SAMPLES-1) / float(AVERAGING_SAMPLES)) + sensorValue / float(AVERAGING_SAMPLES);
}
if((frame % AVERAGING_SAMPLES == 0) || averagedSensorValue == 0)
{
averagedSensorValue = tempAveragedSensorValue;
}
if(++currentGraphSampleCount > GRAPH_SAMPLES_PER_PIXEL)
{
addDatapointToGraph(averagedSensorValue);
currentGraphSampleCount = 0;
}
}
//append value to start of array, and push all other values backwards
void addDatapointToGraph(float value)
{
for(int i=X_RES-1; i> 0; i--)
{
graphValues[i] = graphValues[i-1];
}
graphValues[0] = int(value);
}
float normalizeSensorValue(float value)
{
return deRange(value, LOWEST_OBSERVED_READING, HIGHEST_OBSERVED_READING);
}
float deRange(float value, int lowerBound, int upperBound)
{
return (value - lowerBound) / float(upperBound-lowerBound);
}
void showHeatupMessage()
{
for(int i=20; i >= 0; i--)
{
showHeatupMessageInternal(i);
delay(1000);
}
}
void showHeatupMessageInternal(int remainingSeconds)
{
display.clear();
display.drawString(0, 0, "Heating sensor...");
display.drawString(0, 20, String(remainingSeconds) + " seconds");
display.display();
}
//Saves a bit of power/heat, and avoids a silly ESP wifi access point showing up when the device is on.
void disableWifi() {
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1); //waiting a millisecond is done to cede control to the ESP firmware, so it can actually apply our settings.
}