Go Down

Topic: Tasten und U8g2-lib (Read 671 times) previous topic - next topic

synth1203

Jun 18, 2018, 12:06 pm Last Edit: Jun 18, 2018, 12:25 pm by synth1203
Hallo liebes Forum,
bin frisch hier angekommen weil ich vor einem Problem stehe.

Vorgeschichte: habe mir einen Arduino Nano V3 bestellt und nachdem ich ihn hatte überlegt, was ich damit anstellen möchte. Ergebnis: Ich möchte einen Trigger für die Kamera bauen, welcher auf diverse externe Auslöseevents reagiert, aber auch einene Timer-Events besitzen soll.

Aktuell habe ich folgendes:
- Arduino Nano V3
- OLED-Display (https://www.az-delivery.de/collections/displays/products/1-3zoll-i2c-oled-display?variant=6571890704411)

Zur Auslösung nutze ich aktuell den Pin 13 (welcher ja auch die LED ansteuert, richtig?) mit einer Funktion, die wie folgt aussieht:

Funktion zum Auslösen der Kamera:
Code: [Select]
void takePicture(int timingMS, int breakMS, int howOften, int pin){
  for   (int   i =0; i >=howOften ; i ++ ) {                         
    digitalWrite (pin , HIGH);
    delay(timingMS);             
    digitalWrite(pin , LOW); 
    delay(breakMS);             
  }
}


Zu meinem Problem:
Ich nutze die Display-Bibliothek U8G2, welche gleich ein nettes Menü bereitstellt. Leider auch bisher die einzige Bibliothek die mit dem Display funktioniert. Auch wenn auf der Händlerseite was anderes steht.
Meine einzelnen Funktionen realisiere ich jetzt nicht über die Menüfunktionen von U8G2, sondern über die normalen Ausgabe-Funktionen. Funktioniert so weit sehr gut, aber wenn ich jetzt zum Auslösen komme geht es in die Hose, bzw. sind aktuell vermutlich zwei Fehler drin. Die Auslösefunktion (eben schon gepostet) scheint nicht zu funktionieren, die LED bleibt nämlich immer dunkel, ich erhalte aber beim Compilieren keine Fehler.

Code für das Display, über welches die Auslösezeit eingestellt wird und dann auch ausgelöst wird:
Code: [Select]
    while (digitalRead(cancel) == HIGH) {
      do {
        delay(10);
      } while (digitalRead(select) == LOW);
      u8g2.clearBuffer();
      u8g2.setCursor(5, 25);
      u8g2.print("BULB");
      u8g2.setCursor(5, 45);
      u8g2.print(String(triggerTime) + " ms");
      u8g2.sendBuffer();
      if (digitalRead(left) == HIGH) triggerTime = triggerTime + 1000;
      if ((triggerTime > 1000) and (digitalRead(right) == HIGH)) triggerTime = triggerTime - 1000;
      if (digitalRead(select) == HIGH) {
        do {
          delay(10);
        } while (digitalRead(select) == LOW);
        takePicture(triggerTime, 0, 1, shutterPin);
        u8g2.clearBuffer();
        u8g2.setCursor(5, 25);
        u8g2.print("*** SHUTTER ***");
        u8g2.sendBuffer();
        delay (triggerTime);
      }
    }


Die beiden "do while"-Schleifen hab ich drin, um die Zeitverzögerung abzufangen, bis der jeweilige Pin-Status hergestellt ist und es nicht einfach einen "Durchmarsch" gibt.
Wenn ich diese Schleifen raus lasse, reagiert er auf nichts mehr. Wenn ich sie drin habe, kann ich die Werte von triggerTime verändern, aber nach einmaliger Bestätigung bleibt er in einer Schleife. Theoretisch sollte das Ganze aber ohne die beiden "do while"-Schleifen funktionieren. Oder hab ich einen Denkfehler?

Die Verkabelung für die Schalter läuft auf Masse, sollte also theoretisch auf "INPUT_PULLUP" gestellt sein, weil diese Anschlussvariante ist für U8G2 so beschrieben.
Aktuell betätige ich die einzelnen "Taster" nur durch Kabel, die ich auf dem Steck-Board kurzschließe, da ich noch auf die bestellten Folientaster warte.

Hier nochmal die Konstanten und Variablen:
Code: [Select]
const int shutterPin = 13; // =LED
const int cancel = 4;
const int up = 9;
const int down = 7;
const int left = 8;
const int right = 6;
const int select = 5;

const char *string_main_title = "PT v0.05a"; // UP TO 22 SIGNS
const char *string_list_main =
  "1) Bulb         \n"
  "2) HDR          \n"
  "3) Countdown    \n"
  "4) Zeitraffer   \n"
  "5) Blitz        \n"
  "6) Schall       \n"
  "7) Lichtschranke\n"
  "8) Info         ";

int triggerTime = 1000;


Hier nochmal das Setup:
Code: [Select]
void setup(void) {
  u8g2.begin(/*Select=*/ select, /*Right/Next=*/ right, /*Left/Prev=*/ left, /*Up=*/ up, /*Down=*/ down, /*Home/Cancel=*/ cancel); // Arduboy 10 (Production)
  u8g2.setFont(u8g2_font_6x12_tr);
  u8g2.enableUTF8Print();
  pinMode(shutterPin, OUTPUT);
}


Ich hänge nochmal den kompletten Code als Datei an.

Ich hoffe Ihr habt eine Idee oder seht, was ich falsch mache, bzw. wo ich einen Denkfehler habe.

Tommy56

Warum hängst Du nicht den ganzen Sketch direkt in den Beitrag?

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

gregorss

Hi!

Ich habe nur etwa das erste Viertel Deines Postings gelesen. Beim ersten Code-Schnipsel ist mir aufgefallen, dass die for-Schleife nicht funktionieren kann, weil die Bedingung falsch formuliert ist. Statt ">=" sollte dort wohl "<=" stehen. So wie es jetzt aussieht, wird der Schleifenkörper nie betreten.

Da das syntaktisch korrekt ist, bekommst Du (zumindest hierzu) keine Fehlermeldung. Allerdings wird halt auch nie ausgelöst.

Fang am besten noch einmal mit einem minimalen Code an, mit dem nur ausgelöst und dann gar nichts mehr getan wird. Mach erst dann weiter, wenn das funktioniert. Speichere den neuen Sketch unter einem neuen Namen - dann bleibt der bisherige Code erhalten und Du kannst ihn als Vorlage nutzen.

HTH

Gregor


Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

uwefed

1) Da der Pin 13 direkt eine LED angeschlossen hat ist er nicht 100% geeignet als Eingeng zu funktionieren. Nimm ein anderes Pin; Auch die analogen Pins können als digitale Pins (D14 bis D19) verwendet werden.
2) Die while do Konstruktion ist blockierend. Mach das mit millis und einer finite state machine.


Grüße Uwe

synth1203

@Tommy56, weil ich es aus vielen Foren so kenne, dass es unerwünscht ist.
@gregorss, danke erstmal, das bringt mich weiter ... werde komplett die Bereiche, welche ich erstellen möchte einzeln coden und hinterher in den bestehenden Code ein"pflegen", damit es zum großen ganzen wird.
@uwefed, Pin13 ist als Ausgabe verwendet, da ich aktuell noch keine Kamera dran hängen werde. Später lege ich das noch um, wenn ich die Platine für den Trigger erstelle.
Welche FSM würdest Du empfehlen und warum mit millis?

Ich brauche immer länger für Antworten, da ich auf einem Kreuzfahrtschiff arbeite und das mit dem Internet hier ein wenig schwieriger ist. Nicht wundern also, wenns mal wieder länger dauert. :)

Danke EUch so weit,
LG Ralf aka synth1203

Tommy56

@Tommy56, weil ich es aus vielen Foren so kenne, dass es unerwünscht ist.
Wir legen Wert auf den kompletten Sketch, da die Erfahrung zeigt, dass in >> 90% der Fehler im "geheimen" Teil des Codes liegt.
Besonders wichtig sind dabei Variablendeklarationen.

Bei Libs, die nicht zum Standardumfang der IDE/der Prozessorfamilie gehören ist auch ein Link auf die Herkunft sinnvoll, da es oft mehrere Libs zum gleichen Thema / mit gleichem Namen aber völlig verschiedenen Inhalten gibt.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

gregorss

... werde komplett die Bereiche, welche ich erstellen möchte einzeln coden und hinterher in den bestehenden Code ein"pflegen", damit es zum großen ganzen wird.
Mach das eher nicht. Das Zusammenstricken mehrerer Programme bzw. -teile ist manchmal ziemlich schwierig, weil es z. B. Überschneidungen oder gleiche Variablennamen gibt.

Versioniere Deine Arbeit besser. Dann kannst Du notfalls wieder zu einer funktionierenden Fassung zurückkehren. „Versionieren" hört sich zwar nach Sesselpuperkram an, aber es hilft sehr.

Gruß

Gregor


Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

Tommy56

Wenn man weiß, dass man es zusammen führen will, ist es doch am Einfachsten doppelte Variablennamen zu vermeiden.
Wenn man sprechende Variablennamen verwendet (was man sowieso tun sollte), sollte das sowieso kaum zu Überschneidungen führen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

gregorss

Wenn man weiß, dass man es zusammen führen will, ist es doch am Einfachsten doppelte Variablennamen zu vermeiden.
Wenn man sprechende Variablennamen verwendet (was man sowieso tun sollte), sollte das sowieso kaum zu Überschneidungen führen.
Ja, doppelte Variablennamen zu vermeiden ist ziemlich einfach. Mit Überschneidungen meine ich eher Codeteile mit ähnlicher oder gleicher Funktionalität.

Meiner Erfahrung nach ist es das beste, funktionierende Codeteile bzw. Teil-Codes in Tabs „auszulagern" und im „Hauptsketch" nur noch entsprechende Funktionsaufrufe zu notieren. Das hält den Hauptsketch schön schlank und führt zu Code, der besser zu warten oder anzupassen ist.

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

Tommy56

Ja, so mache ich es auch. Die Tabs mäglichst so angelegt, dass man sie problemlos in neue Projekte übernehmen kann (ok, man könnte auch eine Lib draus machen).

Trotzdem halte ich es für sinnvoll, Tests von technischen Einzelheiten (Module, NTP, ...) erst mal allein auszutesten und nicht im Verbund der gesamten Applikation.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

synth1203

Hallo Ihr Lieben,
letztenendes haben die einzelnen Funktionen nur geringe Unterschiede.
Grundsätzlich wird das Ganze noch ziemlich lange dauern, bis es fertig ist, einerseits weil ich nicht so häufig dazu komme, wie ich Lust habe und andererseits, weil ich auch nicht so einfach an dann später benötigte Hardware komme, wie zu Hause.
Alleine zum löten muss ich einen Termin bei einem Kollegen machen .......

Meine einzelnen Funktionsteile sollten theoretisch auch durch einfaches Zusammenfügen mit dem Menü funktionieren, diverse Variablen müssen sogar immer gleich sein und so viele Variablen werde ich letzenendes gar nicht haben. I.d.R. sind es nur Auslösezeit, Auslöseverzögerung, Bracketing-Anzahl, Verschubzeiten fürs Bracketing, welche ich aber wohl "in time" berechnen werde.
Die Auslöseverzögerung werde ich global aufs alle Funktionsteile wo sie notwendig sind laufen lassen.
Später kommen dann noch die Hardwarevariablen dazu, wenn ich auch die passenden Teile hier habe.

Werde mich jetzt die Tage erstmal in die State-Machine einlesen.
Gute N8, muss morgen früh raus.
LG Ralf aka synth1203

uwefed

@Tommy56, weil ich es aus vielen Foren so kenne, dass es unerwünscht ist.
@gregorss, danke erstmal, das bringt mich weiter ... werde komplett die Bereiche, welche ich erstellen möchte einzeln coden und hinterher in den bestehenden Code ein"pflegen", damit es zum großen ganzen wird.
@uwefed, Pin13 ist als Ausgabe verwendet, da ich aktuell noch keine Kamera dran hängen werde. Später lege ich das noch um, wenn ich die Platine für den Trigger erstelle.
Welche FSM würdest Du empfehlen und warum mit millis?

Ich brauche immer länger für Antworten, da ich auf einem Kreuzfahrtschiff arbeite und das mit dem Internet hier ein wenig schwieriger ist. Nicht wundern also, wenns mal wieder länger dauert. :)

Danke EUch so weit,
LG Ralf aka synth1203
Hier ist es erwünscht den gesamten Sketch zu posten da wie schon gesagt der fehler fast immer im ungeposteten Teil ist bzw erst durch Kenntnis des gesamten Sketches die Fehler sich eröffnen. ZB Du definierst am Anfang des Sketches ein Array mit 5 Elementen, Postest dannaber den Teil wo das Array mit 6 Elementen verwendet wird. Ein Eklatanter Fehler den man nicht finden kann wenn man die Variablendefinition nicht kennt.

Pin 13 als Ausgang ist kein Problem.

Weil man immer auf Tastatureingaben reagieren muß. Wenn Du mit Do While einen Eingang kontrollierst, kannst Du es nicht mit anderen machen.


Darf ich neugierig sein; Wo schipperst gerade herum?

Grüße Uwe

gregorss

Trotzdem halte ich es für sinnvoll, Tests von technischen Einzelheiten (Module, NTP, ...) erst mal allein auszutesten und nicht im Verbund der gesamten Applikation.
Wenn es um Dinge geht, die man separat testen/kennenlernen kann, ist es absolut sinnvoll, das in eigenen Sketchen zu tun. Als ich z. B. den TSSP4P38 (IR-Taster) kennenlernen wollte, habe ich das zunächst separat gemacht und das Ding erst anschließend mit anderen Teilen kombiniert. Wäre dabei etwas schiefgelaufen, hätte ich gewusst, dass ich es separat schon hinbekommen habe.

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

synth1203

Hallo Ihr Lieben, bin die Tage leider zu nix gekommen, nur zur Vorbereitung meines mittlerweile erhaltenen Gehäuses. Ach ja und eine Folientastatur habe ich bestellt.

Muss schauen, wie ich die nächsten 2 Wochen zu irgendwas komme, da mein Team ein wenig dezimiert wurde. Heisst leider Mehrarbeit und Wenigerfreizeit.

@uwefed ... darfst Du... AIDAperla - Metropolenroute ab Hamburg.

Kann mir jemand eine gute Beschreibung/Erklärung zur State-Machine in Deutsch geben?

Würde es gerne zwischendurch lesen, aber da komm ich im Moment an englischsprachige Texte nicht ran ... bei denen schalt ich zur Zeit sofort nach den ersten zwei Sätzen ab. :(

THNX, LG Ralf aka synth1203

gregorss

Kann mir jemand eine gute Beschreibung/Erklärung zur State-Machine in Deutsch geben?
Guck hier. Beachte auch die Folgeseite.

Gruß

Gregor
Wenn man keine Probleme hat, kann man sich welche machen („Großes Lötauge", Medizinmann der M3-Hopi)
Nicht lange fackeln, lass' Backen wackeln! (Seeed)

Go Up