Sorry, aber ich verstehe nicht, was du uns damit sagen möchtest.
Geht.....gebt nicht, was denn nun ?
Kannst du das bitte etwas genauer schreiben und auch zeigen wie es jetzt bei dir aussieht.
Zudem muss ein fehlendes Semikolon ";" eine Fehlermeldung zeigen.
U8G2_SSD1309_128X64_NONAME2_1_HW_I2C u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ 16);
Dieser Code Geht nicht. Alle die mit HW funktionieren nicht. Nur die mit SW. Also alle die hier stehen. Auch die, die Auskommentiert sind. Hatte alle Kommentare Gelöscht die nicht wichtig sind.
Ich hab ein neues Sketch erstellt und Kopiere Blockweise um zu sehen ab wann Bleibt das Display aus.
Dann machst du vermutlich noch einen anderen Fehler, den wir nicht sehen können.
Hardware-I2C funktioniert bei mir an allen I2C-Displays, wenn der Rest der Beschaltung und des Sketches auch stimmt.
Wenn die Verkabelung, die an irgend ein Software-I2C angepasst ist, nicht zu den benötigten Pins für Hardware I2C passt, funktioniert das mit den HW Konstruktoren natürlich nicht…
Ich habe 2 Andere Verkabelungen versucht
U8G2_SSD1309_128X64_NONAME2_1_HW_I2C u8g2(U8G2_R0, /* clock=*/ 32, /* data=*/ 33, /* reset=*/ 17);
U8G2_SSD1309_128X64_NONAME2_1_HW_I2C u8g2(U8G2_R0, /* clock=*/ 21, /* data=*/ 18, /* reset=*/ 17);
Beide Ohne erfolg
Aber ich belasse es erstmal bei der Softwareversion und würd dort den Fehler weiter Suchen weshalb das Ganze Programm nicht Funktioniert
Und wieder schreibst du in Rätseln.
Geht es mit SW, oder nicht ?
Welchen Fehler suchst du dann noch ?
Zeig uns doch mal einFoto deines Aufbaus. Bitte so, dass alles zu erkennen ist.
Mit SW geht dieses Hallo World Sketch. Aber nicht das nachgebaute Projekt. Weil irgendwo in dem Skript scheinbar etwas nicht passt.
Das ganze ist wie auf diesem Schaltplan wieder angeschlossen
Von diesem Github ist auch die *.Ino datei das den OLED nichts anzeigen lässt
Du verstehst es offensichtlich nicht.
Ich möcht nicht sehen, wie es aussehen soll oder könnte, sondern wie es bei dir aussieht. Zumal man fast davon ausgehen kann, das das Projekt im gezeigten Beitrag funktioniert. Bei dir aber nicht.
Allerdings funktioniert der gezeigte Link bei mir nicht. Somit hilft der nicht.
Ich hab Alles im Gehäuse eingebaut und daher schwer Sichtbar wie es genau Verkabelt ist.
Mitlerweile habe ich einen Problemverursacher gefunden.
// switch Vcc / GND on normal pins for convenient wiring
// output is 3.3V for VCC
digitalWrite (switch_vcc_pin, HIGH);
digitalWrite (button_start_vcc_pin, HIGH);
digitalWrite (button_stop_vcc_pin, HIGH);
// pinMode (_GND, OUTPUT); // turn on GND pin first (important!)
// turn on VCC power
// pinMode (switch_vcc_pin, OUTPUT); //<- Dieses Komentar habe ich hinzu gefügt
pinMode (button_start_vcc_pin, OUTPUT);
pinMode (button_stop_vcc_pin, OUTPUT);
// short delay to let chip power up
delay (100);
dies ist so Definiert
const int switch_vcc_pin = 9;
Ist diese Zeile kein Kommentar bleibt der Bildschirm Dunkel
#include <Arduino.h>
#include <Wire.h>
#include <U8g2lib.h> /* aus dem Bibliotheksverwalter */
#include <HX711.h> /* aus dem Bibliotheksverwalter */
#include <ESP32Servo.h> /* https://github.com/jkb-git/ESP32Servo */
#include <Preferences.h> /* aus dem BSP von expressif, wird verfügbar wenn das richtige Board ausgewählt ist */
//
// Hier den Code auf die verwendete Hardware einstellen
//
#define HARDWARE_LEVEL 3 // 1 = originales Layout mit Schalter auf Pin 19/22/21
// 2 = Layout für V2 mit Schalter auf Pin 23/19/22
// 3 = ESP32 DEVKit V2 AZ-Delivery
// In Voreinstellung https://dl.espressif.com/dl/package_esp32_index.json mit eintragen
// Bei Werkzeuge -> Board_> ESP32 Arduino->ESP32 Module auswählen
// Beim flashen (übetragen) die Boottaste gedrückt halten und anschließend Rest drücken.
#define SERVO_ERWEITERT // definieren, falls die Hardware mit dem alten Programmcode mit Poti aufgebaut wurde oder der Servo zu wenig fährt
// Sonst bleibt der Servo in Stop-Position einige Grad offen! Nach dem Update erst prüfen!
#define ROTARY_SCALE 2 // in welchen Schritten springt unser Rotary Encoder.
// Beispiele: KY-040 = 2, HW-040 = 1, für Poti-Betrieb auf 1 setzen
#define USE_ROTARY // Rotary benutzen
#define USE_ROTARY_SW // Taster des Rotary benutzen
//#define USE_POTI // Poti benutzen -> ACHTUNG, im Normalfall auch USE_ROTARY_SW deaktivieren!
//#define FEHLERKORREKTUR_WAAGE // falls Gewichtssprünge auftreten, können diese hier abgefangen werden
// Achtung, kann den Wägeprozess verlangsamen. Vorher Hardware prüfen.
//#define QUETSCHHAHN_LINKS // Servo invertieren, falls der Quetschhahn von links geöffnet wird. Mindestens ein Exemplar bekannt
//
// Ende Benutzereinstellungen!
//
//
// Ab hier nur verstellen wenn Du genau weisst, was Du tust!
//
//#define isDebug 3 // serielle debug-Ausgabe aktivieren. Mit >3 wird jeder Messdurchlauf ausgegeben
// ACHTUNG: zu viel Serieller Output kann einen ISR-Watchdog Reset auslösen!
//#define POTISCALE // Poti simuliert eine Wägezelle, nur für Testbetrieb!
// Ansteuerung der Waage
#define SCALE_READS 2 // Parameter für hx711 Library. Messwert wird aus der Anzahl gemittelt
#define SCALE_GETUNITS(n) (waage_vorhanden ? round(scale.get_units(n)) : simulate_scale(n) )
// Ansteuerung Servo
#ifdef QUETSCHHAHN_LINKS
#define SERVO_WRITE(n) servo.write(180-n)
#else
#define SERVO_WRITE(n) servo.write(n)
#endif
// Rotary Encoder Taster zieht Pegel auf Low, Start/Stop auf High!
#ifdef USE_ROTARY_SW
#define SELECT_SW outputSW
#define SELECT_PEGEL LOW
#else
#define SELECT_SW button_start_pin
#define SELECT_PEGEL HIGH
#endif
// Betriebsmodi
#define MODE_SETUP 0
#define MODE_AUTOMATIK 1
#define MODE_HANDBETRIEB 2
// Buzzer Sounds
#define BUZZER_SHORT 1
#define BUZZER_LONG 2
#define BUZZER_SUCCESS 3
#define BUZZER_ERROR 4
// ** Definition der pins
// ---------------------- fuer Heltec WiFi Kit 32 (ESP32 onboard OLED)-----------------------------
#if (HARDWARE_LEVEL == 1 || HARDWARE_LEVEL == 2)
// OLED fuer Heltec WiFi Kit 32 (ESP32 onboard OLED)
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16);
// Rotary Encoder
const int outputA = 33;
const int outputB = 26;
const int outputSW = 32;
// Servo
const int servo_pin = 2;
// 3x Schalter Ein 1 - Aus - Ein 2
#if HARDWARE_LEVEL == 1
const int switch_betrieb_pin = 19;
const int switch_vcc_pin = 22; // <- Vcc
const int switch_setup_pin = 21;
#else // HARDWARE_LEVEL == 2
const int switch_betrieb_pin = 23;
const int switch_vcc_pin = 19; // <- Vcc
const int switch_setup_pin = 22;
const int vext_ctrl_pin = 21; // Vext control pin
#endif
// Taster
const int button_start_vcc_pin = 13; // <- Vcc
const int button_start_pin = 12;
const int button_stop_vcc_pin = 14; // <- Vcc
const int button_stop_pin = 27;
// Poti
const int poti_pin = 27;
// Wägezelle-IC
const int hx711_sck_pin = 17;
const int hx711_dt_pin = 5;
// Buzzer - aktiver Piezo
static int buzzer_pin = 25;
// ---------------------- ESP32 Module DevKit V2 ------------------------------------------------
#elif (HARDWARE_LEVEL == 3 )
// OLED fuer ESP32 outboard OLED
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 22, /* data=*/ 21, /* reset=*/ 16);
// Rotary Encoder
const int outputA = 33;
const int outputB = 26;
const int outputSW = 32;
// Servo
const int servo_pin = 0;
// 3x Schalter Ein 1 - Aus - Ein 2
const int switch_betrieb_pin = 15;
const int switch_vcc_pin = 9; // <- Vcc
const int switch_setup_pin = 4;
// Taster
const int button_start_vcc_pin = 13; // <- Vcc
const int button_start_pin = 12;
const int button_stop_vcc_pin = 14; // <- Vcc
const int button_stop_pin = 27;
// Poti
const int poti_pin = 7;
// Wägezelle-IC
const int hx711_sck_pin = 17;
const int hx711_dt_pin = 5;
// Buzzer - aktiver Piezo
static int buzzer_pin = 25;
int LED_pin = 2;
#else
#error Hardware Level nicht definiert! Korrektes #define setzen!
#endif
Servo servo;
HX711 scale;
Preferences preferences;
// Datenstrukturen für Rotary Encoder
struct rotary {
int Value;
int Minimum;
int Maximum;
int Step;
};
#define SW_WINKEL 0
#define SW_KORREKTUR 1
#define SW_MENU 2
struct rotary rotaries[3]; // Werden in setup() initialisiert
int rotary_select = SW_WINKEL;
static boolean rotating = false; // debounce management für Rotary Encoder
// Füllmengen für 5 verschiedene Gläser
struct glas {
int Gewicht;
int GlasTyp; //JB
int Tara;
int TripCount; //Kud
int Count; //Kud
};
char *GlasTypArray[3] = { "DIB", "TOF", "DEE"};//DIB = DeutscherImkerBund-Glas DEE= DeepTwist-Glas TOF= TwistOff-Glas //JB
struct glas glaeser[5] = {
{ 125, 0, -9999, 0, 0 },
{ 250, 1, -9999, 0, 0 },
{ 250, 2, -9999, 0, 0 },
{ 500, 1, -9999, 0, 0 },
{ 500, 0, -9999, 0, 0 }
};
// Allgemeine Variablen
int i; // allgemeine Zählvariable
int pos; // aktuelle Position des Poti bzw. Rotary
int gewicht; // aktuelles Gewicht
int tara; // Tara für das ausgewählte Glas, für Automatikmodus
int tara_glas; // Tara für das aktuelle Glas, falls Glasgewicht abweicht
long gewicht_leer; // Gewicht der leeren Waage
float faktor; // Skalierungsfaktor für Werte der Waage
int fmenge; // ausgewählte Füllmenge
int fmenge_index; // Index in gläser[]
int korrektur; // Korrekturwert für Abfüllmenge
int autostart; // Vollautomatik ein/aus
int autokorrektur; // Autokorrektur ein/aus
int kulanz_gr; // gewollte Überfüllung im Autokorrekturmodus in Gramm
int winkel; // aktueller Servo-Winkel
int winkel_hard_min = 0; // Hard-Limit für Servo
int winkel_hard_max = 180; // Hard-Limit für Servo
int winkel_min = 0; // konfigurierbar im Setup
int winkel_max = 85; // konfigurierbar im Setup
int winkel_fein = 35; // konfigurierbar im Setup
float fein_dosier_gewicht = 60; // float wegen Berechnung des Schliesswinkels
int servo_aktiv = 0; // Servo aktivieren ja/nein
int kali_gewicht = 500; // frei wählbares Gewicht zum kalibrieren
char ausgabe[30]; // Fontsize 12 = 13 Zeichen maximal in einer Zeile
int modus = -1; // Bei Modus-Wechsel den Servo auf Minimum fahren
int auto_aktiv = 0; // Für Automatikmodus - System ein/aus?
int waage_vorhanden = 0; // HX711 nicht ansprechen, wenn keine Waage angeschlossen ist, sonst Crash
long preferences_chksum; // Checksumme, damit wir nicht sinnlos Prefs schreiben
int buzzermode = 0; // 0 = aus, 1 = ein. TODO: Tastentöne als buzzermode 2?
bool gezaehlt = false; // Kud Zähl-Flag
bool setup_modern = 1; // Setup als rotierendes Menu
int glastoleranz = 20; // Gewicht für autostart darf um +-20g schwanken, insgesamt also 40g!
// Simuliert die Dauer des Wägeprozess, wenn keine Waage angeschlossen ist. Wirkt sich auf die Blinkfrequenz im Automatikmodus aus.
long simulate_scale(int n) {
long sim_gewicht = 9500;
while (n-- >= 1) {
delay(10); // empirisch ermittelt. n=2: 10, n=3: 40, n=4: 50
}
#ifdef POTISCALE
sim_gewicht = (map(analogRead(poti_pin), 0, 4095, 0, 700));
#endif
return sim_gewicht;
}
#ifdef USE_ROTARY_SW
// Rotary Taster. Der Interrupt kommt nur im Automatikmodus zum Tragen und nur wenn der Servo inaktiv ist.
// Der Taster schaltet in einen von drei Modi, in denen unterschiedliche Werte gezählt werden.
void IRAM_ATTR isr1() {
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 300) { // If interrupts come faster than 300ms, assume it's a bounce and ignore
if ( modus == MODE_AUTOMATIK && servo_aktiv == 0 ) { // nur im Automatik-Modus interessiert uns der Click
rotary_select = (rotary_select + 1) % 3;
#ifdef isDebug
Serial.print("Rotary Button changed to ");
Serial.println(rotary_select);
#endif
}
last_interrupt_time = interrupt_time;
}
}
#endif
#ifdef USE_ROTARY
// Rotary Encoder. Zählt in eine von drei Datenstrukturen:
// SW_WINKEL = Einstellung des Servo-Winkels
// SW_KORREKTUR = Korrekturfaktor für Füllgewicht
// SW_MENU = Zähler für Menuauswahlen
void IRAM_ATTR isr2() {
static int aState;
static int aLastState = 2; // reale Werte sind 0 und 1
if ( rotating ) delay (1); // wait a little until the bouncing is done
aState = digitalRead(outputA); // Reads the "current" state of the outputA
if (aState != aLastState) {
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
if (digitalRead(outputB) != aState) {
rotaries[rotary_select].Value -= rotaries[rotary_select].Step;
} else { // counter-clockwise
rotaries[rotary_select].Value += rotaries[rotary_select].Step;
}
rotaries[rotary_select].Value = constrain( rotaries[rotary_select].Value, rotaries[rotary_select].Minimum, rotaries[rotary_select].Maximum );
rotating = false;
#ifdef isDebug
#if isDebug >= 5
Serial.print(" Rotary Value changed to ");
Serial.println(getRotariesValue(rotary_select));
#endif
#endif
}
aLastState = aState; // Updates the previous state of the outputA with the current state
}
#endif
//
// Skalierung des Rotaries für verschiedene Rotary Encoder oder Simulation über Poti
int getRotariesValue( int rotary_mode ) {
#ifdef USE_ROTARY
return (rotaries[rotary_mode].Value / ROTARY_SCALE);
#elif defined USE_POTI
int poti_min = (rotaries[rotary_mode].Minimum / ROTARY_SCALE);
int poti_max = (rotaries[rotary_mode].Maximum / ROTARY_SCALE);
if( rotaries[rotary_mode].Step > 0 ) {
return (map(analogRead(poti_pin), 0, 4095, poti_min, poti_max));
} else {
return (map(analogRead(poti_pin), 0, 4095, poti_max, poti_min));
}
#else
#error Weder Rotary noch Poti aktiviert!
#endif
}
void setRotariesValue( int rotary_mode, int rotary_value ) {
rotaries[rotary_mode].Value = rotary_value * ROTARY_SCALE;
}
void initRotaries( int rotary_mode, int rotary_value, int rotary_min, int rotary_max, int rotary_step ) {
rotaries[rotary_mode].Value = rotary_value * ROTARY_SCALE;
rotaries[rotary_mode].Minimum = rotary_min * ROTARY_SCALE;
rotaries[rotary_mode].Maximum = rotary_max * ROTARY_SCALE;
rotaries[rotary_mode].Step = rotary_step;
#ifdef isDebug
Serial.print("initRotaries...");
Serial.print(" Rotary Mode: "); Serial.print(rotary_mode);
Serial.print(" rotary_value: "); Serial.print(rotary_value);
Serial.print(" Value: "); Serial.print(rotaries[rotary_mode].Value);
Serial.print(" Min: "); Serial.print(rotaries[rotary_mode].Minimum);
Serial.print(" Max: "); Serial.print(rotaries[rotary_mode].Maximum);
Serial.print(" Step: "); Serial.print(rotaries[rotary_mode].Step);
Serial.print(" Scale: "); Serial.println(ROTARY_SCALE);
#endif
}
// Ende Funktionen für den Rotary Encoder
//
void getPreferences(void) {
preferences.begin("EEPROM", false); // Parameter aus dem EEPROM lesen
faktor = preferences.getFloat("faktor", 0.0); // falls das nicht gesetzt ist -> Waage ist nicht kalibriert
pos = preferences.getUInt("pos", 0);
gewicht_leer = preferences.getUInt("gewicht_leer", 0);
korrektur = preferences.getUInt("korrektur", 0);
autostart = preferences.getUInt("autostart", 0);
autokorrektur = preferences.getUInt("autokorrektur", 0);
kulanz_gr = preferences.getUInt("kulanz_gr", 5);
fmenge_index = preferences.getUInt("fmenge_index", 3);
winkel_min = preferences.getUInt("winkel_min", winkel_min);
winkel_max = preferences.getUInt("winkel_max", winkel_max);
winkel_fein = preferences.getUInt("winkel_fein", winkel_fein);
buzzermode = preferences.getUInt("buzzermode", buzzermode);
kali_gewicht = preferences.getUInt("kali_gewicht", kali_gewicht); //JB
setup_modern = preferences.getUInt("setup_modern", setup_modern);
preferences_chksum = faktor + pos + gewicht_leer + korrektur + autostart + autokorrektur + fmenge_index + winkel_min + winkel_max + winkel_fein + kulanz_gr + buzzermode + kali_gewicht + setup_modern;
i = 0;
int ResetGewichte[] = {125,250,250,500,500,};
int ResetGlasTyp[] = {0,1,2,1,0,};
while( i < 5) {
sprintf(ausgabe, "Gewicht%d", i); //JB
glaeser[i].Gewicht = preferences.getInt(ausgabe, ResetGewichte[i]); //JB
preferences_chksum += glaeser[i].Gewicht; //JB
sprintf(ausgabe, "GlasTyp%d", i); //JB
glaeser[i].GlasTyp = preferences.getInt(ausgabe, ResetGlasTyp[i]); //JB
preferences_chksum += glaeser[i].GlasTyp; //JB
sprintf(ausgabe, "Tara%d", i);
glaeser[i].Tara= preferences.getInt(ausgabe, -9999);
preferences_chksum += glaeser[i].Tara;
sprintf(ausgabe, "TripCount%d", i); //Kud
glaeser[i].TripCount = preferences.getInt(ausgabe, 0);//Kud
preferences_chksum += glaeser[i].TripCount;
sprintf(ausgabe, "Count%d", i); //Kud
glaeser[i].Count = preferences.getInt(ausgabe, 0);//Kud
preferences_chksum += glaeser[i].Count;
i++;
}
preferences.end();
#ifdef isDebug
Serial.println("get Preferences:");
Serial.print("pos = "); Serial.println(pos);
Serial.print("faktor = "); Serial.println(faktor);
Serial.print("gewicht_leer = "); Serial.println(gewicht_leer);
Serial.print("korrektur = "); Serial.println(korrektur);
Serial.print("autostart = "); Serial.println(autostart);
Serial.print("autokorrektur = ");Serial.println(autokorrektur);
Serial.print("kulanz_gr = "); Serial.println(kulanz_gr);
Serial.print("fmenge_index = "); Serial.println(fmenge_index);
Serial.print("winkel_min = "); Serial.println(winkel_min);
Serial.print("winkel_max = "); Serial.println(winkel_max);
Serial.print("winkel_fein = "); Serial.println(winkel_fein);
Serial.print("buzzermode = "); Serial.println(buzzermode);
Serial.print("kali_gewicht = "); Serial.println(kali_gewicht);//JB
Serial.print("setup_modern = "); Serial.println(setup_modern);
i = 0;
while( i < 5 ) {
sprintf(ausgabe, "Gewicht%d = ", i);
Serial.print(ausgabe);
Serial.println(glaeser[i].Gewicht);
sprintf(ausgabe, "GlasTyp%d = ", i);
Serial.print(ausgabe);
Serial.println(GlasTypArray[glaeser[i].GlasTyp]);
sprintf(ausgabe, "Tara%d = ", i);
Serial.print(ausgabe);
Serial.println(glaeser[i].Tara);
i++;
}
Serial.print("Checksumme:");
Serial.println(preferences_chksum);
#endif
}
void setPreferences(void) {
long preferences_newchksum;
int winkel = getRotariesValue(SW_WINKEL);
preferences_newchksum = faktor + winkel + gewicht_leer + korrektur + autostart + autokorrektur + fmenge_index + winkel_min + winkel_max + winkel_fein + kulanz_gr + buzzermode + kali_gewicht + setup_modern;
i = 0;
while( i < 5 ) {
preferences_newchksum += glaeser[i].Gewicht;//JB
preferences_newchksum += glaeser[i].GlasTyp;//JB
preferences_newchksum += glaeser[i].Tara;
preferences_newchksum += glaeser[i].TripCount;//Kud
preferences_newchksum += glaeser[i].Count;//Kud
i++;
}
if( preferences_newchksum == preferences_chksum ) {
#ifdef isDebug
Serial.println("Preferences unverändert");
#endif
getPreferences();
return;
}
preferences_chksum = preferences_newchksum;
preferences.begin("EEPROM", false);
preferences.putFloat("faktor", faktor);
preferences.putUInt("gewicht_leer", gewicht_leer);
preferences.putUInt("pos", winkel);
preferences.putUInt("korrektur", korrektur);
preferences.putUInt("autostart", autostart);
preferences.putUInt("autokorrektur", autokorrektur);
preferences.putUInt("kulanz_gr", kulanz_gr);
preferences.putUInt("winkel_min", winkel_min);
preferences.putUInt("winkel_max", winkel_max);
preferences.putUInt("winkel_fein", winkel_fein);
preferences.putUInt("fmenge_index", fmenge_index);
preferences.putUInt("buzzermode", buzzermode);
preferences.putUInt("kali_gewicht", kali_gewicht);//JB
preferences.putUInt("setup_modern", setup_modern);
i = 0;
while( i < 5 ) {
sprintf(ausgabe, "Gewicht%d", i);
preferences.putInt(ausgabe, glaeser[i].Gewicht);
sprintf(ausgabe, "GlasTyp%d", i);
preferences.putInt(ausgabe, glaeser[i].GlasTyp);
sprintf(ausgabe, "Tara%d", i);
preferences.putInt(ausgabe, glaeser[i].Tara);
sprintf(ausgabe, "TripCount%d", i);
preferences.putInt(ausgabe, glaeser[i].TripCount);//Kud
sprintf(ausgabe, "Count%d", i);
preferences.putInt(ausgabe, glaeser[i].Count);//Kud
i++;
}
preferences.end();
#ifdef isDebug
Serial.println("Set Preferences:");
Serial.print("pos = "); Serial.println(winkel);
Serial.print("faktor = "); Serial.println(faktor);
Serial.print("gewicht_leer = "); Serial.println(gewicht_leer);
Serial.print("korrektur = "); Serial.println(korrektur);
Serial.print("autostart = "); Serial.println(autostart);
Serial.print("autokorrektur = ");Serial.println(autokorrektur);
Serial.print("kulanz_gr = "); Serial.println(kulanz_gr);
Serial.print("fmenge_index = "); Serial.println(fmenge_index);
Serial.print("winkel_min = "); Serial.println(winkel_min);
Serial.print("winkel_max = "); Serial.println(winkel_max);
Serial.print("winkel_fein = "); Serial.println(winkel_fein);
Serial.print("buzzermode = "); Serial.println(buzzermode);
Serial.print("kali_gewicht = "); Serial.println(kali_gewicht); //JB
Serial.print("setup_modern = "); Serial.println(setup_modern);
i = 0;
while( i < 5 ) {
sprintf(ausgabe, "Gewicht%d = ", i);
Serial.print(ausgabe); Serial.println(glaeser[i].Gewicht);
sprintf(ausgabe, "GlasTyp%d = ", i);
Serial.print(ausgabe); Serial.println(GlasTypArray[glaeser[i].GlasTyp]);
sprintf(ausgabe, "Tara%d = ", i);
Serial.print(ausgabe); Serial.println(glaeser[i].Tara);
i++;
}
#endif
}
void setupTripCounter(void) { //Kud
int j;
i = 1;
float TripAbfuellgewicht = 0;
while (i > 0) { //Erster Screen: Anzahl pro Glasgröße
j = 0;
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
//verlasse Screen
i = 0;
delay(250);
}
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
while ( j < 5 ) {
u8g2.setCursor(1, 10 + (j * 13));
sprintf(ausgabe, "%4dg%3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);
u8g2.print(ausgabe);
u8g2.setCursor(50, 10 + (j * 13));
sprintf(ausgabe, "%5d St.", glaeser[j].TripCount);
u8g2.print(ausgabe);
j++;
}
u8g2.sendBuffer();
delay(100);
}
i = 1;
while (i > 0) { //Zweiter Screen: Gewicht pro Glasgröße
j = 0;
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
//verlasse Screen
i = 0;
delay(250);
}
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
while ( j < 5 ) {
u8g2.setCursor(1, 10 + (j * 13));
sprintf(ausgabe, "%4dg%3s", glaeser[j].Gewicht,GlasTypArray[glaeser[j].GlasTyp]);
u8g2.print(ausgabe);
u8g2.setCursor(65, 10 + (j * 13));
// Serial.println(glaeser[j].Gewicht);
// Serial.print("\t");
// Serial.print(glaeser[j].TripCount);
// Serial.print("\t");
// Serial.print(glaeser[j].Gewicht * glaeser[j].TripCount / 1000.0);
// Serial.println();
sprintf(ausgabe, "%5.1fkg", glaeser[j].Gewicht * glaeser[j].TripCount / 1000.0);
u8g2.print(ausgabe);
j++;
}
u8g2.sendBuffer();
delay(100);
}
i = 1;
while (i > 0) { //Dritter Screen: Gesamtgewicht
TripAbfuellgewicht = 0;
j = 0;
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
//verlasse Screen
i = 0;
delay(250);
}
while ( j < 5) {
TripAbfuellgewicht += glaeser[j].Gewicht * glaeser[j].TripCount / 1000.0;
j++;
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB14_tf);
u8g2.setCursor(5, 15);
u8g2.print("Summe Trip:");
u8g2.setFont(u8g2_font_courB18_tf);
u8g2.setCursor(10, 50);
sprintf(ausgabe, "%5.1fkg", TripAbfuellgewicht);
u8g2.print(ausgabe);
u8g2.sendBuffer();
delay(100);
}
i = 1;
while (i > 0) { //Vierter Screen: Zurücksetzen
initRotaries(SW_MENU, 1, 0, 1, -1);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
pos = getRotariesValue(SW_MENU);
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
u8g2.setCursor(10, 12); u8g2.print("Reset");
u8g2.setCursor(10, 28); u8g2.print("Abbrechen");
u8g2.setCursor(0, 12 + ((pos) * 16));
u8g2.print("*");
u8g2.sendBuffer();
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
u8g2.setCursor(105, 12 + ((pos) * 16));
u8g2.print("OK");
u8g2.sendBuffer();
if ( pos == 0) {
j = 0;
while ( j < 5 ) {
glaeser[j].TripCount = 0;
j++;
}
setPreferences();
}
delay(1000);
i = 0;
}
}
}
}
void setupCounter(void) { //Kud
int j;
i = 1;
float Abfuellgewicht = 0;
while (i > 0) { //Erster Screen: Anzahl pro Glasgröße
j = 0;
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
//verlasse Screen
i = 0;
delay(250);
}
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
while ( j < 5 ) {
u8g2.setCursor(1, 10 + (j * 13));
sprintf(ausgabe, "%4dg%3s", glaeser[j].Gewicht,GlasTypArray[glaeser[j].GlasTyp]);
u8g2.print(ausgabe);
u8g2.setCursor(50, 10 + (j * 13));
sprintf(ausgabe, "%5d St.", glaeser[j].Count);
u8g2.print(ausgabe);
j++;
}
u8g2.sendBuffer();
delay(100);
}
i = 1;
while (i > 0) { //Zweiter Screen: Gewicht pro Glasgröße
j = 0;
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
//verlasse Screen
i = 0;
delay(250);
}
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
while ( j < 5) {
u8g2.setCursor(1, 10 + (j * 13));
sprintf(ausgabe, "%4dg%3s", glaeser[j].Gewicht,GlasTypArray[glaeser[j].GlasTyp]);
u8g2.print(ausgabe);
u8g2.setCursor(65, 10 + (j * 13));
// Serial.println(glaeser[j].Gewicht);
// Serial.print("\t");
// Serial.print(glaeser[j].Count);
// Serial.print("\t");
// Serial.print(glaeser[j].Gewicht * glaeser[j].Count / 1000.0);
// Serial.println();
sprintf(ausgabe, "%5.1fkg", glaeser[j].Gewicht * glaeser[j].Count / 1000.0);
u8g2.print(ausgabe);
j++;
}
u8g2.sendBuffer();
delay(100);
}
i = 1;
while (i > 0) { //Dritter Screen: Gesamtgewicht
Abfuellgewicht = 0;
j = 0;
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
//verlasse Screen
i = 0;
delay(250);
}
while ( j < 5 ) {
Abfuellgewicht += glaeser[j].Gewicht * glaeser[j].Count / 1000.0;
j++;
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB14_tf);
u8g2.setCursor(1, 15);
u8g2.print("Summe:");
u8g2.setFont(u8g2_font_courB18_tf);
u8g2.setCursor(10, 50);
sprintf(ausgabe, "%5.1fkg", Abfuellgewicht);
u8g2.print(ausgabe);
u8g2.sendBuffer();
delay(100);
}
i = 1;
while (i > 0) { //Vierter Screen: Zurücksetzen
initRotaries(SW_MENU, 1, 0, 1, -1);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
pos = getRotariesValue(SW_MENU);
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
u8g2.setCursor(10, 12); u8g2.print("Reset");
u8g2.setCursor(10, 28); u8g2.print("Abbrechen");
u8g2.setCursor(0, 12 + ((pos) * 16));
u8g2.print("*");
u8g2.sendBuffer();
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
u8g2.setCursor(105, 12 + ((pos) * 16));
u8g2.print("OK");
u8g2.sendBuffer();
if ( pos == 0) {
j = 0;
while ( j < 5 ) {
glaeser[j].Count = 0;
glaeser[j].TripCount = 0;
j++;
}
setPreferences();
}
delay(1000);
i = 0;
}
}
}
}
void setupTara(void) {
int j;
tara = 0;
initRotaries( SW_MENU, fmenge_index, 0, 4, -1 ); // Set Encoder to Menu Mode, four Selections, inverted count
i = 0;
while ( i == 0 ) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ( digitalRead(SELECT_SW) == SELECT_PEGEL ) {
tara = (int(SCALE_GETUNITS(10)));
if ( tara > 20 ) { // Gläser müssen mindestens 20g haben
glaeser[getRotariesValue(SW_MENU)].Tara = tara;
}
i++;
}
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
j = 0;
while( j < 5 ) {
u8g2.setCursor(3, 10+(j*13));
if ( glaeser[j].Gewicht < 1000 ) {
sprintf(ausgabe, " %3d-%3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);
} else {
sprintf(ausgabe, " %3s-%3s", "1kg", GlasTypArray[glaeser[j].GlasTyp]);
}
u8g2.print(ausgabe);
u8g2.setCursor(75, 10+(j*13));
if ( glaeser[j].Tara > 0 ) {
sprintf(ausgabe, " %4dg", glaeser[j].Tara);
u8g2.print(ausgabe);
} else {
u8g2.print(" fehlt");
}
j++;
}
u8g2.setCursor(0, 10+(getRotariesValue(SW_MENU)*13) );
u8g2.print("*");
u8g2.sendBuffer();
}
delay(2000);
}
void setupCalibration(void) {
float gewicht_raw;
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB12_tf);
u8g2.setCursor(0, 12); u8g2.print("Bitte Waage");
u8g2.setCursor(0, 28); u8g2.print("leeren");
u8g2.setCursor(0, 44); u8g2.print("und mit OK");
u8g2.setCursor(0, 60); u8g2.print("bestätigen");
u8g2.sendBuffer();
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
scale.set_scale();
scale.tare(10);
delay(500);
i = 0;
}
}
u8g2.setFont(u8g2_font_courB12_tf);
initRotaries( SW_MENU, kali_gewicht, 100, 9999, 1 );
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
kali_gewicht = getRotariesValue(SW_MENU);
int blinktime = (millis()/10) % 5;
u8g2.clearBuffer();
u8g2.setCursor(0, 12);u8g2.print("Bitte ");
if (blinktime < 3) {
sprintf(ausgabe, "%dg", kali_gewicht);
} else {
sprintf(ausgabe, " ");
}
u8g2.print(ausgabe);
u8g2.setCursor(0, 28); u8g2.print("aufstellen");
u8g2.setCursor(0, 44); u8g2.print("und mit OK");
u8g2.setCursor(0, 60); u8g2.print("bestätigen");
u8g2.sendBuffer();
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
u8g2.clearBuffer();
u8g2.setCursor(0, 12);u8g2.print("Bitte ");
sprintf(ausgabe, "%dg", kali_gewicht);
u8g2.print(ausgabe);
u8g2.setCursor(0, 28); u8g2.print("aufstellen");
u8g2.setCursor(0, 44); u8g2.print("und mit OK");
u8g2.setCursor(0, 60); u8g2.print("bestätigen");
u8g2.sendBuffer();
gewicht_raw = scale.get_units(10);
faktor = gewicht_raw / kali_gewicht;
scale.set_scale(faktor);
gewicht_leer = scale.get_offset(); // Leergewicht der Waage speichern
#ifdef isDebug
Serial.print("kalibrier_gewicht = ");
Serial.println(kali_gewicht);
Serial.print("gewicht_leer = ");
Serial.println(gewicht_leer);
Serial.print("gewicht_raw = ");
Serial.println(gewicht_raw);
Serial.print(" Faktor = ");
Serial.println(faktor);
#endif
delay(1000);
i = 0;
}
}
}
void setupKorrektur(void) {
int korrektur_alt = korrektur;
rotary_select = SW_KORREKTUR;
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH) {
setRotariesValue(SW_KORREKTUR, korrektur_alt);
korrektur = korrektur_alt;
rotary_select = SW_MENU;
return;
}
korrektur = getRotariesValue(SW_KORREKTUR);
u8g2.setFont(u8g2_font_courB12_tf);
u8g2.clearBuffer();
u8g2.setCursor(10, 12);
u8g2.print("Korrektur");
u8g2.setCursor(40, 28);
u8g2.print(korrektur);
u8g2.setCursor(10, 48); // A.P.
u8g2.print("alter Wert"); // A.P.
u8g2.setCursor(40, 64); // A.P.
u8g2.print(korrektur_alt); // A.P.
u8g2.sendBuffer();
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
u8g2.setCursor(100, 28);
u8g2.print("OK");
u8g2.sendBuffer();
delay(1000);
i = 0;
}
}
rotary_select = SW_MENU;
}
void setupServoWinkel(void) {
int menuitem;
int lastmin = winkel_min;
int lastfein = winkel_fein;
int lastmax = winkel_max;
int wert_alt;
bool wert_aendern = false;
bool servo_live = false;
initRotaries(SW_MENU, 0, 0, 4, -1);
u8g2.setFont(u8g2_font_courB10_tf);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH) {
winkel_min = lastmin;
winkel_fein = lastfein;
winkel_max = lastmax;
if ( servo_live == true ) SERVO_WRITE(winkel_min);
return;
}
if ( wert_aendern == false ) {
menuitem = getRotariesValue(SW_MENU);
} else {
switch (menuitem) {
case 0: servo_live = getRotariesValue(SW_MENU);
break;
case 1: winkel_min = getRotariesValue(SW_MENU);
if ( servo_live == true ) SERVO_WRITE(winkel_min);
break;
case 2: winkel_fein = getRotariesValue(SW_MENU);
if ( servo_live == true ) SERVO_WRITE(winkel_fein);
break;
case 3: winkel_max = getRotariesValue(SW_MENU);
if ( servo_live == true ) SERVO_WRITE(winkel_max);
break;
}
}
u8g2.clearBuffer();
u8g2.setCursor(10, 23); sprintf(ausgabe,"Minimum %3d", winkel_min); u8g2.print(ausgabe);
u8g2.setCursor(10, 36); sprintf(ausgabe,"Feindos. %3d", winkel_fein); u8g2.print(ausgabe);
u8g2.setCursor(10, 49); sprintf(ausgabe,"Maximum %3d", winkel_max); u8g2.print(ausgabe);
u8g2.setCursor(10, 62); u8g2.print( "Speichern");
if ( wert_aendern == false ) {
u8g2.setCursor(10, 10); sprintf(ausgabe,"Livesetup %3s", (servo_live==false?"aus":"ein")); u8g2.print(ausgabe);
u8g2.setCursor( 0, 10+(menuitem*13)); u8g2.print("*");
} else {
if ( menuitem != 0 ) {
u8g2.setCursor(10, 10); sprintf(ausgabe," vorher: %3d", wert_alt); u8g2.print(ausgabe);
} else {
u8g2.setCursor(10, 10); sprintf(ausgabe,"Livesetup %3s", (servo_live==false?"aus":"ein")); u8g2.print(ausgabe);
}
u8g2.setFont(u8g2_font_open_iconic_arrow_1x_t);
u8g2.drawGlyph(0, 10+(menuitem*13), 0x42);
u8g2.setFont(u8g2_font_courB10_tf);
}
u8g2.sendBuffer();
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL)
&& (menuitem < 4 )
&& (wert_aendern == false) ) {
// debounce
delay(10);
while( digitalRead(SELECT_SW) == SELECT_PEGEL )
;
delay(10);
switch (menuitem) {
case 0: initRotaries(SW_MENU, servo_live, 0, 1, 1);
break;
case 1: initRotaries(SW_MENU, winkel_min, winkel_hard_min, winkel_fein, 1);
wert_alt = lastmin;
break;
case 2: initRotaries(SW_MENU, winkel_fein, winkel_min, winkel_max, 1);
wert_alt = lastfein;
break;
case 3: initRotaries(SW_MENU, winkel_max, winkel_fein, winkel_hard_max, 1);
wert_alt = lastmax;
break;
}
wert_aendern = true;
}
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL)
&& (menuitem < 4 )
&& (wert_aendern == true) ) {
// debounce
delay(10);
while( digitalRead(SELECT_SW) == SELECT_PEGEL )
;
delay(10);
if ( servo_live == true )
SERVO_WRITE(winkel_min);
initRotaries(SW_MENU, menuitem, 0, 4, -1);
wert_aendern = false;
}
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL) && (menuitem == 4) ) {
u8g2.setCursor(108, 10+(menuitem*13));
u8g2.print("OK");
u8g2.sendBuffer();
delay(1000);
i = 0;
}
}
}
void setupAutomatik(void) {
int menuitem;
int lastautostart = autostart;
int lastautokorrektur = autokorrektur;
int lastkulanz = kulanz_gr;
bool wert_aendern = false;
initRotaries(SW_MENU, 0, 0, 3, -1);
u8g2.setFont(u8g2_font_courB10_tf);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH) {
autostart = lastautostart;
autokorrektur = lastautokorrektur;
kulanz_gr = lastkulanz;
return;
}
if ( wert_aendern == false ) {
menuitem = getRotariesValue(SW_MENU);
if ( menuitem == 3 )
menuitem = 4; // Eine Zeile Abstand zu "Speichern"
} else {
switch (menuitem) {
case 0: autostart = getRotariesValue(SW_MENU);
break;
case 1: autokorrektur = getRotariesValue(SW_MENU);
break;
case 2: kulanz_gr = getRotariesValue(SW_MENU);
break;
}
}
// Menu
u8g2.clearBuffer();
u8g2.setCursor(10, 10); sprintf(ausgabe,"Autostart %3s", (autostart==0?"aus":"ein")); u8g2.print(ausgabe);
u8g2.setCursor(10, 23); sprintf(ausgabe,"Autokorr. %3s", (autokorrektur==0?"aus":"ein")); u8g2.print(ausgabe);
u8g2.setCursor(10, 36); sprintf(ausgabe,"-> Kulanz %2dg", kulanz_gr); u8g2.print(ausgabe);
u8g2.setCursor(10, 62); u8g2.print( "Speichern");
// Positionsanzeige im Menu. "*" wenn nicht ausgewählt, Pfeil wenn ausgewählt
if ( wert_aendern == false ) {
u8g2.setCursor(0, 10+(menuitem*13)); u8g2.print("*");
} else {
u8g2.setFont(u8g2_font_open_iconic_arrow_1x_t);
u8g2.drawGlyph(0, 10+(menuitem*13), 0x42);
u8g2.setFont(u8g2_font_courB10_tf);
}
u8g2.sendBuffer();
// Menupunkt zum Ändern ausgewählt
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL)
&& (menuitem < 3 )
&& (wert_aendern == false) ) {
// debounce
delay(10);
while( digitalRead(SELECT_SW) == SELECT_PEGEL )
;
delay(10);
switch (menuitem) {
case 0: initRotaries(SW_MENU, autostart, 0, 1, 1);
break;
case 1: initRotaries(SW_MENU, autokorrektur, 0, 1, 1);
break;
case 2: initRotaries(SW_MENU, kulanz_gr, 0, 99, 1);
break;
}
wert_aendern = true;
}
// Änderung im Menupunkt übernehmen
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL)
&& (menuitem < 3 )
&& (wert_aendern == true) ) {
// debounce
delay(10);
while( digitalRead(SELECT_SW) == SELECT_PEGEL )
;
delay(10);
initRotaries(SW_MENU, menuitem, 0, 3, -1);
wert_aendern = false;
}
// Menu verlassen
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL) && (menuitem == 4) ) {
u8g2.setCursor(108, 10+(menuitem*13));
u8g2.print("OK");
u8g2.sendBuffer();
delay(1000);
i = 0;
}
}
}
void setupFuellmenge(void) {
int j,k;
int blinktime;
initRotaries(SW_MENU, fmenge_index, 0, 4, -1);
u8g2.setFont(u8g2_font_courB10_tf);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
pos = getRotariesValue(SW_MENU);
u8g2.clearBuffer();
j = 0;
while( j < 5 ) {
u8g2.setCursor(10, 10+(j*13));
sprintf(ausgabe, "%4dg %3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);
u8g2.print(ausgabe);
j++;
}
u8g2.setCursor(0, 10+(getRotariesValue(SW_MENU)*13));
u8g2.print("*");
u8g2.sendBuffer();
if ( digitalRead(SELECT_SW) == SELECT_PEGEL ) { // Füllmenge gewählt
delay(500);
initRotaries(SW_MENU, glaeser[pos].Gewicht, 30, 1000, 5);
k = 1;
while (k > 0){
if ((digitalRead(button_stop_pin)) == HIGH) return;
blinktime = (millis()/10) % 5;
glaeser[pos].Gewicht = getRotariesValue(SW_MENU);
u8g2.clearBuffer();
j = 0;
while( j < 5 ) {
u8g2.setCursor(10, 10+(j*13));
if (j == pos){
if (blinktime < 3) { sprintf(ausgabe, "%4dg %3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]); }
else { sprintf(ausgabe, "%5s %3s"," ",GlasTypArray[glaeser[j].GlasTyp]);}
}
else {sprintf(ausgabe, "%4dg %3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);}
u8g2.print(ausgabe);
j++;
}
u8g2.sendBuffer();
if ( digitalRead(SELECT_SW) == SELECT_PEGEL ) { // Gewicht bestätigt
delay(500);
initRotaries(SW_MENU, glaeser[pos].GlasTyp, 0, 2, 1);
while (k > 0){
if ((digitalRead(button_stop_pin)) == HIGH) return;
blinktime = (millis()/10) % 5;
glaeser[pos].GlasTyp = getRotariesValue(SW_MENU);
u8g2.clearBuffer();
j = 0;
while( j < 5 ) {
u8g2.setCursor(10, 10+(j*13));
if (j == pos){
if (blinktime < 3) {sprintf(ausgabe, "%4dg %3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);}
else {sprintf(ausgabe, "%4dg %3s",glaeser[pos].Gewicht," ");}
}
else {sprintf(ausgabe, "%4dg %3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);}
u8g2.print(ausgabe);
j++;
}
u8g2.sendBuffer();
if ( digitalRead(SELECT_SW) == SELECT_PEGEL ) { //GlasTyp bestätigt
u8g2.clearBuffer();
j = 0;
while( j < 5 ) {
u8g2.setCursor(10, 10+(j*13));
sprintf(ausgabe, "%4dg %3s", glaeser[j].Gewicht, GlasTypArray[glaeser[j].GlasTyp]);
u8g2.print(ausgabe);
j++;
}
u8g2.setCursor(0, 10+(13*pos));
u8g2.print("*");
u8g2.sendBuffer();
delay(1000);
k = 0; //raus
}
}
}
}
fmenge = glaeser[pos].Gewicht;
tara = glaeser[pos].Tara;
fmenge_index = pos;
i = 0;
}
}
}
void setupParameter(void) {
int menuitem;
int lastbuzzer = buzzermode;
int lastsetup = setup_modern;
bool wert_aendern = false;
initRotaries(SW_MENU, 0, 0, 2, -1);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH) {
buzzermode = lastbuzzer;
setup_modern = lastsetup;
return;
}
if ( wert_aendern == false ) {
menuitem = getRotariesValue(SW_MENU);
if ( menuitem == 2 )
menuitem = 4; // Eine Zeile Abstand zu "Speichern"
} else {
switch (menuitem) {
case 0: buzzermode = getRotariesValue(SW_MENU);
break;
case 1: setup_modern = getRotariesValue(SW_MENU);
break;
}
}
// Menu
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
sprintf(ausgabe,"Buzzer %3s", (buzzermode==0?"aus":"ein"));
u8g2.setCursor(10, 10); u8g2.print(ausgabe);
sprintf(ausgabe,"Menu %6s", (setup_modern==0?" Liste":"Scroll"));
u8g2.setCursor(10, 23); u8g2.print(ausgabe);
u8g2.setCursor(10, 62); u8g2.print("Speichern");
// Positionsanzeige im Menu. "*" wenn nicht ausgewählt, Pfeil wenn ausgewählt
if ( wert_aendern == false ) {
u8g2.setCursor(0, 10+((menuitem)*13)); u8g2.print("*");
} else {
u8g2.setCursor(0, 10+((menuitem)*13)); u8g2.print("-");
}
u8g2.sendBuffer();
// Menupunkt zum Ändern ausgewählt
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL)
&& (menuitem < 2 )
&& (wert_aendern == false) ) {
// debounce
delay(10);
while( digitalRead(SELECT_SW) == SELECT_PEGEL )
;
delay(10);
switch (menuitem) {
case 0: initRotaries(SW_MENU, buzzermode, 0, 1, 1);
break;
case 1: initRotaries(SW_MENU, setup_modern, 0, 1, 1);
break;
}
wert_aendern = true;
}
// Änderung im Menupunkt übernehmen
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL)
&& (menuitem < 2 )
&& (wert_aendern == true) ) {
// debounce
delay(10);
while( digitalRead(SELECT_SW) == SELECT_PEGEL )
;
delay(10);
initRotaries(SW_MENU, menuitem, 0, 2, -1);
wert_aendern = false;
}
// Menu verlassen
if ( (digitalRead(SELECT_SW) == SELECT_PEGEL) && (menuitem == 4) ) {
u8g2.setCursor(108, 10+(menuitem*13));
u8g2.print("OK");
u8g2.sendBuffer();
delay(1000);
i = 0;
}
}
}
void setupClearPrefs(void) {
initRotaries(SW_MENU, 1, 0, 1, -1);
i = 1;
while (i > 0) {
if ((digitalRead(button_stop_pin)) == HIGH)
return;
pos = getRotariesValue(SW_MENU);
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
u8g2.setCursor(10, 12); u8g2.print("Löschen");
u8g2.setCursor(10, 28); u8g2.print("Zurück!");
u8g2.setCursor(0, 12+((pos)*16));
u8g2.print("*");
u8g2.sendBuffer();
if ((digitalRead(SELECT_SW)) == SELECT_PEGEL) {
u8g2.setCursor(105, 12+((pos)*16));
u8g2.print("OK");
u8g2.sendBuffer();
if ( pos == 0) {
preferences.begin("EEPROM", false);
preferences.clear();
preferences.end();
// gelöschte Werte einlesen, sonst bleiben die Variablen erhalten
getPreferences();
}
delay(1000);
i = 0;
}
}
}
void processSetup(void) {
if ( setup_modern == 0 )
processSetupList();
else
processSetupScroll();
}
void processSetupList(void) {
if ( modus != MODE_SETUP ) {
modus = MODE_SETUP;
winkel = winkel_min; // Hahn schliessen
servo_aktiv = 0; // Servo-Betrieb aus
SERVO_WRITE(winkel);
rotary_select = SW_MENU;
initRotaries(SW_MENU, 0, 0, 9, -1);
}
int menuitem = getRotariesValue(SW_MENU);
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.clearBuffer();
if( menuitem < 5 ) {
u8g2.setCursor(10, 10); u8g2.print("Tara");
u8g2.setCursor(10, 23); u8g2.print("Kalibrieren");
u8g2.setCursor(10, 36); u8g2.print("Korrektur");
u8g2.setCursor(10, 49); u8g2.print("Füllmenge");
u8g2.setCursor(10, 62); u8g2.print("Automatik");
u8g2.setFont(u8g2_font_open_iconic_arrow_2x_t);
u8g2.drawGlyph(112, 64, 0x40);
} else {
u8g2.setCursor(10, 10); u8g2.print("Servowinkel");
u8g2.setCursor(10, 23); u8g2.print("Parameter");
u8g2.setCursor(10, 36); u8g2.print("Zähler");//Kud
u8g2.setCursor(10, 49); u8g2.print("Zähler Trip");//Kud
u8g2.setCursor(10, 62); u8g2.print("Clear Prefs");
u8g2.setFont(u8g2_font_open_iconic_arrow_2x_t);
u8g2.drawGlyph(112, 16, 0x43);
}
u8g2.setFont(u8g2_font_courB10_tf);
u8g2.setCursor(0, 10 + (((menuitem)%5) * 13));
u8g2.print("*");
u8g2.sendBuffer();
if ( digitalRead(SELECT_SW) == SELECT_PEGEL ) {
// sollte verhindern, dass ein Tastendruck gleich einen Unterpunkt wählt
delay(250);
while( digitalRead(SELECT_SW) == SELECT_PEGEL ) {
}
#ifdef isDebug
Serial.print("Setup Position: ");
Serial.println(menuitem);
#endif
int lastpos = menuitem;
if (menuitem == 0) setupTara(); // Tara
if (menuitem == 1) setupCalibration(); // Kalibrieren
if (menuitem == 2) setupKorrektur(); // Korrektur
if (menuitem == 3) setupFuellmenge(); // Füllmenge
if (menuitem == 4) setupAutomatik(); // Autostart/Autokorrektur konfigurieren
if (menuitem == 5) setupServoWinkel(); // Servostellungen Minimum, Maximum und Feindosierung
if (menuitem == 6) setupParameter(); // Sonstige Einstellungen
if (menuitem == 7) setupCounter(); // Kud Zählwerk Trip
if (menuitem == 8) setupTripCounter(); // Kud Zählwerk
setPreferences();
if (menuitem == 9) setupClearPrefs(); // EEPROM löschen
initRotaries(SW_MENU, lastpos, 0, 9, -1); // Menu-Parameter könnten verstellt worden sein
}
}
void processSetupScroll(void) {
if ( modus != MODE_SETUP ) {
modus = MODE_SETUP;
winkel = winkel_min; // Hahn schliessen
servo_aktiv = 0; // Servo-Betrieb aus
SERVO_WRITE(winkel);
rotary_select = SW_MENU;
initRotaries(SW_MENU, 124, 0,255, -1);
}
int MenuepunkteAnzahl = 10;
char *menuepunkte[] = {
" Tarawerte","Kalibrieren"," Korrektur"," Füllmenge"," Automatik"," Servoeinst."," Parameter"," Zählwerk","ZählwerkTrip","Clear Prefs"
};
int menuitem = getRotariesValue(SW_MENU);
menuitem = menuitem % MenuepunkteAnzahl;
u8g2.clearBuffer();
//obere Zeile
int oberpos = menuitem-1;
if (menuitem == 0)
oberpos = (MenuepunkteAnzahl-1);
u8g2.setFont(u8g2_font_courB08_tf);
u8g2.setCursor(30,12);
u8g2.print(menuepunkte[oberpos]);
//untere Zeile
int unterpos = menuitem+1;
if (unterpos == MenuepunkteAnzahl)
unterpos=0;
u8g2.setCursor(30,62);
u8g2.print(menuepunkte[unterpos]);
//Mittelzeile
u8g2.drawLine(1, 20, 120, 20);
u8g2.setFont(u8g2_font_courB12_tf);
u8g2.setCursor(6, 38);
u8g2.print(menuepunkte[menuitem]);
u8g2.drawLine(1, 47, 120, 47);
u8g2.sendBuffer();
int lastpos = menuitem;
if ( digitalRead(SELECT_SW) == SELECT_PEGEL ) {
// sollte verhindern, dass ein Tastendruck gleich einen Unterpunkt wählt
delay(250);
while( digitalRead(SELECT_SW) == SELECT_PEGEL ) {}
#ifdef isDebug
Serial.print("Setup Position: ");
Serial.println(menuitem);
#endif
int lastpos = menuitem;
if (menuitem == 0) setupTara(); // Tara
if (menuitem == 1) setupCalibration(); // Kalibrieren
if (menuitem == 2) setupKorrektur(); // Korrektur
if (menuitem == 3) setupFuellmenge(); // Füllmenge
if (menuitem == 4) setupAutomatik(); // Autostart/Autokorrektur konfigurieren
if (menuitem == 5) setupServoWinkel(); // Servostellungen Minimum, Maximum und Feindosierung
if (menuitem == 6) setupParameter(); // Sonstige Einstellungen
if (menuitem == 7) setupCounter(); // Kud Zählwerk
if (menuitem == 8) setupTripCounter(); // Kud Zählwerk Trip
setPreferences();
if (menuitem == 9) setupClearPrefs(); // EEPROM löschen
initRotaries(SW_MENU,lastpos, 0,255, -1); // Menu-Parameter könnten verstellt worden sein
}
}
void processAutomatik(void)
{
int zielgewicht; // Glas + Korrektur
long blinktime;
static int autokorrektur_gr;
int erzwinge_servo_aktiv = 0;
boolean voll = false; //Kud
static int gewicht_vorher; // Gewicht des vorher gefüllten Glases
static long time_vorher; // Messung der Durchlaufzeit
static int sammler_num = 5; // Anzahl identischer Messungen für Nachtropfen
if ( modus != MODE_AUTOMATIK ) {
modus = MODE_AUTOMATIK;
winkel = winkel_min; // Hahn schliessen
servo_aktiv = 0; // Servo-Betrieb aus
SERVO_WRITE(winkel);
auto_aktiv = 0; // automatische Füllung starten
tara_glas = 0;
rotary_select = SW_WINKEL; // Einstellung für Winkel über Rotary
initRotaries(SW_MENU, fmenge_index, 0, 4, 1);
gewicht_vorher = glaeser[fmenge_index].Gewicht + korrektur;
autokorrektur_gr = 0;
}
pos = getRotariesValue(SW_WINKEL);
// nur bis winkel_fein regeln, oder über initRotaries lösen?
if ( pos < ((winkel_fein*100)/winkel_max) ) {
pos = ((winkel_fein*100)/winkel_max);
setRotariesValue(SW_WINKEL, pos);
}
#ifdef USE_ROTARY // TODO: kann das Poti hier überhaupt etwas ändern?
korrektur = getRotariesValue(SW_KORREKTUR);
fmenge_index = getRotariesValue(SW_MENU);
#endif
fmenge = glaeser[fmenge_index].Gewicht;
tara = glaeser[fmenge_index].Tara;
if ( tara <= 0 )
auto_aktiv = 0;
// wir starten nur, wenn das Tara für die Füllmenge gesetzt ist!
// Ein erneuter Druck auf Start erzwingt die Aktivierung des Servo
if (((digitalRead(button_start_pin)) == HIGH) && (tara > 0)) {
// debounce
delay(10);
while( digitalRead(button_start_pin) == HIGH )
;
delay(10);
if ( auto_aktiv == 1 ) {
erzwinge_servo_aktiv = 1;
#ifdef isDebug
Serial.println("erzwinge Servo aktiv");
#endif
}
auto_aktiv = 1; // automatisches Füllen aktivieren
rotary_select = SW_WINKEL; // falls während der Parameter-Änderung auf Start gedrückt wurde
setPreferences(); // falls Parameter über den Rotary verändert wurden
}
if ((digitalRead(button_stop_pin)) == HIGH) {
winkel = winkel_min;
servo_aktiv = 0;
auto_aktiv = 0;
tara_glas = 0;
autokorrektur_gr = 0;
}
// Fehlerkorrektur der Waage, falls Gewicht zu sehr schwankt
#ifdef FEHLERKORREKTUR_WAAGE
int Vergleichsgewicht = (int(SCALE_GETUNITS(SCALE_READS))) - tara;
for (byte j = 0 ; j < 3; j++) { // Anzahl der Wiederholungen, wenn Abweichung zu hoch
gewicht = (int(SCALE_GETUNITS(SCALE_READS))) - tara;
if (abs(gewicht - Vergleichsgewicht) < 50) // Abweichung für Fehlererkennung
break;
delay(100);
}
#else
gewicht = (int(SCALE_GETUNITS(SCALE_READS))) - tara;
#endif
// Glas entfernt -> Servo schliessen
if (gewicht < -20) {
winkel = winkel_min;
servo_aktiv = 0;
tara_glas = 0;
if ( autostart != 1 ) { // Autostart nicht aktiv
auto_aktiv = 0;
}
}
// Automatik ein, leeres Glas aufgesetzt, Servo aus -> Glas füllen
if ((auto_aktiv == 1) && (abs(gewicht) <= glastoleranz) && (servo_aktiv == 0)) {
rotary_select = SW_WINKEL; // falls während der Parameter-Änderung ein Glas aufgesetzt wird
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB24_tf);
u8g2.setCursor(15, 43);
u8g2.print("START");
u8g2.sendBuffer();
// kurz warten und prüfen ob das Gewicht nicht nur eine zufällige Schwankung war
delay(1500);
gewicht = (int(SCALE_GETUNITS(SCALE_READS))) - tara;
voll = false; //Kud
gezaehlt = false; //Kud
if ( abs(gewicht) <= glastoleranz ) {
tara_glas = gewicht;
#ifdef isDebug
Serial.print("gewicht: "); Serial.print(gewicht);
Serial.print(" gewicht_vorher: "); Serial.print(gewicht_vorher);
Serial.print(" zielgewicht: "); Serial.print(fmenge + korrektur + tara_glas + autokorrektur_gr);
Serial.print(" kulanz: "); Serial.print(kulanz_gr);
Serial.print(" Autokorrektur: "); Serial.println(autokorrektur_gr);
#endif
servo_aktiv = 1;
sammler_num = 0;
buzzer(BUZZER_SHORT);
}
}
zielgewicht = fmenge + korrektur + tara_glas + autokorrektur_gr;
// Anpassung des Autokorrektur-Werts
if ( autokorrektur == 1 )
{
if ( (auto_aktiv == 1) // Automatik ist aktiviert
&& (servo_aktiv == 0 ) && (winkel == winkel_min) // Hahn ist geschlossen
&& (gewicht >= zielgewicht ) // Glas ist voll
&& (sammler_num <= 5) // tropfmenge noch nicht erfasst
) {
voll = true;//Kud
if ( (gewicht == gewicht_vorher) && (sammler_num < 5) ) { // wir wollen 5x das identische Gewicht sehen
sammler_num++;
} else if ( gewicht != gewicht_vorher ) { // sonst gewichtsänderung nachführen
gewicht_vorher = gewicht;
sammler_num = 0;
} else if ( sammler_num == 5 ) { // gewicht ist 5x identisch, autokorrektur bestimmen
autokorrektur_gr = (fmenge + kulanz_gr + tara_glas) - (gewicht - autokorrektur_gr);
if ( korrektur + autokorrektur_gr > kulanz_gr ) { // Autokorrektur darf nicht überkorrigieren, max Füllmenge plus Kulanz
autokorrektur_gr = kulanz_gr - korrektur;
#ifdef isDebug
Serial.print("Autokorrektur begrenzt auf ");
Serial.println(autokorrektur_gr);
#endif
}
buzzer(BUZZER_SUCCESS);
sammler_num++; // Korrekturwert für diesen Durchlauf erreicht
}
if ((voll == true) && (gezaehlt == false)) { //Kud
glaeser[fmenge_index].TripCount++;
glaeser[fmenge_index].Count++;
setPreferences();
gezaehlt = true;
}
#ifdef isDebug
Serial.print("Nachtropfen:");
Serial.print(" gewicht: "); Serial.print(gewicht);
Serial.print(" gewicht_vorher: "); Serial.print(gewicht_vorher);
Serial.print(" sammler_num: "); Serial.print(sammler_num);
Serial.print(" Korrektur: "); Serial.println(autokorrektur_gr);
Serial.print(" Zähler Trip: "); Serial.print(glaeser[fmenge_index].TripCount); //Kud
Serial.print(" Zähler: "); Serial.println(glaeser[fmenge_index].Count); //Kud
#endif
}
}
// Glas ist teilweise gefüllt. Start wird über Start-Taster erzwungen
if ((auto_aktiv == 1) && (gewicht > 5) && (erzwinge_servo_aktiv == 1) ) {
servo_aktiv = 1;
voll = false; //Kud
gezaehlt = false;//Kud
buzzer(BUZZER_SHORT);
}
if (servo_aktiv == 1) {
winkel = ((winkel_max * pos) / 100);
}
if ((servo_aktiv == 1) && (( zielgewicht - gewicht ) <= fein_dosier_gewicht)) {
winkel = ( ((winkel_max*pos) / 100) * ((zielgewicht-gewicht) / fein_dosier_gewicht) );
}
if ((servo_aktiv == 1) && (winkel <= winkel_fein)) {
winkel = winkel_fein;
}
// Glas ist voll
if ((servo_aktiv == 1) && (gewicht >= zielgewicht)) {
winkel = winkel_min;
servo_aktiv = 0;
if (gezaehlt == false) { //Kud
glaeser[fmenge_index].TripCount++;
glaeser[fmenge_index].Count++;
setPreferences();
gezaehlt = true;
}
if ( autostart != 1 ) // autostart ist nicht aktiv, kein weiterer Start
auto_aktiv = 0;
if ( autokorrektur == 1 ) // autokorrektur, gewicht merken
gewicht_vorher = gewicht;
buzzer(BUZZER_SHORT);
}
SERVO_WRITE(winkel);
#ifdef isDebug
#if isDebug >= 4
Serial.print("Automatik:");
Serial.print(" Gewicht: "); Serial.print(gewicht);
Serial.print(" Winkel: "); Serial.print(winkel);
// Serial.print(" Dauer "); Serial.print(millis() - scaletime);
// Serial.print(" Füllmenge: "); Serial.print(fmenge);
// Serial.print(" Korrektur: "); Serial.print(korrektur);
// Serial.print(" Tara_glas:"); Serial.print(tara_glas);
Serial.print(" Autokorrektur: "); Serial.print(autokorrektur_gr);
Serial.print(" Zielgewicht "); Serial.print(zielgewicht);
// Serial.print(" Erzwinge Servo: "); Serial.print(erzwinge_servo_aktiv);
// Serial.print(" servo_aktiv "); Serial.print(servo_aktiv);
Serial.print(" auto_aktiv "); Serial.println(auto_aktiv);
#endif
#endif
time_vorher = millis();
u8g2.clearBuffer();
// Gewicht blinkt, falls unter der definierten Füllmenge
// Korrekturfaktor und Füllmenge blinken, wenn sie über den Rotary verstellt werden
blinktime = (millis()/10) % 5;
// wenn kein Tara für unser Glas definiert ist, wird kein Gewicht sondern eine Warnung ausgegeben
if ( tara > 0 ) {
// kein Glas aufgestellt
if ( gewicht < -20 ) {
u8g2.setFont(u8g2_font_courB12_tf);
u8g2.setCursor(28, 30); u8g2.print("Bitte Glas");
u8g2.setCursor(28, 44); u8g2.print("aufstellen");
} else {
u8g2.setCursor(10, 42);
u8g2.setFont(u8g2_font_courB24_tf);
if( (autostart == 1) && (auto_aktiv == 1 ) && (servo_aktiv == 0) && (gewicht >= -5) && (gewicht - tara_glas < fmenge) && (blinktime < 2) ) {
sprintf(ausgabe,"%5s", " ");
} else {
sprintf(ausgabe,"%5dg", gewicht - tara_glas);
}
u8g2.print(ausgabe);
}
} else {
u8g2.setCursor(42, 38);
u8g2.setFont(u8g2_font_courB14_tf);
sprintf(ausgabe,"%6s", "no tara!");
u8g2.print(ausgabe);
}
// Play/Pause Icon, ob die Automatik aktiv ist
u8g2.setFont(u8g2_font_open_iconic_play_2x_t);
u8g2.drawGlyph(0, 40, (auto_aktiv==1)?0x45:0x44 );
u8g2.setFont(u8g2_font_courB12_tf);
// Zeile oben, Öffnungswinkel absolut und Prozent, Anzeige Autostart
u8g2.setCursor(0, 11);
sprintf(ausgabe,"W=%-3d %2s %3d%%", winkel, (autostart==1)?"AS":" ", pos);
u8g2.print(ausgabe);
u8g2.setFont(u8g2_font_courB10_tf);
// Zeile unten, aktuell zu verstellende Werte blinken.
// Verstellung nur wenn Automatik inaktiv, gesteuert über Interrupt-Funktion
if( autokorrektur == 1 ){
u8g2.setCursor( 0, 64);
u8g2.print("a");
u8g2.setCursor(10, 64);
} else {
u8g2.setCursor( 0, 64);
}
if( rotary_select == SW_KORREKTUR && blinktime < 2 ) {
if (glaeser[fmenge_index].Gewicht > 999){
sprintf(ausgabe,"k= %s %3s-%3s",(autokorrektur==1)?"":" ", "1kg", GlasTypArray[glaeser[fmenge_index].GlasTyp] );
} else {
sprintf(ausgabe,"k= %s %3d-%3s",(autokorrektur==1)?"":" ", glaeser[fmenge_index].Gewicht, GlasTypArray[glaeser[fmenge_index].GlasTyp] );
}
} else if ( rotary_select == SW_MENU && blinktime < 2 ) {
sprintf(ausgabe,"k=%-3d" , korrektur + autokorrektur_gr, (autokorrektur==1)?"":" " );
} else {
if (glaeser[fmenge_index].Gewicht > 999){
sprintf(ausgabe,"k=%-3d%s %3s-%3s", korrektur + autokorrektur_gr, (autokorrektur==1)?"":" ", "1kg", GlasTypArray[glaeser[fmenge_index].GlasTyp] );
} else {
sprintf(ausgabe,"k=%-3d%s %3d-%3s", korrektur + autokorrektur_gr, (autokorrektur==1)?"":" ", glaeser[fmenge_index].Gewicht, GlasTypArray[glaeser[fmenge_index].GlasTyp] );
}
}
u8g2.print(ausgabe);
u8g2.sendBuffer();
}
void processHandbetrieb(void)
{
static unsigned long scaletime;
static unsigned long dauer;
if ( modus != MODE_HANDBETRIEB ) {
modus = MODE_HANDBETRIEB;
winkel = winkel_min; // Hahn schliessen
servo_aktiv = 0; // Servo-Betrieb aus
SERVO_WRITE(winkel);
rotary_select = SW_WINKEL;
tara = 0;
}
pos = getRotariesValue(SW_WINKEL);
gewicht = SCALE_GETUNITS(SCALE_READS) - tara;
if ((digitalRead(button_start_pin)) == HIGH) {
servo_aktiv = 1;
}
if ((digitalRead(button_stop_pin)) == HIGH) {
servo_aktiv = 0;
}
#ifdef USE_ROTARY_SW
if ( ((digitalRead(outputSW)) == LOW) /*&& (tara == 0) */ ) { // sonst muss der Taster entprellt werden!
tara = SCALE_GETUNITS(SCALE_READS);
}
#endif
if (servo_aktiv == 1) {
winkel = ((winkel_max * pos) / 100);
} else {
winkel = winkel_min;
}
winkel = constrain(winkel, winkel_min, winkel_max);
SERVO_WRITE(winkel);
#ifdef isDebug
#if isDebug >= 4
Serial.print("Handbetrieb:");
Serial.print(" Gewicht "); Serial.print(gewicht);
Serial.print(" Winkel "); Serial.print(winkel);
Serial.print(" Dauer "); Serial.print(millis() - scaletime);
Serial.print(" servo_aktiv "); Serial.println(servo_aktiv);
#endif
#endif
scaletime = millis();
// Ausgabe OLED. Dauert ca. 170ms
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB24_tf);
u8g2.setCursor(10, 42);
sprintf(ausgabe,"%5dg", gewicht);
// sprintf(ausgabe,"%5dg", dauer);
u8g2.print(ausgabe);
u8g2.setFont(u8g2_font_open_iconic_play_2x_t);
u8g2.drawGlyph(0, 40, (servo_aktiv==1)?0x45:0x44 );
u8g2.setFont(u8g2_font_courB12_tf);
u8g2.setCursor(0, 11);
sprintf(ausgabe,"W=%-3d %3d%%", winkel, pos);
u8g2.print(ausgabe);
u8g2.setCursor(0, 64);
sprintf(ausgabe, "Manuell %s", (tara>0?"Tara":" "));
u8g2.print(ausgabe);
u8g2.sendBuffer();
// u8g2.updateDisplayArea(4,2,12,6); // schneller aber ungenaue Displayausgabe.
dauer = millis() - scaletime;
}
void setup()
{
// enable internal pull downs for digital inputs
pinMode(button_start_pin, INPUT_PULLDOWN);
pinMode(button_stop_pin, INPUT_PULLDOWN);
pinMode(switch_betrieb_pin, INPUT_PULLDOWN);
pinMode(switch_setup_pin, INPUT_PULLDOWN);
#if HARDWARE_LEVEL == 2
pinMode(vext_ctrl_pin, INPUT_PULLDOWN);
#endif
#if (HARDWARE_LEVEL == 1 || HARDWARE_LEVEL == 2)
pinMode(LED_BUILTIN, OUTPUT);
#else // Hardwarelevel 3
pinMode(LED_pin, OUTPUT);
#endif
Serial.begin(115200);
while (!Serial) {
}
#ifdef isDebug
Serial.println("Hanimandl Start");
#endif
// Rotary
#ifdef USE_ROTARY_SW
pinMode(outputSW, INPUT_PULLUP);
attachInterrupt(outputSW, isr1, FALLING);
#endif
#ifdef USE_ROTARY
pinMode(outputA,INPUT);
pinMode(outputB,INPUT);
attachInterrupt(outputA, isr2, CHANGE);
#endif
// switch Vcc / GND on normal pins for convenient wiring
// output is 3.3V for VCC
digitalWrite (switch_vcc_pin, HIGH);
digitalWrite (button_start_vcc_pin, HIGH);
digitalWrite (button_stop_vcc_pin, HIGH);
// pinMode (_GND, OUTPUT); // turn on GND pin first (important!)
// turn on VCC power
// pinMode (switch_vcc_pin, OUTPUT);
pinMode (button_start_vcc_pin, OUTPUT);
pinMode (button_stop_vcc_pin, OUTPUT);
// short delay to let chip power up
delay (100);
// Preferences aus dem EEPROM lesen
getPreferences();
// Servo initialisieren und schliessen
#ifdef SERVO_ERWEITERT
servo.attach(servo_pin, 750, 2500); // erweiterte Initialisierung, steuert nicht jeden Servo an
#else
servo.attach(servo_pin); // default Werte. Achtung, steuert den Nullpunkt weniger weit aus!
#endif
SERVO_WRITE(winkel_min);
// Waage erkennen - machen wir vor dem Boot-Screen, dann hat sie 3 Sekunden Zeit zum aufwärmen
scale.begin(hx711_dt_pin, hx711_sck_pin);
if (scale.wait_ready_timeout(1000)) { // Waage angeschlossen?
scale.power_up();
waage_vorhanden = 1;
#ifdef isDebug
Serial.println("Waage erkannt");
#endif
}
// Boot Screen
u8g2.setBusClock(800000); // experimental
u8g2.begin();
u8g2.enableUTF8Print();
u8g2.clearBuffer();
print_logo();
buzzer(BUZZER_SHORT);
delay(3000);
// Setup der Waage, Skalierungsfaktor setzen
if (waage_vorhanden ==1 ) { // Waage angeschlossen?
if ( faktor == 0 ) { // Vorhanden aber nicht kalibriert
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB18_tf);
u8g2.setCursor( 24, 24); u8g2.print("Nicht");
u8g2.setCursor( 10, 56); u8g2.print("kalibr.");
u8g2.sendBuffer();
#ifdef isDebug
Serial.println("Waage nicht kalibriert!");
#endif
delay(2000);
} else { // Tara und Skalierung setzen
scale.set_scale(faktor);
scale.set_offset(long(gewicht_leer));
#ifdef isDebug
Serial.println("Waage initialisiert");
#endif
}
} else { // Keine Waage angeschlossen
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB24_tf);
u8g2.setCursor( 14, 24); u8g2.print("Keine");
u8g2.setCursor( 6, 56); u8g2.print("Waage!");
u8g2.sendBuffer();
buzzer(BUZZER_ERROR);
#ifdef isDebug
Serial.println("Keine Waage!");
#endif
delay(2000);
}
// initiale Kalibrierung des Leergewichts wegen Temperaturschwankungen
// Falls mehr als 20g Abweichung steht vermutlich etwas auf der Waage.
if (waage_vorhanden == 1) {
gewicht = SCALE_GETUNITS(SCALE_READS);
if ( (gewicht > -20) && (gewicht < 20) ) {
scale.tare(10);
buzzer(BUZZER_SUCCESS);
#ifdef isDebug
Serial.print("Tara angepasst um: ");
Serial.println(gewicht);
#endif
} else if (faktor != 0) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_courB18_tf);
u8g2.setCursor( 24, 24); u8g2.print("Waage");
u8g2.setCursor( 10, 56); u8g2.print("leeren!");
u8g2.sendBuffer();
#ifdef isDebug
Serial.print("Gewicht auf der Waage: ");
Serial.println(gewicht);
#endif
delay(5000);
// Neuer Versuch, falls Gewicht entfernt wurde
gewicht = SCALE_GETUNITS(SCALE_READS);
if ( (gewicht > -20) && (gewicht < 20) ) {
scale.tare(10);
buzzer(BUZZER_SUCCESS);
#ifdef isDebug
Serial.print("Tara angepasst um: ");
Serial.println(gewicht);
#endif
} else { // Warnton ausgeben
buzzer(BUZZER_LONG);
}
}
}
// die drei Datenstrukturen des Rotaries initialisieren
initRotaries(SW_WINKEL, 0, 0, 100, 5 ); // Winkel
initRotaries(SW_KORREKTUR, 0, -20, 20, 1 ); // Korrektur
initRotaries(SW_MENU, 0, 0, 7, 1 ); // Menuauswahlen
// Parameter aus den Preferences für den Rotary Encoder setzen
setRotariesValue(SW_WINKEL, pos);
setRotariesValue(SW_KORREKTUR, korrektur);
setRotariesValue(SW_MENU, fmenge_index);
}
void loop()
{
rotating = true; // debounce Management
// Setup Menu
if ((digitalRead(switch_setup_pin)) == HIGH)
processSetup();
// Automatik-Betrieb
if ((digitalRead(switch_betrieb_pin)) == HIGH)
processAutomatik();
// Handbetrieb
if ((digitalRead(switch_betrieb_pin) == LOW)
&& (digitalRead(switch_setup_pin) == LOW))
processHandbetrieb();
}
void print_logo() {
//#if (HARDWARE_LEVEL == 1 || HARDWARE_LEVEL == 2)
const unsigned char logo_biene1[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
0x00, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x60, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xF8, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x70, 0x00, 0xF0, 0xFF, 0x01,
0x00, 0x00, 0x00, 0x00, 0x03, 0xE0, 0x80, 0xFF, 0xFF, 0x0F, 0x00, 0xFF, 0xFF, 0x80, 0xF1, 0x47, 0xF0, 0x07, 0x00, 0x3E, 0xE0, 0xFF, 0xFF, 0x07,
0xF9, 0x07, 0x7E, 0x00, 0x00, 0x78, 0xF0, 0x03, 0xE0, 0x1F, 0xF8, 0x07, 0x1F, 0x00, 0x00, 0x70, 0x3C, 0x00, 0x00, 0xFE, 0x38, 0xC0, 0x03, 0x00,
0x00, 0xF0, 0x0E, 0x00, 0x00, 0xF8, 0x03, 0xF8, 0x00, 0x00, 0x00, 0xE0, 0x06, 0x00, 0x00, 0xC0, 0x0F, 0x7C, 0x00, 0x00, 0x00, 0xE0, 0x06, 0x00,
0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0xFC, 0x07, 0x00, 0x00, 0x00, 0x70, 0x03, 0x00, 0x00, 0x00, 0xF0, 0x03,
0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x07, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x07, 0x00, 0x00, 0x0F,
0x0F, 0x00, 0x00, 0x78, 0x78, 0xE0, 0x3F, 0x00, 0xC0, 0x07, 0x3E, 0x00, 0x80, 0xFF, 0x3C, 0xC0, 0x7F, 0x00, 0xF0, 0x01, 0xFC, 0x00, 0xE0, 0xFF,
0x1C, 0x80, 0xFF, 0x01, 0x7E, 0x00, 0xF0, 0xFF, 0xFF, 0x3F, 0x0E, 0x00, 0xFE, 0xFF, 0x0F, 0x00, 0xC0, 0xFF, 0xFF, 0x07, 0x0F, 0x00, 0xC0, 0x1F,
0x00, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x07, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x80, 0x03, 0x80, 0x03, 0xE0, 0x00, 0x70, 0x00, 0x00, 0x00, 0xC0,
0x01, 0xC0, 0x03, 0xC0, 0x01, 0xE0, 0x00, 0x00, 0x00, 0xE0, 0x00, 0xE0, 0x81, 0xC3, 0x01, 0xC0, 0x01, 0x00, 0x00, 0x70, 0x00, 0xE0, 0xF1, 0x8F,
0x03, 0x80, 0x03, 0x00, 0x00, 0x38, 0x00, 0xF0, 0xFC, 0x9F, 0x07, 0x00, 0x07, 0x00, 0x00, 0x1C, 0x00, 0xF8, 0x1C, 0x1C, 0x0F, 0x00, 0x06, 0x00,
0x00, 0x1C, 0x00, 0xFE, 0x00, 0x00, 0x1F, 0x00, 0x0C, 0x00, 0x00, 0x0E, 0x00, 0xF7, 0x00, 0x00, 0x7F, 0x00, 0x0C, 0x00, 0x00, 0x06, 0x80, 0x73,
0x00, 0x00, 0xE6, 0x00, 0x0C, 0x00, 0x00, 0x07, 0xE0, 0x71, 0x00, 0x00, 0xC6, 0x03, 0x0C, 0x00, 0x00, 0x07, 0x70, 0x70, 0xF0, 0x0F, 0x86, 0x07,
0x0C, 0x00, 0x00, 0x03, 0x3C, 0x70, 0xFC, 0x3F, 0x06, 0x1F, 0x0E, 0x00, 0x00, 0x03, 0x1E, 0x70, 0xFE, 0x3F, 0x06, 0xFC, 0x07, 0x00, 0x00, 0x87,
0x0F, 0x70, 0x1E, 0x38, 0x06, 0xF0, 0x03, 0x00, 0x00, 0xFE, 0x03, 0xF0, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0x00, 0xF0, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x80, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x0F, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xE0, 0xF1, 0x9F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x3B, 0x9C, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
0x07, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0xE0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7C, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0D,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
//#else
const unsigned char logo_biene2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xc0, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x80, 0x03, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x01, 0x06, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
0x04, 0x02, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x18, 0x03,
0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x18, 0x01, 0x0c, 0x00,
0x00, 0x00, 0x00, 0xda, 0x03, 0x0e, 0x0c, 0x03, 0x06, 0xb8, 0x01, 0x00,
0xc0, 0x00, 0x07, 0x0c, 0x1e, 0x07, 0x03, 0x0c, 0x30, 0x00, 0x40, 0x0c,
0x3c, 0x1c, 0x9e, 0x0f, 0x83, 0x87, 0x22, 0x00, 0x00, 0x00, 0x60, 0x38,
0x9e, 0xcf, 0xe1, 0x20, 0x00, 0x00, 0x80, 0xc1, 0xc9, 0xf1, 0xfe, 0xe7,
0x39, 0x33, 0x30, 0x00, 0x00, 0xb0, 0x0d, 0xc7, 0x0d, 0x7b, 0x1e, 0x93,
0x18, 0x00, 0x00, 0x83, 0x91, 0x9d, 0x03, 0x18, 0x9b, 0x3d, 0x04, 0x00,
0x00, 0x1c, 0xe9, 0x7b, 0x02, 0xec, 0x69, 0x01, 0x02, 0x00, 0x00, 0x20,
0x10, 0xf1, 0x01, 0x70, 0x08, 0x61, 0x00, 0x00, 0x00, 0x60, 0xfe, 0x00,
0x03, 0x18, 0xf0, 0xcf, 0x00, 0x00, 0x00, 0x20, 0x11, 0xf8, 0xe1, 0xd8,
0x83, 0x1d, 0x00, 0x00, 0x00, 0x60, 0x21, 0x46, 0xb0, 0x60, 0x84, 0xc8,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x80, 0x03, 0x18, 0x4c, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0xc2, 0x03, 0x78, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
0x35, 0xf1, 0x00, 0xe0, 0x89, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
0x07, 0xcc, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0x9f, 0x03, 0x98,
0x7f, 0x07, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc7, 0x0f, 0x3f, 0xfc, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xf0, 0xff, 0xef, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0xdf,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xff, 0x9f, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xff, 0x1f, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1e, 0xf8, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x07, 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87,
0xff, 0x1f, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xff, 0x1f,
0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xff, 0x0f, 0x18, 0x00,
0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x01, 0xff, 0x0f, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0x01, 0xfe, 0x0f, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
0xfe, 0x0f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
//#endif
#if (HARDWARE_LEVEL == 1 || HARDWARE_LEVEL == 2)
u8g2.clearBuffer();
u8g2.drawXBM(0,0,80,64,logo_biene1);
u8g2.setFont(u8g2_font_courB14_tf);
u8g2.setCursor(85, 27); u8g2.print("HANI");
u8g2.setCursor(75, 43); u8g2.print("MANDL");
u8g2.setFont(u8g2_font_courB08_tf);
u8g2.setCursor(85, 64); u8g2.print("v.0.2.8");
u8g2.sendBuffer();
#else
u8g2.clearBuffer();
u8g2.drawXBM(0,0,80,64,logo_biene1);
u8g2.setFont(u8g2_font_courB14_tf);
u8g2.setCursor(85, 27); u8g2.print("HANI");
u8g2.setCursor(75, 43); u8g2.print("MANDL");
u8g2.setFont(u8g2_font_courB08_tf);
u8g2.setCursor(85, 64); u8g2.print("v.0.2.8");
u8g2.sendBuffer();
delay(1000);
u8g2.clearBuffer();
u8g2.drawXBM(0,0,80,64,logo_biene2);
u8g2.setFont(u8g2_font_courB08_tf);
u8g2.setCursor(80, 27); u8g2.print("HANI");
u8g2.setCursor(80, 43); u8g2.print("MANDL3.0");
u8g2.setFont(u8g2_font_courB08_tf);
u8g2.setCursor(80, 64); u8g2.print("v.0.3.8");
u8g2.sendBuffer();
#endif
}
// Wir nutzen einen aktiven Summer, damit entfällt die tone Library, die sich sowieso mit dem Servo beisst.
void buzzer(byte type) {
pinMode(buzzer_pin, OUTPUT);
delay(100);
#if (HARDWARE_LEVEL ==3)
pinMode(LED_pin, OUTPUT);
delay(100);
#endif
#if (HARDWARE_LEVEL == 1 || HARDWARE_LEVEL == 2)
if (buzzermode == 1) {
switch (type) {
case BUZZER_SHORT: //short
digitalWrite(buzzer_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
break;
case BUZZER_LONG: //long
digitalWrite(buzzer_pin,HIGH);
delay(500);
digitalWrite(buzzer_pin,LOW);
break;
case BUZZER_SUCCESS: //success
digitalWrite(buzzer_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
delay(100);
digitalWrite(buzzer_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
delay(100);
digitalWrite(buzzer_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
break;
case BUZZER_ERROR: //error
digitalWrite(buzzer_pin,HIGH);
delay(1500);
digitalWrite(buzzer_pin,LOW);
break;
}
}
#else // Fuer Hardwarelevel 3 Buzzer und LED
if (buzzermode == 1) {
switch (type) {
case BUZZER_SHORT: //short
digitalWrite(buzzer_pin,HIGH);
digitalWrite(LED_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
digitalWrite(LED_pin,LOW);
break;
case BUZZER_LONG: //long
digitalWrite(buzzer_pin,HIGH);
digitalWrite(LED_pin,HIGH);
delay(500);
digitalWrite(buzzer_pin,LOW);
digitalWrite(LED_pin,LOW);
break;
case BUZZER_SUCCESS: //success
digitalWrite(buzzer_pin,HIGH);
digitalWrite(LED_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
digitalWrite(LED_pin,LOW);
delay(100);
digitalWrite(buzzer_pin,HIGH);
digitalWrite(LED_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
digitalWrite(LED_pin,LOW);
delay(100);
digitalWrite(buzzer_pin,HIGH);
digitalWrite(LED_pin,HIGH);
delay(100);
digitalWrite(buzzer_pin,LOW);
digitalWrite(LED_pin,LOW);
break;
case BUZZER_ERROR: //error
digitalWrite(buzzer_pin,HIGH);
digitalWrite(LED_pin,HIGH);
delay(1500);
digitalWrite(buzzer_pin,LOW);
digitalWrite(LED_pin,LOW);
break;
}
}
#endif
}
das ist der aktelle Code und später mal noch einen anderen PIN testen
So besser mit den ERsten Kommentaren Löschen oder soll ich den Teil der nicht benötigt wird auch mit entfernen ? zum Posten
Aha .. im aktuellen Code ist aber ein 1306 Konstruktor, kein 1309. Ich dachte aber es geht um ein 1309er 2.42" OLED.
Das ist so konfus hier …
Das sehe ich genau so.
Da hilft keine Hilfe mehr.
Wo möglich braucht der TO keine Hilfe mehr scheint alles funktionieren mit der falscher Display Ansteuerung laut gezeigtem Sketsch.
So ein durcheinander war schon lange hier nicht.
Genau das habe ich zum Anlass genommen, meine Glaskugel zur Inspektion zu geben und mir eine Reservekugel zuzulegen.
Dann schaff ich es zukünftig so ein Wirrwarr früher aufzulösen.
Hoffe ich ....
Vergiss es, meine nach der Inspektion funktionier gar nicht, und die allen neuen da wurde ich sagen, schade um das Glass. Kaffee Satz lesen geht besser
Jetzt Funktioniert alles
Schön, und was genau hat das mit dem nicht funktionierenden Display zu tun ?
Hast keine Tabelle was machen alle Pins?
6 bis 11 sind doch Tabu bei ESP32, wenn man nicht weis wie mit denen umgehet.
Anders rum typisch AZ wen die auf den ESP die nicht benutzbare GPIO mit Nummern beschriften, statt SHD usw.
Ja, chaothischer geht es wirklich nicht. Der Pin wird in jedem gezeigten Sketch anders definiert, genau wie der Oled-Treiber.