PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Hilfe bei einem Code Teil



littlekenny
29.03.2018, 13:18
Hallo zusammen,

vorweg, ich bin Anfänger was die Programmierung eines NodeMCU-Boards angeht!

Ich habe folgenden Code, welcher auch bereits super funktioniert!



#include <RCSwitch.h>

int led = 5; // LED pin (D1)
int button = 16; // push button is connected (D0)
int temp = 0; // temporary variable for reading the button pin status

RCSwitch mySwitch = RCSwitch();

void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT); // declare LED as output
pinMode(button, INPUT); // declare push button as input
mySwitch.enableTransmit(0); //Daten PIN D3 für das Sender Modul
// Optional set protocol (default is 1, will work for most outlets)
mySwitch.setProtocol(1);

// Optional set pulse length.
mySwitch.setPulseLength(759);
}

void loop() {
temp = digitalRead(button);

if (temp == LOW) {
digitalWrite(led, LOW);
Serial.println("bereit zum senden!");
delay(1000);
}
if (temp == HIGH) {
digitalWrite(led, HIGH);
/* Binärcode für die Klingel (433MHZ) */
mySwitch.send("010010010100000101000001");
Serial.println("Signal wurde gesendet");
delay(500);
}
}


Jetzt würde ich gerne wenn das Signal von einem zweiten Taster an einem anderen Pin gesendet wird, einen anderen Binärcode senden!

Hab also 2 Taster, welche jeweils einen anderen Binärcode senden sollen!

Hoffe ihr könnt mir helfen.

Vielen Dank.

Lieben Gruß, littlekenny

Siro
29.03.2018, 15:51
#include <RCSwitch.h>

int led = 5; // LED pin (D1)
int button_1 = 16; // push button is connected (D0)
int button_2 = 5; // müste wohl D1 sein ??? wo der button dran hängt hier den entsprechendn Wert eintragen
int temp = 0; // temporary variable for reading the button pin status


void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT); // declare LED as output
pinMode(button_1, INPUT); // declare push button as input ersten button
pinMode(button_2, INPUT); // declare push button as input zweiter button
mySwitch.enableTransmit(0); //Daten PIN D3 für das Sender Modul
// Optional set protocol (default is 1, will work for most outlets)
mySwitch.setProtocol(1);

// Optional set pulse length.
mySwitch.setPulseLength(759);
}


void loop() {

temp = digitalRead(button_1); // hier fragst Du den ersten Button ab, der Status landet in temp

if (temp == LOW) {
digitalWrite(led, LOW);
Serial.println("bereit zum senden!");
delay(1000);
} else // ansonsten kann er nur High sein
{
digitalWrite(led, HIGH);
/* Binärcode für die Klingel (433MHZ) */
mySwitch.send("010010010100000101000001");
Serial.println("Signal wurde gesendet");
delay(500);
}

temp = digitalRead(button_2); // hier fragst Du den zweiten Button ab, der Status landet wieder in temp

if (temp == LOW) {
digitalWrite(led, LOW);
Serial.println("bereit zum senden!");
delay(1000);
} else // ansonsten kann er nur High sein
{
digitalWrite(led, HIGH);
/* Binärcode für die Klingel (433MHZ) */
mySwitch.send("010010010100000101000001");
Serial.println("Signal wurde gesendet");
delay(500);
}

}


das ist nur ganz grob wie es sein könnte, aber nicht wirklich gut....

In deinem Programm sendet er eigentlich IMMER, weil ja der Button entweder high oder low ist.
Eigentlich gibt es ja nur Sinn zu senden wenn der Button gedrückt wird und dann auch nur einmal.
Man sollte also dann nix mehr tun, bis der Button wieder losgelassen wurde.
Und dann noch nen Moment warten, weit die Tasten meistens Prellen (mehrfach Auslösung) während der Kontakt
schließt oder sich öffnet.

littlekenny
29.03.2018, 16:48
Vielen Dank für deine Hilfe. Probiere es nachher mal aus.

Wie könnte es denn besser aussehen? Bin leider nicht so fit im Programmieren!

Vielen Dank.

Lieben Gruß, littlekenny

Siro
29.03.2018, 21:38
Hallo littlekenny,

Viele Wege führen zum Ziel, deshalb hier mal eine Möglichkeit:

Pseudocode:

wenn Taste gedrückt ist dann
Zaehler = Zahler +1 ansonsten Zaehler = 0
wenn Zaehler = 20 dann Aktion ausführen

Das Programm prüft also ob die Taste gedrückt ist
wenn ja, wird ein Zaehler hochgezählt,
wenn nicht, dann wird der Zaehler auf 0 gesetzt.
Wenn der Zaehlerstand einen bestimmten Wert erreicht, dann soll etwas ausgelöst werden,
aber nur einmal. Zum Beispiel das Senden
Wenn die Taste weiter gedrückt gehalten wird, zaehlt der Zaehler immer weiter hoch,
aber es wird nichts mehr ausgeführt.

Jetzt kommt das Problem: diese kleinen Prozessoren sind "sau schnell"
der Zaehler wird vermutlich hundertausende Male hochzählen bis Du die Taste
wieder losgelassen hast. Das wäre kein Problem, dann muss man halt der Abfragewert entsprechend hoch setzen, das ist aber eine schlechte Lösung.

Eleganter machen wir das jetzt so.

Wir packen in unsere Hauptschliefe eine Verzögerung von z.B "einer" Millisekunde
Nun wissen wir, das der Zaehler maximal jede Millisekunde hochlaufen kann.
Somit haben wir eine recht präzisen Wert für die Abfrage.
Das Prellen einer Taste, wo der Schaltkontakt grade schließt dauert so 20ms (bei schlechten Tasten)
Also ist unser Abfragewert mit 20 recht gut gewählt.
Wir müssen nun mindestens die Taste 20ms gedrückt halten, bis etwas ausgelöst wird.

Im Code würde das nun so aussehen.


int button_1;
int button_2;
int zaehler_b1;
int zaehler_b2;
int status;

void loop(void)
{

status = digitalRead(button_1);
if (status == 0) // wenn Taste gedrückt ist (pin ist low)
{
zaehler_b1++; // eins hochzaehlen
if (zaehler_b1 == 20) // wurde die Taste mindestens 20ms gedrückt dann
{
// senden
}
} else zaehler_b1 = 0; // Taste wurde losgelassen, also zaehler auf 0 setzen

status = digitalRead(button_2);
if (status == 0) // wenn Taste gedrückt ist (pin ist low)
{
zaehler_b2++;
if (zaehler_b2 == 20) // wurde die Taste mindestens 20ms gedrückt dann
{
// senden
}
} else zaehler_b2 = 0; // Taste wurde losgelassen, also zaehler auf 0 setzen

delay(1); // nur 1 Millisekunde warten

}

littlekenny
29.03.2018, 22:28
Vielen Dank.

Hat perfekt gepasst!

Im ganzen sieht es jetzt so aus.


#include <RCSwitch.h>

int led = 5; // LED pin (D1)
int button_1 = 16; // Push Button 1 ist an Pin (D0)
int button_2 = 13; // Push Button 2 ist an Pin (D7)
int zaehler_b1;
int zaehler_b2;
int status;

RCSwitch mySwitch = RCSwitch();

void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT); // LED als Ausgang deklarieren
pinMode(button_1, INPUT); // Button 1 als Eingangssignal deklarieren
pinMode(button_2, INPUT); // Button 2 als Eingangssignal deklarieren
mySwitch.enableTransmit(0); //Daten PIN D3 für das Sender Modul
// Optional Protokol (Standart ist 1)
mySwitch.setProtocol(1);

// Optional - Impulslänge festlegen.
mySwitch.setPulseLength(759);
}

void loop(void)
{

status = digitalRead(button_1);
if (status == 0) // wenn Taste gedrückt ist (pin ist low)
{
zaehler_b1++; // eins hochzaehlen
if (zaehler_b1 == 20) // wurde die Taste mindestens 20ms gedrückt dann
{
/*Status LED geht an*/
digitalWrite(led, HIGH);
/* Binärcode für die Klingel wird gesendet(433MHZ) */
mySwitch.send("000000000");
Serial.println("Signal 1 wurde gesendet");
/*Status LED geht wieder aus*/
digitalWrite(led, LOW);
}
} else zaehler_b1 = 0; // Taste wurde losgelassen, also zaehler auf 0 setzen

status = digitalRead(button_2);
if (status == 0) // wenn Taste gedrückt ist (pin ist low)
{
zaehler_b2++;
if (zaehler_b2 == 20) // wurde die Taste mindestens 20ms gedrückt dann
{
/*Status LED geht an*/
digitalWrite(led, HIGH);
/* Binärcode für die Klingel (433MHZ) */
mySwitch.send("000000000");
Serial.println("Signal 2 wurde gesendet");
/*Status LED geht wieder aus*/
digitalWrite(led, LOW);
}
} else zaehler_b2 = 0; // Taste wurde losgelassen, also zaehler auf 0 setzen

delay(1); // nur 1 Millisekunde warten

}

Gruß, littlekenny

littlekenny
11.04.2018, 09:36
Hallo zusammen,

habe hier doch noch ein kleines Problem....

Wenn der Button zu lang gedrückt wird, durchläuft es die gesamte Schleife und sendet beide Signale gleichzeit, obwohl der Button 2 nicht gerückt wird!?

Hier nochmal der Code:


#include <RCSwitch.h>

int led = 5; // LED pin (D1)
int button_1 = 15; // Push Button 1 ist an Pin (D8)
int button_2 = 13; // Push Button 2 ist an Pin (D7)
int zaehler_b1;
int zaehler_b2;
int status;

RCSwitch mySwitch = RCSwitch();

void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT); // LED als Ausgang deklarieren
pinMode(button_1, INPUT); // Button 1 als Eingangssignal deklarieren
pinMode(button_2, INPUT); // Button 2 als Eingangssignal deklarieren
mySwitch.enableTransmit(0); //Daten PIN D3 für das Sender Modul
// Optional Protokol (Standart ist 1)
mySwitch.setProtocol(1);

// Optional - Impulslänge festlegen.
mySwitch.setPulseLength(759);
}

void loop(void)
{

status = digitalRead(button_1);
if (status == 0) // wenn Taste gedrückt ist (pin ist low)
{
zaehler_b1++; // eins hochzaehlen
if (zaehler_b1 == 20) // wurde die Taste mindestens 20ms gedrückt dann
{
/*Status LED geht an*/
digitalWrite(led, HIGH);
/* Binärcode für die Klingel wird gesendet(433MHZ) */
mySwitch.send("000000000");
Serial.println("Signal 1 wurde gesendet");
/*Status LED geht wieder aus*/
digitalWrite(led, LOW);
}
} else zaehler_b1 = 0; // Taste wurde losgelassen, also zaehler auf 0 setzen

status = digitalRead(button_2);
if (status == 0) // wenn Taste gedrückt ist (pin ist low)
{
zaehler_b2++;
if (zaehler_b2 == 20) // wurde die Taste mindestens 20ms gedrückt dann
{
/*Status LED geht an*/
digitalWrite(led, HIGH);
/* Binärcode für die Klingel (433MHZ) */
mySwitch.send("000000000");
Serial.println("Signal 2 wurde gesendet");
/*Status LED geht wieder aus*/
digitalWrite(led, LOW);
}
} else zaehler_b2 = 0; // Taste wurde losgelassen, also zaehler auf 0 setzen

delay(1); // nur 1 Millisekunde warten

}


Vielen Dank für eure Hilfe

littlekenny
11.04.2018, 12:06
Hallo zusammen,

habe es jetzt soweit, dass er sie separat sendet.

Allerdings, wenn ich jetzt den Button 2 drücke, sendet er den code für Button 2 immer weiter...Bei Button 1 geht es ohne Probleme!



/*
Example for different sending methods

https://github.com/sui77/rc-switch/

*/

#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

int ledPin = 5; // choose the pin for the LED
int inPin1 = 15; // choose the input pin (for a pushbutton)
int inPin2 = 13;
int status_1 = 0; // variable for reading the pin status
int status_2 = 0;


void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // declare LED as output
pinMode(inPin1, INPUT); // declare pushbutton as input
pinMode(inPin2, INPUT); //declare pushbutton 2 as input
mySwitch.enableTransmit(0);

// Optional set protocol (default is 1, will work for most outlets)
mySwitch.setProtocol(1);

// Optional set pulse length.
mySwitch.setPulseLength(759);
}

void loop(){

status_1 = digitalRead(inPin1); // read input value
if (status_1 == HIGH) { // check if the input is HIGH (button released)
digitalWrite(ledPin, HIGH); // turn LED ON
/* Same switch as above, but using binary code */
/*mySwitch.send("010010010100000101000001");*/
Serial.println("Signal 1 wurde gesendet");
delay(1000);
digitalWrite(ledPin, LOW);
} else {

status_2 = digitalRead(inPin2); // read input value
if (status_2 == HIGH) { // check if the input is HIGH (button released)
digitalWrite(ledPin, HIGH); // turn LED ON
/* Same switch as above, but using binary code */
/*mySwitch.send("010010010100000101000001");*/
Serial.println("Signal 2 wurde gesendet");
delay(1000);
digitalWrite(ledPin, LOW);
}
}
}


Vielen Dank.

Siro
11.04.2018, 15:11
Hallo littlekenny,

Ich beziehe mich mal auf "meinen" Code: und gehe davon aus, dass dein Integer bei der CPU 16 Bit ist,
dann passt da maximal der Wert 65535 in dei Zählvariable rein.
Wenn der Zähler tatsächlich überlaufen sollte, bei einem Schleifendurchlauf von 1 Millisekunde
dann wären das 65535 / 1000 = 65,535 Sekunden.
Du müstest also die Taste eine Minute lang drücken bis der Zähler überlaufen würde und dann würde tatsächlich
auch eine neue Message gesendet werden.

Die Wahrscheinlichkeit ist eher gering.
Was ich mir aber vorstellen kann und auch schon erlebt habe ist:
das dass delay(1) nicht funktioniert und nur ein paar Mikrosekunden gewartet wird.
Daher wäre mein erste Gedanke, mach mal aus delay(1) ein delay(2) oder delay(5) und probiere meinen Code nochmal aus.
Alles andere kannst Du ruhig so lassen, das tut keinem weh.

Zudem kann er NIEMALS einen Tastecode senden, wenn diese nicht gedrückt ist.
Demnach wäre hier die Ursache zu suchen, warum er da überhaupt rein kommt.
Das würde nämlich bedeuten, dass deine Abfrage
status = digitalRead(button_2);
nicht richtig funktioniert und oder der Pin irgendwie Störungen drauf hat.
Evenetuell wird hier auch noch ein sogenannter Pullup an dem Pin benötigt. (Widerstand nach Plus)

Probier mal bitte nochmal den ersten Code lediglich mit der veränderten Delayzeit von 2 oder 5
Wenn er tatsächlich einen ButtonCode sendet obwohl die entsprechende Taste nicht gedückt ist,
dann muss geklärt werden woher das kommt.

Deine neueren Codes weiter unten leuchten mir nicht ein,
da Du sendest wenn die Taste nicht gedrückt ist. (button released) ????
Zudem sind da andere ungereimtheiten, die ich jetzt nicht weiter erläutern will.

Siro

ich habe grad noch etwas gefunden wegen dem Widerstand nach Plus (Pullup):
mach mal aus deinem

pinMode(inPin1, INPUT);
pinMode(inPin2, INPUT);

pinMode(inPin1, INPUT_PULLUP);
pinMode(inPin2, INPUT_PULLUP);

littlekenny
11.04.2018, 16:06
Hallo Siro,

vielen Dank.

Hatte auch bisher deinen Code in Nutzung und hat auch sehr gut geklappt.
Musste allerdings mein NodeMCU ESP Modul austauschen, da ich das schmale für ein anderes Projekt benötigte.

Das jetzt eingesetzte ist etwas breiter aber von der PIN Belegung her das selbe!

Hatte auch schon versucht andere PIN Belegungen zu verwenden, aber dies hatte leider auch nicht geklappt.
Werde es heute Abend nochmal mit deinen Vorschlägen ausprobieren und testen.

Vielen Dank.

littlekenny
12.04.2018, 00:02
Vielen Dank nochmal Siro,

die Kombination mit:

pinMode(inPin1, INPUT_PULLUP);
pinMode(inPin2, INPUT_PULLUP);

sowie einem Widerstand brachte dann die Lösung und es läuft wieder super!

33414
33415