ich bin neu auf den Gebiet.
Durch Google und mehrere Einräge habe ich schonmal einen passenden Teil gefunden, der je Taster Eingang einen Ausgang steuert.
Jetzt habe ich aber noch folgende Thematik.
Taster steuert 1 Relais - erledigt
Taster steuert x Relais - open
Taster per kurz druck - open
Taster doppelt oder länger steuer Relais - open
Am Ende müsste ich noch einen Eingang haben, der sozusagen alles ausschaltet, wenn x bestimmte Relais an sindt oder eben x bestimmte Relais anschaltet wenn alle aus sind.
Nun habe ich mehrere Einträge gefunden, wie man das einzeln abbildet aber ich steig nicht dahinter, wie man das kombiniert.
#include <Adafruit_NeoPixel.h>
#define maxTaster 4
constexpr byte taster[maxTaster] {A0, A1, A2, A3};
constexpr byte led[maxTaster] {2, 3, 4, 5};
constexpr uint32_t Entprellzeit {15}; //Entprellzeit für den Taster in ms
bool lastState[maxTaster] = {false};
uint32_t bounceStart[maxTaster];
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
Serial.println();
Serial.println();
for (byte b = 0; b < maxTaster; b++) {
printArrayErklaerung(b);
pinMode(taster[b], INPUT_PULLUP);
digitalWrite(led[b], LOW);
pinMode(led[b], OUTPUT);
digitalWrite(led[b], HIGH);
}
}
void loop() {
for (byte b = 0; b < maxTaster; b++) // frage alles ab
{
if (!digitalRead(taster[b])) // Taste gedrückt?
{
if (!lastState[b]) // vorher nicht gedrückt?
{
lastState[b] = true; // merken, das gedrückt
bounceStart[b] = millis(); // merken, wann ausgelöst
digitalWrite(led[b], !digitalRead(led[b])); // PIN toggeln
}
}
else if (millis() - bounceStart[b] > Entprellzeit)// Taste losgelassen UND BounceTime abgelaufen
{
lastState[b] = false;
}
}
}
Das wichtigste ist vor dem Code eine eindeutige Beschreibung. Ich werde aus dem oben geschriebenem nicht schlau. Bitte noch einmal beschreiben: was soll wann passieren?
Das State-Diagram gibt einen Überblick was es alles in der Library gibt - und ist ein gutes Beispiel warum man ein State-Diagram zeichnen soll. Wäre auch für deine Programm Logik eine Empfehlung.
das liegt wohl eher an deinen Aktionen - die sollen sich nicht gegenseitig blockieren.
Die OneButton wertet die Buttons - nicht blockierend - aus.
Ich weiß nicht, was du kannst.
Aber ja, man kann Dinge (quasi) nebeneinander laufen lassen.
Große Teile des Forums beschäftigen sich mit genau sowas. (ca. 3 mal täglich)
Ich möchte noch einen Schritt weiter gehen!
Klare Gedanken und klare Logik führen zu klaren und widerspruchsfreien Ablauf- und Statusdiagrammen.
Klare und widerspruchsfreie Beziehungs-, Datenfluss-, Ablauf- und Statusdiagramme kann man 1:1 in klare und übersichtliche Programme überführen.
Diese funktionieren dann auch.
Das fertige Programm ist dann ein Abbild des Geistes, der Denkweise, des Programmierers.
// 05.05.2023 created by Ihor Nehrutsa
#include "OneButton.h"
#define PIN_INPUT A0
#define PIN_INPUT_2 A1
const byte RELAY1_PIN = 2;
const byte RELAY2_PIN = 3;
int relaystate = 0;
int relaystate1 = 0;
// Setup a new OneButton on pin PIN_INPUT
// The 2. parameter activeLOW is true, because external wiring sets the button to LOW when pressed.
OneButton button(PIN_INPUT, true);
OneButton button2(PIN_INPUT_2, true);
// In case the momentary button puts the input to HIGH when pressed:
// The 2. parameter activeLOW is false when the external wiring sets the button to HIGH when pressed.
// The 3. parameter can be used to disable the PullUp .
// OneButton button(PIN_INPUT, false, false);
// setup code here, to run once:
void setup()
{
Serial.begin(115200);
Serial.println("\nOneButton Example.");
Serial.println("Please press and hold the button for a few seconds.");
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
// link functions to be called on events.
button.attachLongPressStart(LongPressStart, &button);
button.attachDuringLongPress(DuringLongPress, &button);
button.attachLongPressStop(LongPressStop, &button);
button2.attachClick(Click, &button);
button2.attachLongPressStart(LongPressStart2, &button);
button.setLongPressIntervalMs(1000);
} // setup
// main code here, to run repeatedly:
void loop()
{
// keep watching the push button:
button.tick();
button2.tick();
// You can implement other code in here or just wait a while
delay(10);
} // loop
// this function will be called when the button started long pressed.
void Click(void *oneButton)
{
Serial.println("\t - Click button 2()");
relaystate1 = digitalRead(RELAY2_PIN);
if (relaystate1 == LOW) {
digitalWrite(RELAY2_PIN, HIGH);
}
else {
digitalWrite(RELAY2_PIN, LOW);
}
}
void LongPressStart2(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - LongPressStart(2)");
relaystate = digitalRead(RELAY1_PIN);
relaystate1 = digitalRead(RELAY2_PIN);
if (relaystate == LOW & relaystate1 == LOW) {
digitalWrite(RELAY1_PIN, HIGH);
digitalWrite(RELAY2_PIN, HIGH);
}
else {
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
}
}
void LongPressStart(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - LongPressStart()");
relaystate = digitalRead(RELAY1_PIN);
if (relaystate == LOW) {
digitalWrite(RELAY1_PIN, HIGH);
}
else {
digitalWrite(RELAY1_PIN, LOW);
}
}
// this function will be called when the button is released.
void LongPressStop(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - LongPressStop()\n");
}
// this function will be called when the button is held down.
void DuringLongPress(void *oneButton)
{
Serial.print(((OneButton *)oneButton)->getPressedMs());
Serial.println("\t - DuringLongPress()");
}
// End
Würdet ihr jetzt einfach die Taster erweitern oder gibt es da nen schöneren Weg? Brauche bei meinem Nano aktl schon 23% speicher auf und muss ja auf 8 Taster & Relais kommen.
Nein das geht dann nicht. Bevor man mit dem Programmieren beginnt sollte man erst einmal eine genaue Spezifikation haben was das Programm wann machen soll.
if (digitalRead(buttinoin[0]) == LOW) {
digitalWrite(relayPin[0], HIGH);
if (manchmal == true)
digitalWrite(relayPin[1], HIGH);
}
also wie schon @wwerner geschrieben hat - definiere die genaue Logik / Zustandsverhalten
edit:
vieleicht machst noch mal einen aktualisierten Post von deinem Beitrag #4 sodass er auch stimmt.
Weil hast du jetzt 8 Taster oder 10?
Taster 11 genauer beschreiben ob der nun 4 oder 8 Relais schaltet
Funktion 3
was meinst du genau mit "teilweise". Es gibt keinen c++ Befehl "teilweise". Das musst schon ganz genau beschreiben.