Skip to content

Instantly share code, notes, and snippets.

@ghtomcat
Last active April 8, 2021 14:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghtomcat/8e2ece5004f37976d368bf26f24fc253 to your computer and use it in GitHub Desktop.
Save ghtomcat/8e2ece5004f37976d368bf26f24fc253 to your computer and use it in GitHub Desktop.
/**************************************************************************
read bme280 data and display on ssd1306
**************************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <WiFi.h>
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <WiFiClientSecure.h>
#include <AS5600.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_BME280 bme; // I2C
AMS_5600 ams5600;
// This is GandiStandardSSLCA2.pem, the root Certificate Authority that signed
// the server certifcate for the demo server https://jigsaw.w3.org in this
// example. This certificate is valid until Sep 11 23:59:59 2024 GMT
const char* rootCACertificate = \
"-----BEGIN CERTIFICATE-----\n" \
"MIIF6TCCA9GgAwIBAgIQBeTcO5Q4qzuFl8umoZhQ4zANBgkqhkiG9w0BAQwFADCB\n" \
"iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n" \
"cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n" \
"BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQw\n" \
"OTEyMDAwMDAwWhcNMjQwOTExMjM1OTU5WjBfMQswCQYDVQQGEwJGUjEOMAwGA1UE\n" \
"CBMFUGFyaXMxDjAMBgNVBAcTBVBhcmlzMQ4wDAYDVQQKEwVHYW5kaTEgMB4GA1UE\n" \
"AxMXR2FuZGkgU3RhbmRhcmQgU1NMIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n" \
"DwAwggEKAoIBAQCUBC2meZV0/9UAPPWu2JSxKXzAjwsLibmCg5duNyj1ohrP0pIL\n" \
"m6jTh5RzhBCf3DXLwi2SrCG5yzv8QMHBgyHwv/j2nPqcghDA0I5O5Q1MsJFckLSk\n" \
"QFEW2uSEEi0FXKEfFxkkUap66uEHG4aNAXLy59SDIzme4OFMH2sio7QQZrDtgpbX\n" \
"bmq08j+1QvzdirWrui0dOnWbMdw+naxb00ENbLAb9Tr1eeohovj0M1JLJC0epJmx\n" \
"bUi8uBL+cnB89/sCdfSN3tbawKAyGlLfOGsuRTg/PwSWAP2h9KK71RfWJ3wbWFmV\n" \
"XooS/ZyrgT5SKEhRhWvzkbKGPym1bgNi7tYFAgMBAAGjggF1MIIBcTAfBgNVHSME\n" \
"GDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQUs5Cn2MmvTs1hPJ98\n" \
"rV1/Qf1pMOowDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYD\n" \
"VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMCIGA1UdIAQbMBkwDQYLKwYBBAGy\n" \
"MQECAhowCAYGZ4EMAQIBMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNl\n" \
"cnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNy\n" \
"bDB2BggrBgEFBQcBAQRqMGgwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRy\n" \
"dXN0LmNvbS9VU0VSVHJ1c3RSU0FBZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZ\n" \
"aHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAWGf9\n" \
"crJq13xhlhl+2UNG0SZ9yFP6ZrBrLafTqlb3OojQO3LJUP33WbKqaPWMcwO7lWUX\n" \
"zi8c3ZgTopHJ7qFAbjyY1lzzsiI8Le4bpOHeICQW8owRc5E69vrOJAKHypPstLbI\n" \
"FhfFcvwnQPYT/pOmnVHvPCvYd1ebjGU6NSU2t7WKY28HJ5OxYI2A25bUeo8tqxyI\n" \
"yW5+1mUfr13KFj8oRtygNeX56eXVlogMT8a3d2dIhCe2H7Bo26y/d7CQuKLJHDJd\n" \
"ArolQ4FCR7vY4Y8MDEZf7kYzawMUgtN+zY+vkNaOJH1AQrRqahfGlZfh8jjNp+20\n" \
"J0CT33KpuMZmYzc4ZCIwojvxuch7yPspOqsactIGEk72gtQjbz7Dk+XYtsDe3CMW\n" \
"1hMwt6CaDixVBgBwAc/qOR2A24j3pSC4W/0xJmmPLQphgzpHphNULB7j7UTKvGof\n" \
"KA5R2d4On3XNDgOVyvnFqSot/kGkoUeuDcL5OWYzSlvhhChZbH2UF3bkRYKtcCD9\n" \
"0m9jqNf6oDP6N8v3smWe2lBvP+Sn845dWDKXcCMu5/3EFZucJ48y7RetWIExKREa\n" \
"m9T8bJUox04FB6b9HbwZ4ui3uRGKLXASUoWNjDNKD/yZkuBjcNqllEdjB+dYxzFf\n" \
"BT02Vf6Dsuimrdfp5gJ0iHRc2jTbkNJtUQoj1iM=\n" \
"-----END CERTIFICATE-----\n";
WiFiMulti WiFiMulti;
volatile byte revolutions;
int ang,wind;
int temp,hum,press;
// interrupt routine to count revolutions
void IRAM_ATTR isr() {
revolutions += 1;
}
// Setting clock via ntp...
void setClock() {
configTime(0, 0, "pool.ntp.org", "time.nist.gov");
Serial.print(F("Waiting for NTP time sync: "));
time_t nowSecs = time(nullptr);
while (nowSecs < 8 * 3600 * 2) {
delay(500);
Serial.print(F("."));
yield();
nowSecs = time(nullptr);
}
Serial.println();
struct tm timeinfo;
gmtime_r(&nowSecs, &timeinfo);
Serial.print(F("Current time: "));
Serial.print(asctime(&timeinfo));
}
unsigned long lastTime = 0;
unsigned long timerDelay = 10000; // sensors are checked every 10s
unsigned long lastTimePost = 0;
unsigned long timerDelayPost = 60000; // data is posted every 60s
void setup() {
Wire.begin();
Serial.begin(115200);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
unsigned status;
// default settings
status = bme.begin(0x76);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
Serial.print(" ID of 0x60 represents a BME 280.\n");
Serial.print(" ID of 0x61 represents a BME 680.\n");
while (1) delay(10);
}
WiFi.mode(WIFI_STA);
WiFiMulti.addAP("<ssid>", "<passwort>");
// wait for WiFi connection
Serial.print("Waiting for WiFi to connect...");
while ((WiFiMulti.run() != WL_CONNECTED)) {
Serial.print(".");
}
Serial.println(" connected");
setClock();
// attach pin 12 to interrupt routine
pinMode(12, INPUT);
attachInterrupt(12, isr, FALLING);
}
/*******************************************************
/* Function: convertRawAngleToDegrees
/* In: angle data from AMS_5600::getRawAngle
/* Out: human readable degrees as float
/* Description: takes the raw angle and calculates
/* float value in degrees.
/*******************************************************/
float convertRawAngleToDegrees(word newAngle)
{
/* Raw data reports 0 - 4095 segments, which is 0.087 of a degree */
float retVal = newAngle * 0.087;
ang = retVal;
return ang;
}
void loop() {
// get data every timerDelay ms
if ((millis() - lastTime) > timerDelay) {
display.clearDisplay();
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0,0);
display.print("Temperatur: ");
display.setCursor(70,0);
display.print(bme.readTemperature());
display.setCursor(100,0);
display.print(" *C");
display.setCursor(0,10);
display.print("Luftdruck: ");
display.setCursor(65,10);
display.print(bme.readPressure() / 100.0F);
display.setCursor(100,10);
display.print(" hPa");
display.setCursor(0,20);
display.print("Feuchtigkeit: ");
display.setCursor(80,20);
display.print(bme.readHumidity());
display.setCursor(110,20);
display.print(" %");
display.setCursor(0,30);
display.print("Wind: ");
display.setCursor(50,30);
display.print(revolutions*6*16*0.001885); // revolutions in 60sec to km/h at 16cm diameter
display.setCursor(80,30);
display.print(" km/h");
display.setCursor(0,40);
display.print("Wind: ");
display.setCursor(50,40);
display.print(convertRawAngleToDegrees(ams5600.getRawAngle()));
display.setCursor(80,40);
display.print(" Grad");
display.display();
wind=(revolutions*6*16*0.001885)*100;
ang=convertRawAngleToDegrees(ams5600.getRawAngle());
lastTime = millis();
revolutions=0;
}
// post data every timerDelayPost ms
if ((millis() - lastTimePost) > timerDelayPost) {
WiFiClientSecure *client = new WiFiClientSecure;
if(client) {
client -> setCACert(rootCACertificate);
{
// Add a scoping block for HTTPClient https to make sure it is destroyed before WiFiClientSecure *client is
HTTPClient https;
//Serial.print("[HTTPS] begin...\n");
// add device id and authentication
https.begin("https://element-iot.ch/api/v1/devices/<deviceid>/packets?auth=<authorization>");
hum=bme.readHumidity()*100;
String str1 = String(hum, HEX);
if (str1.length()==3) { str1="0" + str1;};
str1.toUpperCase();
temp=bme.readTemperature()*100;
String str2 = String(temp, HEX);
if (str2.length()==3) { str2="0" + str2;};
str2.toUpperCase();
press=bme.readPressure()/100.0;
String str3 = String(press, HEX);
if (str3.length()==3) { str3="0" + str3;};
str3.toUpperCase();
String str4 = String(wind, HEX);
if (str4.length()==3) { str4="0" + str4;};
if (str4.length()==1) { str4="000" + str4;}
str4.toUpperCase();
String str5 = String(ang, HEX);
if (str5.length()==3) { str5="0" + str5;};
if (str5.length()==2) { str5="00" + str5;}
if (str5.length()==1) { str5="000" + str5;}
str5.toUpperCase();
// submit payload via POST, as json
https.addHeader("Content-Type", "application/json");
String payload="{\"packet\":{\"payload_encoding\":\"binary\",\"payload\":\"";
payload +=str1;
payload +=str2;
payload +=str3;
payload +=str4;
payload +=str5;
payload +="\"}}";
Serial.println(payload);
int httpResponseCode = https.POST(payload);
// httpCode will be negative on error
if (httpResponseCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] POST... code: %d\n", httpResponseCode);
} else {
Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpResponseCode).c_str());
}
https.end();
}
delete client;
} else {
Serial.println("Unable to create client");
}
lastTimePost = millis();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment