GPIO-Steuerung mit Blynk

  • Hallo Zusammen,

    ich versuche gerade, meinen Raspberry Pi 3 B+ über das Handy zu steuern

    Ich habe dazu die App Blynk gefunden, und muss sagen, es ist wirklich ein Kinderspiel, die GPIO-Pins mit der App zu steuern

    Wenn es aber in die umgekehrte Richtung geht, habe ich Probleme

    Ich schaffe es nicht, dass in Blynk eine LED leuchtet, wenn ich am Breadboard einen Button drücke :no_sad:

    Ich habe schon Stunden damit verbracht, eine Lösung aus Dr. Google rauszulocken, aber da wird sehr oft eine Arduino-Steuerung oder ähnliches damit betrieben

    Und dann hätte ich sie endlich gefunden: die perfekte Schritt-für-Schritt Anleitung

    https://www.bc-robotics.com/tutorials/gett…/#comment-90538

    Aber aus irgendeinen Grund funktioniert es bei mir nicht :wallbash:

    Wenn ich den Button in Blynk drücke, leuchtet die LED am Breadboard (so wie es auch sein soll), wenn ich aber den Button am Breadboard drücke, passiert nichts

    Ich hätte aber alles von Anfang an laut Turtorial durchgearbeitet und habe auch in main.cpp genau die Dinge geändert, die im Turtorial markiert sind.....

    Und mir ist mittlerweile folgendes aufgefallen:

    1) Ich starte das Blynk-Programm

    2) Ich gebe im Terminal vom Pi folgendes ein:

    2a) cd /home/pi/blynk-library/linux

    2b) ./build.sh raspberry

    2c) sudo ./blynk --token=MeinAuthenifizierungsCode

    3) Die LED in Blynk leuchtet nicht, wenn ich den Button am Breadboard drücke, sie bleibt dunkel

    4) Wenn ich aber eine Zeit lang warte, fällt auf, dass die LED ganz langsam von alleine immer heller und heller wird (auch wenn ich garnichts gemacht habe nach dem Start)

    5) Nach ca. 3-4 Minuten leuchtet sie ganz hell, bis sie schließlich wieder erlischt

    Weiß jemand, was ich da falsch gemacht habe? :helpnew:

    PS: Ich habe einen Raspberry Pi 3 B+, wo Raspbian Buster (2019-07-10) läuft

    Danke schonmal und

    Lg Fux22

  • > 3) Die LED in Blynk leuchtet nicht, wenn ich den Button am Breadboard drücke, sie bleibt dunkel

    > 4) Wenn ich aber eine Zeit lang warte, fällt auf, dass die LED ganz langsam von alleine immer heller

    > und heller wird (auch wenn ich garnichts gemacht habe nach dem Start)

    > 5) Nach ca. 3-4 Minuten leuchtet sie ganz hell, bis sie schließlich wieder erlischt

    Ich wuerde es mal mit einem richtigen Pullup probieren. Das toent wie wenn der Engangspegel nicht sauber waere.

    Was passiert wenn der Button durch einen Jumper ersetzt wird der mal mit 3.3V und mal mit GND verbunden ist?

  • Danke für deine Antwort

    Ich habe gestern Raspbian Buster neu installiert, um mögliche Fehler auszuschließen, die ich vl. vor der Blynk-Installation gemacht habe...

    Ich habe die Schritt-für-Schritt Anleitung nochmal abgearbeitet

    Die pullUpDnControl habe ich diesmal weggelassen und habe am Breadboard vor dem Button einen PullUp-Widerstand gehängt. Die LED in Blynk leuchtet aber trotzdem nicht, wenn ich den Button am Breadboard drücke (sie wird aber wieder mit der Zeit immer heller)

    Und auch wenn ich den GPIO17 direkt an 3V3 oder an Ground hänge, ändert sich nichts daran...

    Ich habe jetzt mal alles von Schritt 17 und 18 der Anleitung auskommentiert

    Die LED in Blynk wird aber trotzdem langsam immer heller

    Keine Ahnung, wiso das so ist...

    Ich wäre über jede weitere Hilfe sehr dankbar :helpnew:

    Danke und Lg

    Fux22

  • tut mir leid, dass ich mich erst jetzt zurückmelde, hatte nicht viel Zeit letzte Woche....

    Ich habe ein anderes Turtorial gefunden, mit dem ich es hin bekommen habe (den Reed-Schalter habe ich durch einen Button ersetzt):

    https://de.tipsandtrics.com/getting-started-with-blynk-768324

    Es sind aber 2 kleine Fehler in der Anleitung:

    1)

    Code
    sudo npm install -g onoff

    funktioniert nicht mit sudo -> weg lassen, dann passt's

    2)

    Code
    var blynklib = require('/usr/local/lib/node_modules/blynk-library');

    ist das falsche Verzeichnis, die Blynk-Library befindet sich unter /usr/lib/node_modules/blynk-library -> ändern, dann passt's

    Zumindest unter Raspbian Buster....

    Ein Problem habe ich aber noch:

    Wenn der Button am Breadboard gedrückt wird, bekomme ich eine Nachricht aufs Handy

    Ich möchte aber, dass ich nur dann eine Nachricht bekomme, wenn der Button eine gewisse Zeit lang gedrückt wird (z.B. 3 Sekunden)

    Meine Idee war, die Zeit mit new Date().getTime() zu messen

    So wird aber die Zeit wiedergegeben, die seit dem 01.01.1970 vergangen ist (in ms)

    Kann man diese "Stoppuhr" irgendwie auf 0 stellen?

    In den Beispielen, die ich im Internet fand, wurde immer eine Start- und Endzeit verwendet -> Endzeit - Startzeit = Zeit die Vergangen ist, um alle Befehle zwischen der Messung abzuarbeiten

    Ich möchte die Zeit aber nicht messen, ich will nach genau 3 Sekunden eine Nachricht verschicken

    Ich habe auch schon probiert, mit if-else-Schleifen bzw. mit for-Schleifen zu arbeiten:

    Wenn ich den Button drücke, werden mit einer for-Schleife 107 Schritte gezählt, dann wird die Nachricht versendet (dauert ca. 2 Sekunden bei mir...)

    So kommt man aber nur über Umwege zu einer zeitverzögerten Nachricht (was ist, wenn ich aber nach 1:27 Minuten eine Antwort verschicken möchte?)

    Und wenn ich den Button vor Ablauf der Zeit wieder auslasse, müsste das Programm ja sofort aus dem else-Zweig aussteigen, ich bekomme aber trotzdem eine Nachricht...

    Hat jemand eine Idee, wie ich das lösen kann?

    Danke und Lg

    Fux22

  • Kann man diese "Stoppuhr" irgendwie auf 0 stellen?

    Nein, warum auch?

    Lies die aktuelle Zeit und addiere die Wartezeit dazu (-> Endezeit). Anschliessend vergleichst du, ob die aktuelle Zeit grösser oder gleich der Endezeit ist.

    Glaube ersetzt kein Wissen

  • Hat jemand eine Idee, wie ich das lösen kann?

    Du hast eine Schleife, die solange durchlaufen wird, wie zwei Bedingungen erfüllt sind:

    1. Die aktuelle Zeit ist kleiner (oder gleich) dem Zeitpunkt, wenn das Ende der Wartezeit erreicht ist.

    2. Der Taster muss gedrückt sein.

    Ob du nun zwei Variablen verwendest und deren Zustand in der Schleife ermittelst oder das direkt in den Schleifenbedingen schreibst, bleibt dir überlassen.

    Wenn du wissen willst wie man eine Schleife vorzeigt verlässt.

    Glaube ersetzt kein Wissen

  • Danke für deine Antwort(en)

    Ok, ich lese die aktuelle Zeit:

    startzeit = new Date().getTime();

    Addiere die Wartezeit (in ms)

    endzeit = startzeit + 3000;

    aber ich kann nicht "if (startzeit > endzeit) { ...... }" eingeben, das wird ja nie erfüllt

    Darum habe ich vorhin ja gefragt, ob man Date().getTime() auch von 0 anfangen lassen kann, dann brauche ich nur if (startzeit > 3000).....

    Zitat von bombom

    Wenn du wissen willst wie man eine Schleife vorzeigt verlässt.

    Ich weiß, dass das für viele so aussieht, als ob ich zu faul zum selber suchen bin, aber ich habe in den letzten 2 Tagen etliche Stunden lang versucht, selbst eine Lösung zu finden....

    Und ja, ich weiß, dass man mit break eine Schleife unterbrechen kann

    if(Bedingung) { break; }

    else { ......}

    , aber da bekomme ich immer einen SyntaxError: Illegal break statement....

    Ich weiß, dass das Thema eigendlich nicht wirklich kompliziert für dich/euch ist, da ihr euch hier mit viel komplizierteren Fragen rumschlagt, ich währe aber td. über jede weitere Hilfe dankbar :helpnew:

  • Du musst in der Schleife die Zeit (und auch den Zustand des Tasters) immer wieder abfragen.

    Code
    while (aktuelle_Zeit < Ende_Zeit) && Bedingung2
        aktuelle_Zeit = zeit.auslesen
        ist.der.Taster.gedrückt(Bedingung2)

    Wenn Bedingung2 eine boolsche Variablen sind, also entweder true oder false, dann reicht deren Nennung.

    Vorsicht! Durch die Schleife erzeugst du eine hohe CPU-Last, die du für den Anfang ignorieren kannst. Später solltest du dir etwas einfallen lassen.


    edit: Es gibt in C zwei Arten von Schleifen:

    for (i=0 ; i <10 ; i++)

    while (aktuelle_Zeit < End_Zeit)

    Und IF gehört nicht zu den Schleifen, sondern ist eine einfache Abfrage

    Glaube ersetzt kein Wissen

    3 Mal editiert, zuletzt von bombom (1. Oktober 2019 um 11:59)

  • Vielen vielen dank für die Info, damit erklährt sich so einiges :thumbup::danke_ATDE:

    Irgendwas mache ich aber immer noch falsch :wallbash:

    Wenn ich den Button drücke (Value == 1), wird 3 Sekunden gewartet, bis der Text ins Terninal geschrieben wird. Das passt so auch :thumbup:

    Wenn ich aber z.B. nach 1 Sekunde den Button auslasse, wird trotzdem gewartet, bis die Zeit vollständig abgelaufen ist, und dann werden beide Texte ins Terminal geschrieben (= "Wartezeit ist abgelaufen" und "geschlossen")

    Warum wird die Schleife nicht sofort unterbrochen, wenn der Value 0 wird?

    Und warum wird dann ("Wartezeit ist abgelaufen") auch ins Terminal geschrieben? :conf:

    Danke schonmal und Lg

    Fux22

  • Müsste nicht innerhalb der "Zeitschleife" der Status des Button abgefragt werden? Sonst läuft die Schleife doch einfach durch. :conf:

    Genau. :thumbup:

    Irgendwas mache ich aber immer noch falsch :wallbash:

    Ersten es fehlt, wie bereits von hyle angemerkt, die Abfrage des Zustands des Tasters.

    Zweitens kannst du dir die zwei IF-Abfragen in der Schleife sparen, denn die Schleife fragt dies schon ab.

    Drittens die Auswertung warum die Schleife beendet wurde erfolgt nach der Schleife (dieser Punkt scheint trivial zu sein, aber ...), indem du beide Abbruchbedinungen noch einmal abfragst und entsprechend reagierst.

    Viertens, wenn du eine IF-ElseIF-Else-Abfrage machst, dann verwende noch ein abschliessendes "else" um alle andere Sachen abzufangen.

    Fünftens, wo kommt der Wert für "value" her?

    Sechstens, while ((startzeit < endzeit) && value == 1) hier fehlt die Klammer um (value == 1)

    Siebtens, was ist "value"? Verwende eindeutige Namen für Variablen, z.B. Taster oder Tasterzustand

    Achtens, boolsche Variablen muss man nicht mit "0" oder "1" vergleichen. Sie sind sowieso nur "true" oder "false"

    Neuntens, wieso ist in Zeile 6 eine schliessende Klammer

    Sorry für die vielen "edit", mir fällt das nicht immer gleich auf

    Glaube ersetzt kein Wissen

    5 Mal editiert, zuletzt von bombom (2. Oktober 2019 um 12:35)

  • Code
    if (value == 0)
    {
        console.log("geschlossen");
    }
    if (value == 1)
    }

    Sollte die Klammer unter if (value == 1) nicht anders herum sein ?

    Offizieller Schmier und Schmutzfink des Forum.
    Warum einfach wenn's auch schwer geht ?

    Kein Support per PN !
    Fragen bitte hier im Forum stellen. So hat jeder etwas davon.

  • Ok, hier mal mein gesamter Code (mit den neuen Änderungen):

    Der Status vom Button = value, somit brauche ich keine weitere Abfrage für den Button da ja schon der Value abgefragt wird, oder?

    Zitat von bombom

    Drittens die Auswertung warum die Schleife beendet wurde erfolgt nach der Schleife (dieser Punkt scheint trivial zu sein, aber ...), indem du beide Abbruchbedinungen noch einmal abfragst und entsprechend reagierst.

    Wie meinst du das?

    Ich kann ja nicht nach der while-Schleife die if-Abfrage mit break schreiben....:conf:

    Zitat von Der_Imperator

    Sollte die Klammer unter if (value == 1) nicht anders herum sein ?

    Ja, tut mir leid, habe ich i.wie falsch rein kopiert :blush:

  • Der Status vom Button = value, somit brauche ich keine weitere Abfrage für den Button da ja schon der Value abgefragt wird, oder?

    Eigentlich müsste dir der Compiler mindestens eine Warning geben.

    Ich sehe nirgends, dass du die Variable "value" definiert hast.

    Eine Abfrage in der Schleife zu haben die genau das abfragt, ist redundant und somit fehleranfällig.

    Da die Schleife mit zwei Bedingungen beendet werden kann, ist es sinnvoll danach zu unterscheiden welche Bedingung erfüllt bzw. nicht erfüllt war. Bei dir, war es die Taste oder die Zeit. Du willst ja entsprechend darauf reagieren können. Schreib deine if-elseif-else nach der Schleife, etwa so in der Art:

    Code
    if !value
        print ("Taster losgelassen")
    else if (startzeit >= endezeit)
        print ("Zeit abgelaufen)
    else
        print ("Ein schwerer Fehler ist aufgetreten!")
    
    # Formatierung und Syntax entsprechend ergänzen

    Wenn die Variable "value" boolsch ist, dann brauchst du keine Klammer. Es war in der Version vorher eben so, dass dort eine Klammer notwendig war (value == 1).

    Ist es eine Vorgabe, das mit Interrupts zu machen? Und wie sieht die ISR aus?

    Glaube ersetzt kein Wissen

  • Ich habe auf meinem RPi Node.js installiert, das wird von onoff unterstützt

    button.watch(function(err, value) .....) ist so deffiniert

    watch(callback)
    • callback - A callback that gets two arguments (err, value), where err is reserved for an error object and value is the number 0 or 1 and represents the state of the GPIO. The value can also be used to determine whether the interrupt occurred on a rising or falling edge. A value of 0 implies a falling edge interrupt and a value of 1 implies a rising edge interrupt.

    Der Button übergibt so seinen Wert (1 oder 0) also an den Value

    Hier noch der Link zum oberen Zitat: https://github.com/fivdi/onoff


    Ok, ich werde die if-elseif-else Abfrage bei Gelegenheit aus der Schleife auslagern (vl finde ich heute noch Zeit dazu, sonst morgen.....), und melde mich dann nochmal mit dem Ergebnis :thumbup:

    • Offizieller Beitrag

    Der Status vom Button = value, somit brauche ich keine weitere Abfrage für den Button da ja schon der Value abgefragt wird, oder?

    Außerhalb der Schleife (bis zum Ende der Funktion) mag das stimmen, aber da die Schleife quasi in sich geschlossen ist, gilt imho in der Schleife der Wert zu Zeitpunkt des Startes. Das Programm / der Code läuft von oben nach unten durch.

    In dieser Abfolge "weiß" die Variable value nichts von einer steigenden oder fallenden Flanke. Wenn ihr der aktuelle Status nicht bei jedem Durchlauf der Schleife mitgeteil wird, dann bleibt die wie die ist.


    Davon mal abgesehen würde ich das in 2 Funktionen machen.

    Die erste Funktion existiert ja bereits mit button.watch(function(err, value), die Dir den aktuellen Status (value) des Button ausgibt.

    In der zweiten Funktion würde ich die Verarbeitung erledigen und in dieser die erste Funktion abgefragen.

  • button.watch(function(err, value) .....) ist so deffiniert

    Entschuldigung, ich war da oben etwas in Eile und hatte button.watch(function(err, value) komplett übersehen.

    Es spiel hier nicht sooo die Rolle, da der Code noch übersichtlich ist, verwende besser selbst erklärende Variablen-Namen. Hier z.B. wäre es besser anstatt von value so etwas wie button zu schreiben. Das Beispiel das mir gerade einfällt, ist ein Haus mit zwei Wohnungen und du sollst die Taster der Klingel abfragen. Das sind vier Taster, 2 an der Haustür und je einer an den beiden Wohnungstüren. Da kommst du mit value_1 nicht sehr weit. Besser wäre hier Haustuer_oben oder Wohnungstuer_unten. Du kannst das natürlich auch abkürzen HT_o WT_u. Du wirst verstehen was ich meine.

    Glaube ersetzt kein Wissen

  • In dieser Abfolge "weiß" die Variable value nichts von einer steigenden oder fallenden Flanke. Wenn ihr der aktuelle Status nicht bei jedem Durchlauf der Schleife mitgeteil wird, dann bleibt die wie die ist.

    hyle die Interrupts laufen ja asynchron ein und ändern den Wert von value in der ISR im Hintergrund.

    Glaube ersetzt kein Wissen

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!