- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Arduino-Code: fehlende Definition, benötige Hilfe

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    31.03.2014
    Beiträge
    173

    Arduino-Code: fehlende Definition, benötige Hilfe

    Anzeige

    Praxistest und DIY Projekte
    Hallo,

    um mal mit meinen Anfänger-Arduino-Kenntnissen weiterzukommen habe ich mir ein Buch gekauft, welches ich nun Seite für Seite abarbeite. Es handelt sich um das Buch

    MUSIK MIT DEM ARDUINO UND MIDI vom FRANZIS-VERLAG

    Leider scheint das Buch an einigen Stellen fehlerhaft zu sein, denn die enthaltenen Hinweise und Codes funktionieren manchmal nicht. Auf Seite 72 z.B. steht ein Beispielcode, um ein Lauflicht mit einem kurzen Tasterdruck an-, später dann mit nochmaligem kurzen Tasterdruck wieder auszuschalten.
    Hier der Code (zur besseren Übersicht habe ich alle Anmerkungen entfernt, nur die Befehlszeilen belassen):


    Code:
    const int LED_PINS[] = {2, 3, 4, 5};
    const int PUSH_BUTTON = 6;
    int buttonStateOld = 0;
    bool buttonFlag = false;
    
    void setup() 
    {
      for (int a=0; a<4; a++)
      {
        pinMode(LED_PINS[a], OUTPUT);
        }
      pinMode(PUSH_BUTTON, INPUT);
    }
    
    void loop() 
    {
      if (buttonState != buttonStateOld)
      {
        if(buttonState == HIGH)
        {
          if(buttonFlag == false)
          {
            buttonFlag = true;
          }
          else
          {
            buttonFlag = false;
          }        
        }
        buttonStateOld = buttonState;
      }
      if(buttonFlag == true)
      {
        for(int a=0; a<4; a++)
        {
          digitalWrite(LED_PINS[a], HIGH);
          delay(200);
        }
        for(int a=0; a<4; a++)
        {
          digitalWrite(LED_PINS[a], LOW);
          delay(200);      
        }  
      }
    }

    Unter "void loop" gibt es gleich den "if"-Befehl:


    Code:
      if (buttonState != buttonStateOld)

    Allerdings wurde im FRANZIS-Buch der "buttonState" als Variable im Definitions-Bereich des Codes nicht deklariert, was folgerichtig zu einer Fehlermeldung führt. Lediglich "buttonStateOld" wird dort deklariert.
    Das FRANZIS-Buch ist - sagen wir mal - in seinen Hinweisen und Hilfestellungen durchwachsen. Einerseits genau das, was ich vorhabe (MIDI- bzw. HUI-Controller mit dem Arduino bauen), aber die Befehle und Werte, die zum Einsatz kommen, werden teilweise nicht einmal erklärt. Bei meiner Google-Suche komme ich dann manchmal auch nicht weiter, so wie in diesem Fall. Kann mir von Euch hier bitte jemand helfen?

    Ich habe zunächst versucht, im Definitions-Bereich zusätzlich die Zeile für "int buttonState = " einzufügen und mit einem Wert zu versehen, aber da komme ich nicht weiter. Bei "int buttonStateOld =" steht: 0
    Was genau bedeutet eigentlich dort diese Null? Sie ist ja nicht dasselbe, wie die Zahlen bei "const int", wo 2, 3, 4 usw. den zugehörigen PIN des Arduino definieren. Die Null gibt ja hier keine PIN-Nr. an. Bedeutet "0" bei "int buttonStateOld" dasselbe wie LOW, und daraus folgernd müsste "1" dasselbe wie HIGH bedeuten? Oder wofür steht dort der Wert "0"?

    Ich habe es für "int buttonState =" versucht mit folgenden Werten:

    0
    1
    255
    true
    false

    aber alles ohne Erfolg. Zwar wird nun bei der Überprüfung des Codes in allen Varianten kein Fehler mehr angezeigt, aber funktionieren tut es trotzdem nicht. Fakt ist, dass "buttonState" definiert werden muss. Aber mit welchem Wert bzw. Befehl? Und "warum" mit welchem Wert bzw. Befehl?

    Kann mir von Euch jemand hier bitte helfen? Gern auch www-Links, die ich bisher möglicherweise noch nicht entdeckt habe?

    Andi
    Geändert von Andi#87 (17.03.2023 um 21:29 Uhr)

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    55
    Beiträge
    2.207
    In dem geposteten Progrämmchen wird der Button überhaupt nicht abgefragt.
    Weil er auch nicht mit nem Interrupt verbunden ist, kann der also auch nichts bewirken.
    Der ist also völlig wirkungslos...

    Frag einfach zyklisch (also in der loop() ) den Button auch mal ab:

    buttonState=digitalRead(PUSH_BUTTON).

    Dann läufts auch.
    Zuverlässiger wirds, wenn du den Button noch etwas entprellst.

    Allerdings: ein- und ausschalten per Tastendruck wird das Programm, so wie ich das sehe, nicht, sondern die LED's laufen nur, wenn der Button gedrückt _ist_.
    Lässt du ihn los, gehn die wieder aus, weil sich dann buttonState wieder ändert.

    Anmerkung: buttonState kannst du als bool deklarieren, da die nur true und false können muss- das spart Speicher.

    Mal so aus Neugier: welcher Stümper hat das Buch geschrieben?
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    31.03.2014
    Beiträge
    173
    Danke für Deine Antwort. Das habe ich tatsächlich auch noch übersehen... bzgl. Dein Hinweis zu PUSH_BUTTON und Loop...
    Da scheinen wohl noch paar andere Stellen im Code nicht korrekt zu sein. Ich habe zum Verlag und zu einem der Autoren per eMail Kontakt aufgenommen. Ich hoffe, dass man mir antwortet - und evt. Korrekturen zusendet. Ein Lehrbuch mit Fehlern, das ist ein Widerspruch in sich. Ich hoffe sehr, dass sich nicht noch mehr Fehler zeigen in dem Buch.
    Hier ein Link zum Buch/Verlag:
    https://www.franzis.de/maker/raspber...ach-e-book-pdf

    Andi

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    55
    Beiträge
    2.207
    Ja..Franzis nimmt leider so ziemlich alles...

    Und es stimmt: der Code ist ziemlicher Pfusch. Ich weiss zwar nicht, was du alles raus gelöscht hast, aber wenn es wirklich _nur_ Kommentare waren, kommt der nicht mal in die Nähe dessen, was er tun sollte *grusel
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    31.03.2014
    Beiträge
    173
    Hier mal der ursprüngliche Code:

    Code:
    // +++ QUELLCODE FÜR DEN DRUCKTASTER MIT PERMA-LED-LAUFLICHT +++ //
    
    // Definition von Variablen für den Taster + LEDs
    const int LED_PINS[] = {2, 3, 4, 5};
    const int PUSH_BUTTON = 6;
    int buttonStateOld = 0;
    bool buttonFlag = false;
    
    void setup() {
      // Initialisiere digitale Pins als Ausgang in einer For-Schleife
      for (int a = 0; a < 4; a++) {
        pinMode(LED_PINS[a], OUTPUT);
      }
    
      // Initialisiere den Drucktaster als Eingang
      pinMode(PUSH_BUTTON, INPUT);
    }
    
    void loop() {
      if (buttonState != buttonStateOld) {
        // Ändere das Flag nur, wenn der Taster gedrück wird
        if (buttonState == HIGH) {
          if (buttonFlag == false) {
            buttonFlag = true;
          } else {
            buttonFlag = false;
          }
        }
    
        // Speichere den aktuellen Wert des Tasters
        buttonStateOld = buttonState;
      }
    
      if (buttonFlag == true) {
        for (int a = 0; a < 4; a++) {
          // Schalte eine LED an
          digitalWrite(LED_PINS[a], HIGH);
          // Sende eine Nachricht an den seriellen Monitor
          Serial.print("LED Status: LED ");
          Serial.print(LED_PINS[a]);
          Serial.println(" is ON");
          // Warte 50 Millisekunden
          delay(50);
        }
        
        for (int a = 0; a < 4; a++) {
          // Schalte eine LED aus
          digitalWrite(LED_PINS[a], LOW);
          // Sende eine Nachricht an den seriellen Monitor
          Serial.print("LED Status: LED ");
          Serial.print(LED_PINS[a]);
          Serial.println(" is OFF");
          // Warte 50 Millisekunden
          delay(50);
        }
      }
    }
    In Thread #1 hatte ich die Kommentare gelöscht. Ebenfalls den seriellen Monitor. Und die Delays von 50 auf 200 geändert.

    Ob der Code "...nicht mal in die Nähe dessen (kommt), was er tun sollte...", kann ich nicht beurteilen. Möglicherweise verfolgt der Autor ein späteres Ziel und man könnte speziell diesen Code zwar anders schreiben, aber evt. damit das spätere Ziel nicht schon im Blick haben. Wie gesagt, das kann ich mit meinem Kenntnisstand nicht einschätzen, hoffe aber darauf, dass (trotz der enthaltenen Fehler im aktuellen Code) der Autor den Leser an einem "roten Faden" konsequent durchs Buch führt.


    Andi
    Geändert von Andi#87 (19.03.2023 um 12:04 Uhr)

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    55
    Beiträge
    2.207
    Bau da mal die von mir vorgeschlagene Zeile ein.
    Ich bin mir relativ sicher: die LED's werden nur funktionieren, wenn man den Button gedrückt _hält_.

    Zum Entprellen wird hier wohl das delay() mit genutzt, das ist zwar ziemlich hemdsärmelig, müsste aber halbwegs funktionieren.

    Für buttonStateOld brauchts auch keineswegs eine int- da nur zwei Möglichkeiten bestehen, ist eine bool völlig ausreichend.
    Geht in dem Testprogramm natürlich auch, aber irgendwann kommst du an den Punkt, wo du mal den Speicher voll kriegst, daher: gewöhn dir besser an, für Variablen nicht mehr Speicher zu reservieren (genau das passiert am Anfang nämlich) als nötig.

    Was den Aufbau des Buches angeht: ich weiss ja nicht, wie du es durcharbeitest, aber möglicherweise sind da bewusst Fehle im Code, die auf den nächsten Seiten dann untersucht werden?
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    31.03.2014
    Beiträge
    173
    Was den Aufbau des Buches angeht: ich weiss ja nicht, wie du es durcharbeitest, aber möglicherweise sind da bewusst Fehle im Code, die auf den nächsten Seiten dann untersucht werden?
    Das war auch eine Option, die ich erhoffte, aber da habe ich keine Hinweise oder Lösungen/Korrekturen gefunden. Ansonsten wäre das ja durchaus eine gute Möglichkeit, etwas zu lernen. Die Codes werden für die Käufer des Buches auch im Download angeboten. Auch dort ist keine Korrektur zu finden.

    Danke für Deine Tips, werde ich in den kommenden Tagen ausprobieren. Heute komme ich nicht mehr dazu.

    Andi

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.675
    Hi Andi.
    Nu bin ich kein arduino-er - habe nur mikroskopische Erfahrung mit der arduino-IDE (aber ich hab ne Handvoll billigster nano-Clone - umgequarzt auf 20 MHz, bis auf einen der "arduino-konform" ist). Egal. Das Problem sieht irgendwie machbar aus.
    .. Beispielcode, um ein Lauflicht .. Fehlermeldung .. "int buttonState = " einzufügen .. mit folgenden Werten: .. 1 .. alles ohne Erfolg ..
    Hmmm. Ich habe DEINEN Programmcode in die arduino-IDE reinkopiert und in nen nano-Clone geflasht. Klar, geht nicht. Ich habe ne Codezeile eingefügt :
    Code:
    int buttonStateOld = 0;
    int buttonState = 1;        ////<<<<   Einfügung
    bool buttonFlag = false;
    . . . und schon läuft es. Ohne Button :-// als Lauflicht. WENN man ne Buttonfunktion bräuchtewollte, bräuchte man natürlich noch nen Button mit passender Code-Erweiterung.

    Fragen:
    Vorwiderstände an den Dioden?
    Dioden vom arduino über Rv nach GND?
    Läuft Dein arduino mit USB/bootloader? Welcher Bootloader? Bei mir läufts nur mit
    . . . . [Werkzeuge][Prozessor][Old Bootloader] in der IDE.
    . . . ansonsten: mehr fällt mir grad nicht ein.

    Viel Erfolg

    - - - Aktualisiert - - -

    Mal auf die Schnelle
    Ciao sagt der JoeamBerg

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    31.03.2014
    Beiträge
    173
    Ja, das ist richtig. Da habe ich mich nicht klar ausgedrückt. Der Code, so wie er im Buch steht (also ohne irgendwelche Korrekturen), funktioniert zunächst nicht. Durch das Einfügen der Deklarierung von buttonState (so wie auch von Dir vorgeschlagen) funktioniert das insofern, dass das Lauflicht läuft, und zwar ohne weitere Aktion. Danke für Deinen aufmerksamen Hinweis!
    Anliegen speziell dieses Codes soll - laut Beschreibung im Buch - jedoch sein, dass folgendes funktioniert:
    1x kurzer Tastendruck --> Lauflicht geht an
    wieder 1x kurzer Tastendruck, Lauflicht geht wieder aus

    Der vorangegangene Code im Buch macht genau das: sofort nach dem Hochladen läuft das Lauflicht los. Da ist kein Schalter vorgesehen. Entsprechend einfacher ist der Code auch ausgeführt. Anschliessend wird nun der Taster hinzugenommen (mit dem hier erwähnten Code), und der soll die Lauflicht-Funktion an- bzw. ausschalten. Und DAS macht der Code - so wie er im Buch angeboten wird - nicht.

    Ich arbeite mit Bootloader. Kann Dir aber nicht sagen, welcher das ist. Ich beschreibe die ATmegas mit der üblichen Arduino-Software, da ist der Bootloader ja integriert. Für meinen "Buch-Lern-Kurs" verwende ich einen Original-Arduino-UNO bzw. LEONARDO, da ich mit diversen Klones hin und wieder festgestellt habe, dass manches nicht funktioniert. Probleme dieser Art möchte ich zumindest beim Erarbeiten dieses Buches von vornherein ausschliessen.

    __________________________________________________ __________________________________________________ __________________________________________________ _________________

    Hier möchte ich gleich nochmal nachhaken. Wenn ich richtig "gelernt" habe, so gibt es beim Programmieren einen Unterschied zwischen deklarieren und definieren. Das war mir bisher auch noch nicht klar, aber es ergibt Sinn. Nun nehme ich diese Zeile:

    int buttonStateOld = 0;

    Die "Null" bedeutet hier ja keine PIN-Zuweisung am Arduino. Hier können (ganzzahlige) Werte zwischen -32000 bis +32000 (gerundet, 16 bit???) stehen. So zumindest wird es in der Arduino-Sprache beschrieben. Allerdings verarbeitet der doch nur 8 bit, was genaugenommen nur 256 (0-255) Werten entspricht. Warum hier 16 bit-Werte möglich sind, ist mir auch (noch) unklar, ist aber ein anderes Thema.
    Spielt es eine Rolle, ob ich in der erwähnten Zeile "buttonStateOld" überhaupt einen Wert (0 oder 1 oder 1687 ...) eintrage - bzw. kann ich dort irgendeinen Wert einsetzen, der mir grad durch den Kopf geht? Habe ich hier "richtig" gelernt? Mit einem Wert, den man dort einträgt, reserviert man sich lediglich einen Speicherplatz, was bei umfangreichen Codes dann von Bedeutung ist. Ob ich da nun 0 eintrage oder zB 156 ergibt letztlich in binärer Schreibeweise keinen wirklichen Unterschied (ausser den Wert selbst), denn meine 8 verfügbaren Bits werden ja auch bei der (Dezimal-)Zahl 0 reserviert, nur eben (binär) in 0-0-0-0-0-0-0-0 und nehmen genausoviel Speicher in Beschlag, wie zB die (Dezimal-)Zahl 12: 0-0-0-0-1-1-0-0.
    Mir ist noch nicht nicht klar, mit welchem Wert (Dezimalzahl) man diese Deklaration (hier im Beispiel buttonStateOld) definiert. Warum schreibst Du (@ oberallgeier) z.B. buttonState = 1, und nicht etwa 0 oder 181? Eine 1 oder eine 0 geben doch hier nicht HIGH oder LOW an. Warum 0 oder 1?

    Andi


    Nachtrag:
    @Rabenauge:
    Durch Einfügen von
    buttonState=digitalRead(PUSH_BUTTON);
    in den Loop funktioniert das mit dem kurzen Tasterdruck. Aber nur beim anschalten auch zuverlässig. Entgegen Deiner Vermutung läuft das Lauflicht weiter, auch wenn ich den Taster dann loslasse. Mit dem Ausschalten wird es dann aber knifflig. Der Code erkennt den kurzen Tasterdruck für "ausschalten" (also während das Lauflicht läuft) nur dann, wenn die Lauflicht-Sequenz komplett durchgelaufen ist. Also nur dann, wenn ich genau diesen Zeitpunkt erwische, geht auch das Lauflicht wieder aus. Wenn ich mitten in der Sequenz drücke, hat das keinen Einfluss.
    Ich habe das direkt ganz oben im Loop eingetragen:

    Code:
     
    void loop() 
    {
      buttonState=digitalRead(PUSH_BUTTON);
      if (buttonState != buttonStateOld)
      {
        if(buttonState == HIGH)
        {
          if(buttonFlag == false)
    Muss das evt. innerhalb einer der aufgeführten Bedingungen (innerhalb bestimmter geschweifter Klammern) eingesetzt werden, oder muss ein Interrupt geschrieben werden?

    Andi
    Geändert von Andi#87 (20.03.2023 um 21:12 Uhr)

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von Rabenauge
    Registriert seit
    13.10.2007
    Ort
    Osterzgebirge
    Alter
    55
    Beiträge
    2.207
    Der Button wird ja _nur_ ausserhalb der Lauflicht-Prozedur abgefragt.
    Das machen wir da ziemlich hemdsärmelig...
    Man _kann_ das durchaus auch anders coden, so dass _sofort_ auf nen Tastendruck reagiert wird, aber das ist etwas fortgeschrittener.
    Dann nutzt man einen Interrupt (der immer auch mitten in ner laufenden Routine ausgelöst werden kann).
    Vielleicht kommt da in deinem Buch noch was zu- da müssen einige Sachen beachtet werden, damits einwandfrei funktioniert.
    Es gibt da mehrere Möglichkeiten:
    -der Tastendruck wird _auch_ während der Lauflicht-Sequenz erkannt, aber die Reaktion erfolgt auch erst, wenn ein Durchlauf beendet ist
    -die Sequenz wird _sofort_ abgebrochen.
    Durch den Interrupt muss der Button nicht zyklisch abgefragt werden.
    Aber Interrupts haben auch kleinere Tücken- und das geht nicht an jedem Pin.

    int buttonStateOld = 0;

    Die "Null" bedeutet hier ja keine PIN-Zuweisung am Arduino. Hier können (ganzzahlige) Werte zwischen -32000 bis +32000 (gerundet, 16 bit???) stehen. So zumindest wird es in der Arduino-Sprache beschrieben. Allerdings verarbeitet der doch nur 8 bit, was genaugenommen nur 256 (0-255) Werten entspricht. Warum hier 16 bit-Werte möglich sind, ist mir auch (noch) unklar, ist aber ein anderes Thema.

    Es gibt nicht ohne Grund verschiedeneVariablentypen.Im Grunde legst du mit int() fest, wieviel Speicherplatz für die Variable reserviert werden soll.
    Eine Int belegt dann einfach mehrere Speicheradressen, da sie, wie du richtig erkannt hast, eben bei 8bit _nicht_ in eine Speicherstelle passt.
    Deshalb kann es irgendwann wichtig werden, das _richtig_ zu machen, denn grundsätzlich kann man auch alles als float() deklarieren (und dann nur für ein Bit, also ne bool nutzen, das geht), verschwendet dabei aber ne Menge Speicher, den man womöglich noch braucht.
    Umgedreht funktioniert es natürlich nicht: in eine bool() passt keine float() oder int().
    Ob Arduino tatsächlich mit Bool() arbeiten kann (also da tatsächlich nur ein Bit reserviert) , bin ich mir grade nicht ganz sicher, aber zumindest Byte() bringt richtig was, wenn man Speicher sparen will.
    Ein Byte passt in eine Speicherzelle, während Integer schon zwei belegen.
    Byte kann man z.B. prima für die ganzen Pindefinitionen benutzen, das reicht vom Wertebereich her sogar aufm Mega mit seinen >50 Pins mühelos.
    Richtige Speicherfresser sind Strings: pro Zeichen ein Byte.
    Wenn man viele Textausgaben hat, kann es lohnen, die mehrmals zu benutzen.

    Naja, allein zur Speicheroptimierung könnte man noch ne ganze Menge mehr erzählen..bei den kleinen Rechenknechten wird das schnell mal wichtig.

    Ach ja: dein Programm müsste auch dann stoppen, wenn du den Button länger gedrückt hälst- eben so lange, _bis_ er mal abgefragt wird.

    Ich will da aber deinem Buch jetzt nicht vorgreifen...da kommt sicher noch was, denn gerade bei Midi ist Schnelligkeit alles.
    Erfahrungsgemäss muss man unbedingt unter 5ms bleiben zwischen "Ereignis ausgelöst" und "Dinge werden getan", sonst hört man die Verzögerung deutlich.
    Das heisst, man braucht wirklich schnellen Code, da in der Latenz auch Dinge enthalten sind wie "noteOff", Kanal-oder Bankwechsel und anderes.
    Grüssle, Sly
    ..dem Inschenör ist nix zu schwör..

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Antworten: 0
    Letzter Beitrag: 29.01.2013, 20:33
  2. Bascom code auf Arduino Board Flashen **Hilfe**
    Von KoaxPilot im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 13
    Letzter Beitrag: 23.06.2011, 10:14
  3. Benötige Hilfe bei der CC2 auf RP5
    Von blade im Forum C-Control II
    Antworten: 28
    Letzter Beitrag: 19.03.2006, 18:02
  4. Hilfe: BASCOM Definition files?
    Von reiner im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 17.12.2005, 16:03
  5. benötige Hilfe bei meinem Code
    Von Reeper im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 09.12.2005, 16:36

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen