Michael ARDUINO‎ > ‎

michaelsarduino

http://sites.schaltungen.at/arduino-uno-r3/michael-arduino/michaelsarduino

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                          Wels, am 2017-02-08

BITTE nützen Sie doch rechts OBEN das Suchfeld  [                                                              ] [ Diese Site durchsuchen]

DIN A3 oder DIN A4 quer ausdrucken
*******************************************************************************I**
DIN A4  ausdrucken   siehe     http://sites.schaltungen.at/drucker/sites-prenninger
********************************************************I*
~015_b_PrennIng-a_arduino.uno.r3-michael.arduino-michaelsarduino (xx Seiten)_1a.pdf

Untergeordnete Seiten (2):

https://az-delivery.de/



-A01- RFID mit dem Arduino
-A02- DS3231 Real Time Clock

-A03-Software I2C
-A04- Arduino Kompass
-A05- Online Wettervorhersage
-A06- Uhrzeit über ESP8266
-A07- Wetterstation - Basis
-A08- Wetterstation - Außensensor
-A09- Temperaturserver  DHT11
-A10- Arduino IDE Version 1.6.6
-A11- Heißer Draht mit dem Arduino
-A12- Sensordaten auf SD Karte speichern
-A13- Arbeiten mit Dateien auf SD Karte
-A14- SD Card Reader für den Arduino
-A15- Temperatur messen nur mit dem Arduino
-A16- Externen Reset Button
-A17- Widerstände messen
-A18- ESP 8266 als Wlan Router und Wlan Client
-A19- Websiten über ESP8266 abrufen


                  A - Michael Bonacia
          https://plus.google.com/110786353506245861399





-A01- RFID mit dem Arduino

In diesem Post geht es darum, wie man RFID Karten oder Chips mittels eines Lesegeräts (hier beaz-delivery.de) am Arduino ausliest, um dadurch beispielsweise die Berechtigung eines Benutzers zu überprüfen.






Verkabelung
Um die RFID Karten oder Chips auszulesen muss zunächst das Lesegerät mit dem Arduino verbunden werden. Am einfachsten funktioniert das direkt über Jumper Wire und ein Breadboard, wobei man auch eine normale Steckleiste (meist sogar mitgeliefert) anlöten kann.


Von der Verkabelung her muss der SDA Pin am Lesegerät mit Pin 10 des Arduino, SCK mit Pin 13, MOSI mit Pin 11 und MISO mit Pin 12. Zusätzlich muss GND mit dem Ground und 3.3V mit den +3.3V des Arduino.





Software
Praktischerweise gibt es bereits eine fertige Open Source Arduinobibliothek, wodurch sich der Programmieraufwand in Grenzen hält. Die MFRC 522 Bibliothek kann direkt über den Library Manager in der Arduino IDE nachgeladen werden, ansonsten ist sie auch auf Github verfügbar.


Sobald man die Bibliothek nachgeladen hat, kann man unter Datei > Beispiele den Beispielsketch DumpInfo der Bibliothek aufrufen, und auf den Arduino hochladen. Nach dem Öffnen der seriellen Konsole (Baudrate: 9600) wird, sobald ein RFID Gerät in der Nähe ist, seine ID und seine Informationen angezeigt:




Dabei gibt es als passive Sender verschiedene Dinge zur Auswahl, üblich sind jedoch entweder runde Chips für den Schlüsselbund oder Karten im Kreditkartenformat:

Ein praktisches Set zum Einstieg ist das RFID Kit von AZDelivery inklusive Lesegerät, Steckleisten und einer RFID Karte und einem RFID Kit.







-A02- DS3231 Real Time Clock


In diesem Post geht es um die DS3231 Real Time Clock für den Arduino. Mittels diesem Modul kann man die Zeit "abspeichern" und ab dann laufend die aktuelle Zeit abrufen, mit nur wenigen Minuten Abweichung pro Jahr.




Ich habe festgestellt
, dass die Verwendung des RTC Chip- DS3231 ist extrem hart Arduino verwenden. Just Einstellung der Zeit ist ziemlich komplex, nicht zu erwähnen, den Code. Deshalb habe ich eine große und leicht zu bedienen Bibliothek gefunden, die wirklich die Verwendung des DS3231 Chip verbessert. Lassen Sie uns direkt auf sie.

Natürlich müssen Sie zuerst den Chip anschließen. Es ist sehr einfach, tun Sie es entsprechend den Abbildungen oder unten:


VCC -> Arduino 5V
GND -> Arduino GND
SCL -> SCL or A5
SDA -> SDA or A4

Solange ich weiß, gibt es spezielle SCL und SDA Pins auf der ARDUINO UNO und MEGA.



Hardware und Verkabelung

Der Arduino Uno kann dank seines ATmega328 Mikrocontrollers und der Time Bibliothek für den Arduino die Uhrzeit abspeichern, und laufend im Hintergrund aktualisieren. Leider ergibt sich jedoch das Problem, das aufgrund von Interrupts, unterschiedlicher Temperaturen, nicht optimaler Verarbeitung und so weiter sich innerhalb eines Tages bereits eine Abweichung von mehreren Minuten ergibt, was auch mein Wecker Projekt faktisch untauglich gemacht hat.

Die Lösung sind sogenannte Real Time Clocks (RTC), in die man einmal die aktuelle Uhrzeit einmal einspeichert (natürlich kann man sie später auch nochmal überschreiben), und welche dann selbstständig die Uhrzeit aktualisieren, und dass extrem genau.

Die wahrscheinlich beliebteste Real Time Clock ist die DS3231, welche relativ genau ist (normalerweise keine 5 Minuten Abweichung pro Jahr), da sie zusätzlich zum Quarz einen Temperatursensor hat, der die Temperatur misst und davon ausgehend die Abweichung des Quarzes ausrechnen und beheben kann. Die Temperatur kann man sich übrigens auch übertragen lassen.

Zusätzlich hat die DS3231 eine integrierte Batterie (CR 2032, welche man, sobald sie leer ist auch auswechseln kann), welche sicherstellt, dass auch bei einem Stromausfall der Versorgungsspannung die Uhrzeit nicht verloren geht.

Die DS3231 Real Time Clock (hier bei AZDelivery) kommuniziert über I2C mit dem Arduino, weshalb man nur SCL mit A5, SDA mit A4, sowie GND mit dem Ground und Vcc mit +5V verbinden muss. Die beiden anderen Kontakte sind für dieses Beispiel nicht notwendig.


Arduino Sketch
Da die DS3231 RTC so beliebt ist, gibt es bereits verschiedene Bibliotheken für den Arduino, die die Anwendung sehr einfach gestalten. Ich verwende die DS3231 Bibliothek, welche man hier herunterladen kann. Nachdem man die .zip Datei entpackt, und ihren Inhalt in libraries des Arduino Ordners verschoben hat, kann man die Arduino IDE starten und die Bibliothek benutzen.

Praktischerweise gibt es bereits einen fertigen Beispielsketch, in dem man nur noch die aktuelle Uhrzeit eintragen muss (siehe Kommentare im Sketch), und der dann nach einem Upload auf den Arduino über die serielle Schnittstelle (Achtung: Baudrate 115200!) die aktuelle Uhrzeit ausgibt (Datei > Beispiele > DS3231 > Arduino > DS3231_Serial_Easy).

Auch ein fertiger Sketch zum Ausgeben der Temperatur auf der seriellen Konsole ist abrufbar, wobei die Abweichung vom Chip Hersteller mit +/- 3°C angegeben ist. Bei mir war die Temperatur verglichen mit meiner Wetterstation jedoch nur 1°C zu hoch.

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return( (val/16*10) + (val%16) );
}
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS3231 seconds, minutes, hours, day, date, month, year
  // setDS3231time(30,42,21,4,26,11,14);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
void displayTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute<10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10)
  {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch(dayOfWeek){
  case 1:
    Serial.println("Sunday");
    break;
  case 2:
    Serial.println("Monday");
    break;
  case 3:
    Serial.println("Tuesday");
    break;
  case 4:
    Serial.println("Wednesday");
    break;
  case 5:
    Serial.println("Thursday");
    break;
  case 6:
    Serial.println("Friday");
    break;
  case 7:
    Serial.println("Saturday");
    break;
  }
}
void loop()
{
  displayTime(); // display the real-time clock data on the Serial Monitor,
  delay(1000); // every second
}

DS3231 – die Atomuhr des Arduino

Eine Funkuhr läuft wie jede Uhr nicht wirklich präzise. Deswegen gleicht sie sich jede Stunde wieder über das DCF77-Signal mit der Atomuhr ab. Beim Computer nicht anders (wobei die eine RTC mit drin haben), hier geschieht das ganze per Netzwerk über das NTP-Protokoll.
Ein Arduino mag in der Regel mit 16MHz schwingen, doch da gibt es Abweichungen durch Temperatur und Verarbeitung des Quarzes. Doch wie realisiert man am Besten eine Uhr, ohne das ganze DCF-Signal zu dekodieren?

Ein delay von 1000 Millisekunden steht für 16 Millionen Takte (bei 16MHz) nichts tun. Wenn man eine Variable namens Sekunde inkrementiert, dann nimmt das laut Datenblatt des ATmega einen Takt in Anspruch (INC). Will man dann noch einen Pin verändern, braucht das einen halben Takt (SBI/CBI). Bedeutet Jede Sekunde braucht die Sekunde 1,5 Takte mehr. Allerdings ist die Arduino etwas überladener, um es dem Benutzer einfacher zu machen. Des Weiteren sind noch unterschiedliche Befehle dazwischen, die auch noch einige Takte rauben (RJMP, RETI, …). Interrupts verlängern das ganze noch einmal. Bedeutet im Endeffekt, egal, wie genau der Quarz läuft und der delay auch noch so genau eine Sekunde sein mag:
a) Kann man während des delays keine anderen Dinge mehr machen (z.B. Zeit durch Tasten stellen)
b) Wird die Sekunde warten durch nachfolgende Operationen stark ausgedehnt
c) Timer-Interrupts verlassen sich auf den Quarz, der beschriebene Ungenauigkeiten hat
d) Ein ausgelöster Interrupt kann einen anderen am Auslösen hindern

Viel Geschwafel, um eines zu sagen: ohne hohen Aufwand und low-level Coding wird man kaum eine genaue Uhr bauen können. Uhren habe ich schon mehrere gebaut, also muss es ja doch einen Weg geben. Das Stichwort: Real Time Clock, kurz RTC, auf deutsch schlicht Echtzeituhr. Das kleine Wunderding übernimmt Datum und Uhrzeit ohne groß Nachzudenken.

In der Vergangenheit nutzte ich ein DS1307 Modul, musste aber schnell feststellen, dass das fast genau so gut funktioniert, als wenn ich die Methode mit dem delay nutze. Bereits nach einem Tag gab es Abweichungen von mehreren Sekunden. Die Alternative: DS3231. Das Teil solle hoch präzise sein. In China kosten 10 Stück ca. $9. Tut nicht weh, also gekauft. Aus der Post geholt, Zeit eingestellt, eingebaut und nach mehreren Wochen immer noch keine einzige Sekunde daneben.

Die ganze Magie:
Das Modul besitzt einen Temperatursensor, der eventuelle Abweichungen des Quarzes durch Wärmeeinfluss kompensiert. Netter Nebeneffekt: die Raumtemperatur kann auch ausgelesen werden. RTCs sind mit Batterien (standardmäßig CR2032 oder als Akku LIR2032) ausgestattet, die sicherstellen, dass die Zeit nicht verloren geht, wenn der Strom am Hauptgerät ausfällt. Auch um Schaltjahre muss man sich bis 2100 keine Gedanken machen, allerdings um die Sommerzeit, aber darum hat sich ja zum Glück schon Olaf gekümmert.
Angesprochen wird das Modul über I2C, 8 verschiedene Adressen sind mittels Jumpern (Lötbrücken) möglich.

Mittels der Library kann das Modul abgefragt werden, ohne dass man sich einen Kopf drum machen muss. Man muss das Modul nicht einmal initialisieren. Lösung 1: im Loop immer wieder ein time_t struct anlegen, die Zeit von der RTC auslesen und dann die Werte verarbeiten. Geht, aber geht auch einfacher! Der Arduino ist unsere Funkuhr, die RTC unsere Atomuhr. Um die beiden regelmäßig zu synchronisieren, bietet die Time-Library eine Funktion namens setSyncProvider(). Diese rufen wir einfach mit dem Parameter RTC.get() auf, schon fragt der Arduino regelmäßig und selbstständig die Zeit ab und synchronisiert seine interne Zeit damit. Im nachfolgenden Programm kann man dann einfach hour(), minute() und second() nutzen, um die Zeit abzufragen, now() gibt die UNIX-Timestamp an (allerdings nur in CET, wenn auch die restliche Zeit in der Zeitzone definiert ist). year(), month() und day() spucken das Datum aus. Mittels RTC.temperature() wird die Temperatur in °C ermittelt, allerdings mit Faktor 4 ausgegeben. RTC.temperature()/4.0 gibt dann in ¼° Schritten die Temperatur aus, gibt man nur /4 ein, so erhält man einen gerundeten int-Wert, also in 1° Schritten. Die Abweichungen liegen bei ±3.0° laut Datenblatt.

Vorher muss man allerdings noch die Zeit stellen. Dafür gibt es in der Library unter examples den Sketch SetTime. Hier wird zum Zeitpunkt des Kompilierens die Zeit des Computers mit in die HEX-Datei eingebaut und geflasht. Da der Prozess des Aufspielens immer etwas dauert (kompilieren, hochladen), habe ich bei der Funktion getTime(…) tm.Second = Sec+5; eingestellt. Das kompensiert die Verzögerung. Sollte es nicht ganz passen, so einfach die Zahl etwas modifizieren.






-A03- Software I2C

In diesem Post geht es darum, wie man über die Software I2C Bibliothek zwei beliebige Pins des Arduino für eine zusätzliche I2C Verbindungen verwendet.






I2C
I2C, eigentlich I^2C ist ein Protokoll zum Übertragen von Daten zwischen zwei Geräten mit nur zwei Verbindungen: SDA und SCL. SDA ist für die Datenübertragung und SCL für den Takt. Der Arduino hat hardwareseitig eine I2C Verbindung mit SDA an A4 und SCL an A5, welche man über die Wire Bibliothek verwenden kann.


Wie man die Wire Library zum Nutzen von I2C am Arduino verwendet, habe ich bereits hier erklärt.


Software I2C
Manchmal benötigt man jedoch mehr als eine I2C Verbindung pro Arduino, wozu man die Software I2C Library verwenden (verfügbar im Library Manager unter Sketch > Include Library > Manage Libraries) kann. Diese kann eine "virtuelle" I2C Verbindung an zwei beliebigen Pins des Arduino einrichten, jedoch muss man ein paar Dinge beachten.


Zunächst einmal muss man vor der Verwendung den SDA Pin und den SCL Pin definieren. Dabei kann man nicht die aufgedruckten Arduino Bezeichnungen nehmen, sondern muss die Pins in ihren jeweiligen Ports einsortieren. Die genaue Bezeichnung der Pins und der Ports des Arduino, habe ich bereits hier erklärt.


Zur Definition muss man erst den Port, und dann den Pin angeben:




#define SCL_PORT PORTD

#define SCL_PIN 2

#define SDA_PORT PORTC

#define SDA_PIN 0

#include <SoftI2CMaster.h>

http://playground.arduino.cc/Main/SoftwareI2CLibrary



view rawSoftware_I2C_def.ino hosted with ❤ by GitHub

Nun wäre digital Pin 2 der SCL Pin, und A0 der SDA Pin.

Außerdem muss man in setup die künstliche I2C Verbindung über i2c_init() starten.
Um eine Verbindung mit einem Gerät zu starten, verwendet man die Funktion i2c_start(), welche man die Adresse des anderen I2C Geräts und den Modus (I2C_WRITE oder I2C_READ mitgeben muss). Beispielsweise sähe das so aus: i2c_start('0x70'|I2C_WRITE);.

Um die I2C Adresse des anderen Arduinos/Geräts herauszufinden, kann man diesen Sketch verwenden. Nun kann man über i2c_write(); etwas schreiben, oder über i2c_read() etwas lesen. Nach erfolgreicher Datenübertragung sollte man über i2c_stop() die Verbindung unterbrechen.








-A04- Arduino Kompass HMC5883L  - accelerometer


3-Axis Digital Compass IC Honeywell HMC5883L

Arduino based Digital Magnetic Compass

Digitaler Kompass

In diesem Post geht es darum, wie man das HMC5883L Magnetometer mit dem Arduino als Kompass verwendet.

Magnetfeldsensor HMC5883L (auf dem GY-271 Breakoutboard)

https://cdn-shop.adafruit.com/datasheets/HMC5883L_3-Axis_Digital_Compass_IC.pdf







Die Hardware

Zum Bauen des Kompass benötigt man das HMC5883L Magnetometer (hier auf Amazon) und einen Arduino/Mikrocontroller mit I2C, beispielsweise einen preiswerten Arduino Nano Klon (hier auf Amazon). Leider konnte ich kein Magnetometer finden, welches schon verlötet war, weshalb, auch bei dem Verlinktem, ein Lötkolben (hier auf Amazon) notwendig ist.

Die Verkabelung mit dem Arduino ist simpel, da die Kontakte auf der Rückseite beschriftet sind. SDA muss mit dem SDA Pin des Arduino verbunden werden, SCL mit SCL, GND mit dem Ground und entweder VCC mit +3.3V oder VCC_+5V mit +5V.

Der Sensor sollte direkt ins Breadboard gesteckt werden, da er so immer gleich liegt. Ansonsten könnte es zu einer Verfälschung der Messung kommen.


Der Sketch
Zum Auslesen des Sensors, für den es auch ein Modell von Adafruit gibt, hat Adafruit eine extra Bibliothek erstellt, welche jedoch mit allen HMC5883L Modulen funktioniert. Diese kann man direkt über den Library Manager nachladen (Adafruit HMC5883 Unified). Zusätzlich benötigt man noch die Adafruit Unified Sensor Bibliothek, welche man sich auch über den Library Manager herunterladen kann.

Wenn man nach dem Download der Bibliotheken auf Datei > Beispiele > Adafruit HMC5883 Unified klickt, sieht man einen passenden Beispielsketch für den Sensor, welchen man einfach nur auf den Arduino hochladen muss.


Hier der Sketch zum Durchlesen:

/***************************************************************************
This is a library example for the HMC5883 magnentometer/compass

Designed specifically to work with the Adafruit HMC5883 Breakout
http://www.adafruit.com/products/1746

*** You will also need to install the Adafruit_Sensor library! ***

These displays use I2C to communicate, 2 pins are required to interface.

Adafruit invests time and resources providing this open source code,
please support Adafruit andopen-source hardware by purchasing products
from Adafruit!

Written by Kevin Townsend for Adafruit Industries with some heading example from
Love Electronics (loveelectronics.co.uk)

This program is free software: you can redistribute it and/or modify
it under the terms of the version 3 GNU General Public License as
published by the Free Software Foundation.

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 <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);

void displaySensorDetails(void)
{
sensor_t sensor;
mag.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);
Serial.print ("Driver Ver: "); Serial.println(sensor.version);
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT");
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT");
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT");
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}

void setup(void)
{
Serial.begin(9600);
Serial.println("HMC5883 Magnetometer Test"); Serial.println("");

/* Initialise the sensor */
if(!mag.begin())
{
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while(1);
}

/* Display some basic information on this sensor */
displaySensorDetails();
}

void loop(void)
{
/* Get a new sensor event */
sensors_event_t event;
mag.getEvent(&event);

/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" ");
Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print(" ");
Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print(" ");Serial.println("uT");

// Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
// Calculate heading when the magnetometer is level, then correct for signs of axis.
float heading = atan2(event.magnetic.y, event.magnetic.x);

// Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
// Find yours here: http://www.magnetic-declination.com/
// Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
//float declinationAngle = 0.22;
//heading += declinationAngle;

// Correct for when signs are reversed.
if(heading < 0)
heading += 2*PI;

// Check for wrap due to addition of declination.
if(heading > 2*PI)
heading -= 2*PI;

// Convert radians to degrees for readability.
float headingDegrees = heading * 180/M_PI;

Serial.print("Heading (degrees): "); Serial.println(headingDegrees);

delay(500);
}


hmc5883l_example.ino hosted with ❤ by GitHub


Wenn man nun die serielle Konsole öffnet, bekommt man laufend die aktuelle Gradzahl (0 - 360)
angezeigt. Diese kann man nun zum Zeichnen eines graphischen Kompass verwenden, oder aber in einem Sketch weiterverwenden, beispielsweise zur Orientierung eines Roboterautos.





-A05- Online Wettervorhersage ESP8266-01S Wlan Modul

In diesem Post geht es darum, wie man sich über den ESP 8266 eine Online Wettervorhersage holt, und über einen Arduino diese dann auf einem LCD Display anzeigen lässt.



Große Reichweite durch Wlan 802.11 b/g/n Standard!
Universelle Einsatzmöglichkeiten dank drei verfügbarer Betriebsmodi: Wlan Router (AP), Wlan Client (STA) sowie beides gleichzeitig (AP + STA)!
Dank leistungsstarkem 80MHz Prozessor und großem 1MB Speicher, kann der esp8266 01 auch autonom betrieben werden!
Kommunikation mit Sensoren über zwei GPIO Pins möglich!






Die Hardware
Wie bereits erwähnt, benötigt man für dieses Projekt ein ESP8266 Wlan Modul (hier bei AZDelivery ), einen kleinen Arduino, beispielsweise einen preiswerten Arduino Nano Klon, und ein LCD Display (hier bei AZDelivery).

Das LCD Display kann, wie in diesem Post erklärt, ganz normal an den Arduino Nano angeschlossen werden. Zur Kommunikation zwischen dem ESP8266 und dem Arduino kann man die serielle Verbindung benutzen. Dabei muss RX des ESP mit TX des Arduino und umgekehrt verbunden werden. Wie man den ESP8266 anschließt und programmiert, habe ich bereits sehr ausführlich hier erklärt.


Die Sketche

Der ESP8266 Sketch

Als Quelle für aktuelle Wettervorhersagen verwende ich Yahoo! Wetter, da dort das Wetter im XML Format zur Verfügung gestellt wird. XML ist ein Datenformat, welches, im Gegensatz zu HTML Websiten, dazu ausgelegt wurde von Maschinen gelesen zu werden. Genaues zu XML auf Wikipedia.

Das bedeutet, dass der übermittelte Text vergleichsweise kurz und einfach strukturiert ist:






Um eine XML Seite mit der Wettervorhersage für eure Stadt zu erhalten, müsst ihr auf Yahoo! Wetter den Code eurer Stadt herausfinden,





und in die XML URL einfügen: 
http://weather.yahooapis.com/forecastrss?w=676757&u=c
Hier ist 676757 der Code, welchen ihr durch den eurer Stadt ersetzen müsst.

Nun könnt ihr die URL aufrufen, und seht übersichtlich aufgeschlüsselt die aktuellen Wettervorhersagen. 

Diese Seite kann der ESP8266, wie eine normale Website, aufrufen, und in einer Variable abspeichern. In dieser Variable kann das Wlan Modul dann über die Funktion indexOf() die passende Stelle finden, und die Wettervorhersagen herausfiltern. 

Der gesamte Code für den ESP8266 sieht so aus:

#include <ESP8266WiFi.h>

const char* ssid = "**************";
const char* password = "*************";

char server[] = "weather.yahooapis.com"; //Webserver
WiFiClient client;
String website;

void setup() {
Serial.begin(115200);
delay(10);

// Connect to WiFi network
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");


// Print the IP address
//Serial.println(WiFi.localIP());

//Serial.println("\nStarting connection to server...");
//Ausgabe ueber serielle Verbindung

}


void loop() {
if (client.connect(server, 80)) {
//Serial.println("connected to server");
client.println("GET /forecastrss?w=676757&u=c HTTP/1.1"); // /index.html durch gewuenschte Unterseite ersetzen (index.html = Startseite)
client.println("Host: weather.yahooapis.com"); //Adresse des Webservers
client.println("Connection: close");
client.println(); //Verbindungs mit Server aufbauen und HTTP Anfrage senden
}

while(website.length() < 10)
{
while (client.available())
{
website = client.readString();
}
}
if (!client.connected()) {
Serial.println();
//Serial.println("disconnecting from server.");
client.stop();
//Beenden der Verbindung
}



int tagkurzelst = website.indexOf("Date: ");
char tag1 = website[tagkurzelst + 6];
char tag2 = website[tagkurzelst + 7];
char tag3 = website[tagkurzelst + 8];
String tag = String(tag1) + String(tag2) + String(tag3);
int datint = tag.toInt();
int zusatz = 0;
if(datint > 9)
{
zusatz = 1;
}

String dat = String(website[tagkurzelst + 11]) + String(website[tagkurzelst + 12]);


String morgen;
if(tag == "Mon")
{
morgen = "Tue";
}
else
{
if(tag == "Tue")
{
morgen = "Wed";
}
else
{
if(tag == "Wed")
{
morgen = "Thu";
}
else
{
if(tag == "Thu")
{
morgen = "Fri";
}
else
{
if(tag == "Fri")
{
morgen = "Sat";
}
else
{
if(tag == "Sat")
{
morgen = "Sun";
}
else
{
if(tag == "Sun")
{
morgen = "Mon";
}
else
{
//Woche durch ->Fehlermeldung hier moeglich
}
}
}
}
}
}
}
String stelletx = "<yweather:forecast day=\"" + morgen;
int stelle = website.indexOf(stelletx);
int vorhersagelow;
int stellen;


int ort = stelle + 52 + zusatz;
int ort2 = stelle + 53 + zusatz;
String low2 = String(website[ort2]);
if(low2.toInt() == 0)
{
String zwischen = String(website[ort]);
vorhersagelow = zwischen.toInt();
stellen = 0;
}
else
{
String vorhersagelowstring = String(website[ort]) + String(website[ort2]);
vorhersagelow = vorhersagelowstring.toInt();
stellen = 1;
}
Serial.print("|");
Serial.print(vorhersagelow);
Serial.print("|");

int ort3 = ort + 9 + stellen;
int ort4 = ort + 10 + stellen;
int vorhersagehigh;
int weitere;
String high2 = String(website[ort4]);
if(high2.toInt() == 0)
{
String zwischen2 = String(website[ort3]);
vorhersagehigh = zwischen2.toInt();
}
else
{
String vorhersagehighstring = String(website[ort3]) + String(website[ort4]);
vorhersagehigh = vorhersagehighstring.toInt();
}
Serial.print(vorhersagehigh);
Serial.print("|");

delay(14400);

Alles was man vor dem Hochladen nun noch tun muss, ist das passende Wlan Netzwerk samt Passwort eintragen, und den richtigen Code für Yahoo! Wetter eingeben.

Der Arduino Sketch

Der Arduino muss nur die beiden Temperaturen für den nächsten Tag (minimal & maximal) über die serielle Verbindung empfangen, und auf dem LCD Display ausgeben:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
Serial.begin(115200);
lcd.begin(20, 4);
lcd.print("Tomorrow");
delay(10000);
}

void loop() {
if(Serial.available() > 5)
{
String muell = Serial.readStringUntil('|');2
String mindestens = Serial.readStringUntil('|');
String maximal = Serial.readStringUntil('|');
lcd.setCursor(0, 1);
lcd.print("Min. Temp.:");
lcd.print(mindestens);
lcd.print("C");
lcd.setCursor(0,2);
lcd.print("Max. Temp.:");
lcd.print(maximal);
lcd.print("C");
}

delay(1000);
}





Nach dem Anpassen und Hochladen beider Programme sieht man dann laufend die aktuelle Wettervorhersage für den nächsten Tag:





-A05a-  LCD Display steuern


Im letzten Post haben wir uns mit der Kommunikation von Mensch zu Programm, durch ein Potentiometer befasst. Heute wollen wir das Ganze umdrehen und vom Programm Informationen zum Menschen leiten. Das geht am besten mit einem Display um Text anzuzeigen. Am einfachsten und billigsten sind LCD Displays.

HD44780 1602 LCD Module Display Anzeigen 2X16 Zeichen




  • LCD-Zeichen-Modul mit blauem Schwarzlicht
  • Weiten Betrachtungswinkel und hohen Kontrast
  • Industriestandard-HD44780 aequivalent LCD-Kontroller



Ein LCD Display wird durch die Anzahl der Zeichen in einer Reihe und durch die Anzahl der Reihen gekennzeichnet. Das Display oben ist ein 16x2 Display, hat also 2 Reihen und 16 Zeichen pro Reihe. Da die Steuerung eines LCD Displays sehr komplex ist haben einmal ein paar schlaue Leute eine Methode(~Fachbegriff für einen Befehl) geschrieben mit der das ganz einfach ist. Dazu muss man Pin 1, 3, 5, 16 mit dem Ground verbinden und Pin 2 mit +5V. Pin 15 ist für die Hintergrundbeleuchtung zuständig. 5V sind hier das Maximum, ich bevorzuge aber 3.3V da der Text dann nicht so grell wirkt.
Der Vollständigkeit halber: Ein LCD Display kann im 4Bit und im 8Bit Modus betrieben werden, wobei 8Bit nur eine höhere Übertragungsgeschwindigkeit liefern würden, wobei eh das Display an sich und nicht die Datenübertragung der nicht spürbare Flaschenhals ist.
Pin 4, der RS Pin muss zu digital Pin 12, Pin 6, E zu Pin 11, D4 also Pin 11 zum Arduino Pin 5, D5 zu Pin 4, D6 zu Pin 3 und D7 zu Pin 2. Das ganze sieht dann fertig verkabelt so aus:




Zu einem Problem, dass ich hatte und das auch ein Grund war weshalb ich diesen Blog gestartet habe: Ich habe die Kabel immer direkt in die Kontakte des LCD Displays gesteckt was jedoch nie 12 gleichzeitig leitende Kontakte hergestellt hat, da immer eine Kabel so drinsteckte dass es nicht leitend verbunden war. Aus diesem Grund bin ich dazu übergegangen immer eine Steckleiste in die Kontakte des LCD zu löten und dann über das Breadbord eine Verbindung herzustellen.



Um ein LCD Display zu steuern braucht man die Library LiquidCrystal. Ein Bibliothek ist wie ein Sammlung von Befehlen neuen Befehlen die nicht zu den Standard Befehlen gehören. Eine Bibliothek wird über #include <name.h> vor void setup() eingebunden. Nach dem #include <name.h> braucht es kein Semikolon(Strichpunkt). Danach müssen wir dem Programm mit LiquidCrystal name(RS,E,D4,D5,D6,D7); mitteilen wo das LCD Display angeschlossen ist. In meinem Fall ist das LiquidCrystal lcd(12,11,5,4,3,2);. Name.begin(zeichen pro reihe, reihenanzahl); Setzt die Displaygröße fest. Name.setCursor(spalte,reihe); setzt die aktuelle Position fest und name.print("Text"); schreibt einen Text auf das Display. Ich habe als name für das Display mit den oben definierten Pins "lcd" genommen. Mein Beispielsketch zeigt "Hello World!" auf dem Display an, und sieht so aus:



Leider "verschluckt" meine Kamera immer die Schrift, weshalb ich euch das Ergebnis nicht zeigen kann, ihr seht es jedoch in echt, sobald ihr es nachmacht.








-A06- Uhrzeit über ESP8266-01S Wlan Modul

In diesem Post geht es darum, wie man sich über den ESP8266 die aktuelle Uhrzeit holt. Das geht über das NTP (Network Time Protocol).

Für dieses Projekt benötigt man ein ESP 8266 Wlan Modul (hier bei AZDelivery), einen kleinen Arduino, beispielsweise einen billigen Arduino Nano Klon (hier bei AZDelivery), und ein LCD Display.

Das NTP

Das NTP (Network Time Protocol) ist kurz gesagt ein Online Protokoll zur Übertragung der aktuellen Uhrzeit. Diese wird jedoch nicht in einem "normalen" Format übertragen, sondern in Sekunden seit dem Jahr 1900. Dadurch lässt sich zusätzlich zur Zeit auch das Datum ausrechnen. 

Zur Umrechnung in Stunden, Minuten und Sekunden, muss man durch die jeweilige Anzahl an Sekunden Modulo (= Division mit Rest) rechnen. Für Division mit Rest verwendet man das % Zeichen, es hat jedoch nichts mit Prozentrechnung zu tun.

Die Hardware

An den Arduino Nano kann man ganz normal das LCD Display anschließen. Die Verbindung zum ESP 8266 funktioniert seriell, also TX des Nano mit RX des ESP und umgekehrt. Die restliche Verkabelung des ESP zur Stromversorgung, und die Verkabelung zur Programmierung des ESP 8266, habe ich bereits hier erklärt.

Die Sketche


Der ESP8266 Sketch

Für den Sketch des ESP8266 benötigt man die WifiUdp Bibliothek, sowie die ESP8266WiFi Standardbibliothek. Nun muss man zunächst eine Anfrage über die selbstgebaute Funktion sendNTPpacket senden, und anschließend die empfangenen Daten auswerten und umwandeln. Zum Schluss müssen noch die drei Variablen über die serielle Verbindung an den Arduino gesendet werden.

Hier der gesamte Sketch für den ESP8266:


#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

char ssid[] = "************";
char pass[] = "**************";


unsigned int localPort = 2390;

IPAddress timeServer(129, 6, 15, 28);

const int NTP_PACKET_SIZE = 48;

byte packetBuffer[ NTP_PACKET_SIZE];


WiFiUDP udp;

void setup()
{
Serial.begin(115200);

WiFi.begin(ssid, pass);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
}


udp.begin(localPort);

}

void loop()
{
sendNTPpacket(timeServer);
delay(1000);

int cb = udp.parsePacket();

udp.read(packetBuffer, NTP_PACKET_SIZE);

unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);

unsigned long secsSince1900 = highWord << 16 | lowWord;

const unsigned long seventyYears = 2208988800UL;
unsigned long epoch = secsSince1900 - seventyYears;

int stund = (epoch % 86400L) / 3600 + 1;
int minut = (epoch % 3600) / 60;
int sekunde = epoch % 60;
String stunde = String(stund);
String minutestring = String(minut);
if(minut < 10)
{
minutestring = "0" + minutestring;
}


Serial.println(stunde);
Serial.println("|");
Serial.println(minutestring);
Serial.println("|");
Serial.println(sekunde);
Serial.println("|");

delay(10000);
}


unsigned long sendNTPpacket(IPAddress& address)
{
//Serial.println("sending NTP packet...");
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;

// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
}


time_ntp_esp_ardu.ino hosted with ❤ by GitHub

Der Arduino Sketch

Der Arduino liest laufend den seriellen Buffer aus, und speichert die empfangenen Werte über den Befehl setTime(), der Time Bibliothek ab. Diese verwaltet die Zeit, und zählt automatisch mit, schaltet also weiter.

Ohne die (aktuell im Sketch vorhandene) Aktualisierung der Zeit über den ESP alle 10 Sekunden, würde die Uhr pro Stunde bis zu drei Minuten falsch gehen. Der Vorteil des ESP gegenüber einem konventionellen DCF77 Empfänger, ist der wesentliche bessere Preis, bei gleichzeitig mehr Einsatzmöglichkeiten.


Außerdem aktualisiert der Arduino laufend das LCD Display, damit immer die Sekunden genaue Uhrzeit angezeigt wird.


Der Arduino Sketch sieht so aus:


#include <Time.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
Serial.begin(115200);
lcd.begin(20, 4);
lcd.print("Time:");
setTime(12,12,12, 12, 12, 12);
delay(10000);
}

void loop() {
if(Serial.available() > 5)
{
delay(100);
String stund = Serial.readStringUntil('|');
delay(100);
String minut = Serial.readStringUntil('|');
delay(100);
String sekund = Serial.readStringUntil('|');
int stunde = stund.toInt();
int minutee = minut.toInt();
int sekunde = sekund.toInt();
setTime(stunde, minutee, sekunde, 12, 12, 12); //stunde, minute, sekunde, tag, monat, jahr
}
lcd.setCursor(0, 1);
lcd.print(hour());
lcd.setCursor(2, 1);
lcd.print(":");
lcd.setCursor(3, 1);
lcd.print(minute());
lcd.setCursor(5, 1);
lcd.print(":");
lcd.setCursor(6, 1);
lcd.print(second());
delay(10);
}

a

time_ntp_ardu.ino hosted with ❤ by GitHub






-A07- Wetterstation - Basis


Im zweiten Artikel über die Wetterstation für Zuhause geht es darum, wie man die Basisstation baut, und sich die Temperatur auf dem LCD Display anzeigen lässt.

Wie man den Außensensor, inklusive DHT11 Temperatursensor (hier auf Amazon) baut und programmiert, habe ich bereits im vorherigen Post beschrieben.

Die Basisstation

Die Basis besteht aus drei Teilen: Einem LCD Display (hier bei AZDelivery), dem 433Mhz Empfänger (Sender und Empfänger Set hier bei AZDelivery), und einem etwas größeren Arduino (hier bei AZDelivery).

Die Verkabelung ist leider etwas komplizierter, da die VirtualWire Bibliothek zum Empfangen der Daten und die LiquidCrystal Bibliothek zum Verwenden des LCD Displays teilweise inkompatibel sind.

So kann man das LCD Display nicht wie im Beispielsketch der Liquid Crystal Bibliothek anschließen, sondern muss einige Pins tauschen, da VirtualWire diese auch als Standardpins verwendet. Den genauen Hintergrund konnte ich auch nach dem Lesen mehrerer Seiten nicht herausfinden.

Mit der folgenden Verkabelung funktioniert es jedoch:

Leider gibt es den 433Mhz Empfänger nicht in Fritzing: VCC muss mit den +5V verbunden werden, GND mit dem Ground und ein Data Pin mit digital Pin 11 des Arduino.


Der Sketch

Der Sketch ist, abgesehen von der komplizierten Belegung der Pins, sehr simpel. Zunächst muss man die Temperatur über die VirtualWire Bibliothek und den 433Mhz Empfänger empfangen, und anschließend über lcd.println() auf dem Display ausgeben. Der Code ist relativ selbsterklärend:


#include <LiquidCrystal.h>
#include <VirtualWire.h>
LiquidCrystal lcd(4, 9, 5, 13, 3, 2);

void setup() {
lcd.begin(20, 4);
lcd.setCursor(0,0);
lcd.print("outdoor temperature:");

vw_rx_start();
vw_set_ptt_inverted(true);
vw_set_rx_pin(11);
vw_set_tx_pin(8);
vw_setup(2000);


Serial.begin(9600);
Serial.println("Start.");
lcd.setCursor(0, 4);
lcd.print("michaelsarduino");
}

void loop() {
lcd.setCursor(0,1);
uint8_t message_array[VW_MAX_MESSAGE_LEN];
uint8_t laenge = VW_MAX_MESSAGE_LEN;
vw_wait_rx();


vw_get_message(message_array, &laenge);
lcd.print((char)message_array[0]);
lcd.print((char)message_array[1]);
lcd.print("C");
Serial.print((char)message_array[0]);
Serial.println((char)message_array[1]);

}

wetterstation_basis_ardu.ino hosted with ❤ by GitHub


Weitere Ausbaumöglichkeiten

Auch für die Basis gibt es natürlich weitere Ausbaumöglichkeiten. So könnte man nicht nur zusätzliche Messwerte erheben, sondern natürlich auch Statistiken auf einer angeschlossenen SD Karte speichern, und diese dann auf einem Display visualisieren. 

Wenn man den Außensensor und die Basis jedoch wie beschrieben baut, erhält man eine ganz ordentliche Wetterstation, welche laufend die aktuelle Außentemperatur anzeigt.






-A08- Wetterstation - Außensensor

In diesem und dem nächsten Artikel geht es darum, wie man eine kleine Wetterstation für Zuhause baut, welche einem die aktuelle Außentemperatur anzeigen kann.

433 MHz Funk - Sende und Empfänger Modul


  • - Transmitter und Receiver Set: XY-FST Sender/ Transmitter + XY-MK-5V Empfänger / Receiver
  • - Ermöglicht Schaltung von 433 MHz Geräten (z.B. Funksteckdosen) mit Raspberry oder Arduino
  • - Kompatibel für Breadboards (nicht im Lieferumfang)
  • - Lieferumfang: 1x 433 MHz XY-FST Sender, 1x 433 MHz XY-MK-5V Empfänger





Der Außensensor

In diesem Post möchte ich den Bau, und die Programmierung des Außensensors zeigen. Dieser besteht aus nur drei Teilen. Einem Temperatursensor, dafür verwende ich den DHT11 (hier auf Amazon) und einem kleinen Arduino/Mikrocontroller, hierfür bietet sich der Arduino Nano, oder ein preiswerter Klon dessen (hier auf az-delivery.com), an,  da er zwar ein vollwertiger Arduino, inklusive einfacher Programmierung über USB ist, jedoch sehr klein ist, und nur wenig Strom verbraucht.

Zusätzlich benötigt man einen 433Mhz Sender und Empfänger Set (hier bei AZDelivery). Über dieses kann der Außensensor die aktuelle Temperatur an den Empfänger, also letztendlich das LCD Display (hier bei AZDelivery), senden.

Die Verbindung der Geräte mit dem Nano ist einfach: Der DHT 11 hat drei beschriftete Pins, GND muss mit dem Ground verbunden werden, S mit einem digital Pin des Arduino, und der mittlere Pin mit den +5V des Arduino Nano. Auch die Pins des 433Mhz Senders sind beschriftet, VCC mit +5V, GND mit dem Ground, und ATAD mit einem digital Pin des Arduino.


Der Sketch

Das Auslesen des DHT11 Temperatursensors geht über die dht11 Bibliothek, durch den Befehl DHT11.temperature(). Das Übertragen der Temperatur gestaltet sich etwas komplizierter, da der Befehl zum Senden von Daten, der verwendeten Bibliothek VirtualWire, nur bestimmte Formate akzeptiert (siehe Code). 

Das Einzige, was man noch ändern muss, sind die Datenpins des DHT11 und des 433Mhz Senders. 
Der fertige Code für den Sender sieht so aus:

#include <dht11.h>
#include <VirtualWire.h>

dht11 DHT11;

#define DHT11PIN 3

void setup()
{
vw_set_ptt_inverted(true);
vw_set_tx_pin(8);
vw_setup(2000);
Serial.begin(9600);
Serial.println("DHT11 TEST PROGRAM ");
Serial.print("LIBRARY VERSION: ");
Serial.println(DHT11LIB_VERSION);
Serial.println();
}

void loop()
{

int chk = DHT11.read(DHT11PIN);
int temp = DHT11.temperature;
char *temperatur = "0";
switch (temp)
{
case 10:
temperatur = "10";
break;
case 11:
temperatur = "11";
break;
case 12:
temperatur = "12";
break;
case 13:
temperatur = "13";
break;
case 14:
temperatur = "14";
break;
case 15:
temperatur = "15";
break;
case 16:
temperatur = "16";
break;
case 17:
temperatur = "17";
break;
case 18:
temperatur = "18";
break;
case 19:
temperatur = "19";
break;
case 20:
temperatur = "20";
break;
case 21:
temperatur = "21";
break;
case 22:
temperatur = "22";
break;
case 23:
temperatur = "23";
break;
case 24:
temperatur = "24";
break;
case 25:
temperatur = "25";
break;
case 26:
temperatur = "26";
break;
case 27:
temperatur = "27";
break;
case 28:
temperatur = "28";
break;
}
Serial.println(temperatur);
vw_send((uint8_t*)temperatur, 2);
vw_wait_tx();
delay(200);
}


Weitere Ausbaumöglichkeiten

Abhängig davon, ob der Außensensor über die Steckdose, oder über eine Batterie betrieben wird, könnte man die Frequenz des Sendens der aktuellen Temperatur herunterstellen. So kann man die Temperatur etwa nur jede Minute senden, und dazwischen in den Stand-by Modus gehen. Die Verwendung des Stand-by Modus mit dem Arduino, habe ich bereits hier erklärt.


Kommentare:
Zeilen 26 bis 85 koennen doch auch durch "temperature = String(temp);" erfuellt werden, oder?Antworten

Antworten
Hatte ich auch probiert, funktioniert aber leider nicht.
Fehlermeldung(wenn man switch ausklammer):
wetterstation_sender.ino: In function 'void loop()':
wetterstation_sender.ino:25:33: error: cannot convert 'String' to 'char*' in initialization
Fehler beim Kompilieren.

Antworten
den ganzen switch rausschmeißen und dafür..
sprintf(temperatur, "%d", temp);
.. einsetzen.





-A09- Temperaturserver  ESP8266-01S Wlan Modul

In diesem Post geht es darum, wie man einen Temperaturserver baut und programmiert, über den man jederzeit die aktuelle Temperatur über eine Website abfragen kann.

Die Hardware

Zum Messen der Temperatur verwende ich den DHT11 (hier auf Amazon). Dieser kann gleichzeitig auch noch die Luftfeuchtigkeit messen. Zum Auslesen des Sensors verwende ich einen Arduino Uno (hier bei AZDelivery). Dieser sendet dann auch die Temperatur an den ESP 8266 (hier bei AZDelivery), welcher sie als Webserver im Wlan Netz/ Internet bereitstellt.

Der DHT11 hat drei Pins. S muss mit einem digital Pin des Arduino verbunden werden, - mit dem Ground und der mittlere Pin mit den +5V des Arduino. Die Verkabelung des ESP 8266 ist etwas komplizierter. Aus diesem Grund gibt es einen extra Post zur Verbindung und Programmierung des ESP 8266 mit dem Arduino. Im eigentlich Betrieb muss TX mit RX und RX mit TX zur seriellen Kommunikation mit dem Arduino verbunden werden.

Die Software

Für dieses Projekt benötigt man zwei Sketche. Der Erste ist der Arduino Sketch. Dieser muss über die DHT11 Bibliothek die aktuelle Temperatur auslesen, und per serieller Verbindung an den ESP 8266 senden.

Hier der Code dazu:

#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 2

void setup()
{
Serial.begin(115200);
}

void loop()
{
DHT11.read(DHT11PIN);
float temp = DHT11.temperature - 1.0;
Serial.println(temp);
delay(2000);
}

a

temp_server_ardu.ino hosted with ❤ by GitHub

Der zweite Sketch, ist der Sketch für den ESP 8266. Dieser muss eine Verbindung mit einem Wlan Netzwerk herstellen, und einen Webserver starten. Danach muss er über die serielle Verbindung mit dem Arduino laufend die aktuelle Temperatur in einer Variable abspeichern, und so die Website aktuell halten.

Der Code hierfür sieht so aus:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>

String temp = "Bisher noch nichts empfangen";
const char* ssid = "***************";
const char* password = "***************";
MDNSResponder mdns;

ESP8266WebServer server(80);




void handleRoot() {
server.send(200, "text/html", "<html> Aktuelle Temperatur: ");
server.send(200, "text/html", temp);
server.send(200, "text/html", "</html>");
}

void handleNotFound(){
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}

void setup(void){
Serial.begin(115200);
WiFi.begin(ssid, password);

// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}

if (mdns.begin("esp8266", WiFi.localIP())) {
//Serial.println("MDNS responder started");
}

server.on("/", handleRoot);

server.on("/inline", [](){
server.send(200, "text/plain", "this works as well");
});

server.onNotFound(handleNotFound);

server.begin();
//Serial.println("HTTP server started");
}


void loop(void){
if(Serial.available() > 0)
{
temp = Serial.readString();
}

mdns.update();
server.handleClient();
}

a
temp_server_esp8266.ino hosted with ❤ by GitHub

Sobald man nun die Standardadresse des ESP 8266 im Webbrowser öffnet (siehe verlinkter Post) bekommt man die aktuelle Temperatur angezeigt:






-A10- Arduino IDE Version 1.6.6

In diesem Post möchte ich die neue Arduino IDE Version 1.6.6 mit viele tollen Neuerungen vorstellen.

a



Zunächst einmal müsst ihr dazu natürlich die Arduino IDE Version 1.6.6 hier für euer System herunterladen. Dabei können beide Versionen natürlich parallel verwendet werden. Dadurch könnt ihr die Neuerungen erst testen, bevor ihr die alte Version löscht.

Der Serielle Plotter

Der Serieller Plotter ist eine Art automatischer Diagramm Ersteller. Dabei muss man vom Arduino nur Daten über die serielle Verbindung senden, und die IDE erstellt automatisch ein Zeit - Messwert Diagramm. Dabei wird auch die Skalierung immer entsprechend angepasst, so dass die Werte schön ablesbar sind. Ihr könnt den Plotter über Werkzeuge > Serieller Plotter in der Arduino IDE abrufen.

Der Bibliotheksverwalter

Ab Version 1.6.6 gibt es den Bibliotheksverwalter. Das ist ein zentraler Ort, um die installierten Bibliotheken zu verwalten. Der große Vorteil ist, das man automatisch angezeigt bekommt, für welche Bibliotheken es ein Update gäbe. Dank eines Update Buttons kann man sie dann auch mit einem Klick updaten. Ihr findet den Bibliotheksverwalter unter Sketch > Bibliothek einbinden > Bibliotheken verwalten.


Zusätzlich gibt es eine Liste mit allen Bibliotheken, welche man auch über einen Knopfdruck installieren kann.

Arduino ISP

Zusätzlich wurde die In System Programmer Funktionen erweitert. So kann man nun mit mehr Boards über die Arduino IDE seinen AVR Mikrocontroller programmieren:



Bugfixes

Es sollen eine ganze Menge an Bugs gefixt worden sein. Eine ganze Liste der Bugfixes findet ihr hier. Es sind jedoch auch neue Bugs entstanden, beispielsweise erscheint bei mir die Meldung, dass keine boards.txt gefunden wurde. Trotzdem funktioniert bei mir alles einwandfrei.


Man liest jedoch auch von Personen, bei denen die neue Version überhaupt nicht funktioniert.

Ich würde euch empfehlen sie einfach mal herunter zu laden und auszuprobieren, da es doch eine Menge cooler neuer Features gibt. Wenn alles klappt ist es prima, wenn nicht ist nach einem Löschen des Ordners der Spuk wieder vorbei.








-A11- Heißer Draht mit dem Arduino

In diesem Post geht es darum, wie man das Spiel "Heißer Draht" mit dem Arduino nachbauen kann. Heißer Draht ist ein Geschicklichkeitsspiel, bei dem man mit einer Metallöse einen (gebogenen) Draht entlangfahren muss, ohne ihn zu berühren. Berührt man den Draht, so schließt sich der Stromkreis, und ein Licht leuchtet/ein Ton ertönt und der Spieler hat verloren.



By Ronnierber (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0) or GFDL (http://www.gnu.org/copyleft/fdl.html)], via Wikimedia Commons

Der Aufbau von heißer Draht

Zunächst einmal benötigt man einen Kuperdraht, welcher logischerweise nicht isoliert sein darf, da sonst ein Kontakt der Öse mit dem Draht nicht den Stromkreislauf schließen würde. Dabei verbindet man über den Kuperdraht die +5V des Arduino mit einem analog Pin, dazwischen sollte man jedoch zusätzlich noch einen Widerstand hinzufügen, damit nicht zu viel Strom fließt.

Die Kupferöse muss man mit dem Ground des Arduino verbinden. Dadurch wird sobald ein Kontakt hergestellt wird der analog Pin auf 0 gezogen, und der Spieler hat die Runde verloren.

Um dies zu signalisieren kann man beispielsweise eine LED an Pin 13 anschließen, welche bei einer Niederlage anfängt schnell zu blinken.

Die Software

Zur Auswertung muss man im Sketch eigentlich nur überprüfen, ob der Status des analog Pins nicht unter einen gewissen Richtwert fällt. Dann soll die LED blinken.

void setup() {
pinMode(13, OUTPUT);

}

void loop() {
if(analogRead(3) < 50)
{
for(int x = 0;x < 100; x++)
{
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);
}
}

}


heißer_draht.ino hosted with ❤ by GitHub

Durch ein anpassen des Richtwertes kann man ganz leicht den Schwierigkeitsgrad des Spiels erhöhen, da dadurch schon eine sehr nahe Öse am Draht zu einer Niederlage führen würde.

Ansonsten kann man das Spiel ohne großen Umstand, auch nach Fertigstellung, ändern, indem man einfach den Kuperdraht in eine andere Form verbiegt, und dadurch den Parcours ändert.




-A12- Sensordaten auf SD Karte speichern

In diesem Post möchte ich ein kleines Anwendungsbeispiel zur Verwendung von SD Karten zum Speichern von Sensorwerten liefern. Dabei möchte ich nur mit dem Arduino die Temperatur messen, und dann die Temperatur mit der aktuellen Zeit auf der SD Karte speichern.


Die Hardware

Auf der Hardware Seite benötigt man nur einen Arduino (Klon) (hier bei AZDelivery), sowie einen SD Card Reader samt SD Karte. Dieser Sketch funktioniert prinzipiell mit jedem SD Card Reader, da sie alle über SPI mit dem Arudino kommunizieren. Dabei kann ich euch diesen SD Card Reader auf Amazon empfehlen. 
Wie man den Arduino mit dem SD Card Reader verbindet, habe ich bereits hier erklärt.

Zur Messung der Temperatur benötigt man durch einen kleinen Trick keine Zusatzhardware, sondern nur den Arduino. Wie das geht habe ich in diesem Post erklärt.

Der Sketch

Um jeweils die aktuelle Uhrzeit zu haben, muss man vor dem Einsatz des Sketches die aktuelle Uhrzeit in der Methode setTime() angeben. Das ist die einfachste und kostengünstigste Art. Dabei kann die Uhr jedoch bei längeren Einsätzen leider start abweichen. Welche Arten die Zeit zu bekommen es für den Arduino gibt, habe ich bereits hier erklärt.

Um die Temperatur zu messen kann man einfach die vordefinierte Funktion des verlinkten Post nehmen und anwenden, durch aufrufen von readTemp(). 

Um die Werte nun auf die SD Karte zu speichern, verkette ich das Datum als String mit der Uhrzeit als String und der gemessenen Temperatur.

Der gesamte Arduino Sketch sieht so aus:

#include <SPI.h>
#include <SD.h>
#include <Time.h>

File Datei;

void setup() {
Serial.begin(9600);

setTime(13,58,10,01,11,15);

Serial.print(hour());
Serial.print(":");
Serial.print(minute());
Serial.print(":");
Serial.print(second());
Serial.print("|");
Serial.print(day());
Serial.print(".");
Serial.print(month());
Serial.print(".");
Serial.println(year());

pinMode(10, OUTPUT);

SD.begin(10);

Datei = SD.open("temp.txt", FILE_WRITE);


}

void loop() {
long temp = readTemp();
long zwe = temp / 10000;
long temperaturinc = zwe - 5;
int tag_g = day();
int mon_g = month();
int jahr_g = year();
String doppel = " : ";
String datum = tag_g + doppel + mon_g + doppel + jahr_g;
int stunde_g = hour();
int minute_g = minute();
String zeit = stunde_g + doppel + minute_g;
String zeile = datum + " | " + zeit + " | " + temperaturinc;
Datei.println(zeile);
Datei.flush();

delay(60000);
}

long readTemp() {
long result;
// Read temperature sensor against 1.1V reference
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = (result - 125) * 1075;
return result;
}

Temp_SD_Ardu.ino hosted with ❤ by GitHub

Nun wird jede Minute die aktuelle Raumtemperatur als weitere Zeile in das Textdokument TEMP hinzugefügt.

Falls man vorhat die Daten genauer auszuwerten, sollte man überlegen sie in eine SQL Tabelle einzufügen. Dadurch kann man Abfragen nach dem Typus: Wann war es wärmer als 25 °C, oder was ist die Durchschnittstemperatur um 20:00 stellen. 




-A13- Arbeiten mit Dateien auf SD Karte

In diesem Post geht es darum, wie man mittels der SD Library des Arduino mit Dateien arbeitet, welche auf einer SD Karte gespeichert sind, welche über einen SD Card Reader mit dem Arduino verbunden ist.

Wer den gestrigen Post verpasst hat, empfehle ich, ihn sich noch anzuschauen, da erklärt, wie man einen SD Card Reader mit dem Arduino korrekt verbindet und einen ersten Test durchführt. Prinzipiell kann man jeden SD Card Reader für den Arduino mit der SD Library benutzen. Ich kann euch diesen SD Card Reader auf Amazon empfehlen.

Um eure SD Karte überhaupt zu verwenden, müsst ihr sie erst initialisieren. Das funktioniert über den Befehl SD.begin(). Dabei muss man in Klammern den SS beziehungsweise CS Pin eures Arduinos angeben. Beim Arduino Uno würde man die SD Karte also über SD.begin(10) initialisieren. Dieser Befehl würde bei einem Fehler eine Fehlermeldung zurück geben. Deshalb sollte man SD.begin() in eine if Abfrage stecken, und im Fall der Fälle den Sketch abbrechen lassen.

Um eine Datei zu bearbeiten beziehungsweise zu lesen, muss man sie, wie am PC, erst einmal öffnen: Objekt Datei = SD.open("Name der Datei", Art). Dabei gibt es zwei unterschiedliche Arten eine Datei zu öffnen. Den "Lesemodus" und den "Schreibmodus". Wenn du eine neue Datei erstellen willst, so öffnest du sie einfach im Schreibmodus und sie wird automatisch erstellt. Der "Lesemodus" wird durch FILE_READ und der "Schreibmodus" durch FILE_WRITE angegeben.

Sobald man das Lesen/Schreiben einer Datei abgeschlossen hat, muss man sie über Datei.close() schließen. Datei steht hierbei stellvertretend für das Objekt der Klasse File, das du erzeugt hast, durch das Öffnen einer Datei.

Hier ein kleines Codebeispiel zum Erstellen/Öffnen einer Datei:

#include <SPI.h>
#include <SD.h>

File Datei;

void setup() {
Serial.begin(9600);

if(!SD.begin(10))
{
Serial.println("Verbindung zur SD Karte fehlgeschlagen");
return;
}


Datei = SD.open("beispiel.txt", FILE_WRITE);
Datei.close();
}


void loop() {
// put your main code here, to run repeatedly:

}


Datein_oeffnen.ino hosted with ❤ by GitHub

Das Schreiben in eine Datei beziehungsweise das Auslesen einer Datei gestaltet sich sehr ähnlich, wie das Arbeiten mit einer seriellen Verbindung. Das bedeutet zum Schreiben in eine Datei kann man den Befehl Datei.println("Dieser Text wird in die Datei geschrieben"); verwenden.

Um eine Datei auszulesen muss man die Funktion Datei.read() verwenden. Dabei gibt read immer nur das nächste Zeichen zurück. Um also die gesamte Datei auszulesen, muss man den Befehl in einer while Schleife unterbringen, welche über Datei.available() überprüft, ob noch Zeichen "übrig" sind.

Ein einfaches Beispiel zum Schreiben in eine Datei, und dem Auslesen aus einer Datei, sieht so aus:

#include <SPI.h>
#include <SD.h>

File Datei;

void setup() {
Serial.begin(9600);

if(!SD.begin(10))
{
Serial.println("Verbindung zur SD Karte fehlgeschlagen");
return;
}


Datei = SD.open("beispiel.txt", FILE_WRITE);
Datei.println("Dieser Text wird in die Datei geschrieben");
Datei.close();

Datei = SD.open("beispiel.txt", FILE_READ);
while (Datei.available()) {
Serial.write(Datei.read());
}
Serial.println(" ");
Datei.close();

}


void loop() {
// put your main code here, to run repeatedly:

}

Datei_lesen_schreiben.ino hosted with ❤ by GitHub







-A14- SD Card Reader für den Arduino

In diesem Post geht es darum, wie man ein SD Karten Modul mit dem Arduino verbindet. Dadurch kann man sehr leicht und kostengünstig den Speicher des Arduino mittels SD Karten extrem erweitern.


Die Verkabelung

Welchen SD Card Reader für den Arduino man wählt, ist eigentlich egal, da sie alle mittels dem SPI Protokoll mit dem Arduino kommunizieren. Dementsprechend kann man sie alle mit der Standard SD Library des Arduino verwenden. Hier findet ihr meinen SD Card Reader für den Arduino auf Amazon.  

Da der Reader und der Arduino über SPI kommunizieren, muss man nur 6 Pins verbinden. Dabei gibt es vier Datenpins: MISO, MOSI, SCK und SS, manchmal auch als CS bezeichnet. Dabei könnt ihr für MISO, MOSI und SCK entweder den SPI Header verwenden, oder Pin 11 bis 13, wobei sie mit dem selben Pin am Mikrocontroller verbunden sind. Das heißt, wenn du den SPI Header statt den digital Pins verwendest, kannst du die digital Pins trotzdem nicht anderweitig verwenden. SS beziehungsweise CS ist am Arduino Uno immer digital Pin 10.

Das Pinout des SPI Headers des Uno ist:


1: MISO, oder digital 12
2: Ground
3: SCK, oder digital 13
4: MOSI, oder digital 11
5: Reset
6: +5V

Solltet ihr einen anderen Arduino als den Arduino Uno verwenden, können die Pins abweichen, das Prinzip ist jedoch das Selbe. Hier findet ihr das Pinout der Arduinos im Überblick.

Bei meinem SD Reader gibt es komischerweise 2 Ground Pins und 5V und 3.3V. Diese müssen alle vier angeschlossen werden, damit der Reader aktiviert ist.


SD Card Modul
SD Karten-Leser Modul SPI SD
Card Sockel für Arduino ARM MCU



  • SD Card Modul für Arduino
  • Lesen und Schreiben
  • SD SPI Pin Ausgang, MOSI, SCK, MISO und CS
  • Eingangsspannung: 3,3V / 5V

Die Software

Praktischerweise gibt es, wie bereits erwähnt, eine einheitliche SD Library für den Arduino, welche mit allen Modellen von SD Card Reader zusammen arbeiten kann. Dabei ist die Bibliothek schon mit der Arduino IDE installiert, muss also nur noch im Sketch nachgeladen werden.

Zusätzlich ist ein Beispielsketch (Datei > Beispiele > SD > CardInfo) mitgeliefert, mithilfe dessen man die Schaltung, den SD Card Reader und die SD Karte selbst testen kann. Dabei müsst ihr nur angeben, was der SS beziehungsweise CS Pin eures Arduinos ist, beim Uno beispielsweise 10.

Hier ist der Sketch nochmal abgebildet:

/*
SD card test

This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.

The circuit:
* SD card attached to SPI bus as follows:
** MOSI - pin 11 on Arduino Uno/Duemilanove/Diecimila
** MISO - pin 12 on Arduino Uno/Duemilanove/Diecimila
** CLK - pin 13 on Arduino Uno/Duemilanove/Diecimila
** CS - depends on your SD card shield or module.
Pin 4 used here for consistency with other Arduino examples


created 28 Mar 2011
by Limor Fried
modified 9 Apr 2012
by Tom Igoe
*/
// include the SD library:
#include <SPI.h>
#include <SD.h>

// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 10;

void setup()
{
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}


Serial.print("\nInitializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(10, OUTPUT); // change this to 53 on a mega


// we'll use the initialization code from the utility libraries
// since we're just testing if the card is working!
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
Serial.println("initialization failed. Things to check:");
Serial.println("* is a card is inserted?");
Serial.println("* Is your wiring correct?");
Serial.println("* did you change the chipSelect pin to match your shield or module?");
return;
} else {
Serial.println("Wiring is correct and a card is present.");
}

// print the type of card
Serial.print("\nCard type: ");
switch (card.type()) {
case SD_CARD_TYPE_SD1:
Serial.println("SD1");
break;
case SD_CARD_TYPE_SD2:
Serial.println("SD2");
break;
case SD_CARD_TYPE_SDHC:
Serial.println("SDHC");
break;
default:
Serial.println("Unknown");
}

// Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
if (!volume.init(card)) {
Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
return;
}


// print the type and size of the first FAT-type volume
uint32_t volumesize;
Serial.print("\nVolume type is FAT");
Serial.println(volume.fatType(), DEC);
Serial.println();

volumesize = volume.blocksPerCluster(); // clusters are collections of blocks
volumesize *= volume.clusterCount(); // we'll have a lot of clusters
volumesize *= 512; // SD card blocks are always 512 bytes
Serial.print("Volume size (bytes): ");
Serial.println(volumesize);
Serial.print("Volume size (Kbytes): ");
volumesize /= 1024;
Serial.println(volumesize);
Serial.print("Volume size (Mbytes): ");
volumesize /= 1024;
Serial.println(volumesize);


Serial.println("\nFiles found on the card (name, date and size in bytes): ");
root.openRoot(volume);

// list all files in the card with date and size
root.ls(LS_R | LS_DATE | LS_SIZE);
}


void loop(void) {

}

SD_Reader_TestSketch.ino hosted with ❤ by GitHub



Wenn ihr nun nach dem Upload des Sketches die serielle Konsole mit Datenrate 9600 öffnet, werdet ihr die, auf der SD Karte gespeicherten, Dateien sehen:



Fazit

SD Karten sind eine gute Möglichkeit die Speicherkapazität des Arduinos zu erweitern, insbesondere da sie billiger und größer sind als externer EEPROM, und zusätzlich dank der SPI Kommunikation einfach zu verbinden. Sehr empfehlen kann ich euch für den Einstieg diesen SD Card Reader auf Amazon.

Im nächsten Post geht es darum, wie man mit Dateien auf der SD Karte mit dem Arduino arbeitet.





-A15- Temperatur messen nur mit dem Arduino - ohne ext. Sensor

In diesem Post geht es darum, wie man die Temperatur mit dem Arduino messen kann, ohne einen externen Sensor zu benötigen.

Die Funktionsweise

Dieser kleine Trick funktioniert leider nicht bei allen Arduinos, sondern nur bei Arduinos mit einem ATmega328P. Mit einem ATmega168P funktioniert das Ganze auch, dieser wird jedoch in keinem "offiziellen" Arduino, sondern nur in manchen Klonen, verwendet. Eventuell finden sich jedoch auch noch weitere unterstützte Mikrocontroller. Im Zweifelsfall also einfach mal ausprobieren.

Der Grund warum, das Thermometer nur mit diesen Arduinos funktioniert ist, dass im 328P und im 168P beim Switch, welches entscheidet welcher Pin mit dem Analog zu Digital Converter verbunden wird, einen "leere" Verbindung ist. Diese hat man genutzt, um ein rudimentäres Thermometer einzubauen. 

Dieses ist jedoch nicht so genau. Im Datenblatt steht eine Abweichung von +/- 10 °C. Wenn man das Thermometer jedoch einmal kalibriert, kann man es bis zu ca. 1°C genau bekommen.

Die Funktion zum Auslesen des Thermometers ist nicht in der Arduino Bibliothek dabei, weshalb man sie im jeweiligen Sketch erst noch definieren muss. Dabei kann der Code einfach von hier kopiert werden. 

Hier einmal die Funktion inklusive Beispielsketch zum Testen und Kalibrieren:

long readTemp() {
long result;
// Read temperature sensor against 1.1V reference
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3);
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Convert
while (bit_is_set(ADCSRA,ADSC));
result = ADCL;
result |= ADCH<<8;
result = (result - 125) * 1075;
return result;
}

void setup() {
Serial.begin(9600);
}

void loop() {
Serial.println( readTemp(), DEC );
delay(1000);
}

Temperatur_Ardu.ino hosted with ❤ by GitHub

Der Wert wird in Milli °C angegeben. Das bedeutet 20000 steht für 20°C. Um das Thermometer zu kalibrieren solltet ihr euch ein genaues Thermometer besorgen, und die Temperaturdifferenz zum Messwert des Arduino hinzu addieren beziehungsweise subtrahieren.

Beim mir war die Differenz immer fast konstant +5°C. Durch abziehen von 5, kann mein Arduino Thermometer jetzt sehr genau messen.

Wem das nicht genau genug ist, kann ich diesen Sensor für Temperatur und Feuchtigkeit (DHT11) empfehlen. Wer es noch genau will, wählt den DHT22.





-A16- Externen Reset Button

In diesem Post geht es darum, wie man sich einen externen Reset Button für einen Mikrocontroller/Arduino baut.

Wozu einen externen Reset Button?


Wie du sicherlich weißt, gibt es auf dem Arduino Board ja bereits einen Reset Button(der weiße Button neben dem USB Port) , weshalb sich die Frage aufdrängt wozu man einen externen Reset Button benötigt.

Das Problem mit dem Reset Button ist, dass es sehr leicht verdeckt beziehungsweise verbaut wird, und dadurch nicht mehr erreichbar ist. Das tritt meistens schon dann ein, wenn man ein Shield auf den Arduino setzt. Spätestens jedoch, wenn man den Arduino in einem Projekt verbaut, eventuell sogar ohne Arduino Board, also nur den Mikrocontroller.

Funktionsweise

(Fast) jeder Mikrocontroller hat einen Reset Pin. Dieser Pin resetet den Mikrocontroller, startet ihn also neu, sobald er auf einen gewissen Zustand gezogen wird, in den meisten Fällen auf LOW. Das bedeutet, man muss nur einen Button bauen, welcher den Reset Pin über einen Pull Up Widerstand mit +5 V verbindet, und sobald der Knopf gedrückt wird mit dem Ground. 

Also Schaltung sieht dass so aus:


Wenn ihr nun den Button drückt, so startet der Arduino neu, auch alle Variablen werden zurückgesetzt. Solltet ihr etwas speichern wollen, so müsst ihr dies im EEPROM des Mikrocontroller tun.




-A17- Widerstände messen

In diesem Post geht es darum, wie man die Stärke eines unbekannten Widerstands mit dem Arduino messen kann.




Das Prinzip zur Messung eines unbekannten Widerstands beruht darauf, dass man zwei Widerstände in Serie schaltet, wobei die Stärke des einen bekannt sein muss. Außerdem sollte der bekannte Widerstand nicht zu klein sein (ungefähr 1kOhm), da der unbekannte Widerstand sehr klein sein könnte und durch zwei kleine Widerstände sehr viel Strom fließen könnte.

Durch das Messen der abfallenden Spannung kann man auf das Verhältnis schließen, wodurch man die Größe des unbekannten Widerstands errechnen kann.

float Ausgangsspannung = 5.0;
int MessPin = 5;
int R1=1000.0;
long Messwert;
float SpannungR2;
float Widerstand;

void setup()
{
Serial.begin(9600);
Serial.println("Widerstand messen:");
Serial.println();
}

void loop()
{
//5 mal Messen und Mittelwert bilden
Messwert=0;
for(int i=0;i<5;i++){
Messwert+=analogRead(MessPin);
}
Messwert=trunc(Messwert/5);

//Berechnen der Spannung
SpannungR2=(Ausgangsspannung/1023.0)*Messwert;
Serial.print("Spannung an R2: ");
Serial.print(SpannungR2,2);
Serial.println(" Volt!");
//Ausrechnen des Widerstands mit Formel: (R2 = R1 * (U2/U1))
Widerstand=R1*(SpannungR2/(Ausgangsspannung-SpannungR2));
Serial.print("Der Widerstand hat ");
Serial.print(Widerstand,2);
Serial.println(" Ohm.");
Serial.println();
delay(5000);
}

widerstand_messen.ino hosted with ❤ by GitHub


So sieht die Schaltung von oben als Fritzingschaltung aus:


Nach dem Upload des Sketches auf den Arduino und das Aufbauen der Schaltung müsst ihr am PC die serielle Konsole öffnen. Nun bekommt ihr alle 10 Sekunden die Stärke des momentanen Widerstands angezeigt.



In diesem Fall steckt ein 10kOhm Widerstand in der Schaltung, und der Arduino errechnete, dass er 10,1kOhm groß wäre. Der Hauptgrund für diese Abweichung ist, dass wir im Sketch von 5 V Spannung des Arduino ausgehen. Das ist jedoch falsch. 

Um genauer zu messen, sollte man deshalb an den AREF Pin des Arduino eine "gesicherte" Spannung anschließen, etwa 3 AA Batterien, oder ein externes 5 V Spannungsgerät. Wenn man nun die neue Spannung im Sketch einträgt und erneut messen lässt ist das Ergebnis wesentlich genauer.

Eine weitere Möglichkeit wäre es, einen genaueren Referenzwiderstand zu wählen, meiner etwa hat eine Toleranz von 5%, was zum Messen eher ungünstig ist.
michaelsarduino: Widerstände messen





-A18- ESP 8266 als Wlan Router und Wlan Client - ESP8266-01S Wlan Modul

In diesem Post geht es darum, wie man den ESP 8266 (hier bei AZDelivery) sowohl als Wlan Client, im Netzwerk deines Wlan Routers, aber auch parallel dazu als eigenständigen Wlan Router verwenden kannst.



Wozu zwei Wlan Netzwerke?

Der große Vorteil davon den ESP als Wlan Client und als Wlan Router gleichzeitig zu verwenden, ist dass man gleichzeitig die Internetverbindung vom Wlan Router bekommt, und so beispielsweise Daten online laden kann, und man trotzdem den ESP mobil und unabhängig, also ohne einen externen Wlan Router verwenden kann. Dieses Anforderungsprofil tritt wahrscheinlich häufiger bei mobilen Roboter/Gefährten auf, natürlich gibt es jedoch auch noch weitere Anwendungsfälle.

Der Arduino Sketch

Der Arduino Sketch für den ESP besteht aus dem "normalen" Aufbau eines Wlan Netzwerkes, und danach der Verbindung mit einem bereits bestehenden Wlan Netzwerk. Wie man den ESP 8266 als Wlan Router konfiguriert, habe ich bereits hier erklärt, und wie man den ESP 8266 mit einem Wlan Netzwerk verbindet, hier.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <WiFiUdp.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>


ESP8266WebServer server(80);

const char* ssid = "******************"; //Name des bestehenden Wlan Netzwerks
const char* password = "**************"; //Passwort des bestehenden Wlan Netzwerks

MDNSResponder mdns;
void setup() {
Serial.begin(115200);

WiFi.softAP("esp8266_ap", "michaelsarduino"); //Name und Passwort des neuen Wlan Netzwerks

WiFi.begin(ssid, password); //Verbinden mit Wlan Router

Serial.println("Verbindung wird aufgebaut:");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}

if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}

server.on("/", handleRoot);

server.on("/inline", [](){
server.send(200, "text/plain", "Funktioniert");
});

server.begin(); //Starten des Webservers
}

void loop() {
server.handleClient();
mdns.update();
}

void handleRoot() {
server.send(200, "text/html", "<html> <h3>ESP NETWORK</h3> schamlose Eigenwerbung: <b>michaelsarduino.blogspot.de/</b> </html>"); //hier HTML Code einfügen
}

ESP8266_Wifi_Client&Server hosted with ❤ by GitHub

Wenn ihr innerhalb eures bestehenden Netzwerks die Website des ESP aufrufen wollt, so müsst ihr die übliche IP Adresse eures ESP aufrufen, welche man auch in der Konfigurationsoberfläche des Wlan Routers ausgelesen kann. 

Wenn ihr die Website über das Wlan Netzwerk des ESP 8266  aufrufen wollt, könnt ihr den Server unter http://192.168.4.1 aufrufen.





-A19- Websiten über ESP8266 abrufen - ESP8266-01S Wlan Modul

In diesem Post geht es darum, wie man einen Arduino Sketch für den ESP 8266 schreiben kann, mithilfe dessen man eine Internetseite abrufen kann.



Der Arduino Sketch für den ESP 8266

Um eine Website abzurufen muss man ein Objekt der Klasse client erstellen. Dieses kann Websiten abrufen. Praktischerweise gibt is der WiFi Bibliothek für das offizielle Wlan Shield des Arduino einen Beispielsketch, welchen man nur leicht an den ESP 8266 anpassen muss.

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>


char ssid[] = "*******************"; //WLAN Netzwerk
char pass[] = "***************"; //WLAN Passwort

int status = WL_IDLE_STATUS;
char server[] = "michaelsarduino.blogspot.de"; //Webserver

WiFiClient client;

void setup() {
Serial.begin(115200);

while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
//mit Wlan Netzwerk verbinden
status = WiFi.begin(ssid, pass);

//kurzes warten fuer Verbindungsversuch
delay(10000);
}
Serial.println("Connected to wifi");
printWifiStatus();

Serial.println("\nStarting connection to server...");
//Ausgabe ueber serielle Verbindung
if (client.connect(server, 80)) {
Serial.println("connected to server");
client.println("GET /index.html HTTP/1.1"); // /index.html durch gewuenschte Unterseite ersetzen (index.html = Startseite)
client.println("Host: michaelsarduino.blogspot.de"); //Adresse des Webservers
client.println("Connection: close");
client.println(); //Verbindungs mit Server aufbauen und HTTP Anfrage senden
}
}

void loop() {
while (client.available()) {
char c = client.read();
Serial.write(c);
} //Ausgabe des empfangenen HTML Codes

if (!client.connected()) {
Serial.println();
Serial.println("disconnecting from server.");
client.stop();
//Beenden der Verbindung

while (true);
}
}


void printWifiStatus() {
//Ausgabe des WLan Netzwerks
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

//Ausgabe IP Adresse
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
}

Website_Abrufen_ESP8266.ino hosted with ❤ by GitHub

In diesem Sketch musst du nur noch den Namen deines Wlan Netzwerkes und das Passwort angeben, und schon verbindet sich der ESP 8266 automatisch mit dem Internet und ruft diesen Blog auf.

Wie man einen Arduino Sketch auf den ESP 8266 hoch lädt, erfährst du hier.

Um das Ergebnis zu sehen, musst du nach dem Neustart des ESP die serielle Konsole öffnen. Nun siehst du, wie sich der ESP 8266 mit deinem Wlan Netzwerk verbindet. Nach kurzer Zeit, läuft ganz viel Text (wirklich sehr viel) über deinen Bildschirm.

Das ist der HTML Code dieses Blogs. Dieser wird normalerweise durch den Browser übersetzt, wodurch du diesen Blog als ansprechende Seite mit Bildern und Farben siehst. Um die Zielseite zu ändern, musst du einfach an der markierten Stelle einen anderen Server und eine andere Unterseite angeben.

Um aus der Website eine bestimmte Information herauszulesen, kannst du die Funktion indexOf() auf den HTML Code String loslassen. Diese Funktion sucht eine angegebene Zeichenkette im String und gibt dir die erste Stelle als Zahl im Text an. Dadurch kannst du die dortigen Zeichen in eine extra Variable speichern, wodurch du die gesuchte Information "extrahiert" hast.

Fazit

Über den ESP 8266 (hier bei AZDelivery) lassen sich leicht Websiten abrufen, wodurch man sich Informationen aus dem Internet besorgen kann. Beispiele für Anwendungsfälle gäbe es viele: Wetterinformationen, Sportergebnisse, aktuelle Daten(Statistiken) ...







DIN A4  ausdrucken
********************************************************I*
Impressum: Fritz Prenninger, Haidestr. 11A, A-4600 Wels, Ober-Österreich, mailto:[email protected]
ENDE