// Stefan Zilt Klimastein
// Version 1.0 20.10.23
#include <Wire.h>
#include <SSD1306Ascii.h>
#include <SSD1306AsciiWire.h>
#include <Adafruit_AHTX0.h>
#include <EEPROM.h>
// AHT10/20
Adafruit_AHTX0 aht;
// Display
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
const char* fontName[] = {
"Arial14",
"Arial_bold_14",
"Callibri11",
"Callibri11_bold",
"Callibri11_italic",
"Callibri15",
"Corsiva_12",
"fixed_bold10x15",
"font5x7",
"font8x8",
"Iain5x7",
"lcd5x7",
"Stang5x7",
"System5x7",
"TimesNewRoman16",
"TimesNewRoman16_bold",
"TimesNewRoman16_italic",
"utf8font10x16",
"Verdana12",
"Verdana12_bold",
"Verdana12_italic",
"X11fixed7x14",
"X11fixed7x14B",
"ZevvPeep8x16"
};
const uint8_t* fontList[] = {
Arial14,
Arial_bold_14,
Callibri11,
Callibri11_bold,
Callibri11_italic,
Callibri15,
Corsiva_12,
fixed_bold10x15,
font5x7,
font8x8,
Iain5x7,
lcd5x7,
Stang5x7,
System5x7,
TimesNewRoman16,
TimesNewRoman16_bold,
TimesNewRoman16_italic,
utf8font10x16,
Verdana12,
Verdana12_bold,
Verdana12_italic,
X11fixed7x14,
X11fixed7x14B,
ZevvPeep8x16
};
uint8_t nFont = sizeof(fontList)/sizeof(uint8_t*);
SSD1306AsciiWire display;
// Trendvariablen
int trent_x = 0;
int trent_n = 300; // Durchschnittswerte ins sek
float temp_trent;
float hydr_trent;
float temp_t;
float hydr_t;
float temp_t2;
float hydr_t2;
char temp_txt[8];
char hydr_txt[8];
int balken = 0;
bool balken_x = true;
float test;
float temperatur_ist;
float feuchtigkeit_ist;
char text;
// INput
int Taster = 2;
int Taster_status = 0;
// Loopvar
long Timer_1 = millis();
// RGB LED
int LEDblau = 5; // Farbe blau an Pin 3
int LEDrot = 3; // Farbe rot an Pin 5
int LEDgruen=6; // Farbe gruen an Pin 6
int brightness1a = 100;
int brightness1b = 100;
int brightness1c = 100;
int dunkel = 255; // Zahlenwert 0 bedeutet Spannung 0V – also LED aus.
int dimmer_ok = 0;
int led_helligkeit;
int led_I = 1;
// Menue Var
bool menue_on = false;
int menue_pos= 0;
char* menue_txt;
int menue_wert;
long menue_ontime = millis();
long untermenue_klick = millis();
int grw_feuchte=1;
long Auswahl_entprellen = 0;
long Auswahl_entprellen_UP = 0;
long Auswahl_entprellen_DOWN = 0;
bool tippup= false;
bool tippdown= false;
bool auswahl= false;
char* texter;
char* number;
float zwergli;
long LED_BLINKER = millis();
bool BLINKER = false;
int TMP[5];
int DB_Feuchte[20];
int DB_F = 0;
int aa;
bool line_f = false;
long line_f_time;
bool line_f2 = false;
long line_f_time2;
bool led_fade = true;
bool led_feuchte_hysterese = false;
int display_hintergrund = false;
// Setup
void setup() {
Wire.begin();
Wire.setClock(400000L);
Serial.begin(9600);
display.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
// starten AHT10
if (!aht.begin()) {
Serial.println("Kein Geber AHT? Check");
delay(100);
}
// EE-Promm lesen
grw_feuchte = read_int(0);
if (grw_feuchte < 1 || grw_feuchte > 512 ){
grw_feuchte = 60;
}
TMP[0] = grw_feuchte;
led_helligkeit = read_int(2);
if (led_helligkeit < 1 || led_helligkeit > 200 ){
led_helligkeit = 100;
}
TMP[1] = led_helligkeit;
display.setFont(Verdana12);
display.clear();
// IOs Konfig
pinMode(LEDblau, OUTPUT);
pinMode(LEDgruen, OUTPUT);
pinMode(LEDrot, OUTPUT);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, INPUT_PULLUP);
}
// Normalprogram
void loop() {
// Tasten abrufen
int taste1 = digitalRead(11);
int Taster_up = digitalRead(10);
int Taster_down = digitalRead(12);
if(taste1 == LOW && Auswahl_entprellen < millis()){
menue_ontime = millis();
menue_on = true;
auswahl = true;
Auswahl_entprellen = 300 + millis();
menue_ontime = millis();
menue_pos++;
if (menue_pos > 3){menue_pos = 1;}
}
if(Taster_up == LOW && Auswahl_entprellen_UP < millis()){
menue_ontime = millis();
Auswahl_entprellen_UP = 80 + millis();
tippup = true;
}
if(Taster_down == LOW && Auswahl_entprellen_DOWN < millis()){
menue_ontime = millis();
Auswahl_entprellen_DOWN = 80 + millis();
tippdown = true;
}
// Taste Rechts Anzeige ausgeben
if(tippup == true && menue_on == false ){
line_f = true;
tippup = false;
line_f_time = millis();
display.clear();
display.setFont(fixed_bold10x15);
display.set1X();
display.setCursor(0, 0);
display.println("Feuchte");
display.set2X();
display.setCursor(0, 30);
display.println(hydr_t,1);
display.setCursor(90, 30);
display.print("%");
display.set1X();
display.setCursor(0,40);
display.println("Schnitt");
display.setCursor(84,40);
display.println(trent_n/60);
display.setCursor(98,40);
display.print("min");
}
if(line_f == true && line_f_time+3000 < millis()){
line_f = false;
display.clear();
}
// Taste Links Anzeige ausgeben
if(tippdown == true && menue_on == false ){
line_f2 = true;
tippdown = false;
line_f_time2 = millis();
display.clear();
display.setFont(fixed_bold10x15);
display.set1X();
display.setCursor(0, 0);
display.println("Temperatur");
display.set2X();
display.setCursor(0, 30);
display.println(temp_t,1);
display.setCursor(90, 30);
display.print("C");
display.set1X();
display.setCursor(0,40);
display.println("Schnitt");
display.setCursor(84,40);
display.println(trent_n/60);
display.setCursor(98,40);
display.print("min");
}
if(line_f2 == true && line_f_time2+3000 < millis()){
line_f2 = false;
display.clear();
}
// Taste Vorne Setupmenüe aufrufen
if(auswahl == true && menue_on == true && line_f == false && line_f2 == false){
menue_wert=0;
display.clear();
TMP[0]=grw_feuchte;
switch (menue_pos)
{
case 0:
break;
case 1:
menue_txt = "Setup\n Klimastein\n Ver. 1.0";
break;
case 2:
menue_txt = "Feuchte";
menue_wert = grw_feuchte;
break;
case 3:
menue_txt = "LEDlight";
menue_wert=led_helligkeit;
break;
default:
break;
}
auswahl = false;
}
if(tippup == true && menue_on == true || tippdown == true && menue_on == true){
Serial.println("drin");
switch (menue_pos)
{
case 1:
break;
case 2:
if(tippup == true ){ grw_feuchte++ ;}
if(tippdown == true ){ grw_feuchte-- ;}
if(grw_feuchte < 1){grw_feuchte = 1;}
if(grw_feuchte > 95){grw_feuchte = 95;}
menue_wert=grw_feuchte;
break;
case 3:
if(tippup == true ){ led_helligkeit++ ;}
if(tippdown == true ){ led_helligkeit-- ;}
if(led_helligkeit < 1){led_helligkeit = 1;}
if(led_helligkeit > 200){led_helligkeit = 200;}
menue_wert=led_helligkeit;
break;
default:
break;
}
tippup = false;
tippdown = false;
}
if(menue_on==true){
display.set1X();
display.setCursor(0, 0);
texter = menue_txt;
display.println(texter);
if(menue_wert>0){
display.setCursor(0, 40);
display.set2X();
display.println(menue_wert);
}
}
if(menue_on == true && (menue_ontime+3000) < millis()){
menue_pos = 0;
menue_on = false;
menue_txt = "";
menue_wert = ".";
// Autosave bei Änderung
if(grw_feuchte != TMP[0]){
write_int(0, grw_feuchte );
}
if(led_helligkeit != TMP[1]){
write_int(2, led_helligkeit );
}
display.clear();
}
if (Timer_1+1000 < millis()){
// Sensor AHT 10/20
sensors_event_t humidity, temp;
aht.getEvent(&humidity, &temp);
temperatur_ist = temp.temperature;
feuchtigkeit_ist = humidity.relative_humidity;
temp_trent = temp_trent + temperatur_ist;
hydr_trent = hydr_trent + feuchtigkeit_ist;
trent_x++;
if (trent_x == trent_n ) {
if(display_hintergrund == 0){display_hintergrund = 1;}
else{display_hintergrund = 0;}
display.invertDisplay(display_hintergrund);
// Durchschnitt
temp_t2 = round(temp_trent*10.0 / trent_n)/10.0;
hydr_t2 = round(hydr_trent*10.0 / trent_n)/10.0;
trent_x = 1;
temp_trent = temp_t = temp_t2;
hydr_trent = hydr_t = hydr_t2;
}
if (menue_on == false && line_f == false && line_f2 == false) {
balken = round(128 / trent_n * trent_x);
if(balken_x==false){
dimmer_ok = 255-(balken/2);
}
else{
dimmer_ok = (balken/2)+150;
}
}
if (Timer_1+1000 < millis() && menue_on == false && line_f == false && line_f2 == false){
display.setFont(fixed_bold10x15);
display.set2X();
display.setCursor(0, 0);
display.println(temperatur_ist,1);
display.setCursor(90, 0);
display.println("C");
display.setCursor(5, 52);
display.println(feuchtigkeit_ist,1);
display.setCursor(92, 52);
display.println("%");
}
// RGB LED Ansteuerung
if((LED_BLINKER+1000)<millis()){
//Fader
if(led_I<led_helligkeit && led_fade == true){ led_I++;}
if(led_fade == false){ led_I--;}
if(led_I==led_helligkeit){led_fade = false;}
if(led_I == 1){led_fade=true;}
// Blinktakt
if(BLINKER==false){
BLINKER=true;
}
else{ BLINKER=false;}
LED_BLINKER = millis();
}
analogWrite(LEDgruen, dunkel);
analogWrite(LEDblau, dunkel);
analogWrite(LEDrot, dunkel);
//LED Blau wenn zu feucht
if(float(grw_feuchte)<feuchtigkeit_ist||led_feuchte_hysterese==true){
led_feuchte_hysterese=true;
if(BLINKER==true){
analogWrite(LEDblau, 255-led_helligkeit);
}
else{
analogWrite(LEDblau, dunkel);
}
}
if(feuchtigkeit_ist<float(grw_feuchte)-3.0){ led_feuchte_hysterese = false;}
if(led_feuchte_hysterese==false){
analogWrite(LEDgruen, 255-led_I);
}
Timer_1 = millis();
}
}
// Lesen aus EEPROM
int read_int(int address)
{
long byte_2 = EEPROM.read(address);
long byte_1 = EEPROM.read(address + 1);
int val = ((byte_2 << 0) & 0xFFFFFF) + ((byte_1 << 8) & 0xFFFFFFFF);
return val;
}
// Schreibe in EEPROM
void write_int(int address, int value)
{
byte byte_2 = (value & 0xFF);
byte byte_1 = ((value >> 8) & 0xFF);
EEPROM.update(address, byte_2);
EEPROM.update(address + 1, byte_1);
}