ich habe vor einige externe Schalter und Buttons für ein Projekt zu verwenden.
Nun habe ich schon ein Script geschrieben. Mit diesem kann ich schon wunderbar die Buttons benutzen (erledigt mit Keyboard.write). Jedoch habe ich bei den Schaltern (0 | 1) noch einige Probleme....
Wenn ich den Schalter runter drücke, also auf 1, dann sendet er wie gewollt den Buchstaben Y, jedoch aber immer hintereinander (Spam).... Ich möchte aber das er nur 1x diesen Buchstaben sendet. Das könnte man natürlich machen, indem man die Delay hochsetzt - aber das ist ja auch net so elegant. Wenn ich den Schalter hochdrücke, soll er außerdem auch wieder das Y senden.
Hat jemand eine Lösung für mein Problem, welche Sketches, gerne auch Templates, ich verwenden soll?
Stimmt auch, aber der Schalter hakt eigentlich relativ schnell ein @my_xy_projekt@uwefed
Wenn ich jetzt dieses System noch an weiteren Schaltern anwenden möchte, wo müsste ich dann noch was ändern, evtl. an diesem const byte pin = 2; ?...
Oder kann ich einfach CopyPaste und halt nur im Void loop die einzelnen Pins und Tastaturbefehle ändern?
Du könntest die MoToButtons Klasse meiner MobaTools verwenden. Die ist genau dafür gemacht und verwaltet bis zu 32 Taster/Schalter in einer Instanz. Da kannst Du ganz einfach den Moment des Drückens und Loslassens erkennen und entsprechend einmalige Aktionen auslösen.
Im Beispiel PrintStates2.ino werden da jeweils beim Drücken/Loslassen Texte auf dem seriellen Monitor ausgegeben. WIe lange die Taste gedrückt wird ist dabei egal. Das ist ja sowas ähnliches wie Du brauchst.
Entweder Du kopierst dir die MoToButtons.h in dein Sketchverzeichnis und bindest sie mit #include "MoToButtons.h"
ein. Oder Du installierst die MobaTools komplett über den Bibliotheksmanager. Auch wenn Du sie komplett installierst, wird nur das in deinen Sketch eingebunden, was Du auch verwendest.
P.S.:
Delay() brauchst Du dabei nicht, und solltest Du auch nicht verwenden.
Hallo
Hier kommt ein Beispiel mit OOP.
Die Informationen über den Knopf und Buchstabe sind einfach in einem struct/array angelegt. Weitere Kombinationen aus Knöpfen und Buchstaben lassen sich hier durch COPY/PASTE in das array hinzufügen ohne den weitern Code anzufassen.
/* BLOCK COMMENT
ATTENTION: This Sketch contains elements of C++.
https://www.learncpp.com/cpp-tutorial/
https://forum.arduino.cc/t/arduino-leonardo-schalter/941345/12
*/
#define ProjectName "Arduino Leonardo Schalter"
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct TIME { // has the following members
unsigned long duration; // memory for interval time
unsigned long stamp; // memory for actual time
};
struct BUTTON2LETTER {
byte pin; // portPin o---|button|---GND
char char_; // letter
TIME scan; // information for debouncing
int statusQuo; // last buttonState
} button2letters[] { // add buttons and letters & co as you like
{A0, 'H', 20, 0, false},
{A1, 'A', 20, 0, false},
{A2, 'L', 20, 0, false},
{A3, 'O', 20, 0, false},
};
// -------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println(F("."));
Serial.print(F("File : ")), Serial.println(__FILE__);
Serial.print(F("Date : ")), Serial.println(__DATE__);
Serial.print(F("Project: ")), Serial.println(ProjectName);
pinMode (LED_BUILTIN, OUTPUT); // used as heartbeat indicator
// https://www.learncpp.com/cpp-tutorial/for-each-loops/
for (auto button2letter : button2letters) pinMode(button2letter.pin, INPUT_PULLUP);
}
void loop () {
currentTime = millis();
digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
for (auto &button2letter : button2letters) {
if (currentTime - button2letter.scan.stamp >= button2letter.scan.duration) {
button2letter.scan.stamp = currentTime;
int stateNew = !digitalRead(button2letter.pin);
if (button2letter.statusQuo != stateNew) {
button2letter.statusQuo = stateNew;
if (stateNew) Serial.print(button2letter.char_);
}
}
}
}
Ich wünsche einen geschmeidigen Rutsch ins Neue Jahr und viel Spass beim Programmieren in C++.
Ich weis echt nicht, warum ihr alle so gern das Rad neu erfindet. Für diese ganze Problematik gibt's doch wahrlich genug fertige Lösungen. Wem meine Lib nicht gefällt, der findet reichlich Alternativen.
Mit den Arduinos kann man so tolle Sachen machen. Warum sich immer wieder mit den schon längst gelösten Basic's beschäftigen? Ihr verwendet doch auch digitalWrite um einen Pin zu setzen, und hantiert nicht mit den Ports direkt rum. Das gilt in meinen Augen genau so für die Taster/Schalter und Zeitaufgaben Problematik. Da gibt's überall fertige Lösungen für.
Aber jeder wie er mag. Ich kann nichts daran finden die 1000+1ste Lösung für diese Problem zu finden
Ahh jetzt hab ich das System (hoffe ich mal halbwegs) verstanden..
Ich habe das Script mal so übernommen - jetzt sind wir aber wieder teilweise am #1 Post von mir angekommen Er sendet wieder 2 oder mehr Befehle bei einem Drücker.
Las mir mal nen Moment.
Ich komm hier wieder her...
So. Ich erklär mal, warum ein delay kontraproduktiv ist:
egal wie Du es machst, wenn Du ein delay startest, nachdem Du einen Input abgefragt hast, bist Du für diese Zeit blind und kannst die anderen Pins nicht abfragen.
nehmen wir mal an, Du hast ein delay von 100 ms - die hab ich jetzt gesetzt - und an den ersten 3 Pin findet eine Abfrage statt - dann bist Du am vierten Pin erst nach 300+x ms.
Das sind Welten....
ich habe jetzt auch 100ms genommen. Aber ich warte nur für den jeweiligen Pin.
Kommt also zwischendurch ein anderer Pin - Kein Problem, ich laufe immer wieder alle Abfragen durch....
#include <Keyboard.h>
const byte schalt[] = {7, 9, 11, 12};
bool lastPinZustand[sizeof(schalt)]; // das sizeof geht so nur, weil pin die Größe byte hat
const char buchstabe[sizeof(schalt)] = {'X', 'Y', '/', '*'};
const uint32_t bounceTime = 100;
uint32_t bounceMerker[sizeof(schalt)] = {0};
void setup ()
{
Serial.begin(115200);
Serial.println(F("Start..."));
for (byte b = 0; b < 2; b++)
{
lastPinZustand[b] = digitalRead(schalt[b]);
}
pinMode(schalt[0], INPUT_PULLUP);
pinMode(schalt[1], INPUT_PULLUP);
pinMode(schalt[2], INPUT);
pinMode(schalt[3], INPUT);
}
void loop()
{
Keyboard.begin();
uint32_t myMillis = millis();
for (byte b = 0; b < sizeof(schalt); b++)
{
if (myMillis - bounceMerker[b] >= bounceTime)
{
if (!digitalRead(schalt[b]) != lastPinZustand[b])
{
lastPinZustand[b] = !lastPinZustand[b];
bounceMerker[b] = myMillis;
if (!lastPinZustand[b])
{
Keyboard.write(buchstabe[b]);
Serial.println(buchstabe[b]);
}
}
}
}
Keyboard.end();
}
Stimmt ist mir auch aufgefallen, wollte 2 Schalter gleichzeitig betätigen - ging nur einer.
Aber danke fürs Script.
Jetzt sendet er jedoch kein Befehl mehr, wenn ich von eingeschaltet zu ausgeschaltet drücke (1 -> 0) ..... xD -.-