==== Arduino Einstieg ==== Mein Einstieg begann mit einem Nachbau eines Arduino Uno.\\ \\ Conrad bot einen Nachbau zum Preis von ca. 17 Euro an:\\ \\ Ein Ebay-Shop in China zum Preis von unter 7 Euro inkl. 4 Wochen Lieferzeit:\\ {{::arduino_uno.jpg?400|}} \\ Pinbelegung gibt es u.a. hier:\\ https://www.google.com/search?q=pinbelegung+arduino&client=firefox-b&tbm=isch&tbo=u&source=univ&sa=X&ved=0ahUKEwi045P7w_7aAhWu0aYKHbWvDcsQsAQILQ&biw=1536&bih=722&dpr=1.25#imgrc=hc-2ehD1OmQYJM:\\ \\ ==== IDE-Software download ==== \\ So startete ich also mit der Herunterladen der IDE und entpacken der zip-Datei.\\ https://www.arduino.cc/en/Main/Software\\ \\ Hier lade ich die ZIP-Version herunter, ohne lässtige Installation.\\ Der Anschluss des Arduino Uno (Nachbaus) erfolgt mit dem USB-Kabel.\\ \\ \\ ==== Treiberinstallation ==== Zunächst scheitert dies an dem fehlenden Treiber.\\ {{::arduino_treiber1.jpg|}} \\ Der Treiber befindet sich glücklicherweise in dem entpackten Verzeichnis arduino-1.8.5-windows\arduino-1.8.5\drivers\\ \\ \\ Über den Gerätemanager installieren wir den Teriber wie folgt:\\ {{::arduino_treiber2.jpg|}} \\ \\ {{::arduino_treiber3.jpg|}} \\ //Auf dem Computer nach Treibern suchen//\\ \\ {{::arduino_treiber4.jpg|}} \\ \\ Der passende Treiber wurde gefunden und um eine Bestätigung wird gebeten:\\ {{::arduino_treiber5.jpg|}}\\ \\ Klicke auf Installieren.\\ \\ Das Gerät ist nun installiert und verfügbar.\\ {{::arduino_treiber6.jpg|}} \\ {{::arduino_treiber7.jpg|}} \\ \\ ==== IDE-Software erster Start ==== Die Software {{::ide.jpg|}} wird gestartet und dort das Modul und der Port (Com-Schnittstelle) ausgewählt.\\ \\ {{::ide_1.jpg|}} \\ \\ Dazu wählt man den Menüpunkt Werkzeug / Board.\\ Hier steht nun Arduino Uno und kann sonst ausgewählt werden.\\ {{::ide_2.jpg|}} \\ \\ \\ Unter Werkzeug / Port muss noch der richtige Port ausgewählt werden. In meienm Fall COM3.\\ {{::ide_3.jpg|}} \\ \\ \\ Unter Datei / Beispiele findet man ganz viele Beispiele die als Vorlage für eigene Projekt dienen können.\\ {{::ide_5.jpg|}} \\ \\ \\ Unter Werkzeug / Serieller Monitor bzw. Serieller Plotter steht die Ausgabe von Daten zur Verfügung.\\ {{::ide_4.jpg|}} \\ \\ ==== Erstes Beispiel ==== Die interne LED soll blinken wenn der Analogeingang A0 ausgelesen wird.\\ In der IDE wird dazu ein neues Gerüst erzeugt:\\ Datei / Neu\\ und folgender Code hinein kopiert: // Definition der Ports int sensorValue0 = 0; // Analog Eingang A0 int ledPin = 13; // die interne LED // Grundgeruest void setup() { Serial.begin(9600); // initialize serial communications at 9600 bps: pinMode(ledPin, OUTPUT); // setze pin der internen led auf ausgang } // Schleife void loop() { sensorValue0 = analogRead(sensorValue0); // Einlesen der Messwerte Serial.print("sensor = "); // Ausgabe eines Textes Serial.println(sensorValue0); // Ausgabe der Messwerte zum Serial Monitor mit Zeilenumbruch digitalWrite(ledPin, HIGH); // LED einschalten delay(200); // Wartezeit in ms digitalWrite(ledPin, LOW); // LED ausschalten delay(1000); // Wartezeit in ms } Nach dem übertragen blinkt die interne LED und am Seriellen Monitor / Plotter werden die Messwerte ausgegeben.\\ \\ {{::ide_6.jpg|}} \\ \\ ==== Abstand messen ==== Ich messe den Abstand mit einem Ultraschallmodul HC-SR04.\\ Dabei werden VCC mit dem Arduino-5Volt-Ausgang, GND mit dem Arduino-GND, Trigger mit dem Arduino-D12 und Echo mit dem Arduino-D13-Pin verbunden. Das folgende Script misst die Entfernung und gibt sie in cm über den Seriellen Monitor aus:\\ \\ // // arduino_uno_ultraschall_4.ino // int TriggerPin = 12; // Digital 12 -> HC-SR04 Trigger int EchoPin = 13; // Digital 13 -> HC-SR04 Echo // HC-SR04 Vcc -> 5V, GNG -> GND void setup() { Serial.begin(9600); } void loop() { // establish variables for duration of the ping, // and the distance result in inches and centimeters: long duration, cm; // The PING))) is triggered by a HIGH pulse of 2 or more microseconds. // Give a short LOW pulse beforehand to ensure a clean HIGH pulse: pinMode(TriggerPin, OUTPUT); digitalWrite(TriggerPin, LOW); delayMicroseconds(2); digitalWrite(TriggerPin, HIGH); delayMicroseconds(10); digitalWrite(TriggerPin, LOW); // The same pin is used to read the signal from the PING))): a HIGH // pulse whose duration is the time (in microseconds) from the sending // of the ping to the reception of its echo off of an object. pinMode(EchoPin, INPUT); duration = pulseIn(EchoPin, HIGH); // convert the time into a distance cm = microsecondsToCentimeters(duration); if (cm <= 500) { Serial.print(cm); Serial.println(""); } else Serial.println("Ungueltige Messung ! Entfernung groesser als 5 Meter !!!"); delay(100); } long microsecondsToCentimeters(long microseconds) { // The speed of sound is 340 m/s or 29 microseconds per centimeter. // The ping travels out and back, so to find the distance of the // object we take half of the distance travelled. return microseconds / 29 / 2; } \\ \\ Im zweiten Beispiel sind die Bauteile wie folgt verkabelt:\\ \\ Sensor - Arduino\\ +5V - +5V\\ Gnd - Gnd\\ Trig - 13 Digital\\ Echo - 12 Digital\\ \\ Der Programmcode gibt die Messwerte in cm aus: // // http://www.instructables.com/id/Simple-Arduino-and-HC-SR04-Example/ // // arduino_uno_ultraschall_3.ino // /* HC-SR04 Ping distance sensor] VCC to arduino 5v GND to arduino GND Echo to Arduino pin 13 Trig to Arduino pin 12 Red POS to Arduino pin 11 Green POS to Arduino pin 10 560 ohm resistor to both LED NEG and GRD power rail More info at: http://goo.gl/kJ8Gl Original code improvements to the Ping sketch sourced from Trollmaker.com Some code and wiring inspired by http://en.wikiversity.org/wiki/User:Dstaub/robotcar */ #define trigPin 13 #define echoPin 12 //#define led 11 //#define led2 10 void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); //pinMode(led, OUTPUT); //pinMode(led2, OUTPUT); } void loop() { // long duration, distance; float duration, distance; digitalWrite(trigPin, LOW); // Added this line delayMicroseconds(2); // Added this line digitalWrite(trigPin, HIGH); // delayMicroseconds(1000); - Removed this line delayMicroseconds(10); // Added this line digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = (duration/2) / 29.1; Serial.print(distance); Serial.println(" cm"); delay(1000); } 2422.06 cm 2421.63 cm 2421.80 cm 2421.48 cm 2421.55 cm 2421.68 cm 2421.56 cm 2421.51 cm 2421.82 cm 2421.82 cm 2421.96 cm 2422.56 cm 2422.37 cm 2422.08 cm 2422.66 cm 2422.30 cm 2422.27 cm 2422.22 cm 2422.46 cm 2422.10 cm 2421.63 cm \\ \\ Möchte man die Messwerte gemittelt ausgeben, müssen die Messwerte zunächst Summiert und durch die Anzahl der Messwerte geteilt werden.\\ Dazu verwende ich eine For-Schleife die nach einer vorgegebenen Anzahl an Messwerte die Loop-Schleife beendet und den Mittelwert bildet. // // http://www.instructables.com/id/Simple-Arduino-and-HC-SR04-Example/ // // // arduino_uno_ultraschall_8.ino // // https://www.arduinoforum.de/arduino-Thread-Gewichteten-Durchschnitt-berechnen-20-Werte-in-fortlaufender-Variable-speichern // http://www.arduino-tutorial.de/schleifen/ /* HC-SR04 Ping distance sensor] VCC to arduino 5v GND to arduino GND Echo to Arduino pin 13 Trig to Arduino pin 12 Red POS to Arduino pin 11 Green POS to Arduino pin 10 560 ohm resistor to both LED NEG and GRD power rail More info at: http://goo.gl/kJ8Gl Original code improvements to the Ping sketch sourced from Trollmaker.com Some code and wiring inspired by http://en.wikiversity.org/wiki/User:Dstaub/robotcar */ #define trigPin 13 #define echoPin 12 //int i; // schleifenzaehler float duration, distance; float summeallermesswerte = 0; int zaehler = 0; float mittelwert = 0; int durchlaeufe = 99; // hier die gewünschte Anzahl eintragen void setup() { Serial.begin (9600); pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); } // void-setup-ende void loop() { for (int i=0; i \\ Quelle: http://www.arduino-tutorial.de/schleifen/\\ \\ ==== Netzwerk-Shield ==== In China kann ein Netzwerkshield für rund 5 Euro bestellt werden.\\ Nach 4 Wochen liegt es nun endlich auf meinem Schreibtisch:\\ {{::arduino_uno_netzwerk_shield1.jpg?200|}} {{::arduino_uno_netzwerk_shield2.jpg?200|}} {{::arduino_uno_netzwerk_shield3.jpg?200|}} \\ Nach dem Zusammenbau:\\ {{::arduino_uno_netzwerk_shield4.jpg?200|}} \\ belegt das Netzwerkshild die PINs 4, 10, 11, 12 und 13.\\ Diese stehen dann nicht mehr zur Verfügung.\\ Das muss für andere Projekte beachtet werden.\\ \\ Ein Beispielscript überträgt Daten an einen Server:\\ /* * * * Kurzfassung * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include // Hier muss eine eigene IP-Adresse, Gateway und DNS eingetragen werden, // wenn die Netzwerkkonfiguration nicht über DHCP bezogen wird // Sofern nicht mehrere Ethernet-Apdater gleichzeitig verwendet werden, // braucht die MAC-Adresse nicht geändert werden // Bitte darauf achten, dass die Adressen im Netzwerk nicht doppelt vergeben sind byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 178, 111); IPAddress gateway(255, 255, 255, 0); IPAddress dnServer(192, 168, 178, 1); // IP-Adresse statt Domainname zum Webserver mit Upload-Skript // Bei verwendung der IP-adresse ist "static char serverName[]" stattdessen auszukommentieren IPAddress server(192, 168, 178, 222); // Domainname statt IP-Adresse zum Webserver mit beelogger-Skript //static char server[] = "meineDomain.de"; // Verzeichnis in dem die Webserver-Skripte für den jeweiligen Logger liegen (mit nachgestelltem "/") // z.B. const char* pfad[1][1]={"test/"}; const char* pfad[1][1]={"/arduino/"}; // Passwort vom Webserver-Skript static char Passwort[] = "!meinPasswort!"; EthernetClient client; // Test-Messdaten (regulär kommen die Messdaten von den Sensoren) float wert1 = 25.00; float wert2 = 35.00; float wert3 = 40.00; float wert4 = 60.00; float wert5 = 50000.00; long wert6 = 25000; long wert7 = 200; long wert8 = 500; long Check; void setup() { Serial.begin(9600); delay(5000); pinMode(4,OUTPUT); // Pin 4 wird für die Deaktivierung der SD-Karte genutzt, digitalWrite(4,HIGH); // falls ein entsprechendes Ethernet-Shield mit SD-Adapter verwendet wird // Für Verwendung der Konfiguration über DHCP //if (Ethernet.begin(mac) == 0) Serial.println("Fehler bei der Konfiguration des Ethernet-Adapters ueber DHCP"); // Für Verwendung die eigenen Konfiguration Ethernet.begin(mac, ip, dnServer, gateway); delay(1000); } void loop() { Check = round(wert1+wert2+wert3+wert4+wert5+wert6+wert7+wert8); Serial.println(F("Verbinde zum Server ...")); for (byte i = 0; i < 5; i++) { // Anzahl der Wiederholungen bei Verbindungsproblemen // oder korrupten Daten, die vom Webserver empfangen werden if (client.connect(server, 80)){ client.print("GET /"); client.print(pfad[0][0]); client.print("messwerteintragen.php?wert1="); client.print (wert1); client.print ("&wert2="); client.print (wert2); client.print ("&wert3="); client.print (wert3); client.print ("&wert4="); client.print (wert4); client.print ("&wert5="); client.print (wert5); client.print ("&wert6="); client.print (wert6); client.print ("&wert7="); client.print (wert7); client.print ("&wert8="); client.print (wert8); client.print ("&Check="); client.print (Check); client.print ("&Passwort="); client.print (Passwort); client.println (" HTTP/1.1"); client.print("Host:"); client.println(server); client.println("Connection: close"); client.println(); delay(10000); Serial.println(F("Verbindung erfolgreich")); } else Serial.println(F("Verbindung fehlgeschlagen")); unsigned long start = millis(); char c; while ((millis() - start < 2000) and (client.connected() )) { c = client.read(); //Serial.print(c); //Debugausgabe if (c=='*') { i=10; Serial.println(F("Upload erfolgreich")); } }; client.stop(); client.flush(); delay(1000); Serial.println(F("Verbindung beendet")); Serial.println(); } // Test-Messdaten um 1 erhöhen //TempIn++; //TempOut++; //FeuchteIn++; //FeuchteOut++; //Licht++; //Gewicht++; //BienenIn++; //BienenOut++; //delay(1000); } \\ \\ ==== Blitzdetektor ==== \\ Um Blitze mit dem Arduino Uno zu bestimmen, habe ich im Netz eine kleine Schaltung und Code gefunden.\\ {{::arduino_blitz1.jpg?400|}} {{::arduino_blitz2.jpg?400|}} \\ Der Code zeigt im SerialMonitor bei ersten Tests mit Berührungen der Antenne mit meinem Finger Signale an.\\ // More information at: https://www.aeq-web.com?ref=arduinoide // https://www.aeq-web.com/arduino-blitzdetektor/ // // ardunino_uni_blitzdetektor_1 // #define FASTADC 1 #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif int data = 512; int storage[512]; long FlashStart; long FlashEnd; long tmr; int reading; int count; int maximum; int minimum; bool toSend; void setup() { #if FASTADC sbi(ADCSRA, ADPS2) ; cbi(ADCSRA, ADPS1) ; cbi(ADCSRA, ADPS0) ; #endif Serial.begin(9600); pinMode(A5, INPUT); Serial.println(micros()); FlashStart = 0; FlashEnd = 0; reading = 0; count = 0; maximum = 0; minimum = 1023; toSend = false; tmr = millis(); } void loop() { reading = (analogRead(A5)); storage[count] = reading; if ((!toSend) && (count != 0) && ((reading > storage[count - 1] + 10) || (reading < storage[count - 1] - 10))) { toSend = true; } count = count + 1; if ((count == 512) && (toSend)) { count = 0; FlashEnd = millis(); sendData(); FlashStart = millis(); } else if (count == 512) { count = 0; FlashEnd = millis(); FlashStart = millis(); } } void sendData() { int getout; for (int i = 0; i < data; i++) { getout = storage[i]; } double tm = ((millis() - tmr) / 1000); Serial.print("Flash Value: "); Serial.print(getout); Serial.print(" - Last Flash: "); Serial.print(tm); Serial.println(" sec"); tmr = millis(); toSend = false; } \\ Den Code habe ich erweitert. Nun blinkt die interne LED und ein Digitalanschluss soll eine externe LED oder einen Optokoppler schalten.\\ Der Code ist folgender: //More information at: https://www.aeq-web.com?ref=arduinoide // das Original Script misst eine Blitz in einiger Entfernung // // das geänderte Script lässt die interne LED bei einem Blitzergeinis blinken // // in der nächsten Änderung schaltet dann ein Digitalausgang eine externe LED oder andere Dinge // z.b. einen Optokoppler oder den Eingang eines NodeMCU8266 // // // digitalausgang int exdigi = 7; // Digitalausgang für externe Schaltung // Blitzdetektor: #define FASTADC 1 #ifndef cbi #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) #endif #ifndef sbi #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) #endif int data = 512; int storage[512]; long FlashStart; long FlashEnd; long tmr; int reading; int count; int maximum; int minimum; bool toSend; void setup() { #if FASTADC sbi(ADCSRA, ADPS2) ; cbi(ADCSRA, ADPS1) ; cbi(ADCSRA, ADPS0) ; #endif Serial.begin(9600); pinMode(A5, INPUT); Serial.println(micros()); FlashStart = 0; FlashEnd = 0; reading = 0; count = 0; maximum = 0; minimum = 1023; toSend = false; tmr = millis(); pinMode(13, OUTPUT); // interne LED // digitalausgang pinMode(exdigi, OUTPUT); // setze den Digitalausgang als Ausgang } void loop() { reading = (analogRead(A5)); storage[count] = reading; if ((!toSend) && (count != 0) && ((reading > storage[count - 1] + 10) || (reading < storage[count - 1] - 10))) { toSend = true; } count = count + 1; if ((count == 512) && (toSend)) { count = 0; FlashEnd = millis(); sendData(); FlashStart = millis(); } else if (count == 512) { count = 0; FlashEnd = millis(); FlashStart = millis(); } } void sendData() { int getout; for (int i = 0; i < data; i++) { getout = storage[i]; } double tm = ((millis() - tmr) / 1000); Serial.print("Flash Value: "); Serial.print(getout); Serial.print(" - Last Flash: "); Serial.print(tm); Serial.println(" sec"); tmr = millis(); toSend = false; // digitalausgang schalten: Serial.println(" - Digitalausgang wird geschaltet - "); digitalWrite(exdigi, HIGH); // sets the digital pin 13 on delay(1000); // waits for a second digitalWrite(exdigi, LOW); // sets the digital pin 13 off delay(100); // lasse interne LED leuchten Serial.println(" - interne LED blinkt - "); digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); delay(100); digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); delay(100); digitalWrite(13, HIGH); delay(100); digitalWrite(13, LOW); delay(100); } Die dazugehörige Schaltung folgt, sobald ich sie erfolgreich erprobt habe :-)\\ \\ Neuer Stand: Die Schaltung funktioniert. Ein Optokoppler schaltet den Digitaleingang D1 eines NodeMCU ESP8266 von LOW auf HIGH.\\ Der auf dem ESP8266 laufende Code (esp8266_blitzdetektor_1) überwacht den Eingang D1 und gibt dann per Wlan eine Meldung an meine RaspberryPi-Webserver:\\ \\ // Quelle: https://techtutorialsx.com/2016/12/11/esp8266-external-interrupts/ // Quelle: https://github.com/esp8266/Arduino/issues/584 // // Pinzuordnung am esp8266 // static const uint8_t D0 = 16; // static const uint8_t D1 = 5; // static const uint8_t D2 = 4; // static const uint8_t D3 = 0; // static const uint8_t D4 = 2; // static const uint8_t D5 = 14; // static const uint8_t D6 = 12; // static const uint8_t D7 = 13; // static const uint8_t D8 = 15; // static const uint8_t D9 = 3; // static const uint8_t D10 = 1; #include // wlan einbinden const char* ssid = "hallonetz"; // wlan ssid eintragen const char* password = "xyz"; // wlan zugangspasswort eintragen const char* host = "192.168.178.28"; //Web Server auf die Daten gespeichert werden const char* SensorID = "ESP8266_blitz"; const byte interruptPin = 5; volatile byte interruptCounter = 0; int numberOfInterrupts = 0; const char* meldung = "Blitz"; void setup() { // Kontakt zum wlan aufnehmen Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // Kontakt zum wlan aufnehmen - code ende - Serial.begin(9600); pinMode(interruptPin, INPUT); attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, RISING); } void handleInterrupt() { interruptCounter++; Serial.println(" - Blitz erkannt - "); //Serial.println(numberOfInterrupts); // wlan datenübergabe - beginn Serial.print("Verbindungsaufbau ... "); Serial.println(host); // Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } // uri erstellent // esp8266.php?wert1=xa&wert2=yb String url = "/abstand.php?"; url += "wert1="; url += SensorID; url += "&wert2="; url += meldung; Serial.print("Requesting URL: "); Serial.println(url); // senden client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); Serial.println("Werte an WebServer uebergeben"); delay(10); // Read all the lines of the reply from server and print them to Serial while(client.available()){ String line = client.readStringUntil('\r'); //Serial.print(line); } Serial.println(); Serial.println("Verbindung wird beendet ..."); // wlan datenübergabe - ende } void loop() { if(interruptCounter>0){ interruptCounter--; numberOfInterrupts++; //Serial.print("An interrupt has occurred. Total: "); //Serial.println(numberOfInterrupts); //delay(1000); // wartezeit //Serial.print("Ergebnis: "); //Serial.println(numberOfInterrupts); } // reset des zaehlers und ausgabe fue den benutzer numberOfInterrupts = 0; //Serial.print("Reset: "); //Serial.println(numberOfInterrupts); } // loop ende \\ ==== Frequenzgenerator ==== Im [[http://www.elektronik-labor.de/Arduino/Rechteck.html|Internet]] habe ich von einem Frequenzgenerator mittels Arduino erfahren.\\ Den könnte ich ja direkt für andere Projekt nutzen, wie z.b. meinem Geigerzähler.\\ \\ Also habe ich meinen Arduino Uno mit einem leicht abgewandelten Code gefüttert. Hier wird die Frequenz fest vorgegeben und nicht durch Eingabe abgefragt:\\ //------------------------ // Frequenzgenerator // http://www.elektronik-labor.de/Arduino/Rechteck.html //------------------------- // Patrick's Arduino :-) // Frequenz-/Rechteckgenerator #define INLENGTH 5 //maximale Größe der Zahl #define INTERMINATOR 'H' //'H' von 'Hz' char inString[INLENGTH+2]; int inCount; #define MinFreq 33 #define MaxFreq 65535 #define Ausgangspin 12 //muss kein PWM-Pin sein unsigned int Frequenz = 1000; //Hz (Maximum: 65535 Hz) void setup(){ Serial.begin(9600); //Serial.println("Bitte angeben wieviel Hz ausgegeben werden sollen (mit 'Hz')!"); tone(Ausgangspin, Frequenz); Serial.print("Es wird gesetzt: "); Serial.print(Frequenz,DEC); Serial.println("Hz"); } void loop(){ //Eingabe(); //Eingabe-Funktion, die Eingabe-String entgegennimmt //Zeichenkette -> Zahl //Alternative: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176289764 //Frequenz=atol(inString); //Frequenz="100Hz"; //Bereich prüfen Frequenz=constrain(Frequenz, MinFreq, MaxFreq); tone(Ausgangspin, Frequenz); } void Eingabe(){ inCount=0; //Ziffern-Zähler rücksetzen do { while (Serial.available()==0); inString[inCount] = Serial.read(); if(inString[inCount]==INTERMINATOR) break; if((inString[inCount]<'0')||(inString[inCount]>'9')){ //continue; //geht nicht inCount--; //-> Workaround } } while(++inCount < (INLENGTH+1)); Serial.flush(); } \\ \\ ==== Winkelgeber ==== Im Internet habe ich eine Seite gefunden, die den Anschluss eines Drehimpulsgebers (KY-040 Rotary Encoder Drehgeber) beschreibt.\\ Als der Geber endlich auf dem Schreibtisch lag, kopierte ich den Code und kämpfte zunächst mit der Pinbelegung.\\ \\ {{:drehgeber:geber1.jpg?400|}} \\ Mein Geber ist wie folgt an dem Arduino angeschlossen:\\ \\ Geberpin - Arduinopin\\ CLK - 6\\ DT - 5\\ SW - 2\\ \\ \\ \\ drehimpulsgeber_4.ino // Den Rotary encoder KY-040 auslesen // Die Taste speichert den aktuellen Wert ins EEPROM // // Matthias Busse 10.2017 Version 1.0 // // http://shelvin.de/rotary-encoder-ky-040-auslesen-und-wert-in-eeprom-ablegen/#more-2516 // #include // standard Arduino Library int ra = 6; // Pin 6 zu CLK am KY-040 int rb = 5; // Pin 7 zu DT am KY-040 int sw = 2; // Pin 8 zu SW am KY-040 int pos, alast, aval; int eeadr=14; // Speicheradresse wird hier gewählt void setup() { pinMode (ra,INPUT); // Rotary Encoder A & B ist in pinMode (rb,INPUT); pinMode(sw, INPUT); // Schalter ist in digitalWrite(sw, HIGH); // interner Pull up Widerstand auf 5V EEPROM.get(eeadr, pos); alast = digitalRead(ra); Serial.begin (38400); Serial.print("Startpos: "); Serial.println(pos); } void loop() { if( digitalRead(sw) == 0) { // Taste gedrückt? EEPROM.put(eeadr, pos); Serial.print("geschrieben: "); Serial.println(pos); while (digitalRead(sw) == 0); // warten bis die Taste losgelassen wird } aval = digitalRead(ra); // Encoder gedreht? if (aval != alast){ // wenn gedreht if (digitalRead(rb) != aval) { pos++; } // rechts rum else { pos--; } // sonst links Serial.print("Pos: "); Serial.println(pos); } alast = aval; } \\ Ausgabe beim drehen des Gebers: Startpos: -3 Pos: -2 Pos: -1 Pos: 0 Pos: 1 Pos: 2 Pos: 3 Pos: 4 Pos: 3 Pos: 4 Pos: 3 Pos: 4 Pos: 5 Pos: 6 Pos: 7 Pos: 8 Pos: 9 Pos: 10 Pos: 11 Pos: 10 Pos: 11 Pos: 10 Pos: 9 Pos: 8 Pos: 7 Pos: 6 Pos: 5 Pos: 4 Pos: 3 Pos: 2 Pos: 3 Pos: 2 Pos: 3 Pos: 2 Pos: 1 Pos: 0 Pos: 1 Pos: 0 Pos: -1 Pos: -2 Pos: -1 Pos: -2 Pos: -3 \\ \\ Die Suche nach einem anderen Code ergab:\\ \\ drehgeber_5.ino\\ // Quelle: http://www.linkerkit.de/index.php?title=KY-040_Kodierter_Drehschalter_%28Rotary_Encoder%29 // Initialisierung benötigter Variablen int Counter = 0; boolean Richtung; int Pin_clk_Letzter; int Pin_clk_Aktuell; // Definition der Eingangs-Pins int pin_clk = 6; int pin_dt = 5; int button_pin = 2; void setup() { // Eingangs-Pins werden initialisiert... pinMode (pin_clk,INPUT); pinMode (pin_dt,INPUT); pinMode (button_pin,INPUT); // ...und deren Pull-Up Widerstände aktiviert digitalWrite(pin_clk, true); digitalWrite(pin_dt, true); digitalWrite(button_pin, true); // Initiales Auslesen des Pin_CLK Pin_clk_Letzter = digitalRead(pin_clk); Serial.begin (38400); } // Das Programm überprüft, falls eine Änderung der Pin-Zustände sich ereignet hat, welcher der beiden // Pins sich zuerst geändert hatte, was auf die Drehrichtung schließen lässt. // Diese Information erhält man, in dem man einen der beiden Pin-Werte aus einem vorherigen // Durchlauf mit dem Wert des aktuellen Durchlaufs vergleicht. // Nachdem die Richtung festgestellt wurde, werden die Schritte von der Startposition an gezählt und ausgegeben. // Ein Drücken auf den Knopf des Drehgebers resettet die aktuelle Position. void loop() { // Auslesen des aktuellen Statuses Pin_clk_Aktuell = digitalRead(pin_clk); // Überprüfung auf Änderung if (Pin_clk_Aktuell != Pin_clk_Letzter) { if (digitalRead(pin_dt) != Pin_clk_Aktuell) { // Pin_CLK hat sich zuerst verändert Counter ++; Richtung = true; } else { // Andernfalls hat sich Pin_DT zuerst verändert Richtung = false; Counter--; } Serial.println ("Drehung erkannt: "); Serial.print ("Drehrichtung: "); if (Richtung) { Serial.println ("Im Uhrzeigersinn"); } else { Serial.println("Gegen den Uhrzeigersinn"); } Serial.print("Aktuelle Position: "); Serial.println(Counter); Serial.println("------------------------------"); } // Vorbereitung für den nächsten Druchlauf: // Der Wert des aktuellen Durchlaufs ist beim nächsten Druchlauf der vorherige Wert Pin_clk_Letzter = Pin_clk_Aktuell; // Reset-Funktion um aktuelle Position zu speichern if (!digitalRead(button_pin) && Counter!=0) { Counter = 0; Serial.println("Position resettet"); } } \\ Ausgabe:\\ Drehung erkannt: Drehrichtung: Gegen den Uhrzeigersinn Aktuelle Position: -1 ------------------------------ Drehung erkannt: Drehrichtung: Gegen den Uhrzeigersinn Aktuelle Position: -2 ------------------------------ Position resettet Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 1 ------------------------------ Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 2 ------------------------------ Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 3 ------------------------------ Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 4 ------------------------------ Drehung erkannt: Drehrichtung: Gegen den Uhrzeigersinn Aktuelle Position: 3 ------------------------------ Drehung erkannt: Drehrichtung: Gegen den Uhrzeigersinn Aktuelle Position: 2 ------------------------------ Drehung erkannt: Drehrichtung: Gegen den Uhrzeigersinn Aktuelle Position: 1 ------------------------------ Drehung erkannt: Drehrichtung: Gegen den Uhrzeigersinn Aktuelle Position: 0 ------------------------------ \\ Diese habe ich nun so angepasst, dass eine volle Umdrehung des Gebers auch die 20 Schritte die er hat, anzeigt:\\ \\ drehgeber_6.ino\\ // Initialisierung benötigter Variablen int Counter = 0; int Counter2 = 0; boolean Richtung; int Pin_clk_Letzter; int Pin_clk_Aktuell; // Definition der Eingangs-Pins int pin_clk = 6; int pin_dt = 5; int button_pin = 2; void setup() { // Eingangs-Pins werden initialisiert... pinMode (pin_clk,INPUT); pinMode (pin_dt,INPUT); pinMode (button_pin,INPUT); // ...und deren Pull-Up Widerstände aktiviert digitalWrite(pin_clk, true); digitalWrite(pin_dt, true); digitalWrite(button_pin, true); // Initiales Auslesen des Pin_CLK Pin_clk_Letzter = digitalRead(pin_clk); Serial.begin (38400); } // Das Programm überprüft, falls eine Änderung der Pin-Zustände sich ereignet hat, welcher der beiden // Pins sich zuerst geändert hatte, was auf die Drehrichtung schließen lässt. // Diese Information erhält man, in dem man einen der beiden Pin-Werte aus einem vorherigen // Durchlauf mit dem Wert des aktuellen Durchlaufs vergleicht. // Nachdem die Richtung festgestellt wurde, werden die Schritte von der Startposition an gezählt und ausgegeben. // Ein Drücken auf den Knopf des Drehgebers resettet die aktuelle Position. void loop() { // Auslesen des aktuellen Statuses Pin_clk_Aktuell = digitalRead(pin_clk); // Überprüfung auf Änderung if (Pin_clk_Aktuell != Pin_clk_Letzter) { if (digitalRead(pin_dt) != Pin_clk_Aktuell) { // Pin_CLK hat sich zuerst verändert Counter ++; Richtung = true; } else { // Andernfalls hat sich Pin_DT zuerst verändert Richtung = false; Counter--; } Serial.println ("Drehung erkannt: "); Serial.print ("Drehrichtung: "); if (Richtung) { Serial.println ("Im Uhrzeigersinn"); } else { Serial.println("Gegen den Uhrzeigersinn"); } Serial.print("Aktuelle Position: "); Counter = Counter; Serial.println(Counter); Serial.print("Wahre aktuelle Position: "); Counter2 = (Counter/2); Serial.println(Counter2); Serial.println("------------------------------"); } // Vorbereitung für den nächsten Druchlauf: // Der Wert des aktuellen Durchlaufs ist beim nächsten Druchlauf der vorherige Wert Pin_clk_Letzter = Pin_clk_Aktuell; // Reset-Funktion um aktuelle Position zu speichern if (!digitalRead(button_pin) && Counter!=0) { Counter = 0; Serial.println("Position resettet"); } } Ausgabe:\\ Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 18 Wahre aktuelle Position: 9 ------------------------------ Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 19 Wahre aktuelle Position: 9 ------------------------------ Drehung erkannt: Drehrichtung: Im Uhrzeigersinn Aktuelle Position: 20 Wahre aktuelle Position: 10 ------------------------------ \\ \\ === Quellen === https://www.arduino.cc/en/Reference/Ethernet\\ https://www.aeq-web.com/arduino-blitzdetektor/\\ http://www.elektronik-labor.de/Arduino/Rechteck.html\\ http://shelvin.de/rotary-encoder-ky-040-auslesen-und-wert-in-eeprom-ablegen/#more-2516\\ http://www.linkerkit.de/index.php?title=KY-040_Kodierter_Drehschalter_%28Rotary_Encoder%29 \\ \\