Benutzer-Werkzeuge

Webseiten-Werkzeuge


arduino_einstieg

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:

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.

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:



Auf dem Computer nach Treibern suchen



Der passende Treiber wurde gefunden und um eine Bestätigung wird gebeten:


Klicke auf Installieren.

Das Gerät ist nun installiert und verfügbar.



IDE-Software erster Start

Die Software wird gestartet und dort das Modul und der Port (Com-Schnittstelle) ausgewählt.



Dazu wählt man den Menüpunkt Werkzeug / Board.
Hier steht nun Arduino Uno und kann sonst ausgewählt werden.



Unter Werkzeug / Port muss noch der richtige Port ausgewählt werden. In meienm Fall COM3.



Unter Datei / Beispiele findet man ganz viele Beispiele die als Vorlage für eigene Projekt dienen können.



Unter Werkzeug / Serieller Monitor bzw. Serieller Plotter steht die Ausgabe von Daten zur Verfügung.


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.



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<durchlaeufe; i++){ // for-schleifen-beginn

  // Ausgabe des aktuellen Durchlauf
  //Serial.print("I: ");
  //Serial.println(i);
  
  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;

  // Ausgabe des aktuellen Messwertes  
  //Serial.print("Abstand: ");
  //Serial.print(distance);
  //Serial.println(" cm");

  summeallermesswerte = summeallermesswerte + distance;
  //Serial.print("Summe: ");
  //Serial.print(summeallermesswerte);
  //Serial.println(" cm");

  zaehler = zaehler + 1;
  //Serial.print("Zähler: ");
  //Serial.println(zaehler);

  mittelwert = summeallermesswerte / zaehler;
  //Serial.print("Mittelwert: ");
  //Serial.print(mittelwert);
  //Serial.println("cm");
  
  delay(100);

} // for-schleifen-ende


// endausgabe
  // Ausgabe des Mittelwertes
  Serial.print("letzter Mittelwert: ");
  Serial.print(mittelwert);
  Serial.println("cm");



// Reset aller Ausgangswerte
  summeallermesswerte = 0;
  zaehler = 0;
  mittelwert = 0;

} // void-loop-ende


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:

Nach dem Zusammenbau:


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 <http://www.gnu.org/licenses/>.
*/
 
 
#include <SPI.h>
#include <Ethernet.h> 
 
// 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.

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 <ESP8266WiFi.h>  // 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 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.


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 <EEPROM.h> // 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

arduino_einstieg.txt · Zuletzt geändert: 30.11.2020 (Externe Bearbeitung)