c't Make

http://sites.schaltungen.at/arduino-uno-r3/c-t-make

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                             Wels, am 2018-05-22

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

DIN A3 oder DIN A4 quer ausdrucken
*******************************************************************************I**
DIN A4  ausdrucken   siehe
********************************************************I*
~015_b_PrennIng-a_arduino.uno.r3-c-t-make (xx Seiten)_1a.pdf


Make:
Heise-Verlag

Geballtes Arduino-Wissen in zwei Heften, Grundlagenkenntnisse für Einsteiger, Hardware, IDE, Libraries genau erklärt, inkl. Arduino UNO R3
 




Arduino-Projekte
Mark Geddes

25 Bastelprojekte für Maker zum Loslegen

Autor: Geddes, Mark
von dpunkt.Verlag
246 Seiten, Softcover
ersch. 01/2017
ISBN: 978-3-86490-415-8

ISBN 9783864904158
shop.heise.de/arduino-buch
https://www.amazon.com/Arduino-Projekte/dp/3864904153



Inhaltsverzeichnis
https://www.edv-buchversand.de/productinfo.php?replace=false&cnt=productinfo&mode=2&type=2&id=dp-4158&index=1&nr=0&sid=361569060588cef1ce9a2c7953e11b22af021a5f



Make Arduino special 2017

Make Arduino Special Teil 1 & 2 inkl. Arduino UNO  € 29,90

Bundle

https://shop.heise.de/katalog/make-arduino-special-teil-1-2-inkl-arduino-uno





https://static.onleihe.de/content/bookwire_nat/20171027/9783957880567/v9783957880567.pdf
http://www4.onleihe.at/wien/frontend/mediaInfo,0-0-405900326-200-0-0-0-0-0-0-0.html
https://www.buecher.de/shop/sonstige-themen/make-arduino-special-ebook-pdf/make-redaktion/products_products/detail/prod_id/44503413/





c't Make:
Arduino special
Hardware & Software einfach erklärt

Autor:
Jahr: 2016
Verlag: Heise Medien Gruppe GmbH & Co. KG
ISBN: 9783957880567


Inhalt:

Das erste Arduino-Sonderheft des deutschsprachigen DIY-Magazins Make bietet Anfängern einen leichten Einstieg in die Programmierung von Mikrocontrollern.
Es sind keine Vorkenntnisse für die Umsetzung der ersten Beispiele erforderlich.
Die weiteren Beispiele bauen aufeinander auf und erweitern das Wissen des Lesers allmählich.
Das Heft führt nicht nur in theoretische Grundlagen ein, sondern zeigt auch, wie man praktische Projekte wie Batterietester, Systhesizer, Lärmampel und ein Temperaturmessgerät aufbaut.







********************************************************I*



Ihr Weg zum Arduino-Profi

Grundlagen
Arduino-IDE unter die Haube geschaut
Libraries verstehen und selbst bauen
Effizient programmieren
Ports, Timer & Interupt einsetzen
bit-Operationen richtig anwenden
SD-Karte lesen und beschreiben - ARDUINO UNO als Datenlogger
Digital-Analog-Konverter aus Widerstände


https://static.onleihe.de/content/bookwire_nat/20171027/9783957881823/v9783957881823.pdf

300_b_Make-x_c't Make - Arduino-special (2017) ARDUINO UNO als Datenlogger_1a.pdf

Make: Arduino special (2017)  eBook,  *.pdf vorhanden

Arduino als Sound-Player,

VGA-Karte und Datenlogger

3/2017
www.make-magazin.de


Das zweite Arduino-Sonderheft des Make-Magazins lüftet die Geheimnisse der Arduino-IDE und der Hardware-nahen Programmierung. Timer, Interrupts, Ports, Bit-Operationen:
All das wird verständlich anhand praktischer Beispiele erklärt.
Darauf aufbauend zeigt das Heft, wie man SD-Karten an den Arduino anschließt und für Projekte wie Datenlogger mit Echtzeituhr und fantastisch klingende Sound-Player nutzt.
Ein großes Kapitel widmet sich der Ansteuerung von VGA-Monitoren und wie der Arduino dort mehrfarbige Grafiken anzeigt.
Lernen Sie zudem, wie man effizient und übersichtlich programmiert und eigene Bibliotheken für die Arduino-IDE baut.

Format: Kindle Edition
Dateigröße: 7304 KB
Verlag: Heise Medien;
Auflage: 2 (1. August 2017)



                   Inhaltsverzeichnis
2 Befehlsreferenz - Übersicht wichtiger ARDUINO Befehle und Funktionen
3 Inhaltsverzeichnis
  4 Bibliotheksbesuch - ARDUINO-IDE
  5 Unter der Haube der Arduino-IDE
  8 Effizienter programmieren - macht Sketche übersichtlicher
11 Eigene Libraries bauen

14 Hardware-Interna
15 Ports-Programmierung
18 Interrupts
21 Timer
22 Praxis
26 Arduino am VGA-MONITOR
40 KARTENSPIELE - SD-Karten-Speicher

41 Kleine Speicher-Kartenkunde
43 SD-Bibliothek - ARDUINO UNO mit FAT32
45 DatenLogger.ino - SD-Karte dient als Datenspeicher zum Aufzeichnen von Meßdaten
47 Datentagebuch
52 Audio mit ARDUINO UNO  -  Sound Player
62 Impressum



              Make: Arduino special 3/2017


      Übersicht wichtiger Befehle und Funktionen

Struktur & Programmfluss
Grundsätzliche Sketch-Struktur

void setup() {     // läuft nur einmal beim Start
}
void loop() {        // wiederholt sich kontinuierlich
}

Kontroll-Strukturen

if (x < 5) { ... } else { ... }
while (x < 5) { ... }
for (int i = 0; i < 10; i++) { ... }
break;           // Schleife sofort beenden
continue;       // weiter mit nächster Iteration
switch (var) {
case 1:
...
break;
case 2:
...
break;
default:
...
}
return x;    // x ist der Rückgabewert
return;       // ohne Rückgabewert

Funktionen

<ret. type> <name>(<params>) { ... }
bspws. int double(int x) {return x*2;}


Operatoren
Allgemein
= Zuweisung
+ Addieren - Subtrahieren
* Multiplizieren / Dividieren
% Modulo
== gleich != ungleich
< kleiner als > größer als
<= kleiner oder gleich
>= größer oder gleich
&& logisch UND || logisch ODER
! NICHT

Kombinierte Operatoren

++ Variable um 1 erhöhen
-- erniedrigen
+= wie a = a + b
-= wie a = a - b
*= wie a = a * b
/= wie a = a / b
&= wie a = a & b
|= wie a = a | b

Bitoperatoren
& bitweises UND | bitweises ODER
^ bitweises ODER ~ bitweises NICHT
<< um 1 Bit nach links schieben
>> um 1 Bit nach rechts schieben

Pointer
& Referenz: Adresse des Pointers
* Dereferenzierer: Ziel des Pointers


Eingebaute Funktionen

Pin Input/Output
Digital I/O - Pins 0-13 A0-A5
pinMode(pin, [INPUT, OUTPUT, INPUT_PULLUP])
int digitalread(pin)
digitalWrite(pin, [HIGH, LOW])

Analog In - pins A0-A5
int analogRead(pin)
analogReference( [DEFAULT, INTERNAL, EXTERNAL])

PWM Out - pins 3 5 6 9 10 11
analogWrite(pin, value)

Advanced I/O
tone(pin, Freq_Hz)
tone(pin, Freq_Hz, Dauer_ms)
noTone(pin)
shiftOut(dataPin, clockPin, [MSBFIRST, LSBFIRST], WERT)
unsigned long pulseIn(pin, [HIGH, LOW])

Zeit
unsigned long millis()     // läuft nach 50 Tagen über
unsigned long micros()   // läuft nach 70 Minuten über
delay(msec)
delayMicroseconds(usec)

Mathe-Funktionen
min(x, y) max(x, y) abs(x)
sin(rad) cos(rad) tan(rad)
sqrt(x) pow(Basis, Exponent)
constrain(x, Minl, Maxl)
map(val, fromL, fromH, toL, toH)

Zufallszahlen
randomSeed(seed) // long oder int
long random(max) // 0 bis max-1
long random(min, max)

bits und Bytes
lowByte(x) highByte(x)
bitRead(x, bitn)
bitWrite(x, bitn, bit)
bitSet(x, bitn)
bitClear(x, bitn)
bit(bitn) // bitn: 0=LSB 7=MSB

Konvertierung von Datentypen
char(Wert) byte(Wert)
int(Wert) word(Wert)
long(Wert) float(Wert)
//int(Fließkommazahl) wandelt bspws
//Fließkommazahl in Integer-Wert um

Externe Interrupts
attachInterrupt(interrupt, func, [LOW, CHANGE, RISING, FALLING])
detachInterrupt(interrupt)
interrupts()
noInterrupts()


Variablen, Arrays und Daten
Datentypen
boolean true | false
char -128 - 127, 'a' '$' etc.
unsigned char 0 - 255
byte 0 - 255
int -32768 - 32767
unsigned int 0 - 65535
word 0 - 65535
long -2147483648 - 2147483647
unsigned long 0 - 4294967295
float -3.4028e+38 - 3.4028e+38
double wie float
void kein Rückgabewert/unbestimmt

Strings
char str1[8] =
{'A','r','d','u','i','n','o','\0'};   // manuelle \0 Null-Terminierung
char str2[8] =
{'A','r','d','u','i','n','o'};        // Compiler fügt Null-Terminierung hinzu
char str3[] = "Arduino";
char str4[8] = "Arduino";

Numerische Konstanten
123 dezimal
0b01111011 binär
0173 oktal (Basis 8)
0x7B hexadezimal (Basis 16)
123U erzwinge unsigned
123L erzwinge long
123UL erzwinge unsigned long
123.0 erzwinge floating point
1.23e6 1.23*10^6 = 1230000

Eigenschaften von Variablen
static Variable bleibt über Aufrufe erhalten
volatile Variable im RAM statt Register speichern
const Konstante, nur lesbar
PROGMEM im Flash ablegen

Arrays
int myPins[] = {2, 4, 8, 3, 6};
int myInts[6];    // Array mit 6 ints
myInts[0] = 42; // Zuweisung der ersten Stelle
myInts[6] = 12; // Fehler, da 6. Variable
                       // den 5. Platz belegt


Bibliotheken

Serial
– serielle Kommunikation mit PC
oder via RX/TX
begin(long Baudrate) // bis 115200
end()
int available() // Anzahl empfangener Bytes
int read() // -1 wenn keine Daten
int peek() // Lesen ohne den Puffer
zu löschen
flush() // Puffer löschen
print(data) println(data)
write(byte) write(char * string)
write(byte * data, size)
SerialEvent() // wenn Daten fertig

SoftwareSerial.h – serielle Kommunikation
über beliebige Pins
SoftwareSerial(rxPin, txPin)
begin(long Baudrate) // bis 115200
listen() // immer nur eine serielle
isListening() // kann empfangen
read, peek, print, println, write

EEPROM.h – Zugriff auf nicht
flüchtigen Speicher
byte read(Addr)
write(addr, byte)
EEPROM[index]

Servo.h – Servo-Motoren steuern
attach(pin, [min_uS, max_uS])
write(Winkel) // 0 bis 180
writeMicroseconds(uS)
// 1000-2000; 1500 ist Mitte
int read() // 0 bis 180
bool attached()
detach()

Wire.h – I2C-Kommunikation
begin()
begin(Addr) // Slave ansprechen
requestFrom(Addr, count)
beginTransmission(Addr) // Schritt 1
send(byte) // Schritt 2
send(char * string)
send(byte * data, size)
endTransmission() // Schritt 3
int available() // verfügbare Bytes
byte receive() // nächstes Byte lesen
onReceive(handler)
onRequest(handler)


http://overapi.com/arduino




Blink.ino
 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 }

 void loop() {
 digitalWrite(LED_BUILTIN, HIGH);
 delay(1000);
 digitalWrite(LED_BUILTIN, LOW);
 delay(1000);
 }


SimpleLed.ino
 class Led {
 private:
 uint8_t _pin;

 public:
 Led(const uint8_t pin) {
 _pin = pin;
 pinMode(_pin, OUTPUT);
 }

 void on() {
 digitalWrite(_pin, HIGH);
 }

 void off() {
 digitalWrite(_pin, LOW);
 }
 };

 Led statusLed(LED_BUILTIN);

 void setup() {}

 void loop() {
 statusLed.on();
 delay(1000);
 statusLed.off();
 delay(1000);
 }



Led.h

 class Led {
 private:
 uint8_t _pin;

 public:
 Led(const uint8_t pin) {
 _pin = pin;
 pinMode(_pin, OUTPUT);
 }

 void on() {
 digitalWrite(_pin, HIGH);
 }

 void off() {
 digitalWrite(_pin, LOW);
 }
 };


Led.cpp
 #include "Led.h"

 Led::Led(const uint8_t pin) {
 _pin = pin;
 pinMode(_pin, OUTPUT);
 }

 void Led::on() {
 digitalWrite(_pin, HIGH);
 }

 void Led::off() {
 digitalWrite(_pin, LOW);
 }


Led2.h
 #ifndef OO_LED
 #define OO_LED

 #include <Arduino.h>

 class Led {
 private:
 uint8_t _pin;

 public:
 Led(const uint8_t pin);
 void on();
 void off();
 };
 #endif




Blink.ino
 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 }

 void loop() {
 digitalWrite(LED_BUILTIN, HIGH);
 delay(1000);
 digitalWrite(LED_BUILTIN, LOW);
 delay(1000);
 }



BlinkRaw.ino
 void setup() {
 DDRB = 0b00100000;
 }

 void loop() {
 PORTB = 0b00100000;
 delay(1000);
 PORTB = 0b00000000;
 delay(1000);
 }



BlinkBits.ino
 void setup() {
 DDRB |= 0b00100000;
 }

 void loop() {
 PORTB |= 0b00100000;
 delay(1000);
 PORTB &= 0b11011111;
 delay(1000);
 }



BlinkBV.ino

 void setup() {
 DDRB |= _BV(5);
 }

 void loop() {
 PORTB |= _BV(5);
 delay(1000);
 PORTB &= ~_BV(5);
 delay(1000);
 }


BlinkMain.ino
 #include <avr/io.h>
 #include <util/delay.h>

 int main() {
 DDRB |= _BV(DDB5);

 while (true) {
 PORTB |= _BV(PORTB5);
 _delay_ms(1000);
 PORTB &= ~_BV(PORTB5);
 _delay_ms(1000);
 }
 }




Button.ino
 const uint8_t BUTTON = 2;

 uint8_t buttonState = 0;

 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 pinMode(BUTTON, INPUT);
 }

 void loop() {
 buttonState = digitalRead(BUTTON);

 if (buttonState == HIGH) {
 digitalWrite(LED_BUILTIN, HIGH);
 } else {
 digitalWrite(LED_BUILTIN, LOW);




ButtonMitInterrupt.ino
 const uint8_t BUTTON = 2;

 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 pinMode(BUTTON, INPUT);
 attachInterrupt(digitalPinToInterrupt(BUTTON),:.switchPressed, CHANGE);
 }

 void loop(){}

 void switchPressed() {
 if (digitalRead(BUTTON) == HIGH)
 digitalWrite(LED_BUILTIN, HIGH);
 else
 digitalWrite(LED_BUILTIN, LOW);
 }



BlinkMitInterruptVolatile.ino
 const uint8_t BUTTON = 2;

 volatile uint8_t buttonStatus = LOW;

 void setup () {
 pinMode(LED_BUILTIN, OUTPUT);
 attachInterrupt(digitalPinToInterrupt(BUTTON), switchPressed, :.CHANGE);
 }

 void loop (){
 digitalWrite(LED_BUILTIN, buttonStatus);
 }

 void switchPressed() {
 buttonStatus = digitalRead(BUTTON);
 }




BlinkMitTimer.ino

 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.begin(9600);

 noInterrupts();
 TCCR1A = 0;
 TCCR1B = 0;

 OCR1A = 15624;
 TCCR1B |= _BV(WGM12);
 TCCR1B |= _BV(CS10);
 TCCR1B |= _BV(CS12);
 TIMSK1 |= _BV(OCIE1A);
 interrupts();
 }

 ISR(TIMER1_COMPA_vect) {
 digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
 }

 void loop() {
 Serial.println("Hallo.");
 delay(1000);
 }




BlinkMitTimerOverflow.ino

 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.begin(9600);

 noInterrupts();
 TCCR1A = 0;
 TCCR1B = 0;

 TCNT1 = 65535 - 15624;
 TCCR1B |= _BV(CS10);
 TCCR1B |= _BV(CS12);
 TIMSK1 |= _BV(TOIE1);
 interrupts();
 }

 ISR(TIMER1_OVF_vect) {
 TCNT1 = 65535 - 15624;
 digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
 }

 void loop() {
 Serial.println("Hallo.");
 delay(1000);
 }



BlinkAVR.ino


 #include <avr/io.h>

 int main() {
 DDRB |= _BV(DDB5);

 noInterrupts();
 TCCR1A = 0;
 TCCR1B = 0;

 OCR1A = 15624;
 TCCR1B |= _BV(WGM12);
 TCCR1B |= _BV(CS10);
 TCCR1B |= _BV(CS12);
 TIMSK1 |= _BV(OCIE1A);
 interrupts();

 while (true) ;
 }

 ISR(TIMER1_COMPA_vect) {
 PORTB ^= _BV(PORTB5);
 }




Shields und Module mit SD-Karten-Slots gibt es reichlich und in jeder Preisklasse.




Sechs Pins reichen, um ein SD-Modul (inklusive Pegelwandler) mit dem Arduino zu verbinden.
Die obige Abbildung ist nur exemplarisch und variiert von Modul zu Modul.




FAT32 DateiSystem
Um Daten auf Massenspeichern strukturiert und wiederauffindbar ablegen zu können, bedarf es eines Dateisystems.
Dazu gehört mindestens ein Verzeichnis, das Informationen zu abgelegten Daten
aufnimmt, beispielsweise ein Zuordnungsname (vulgo Dateiname) so wie
Daten über den Ort, wo die Datei auf dem Datenträger beginnt. Das Dateisystem dient als Schnittstelle zwischen
Massenspeicher und Anwendungen.
Die Anwendung bittet etwa das Dateisystem, eine Datei bestimmten Namens zu öffnen, um lesend darauf zuzugreifen.
Das Dateisystem initialisiert einen internen Zeiger auf den Anfang der Datei, liefert das erste Byte zurück und erhöht
den Zeiger um 1.
Durch weitere Aufrufe erhält die Anwendungen sequenziell alle weiteren Daten.
Ein Schreibvorgang funktioniert analog dazu.
Um die interne Organisation des Massenspeichers und ob etwa eine Festplatte mit runden Scheiben, eine SSD, ein
USB-Stick oder eine SD-Karte mit NANDFlash oder eine DVD-RW benutzt wird,
muss man sich keinerlei Gedanken mehr machen.
Stattdessen kümmert sich das Dateisystem um die Größe von Blöcken, Clustern, Sektoren und Partionen.
Diverse Dateisysteme weisen unterschiedliche Eigenschaften und damit je nach Einsatzzweck verschiedene
Vor- und Nachteile auf. Eines der am weitesten verbreiteten ist FAT32, mit
dem auch viele Datenträger vorformatiert  sind.

Die SD-Bibliothek
Der Arduino lernt den Umgang mit FAT32.



Karteninfo.ino
 #include <SD.h>

 const uint16_t BAUD_RATE = 9600;
 const uint8_t CHIP_SELECT_PIN = 10;

 void setup() {
 Serial.begin(BAUD_RATE);
 Serial.print("SD-Karte wird initialisiert... ");

 Sd2Card card;
 if (!card.init(SPI_HALF_SPEED, CHIP_SELECT_PIN)) {
 Serial.println("Die Karte konnte nicht :.initialisiert werden.");
 return;
 } else {
 Serial.println("Alles prima!");
 }

 Serial.print("\nKarten-Typ: ");
 switch (card.type()) {
 case SD_CARD_TYPE_SD1:
 Serial.println("SD V1");
 break;
 case SD_CARD_TYPE_SD2:
 Serial.println("SD V2");
 break;
 case SD_CARD_TYPE_SDHC:
 Serial.println("SDHC");
 break;
 default:
 Serial.println("Unbekannt");
 }

 SdVolume volume;
 if (!volume.init(card)) {
 Serial.println("Es konnte keine :.FAT16/FAT32-Partition gefunden werden.");
 return;
 }

 Serial.print("Dateisystem: FAT");
 Serial.println(volume.fatType(), DEC);
 Serial.println();

 uint64_t kapazitaet = volume.blocksPerCluster();
 kapazitaet *= volume.clusterCount();
 kapazitaet *= 512;

 Serial.print("Kapazität (Bytes): ");
 char buffer[100];
 sprintf(buffer, "%0ld", kapazitaet / 1000000L);
 Serial.print(buffer);
 sprintf(buffer, "%0ld", kapazitaet % 1000000L);
 Serial.println(buffer);

 Serial.print("Kapazität (KBytes): ");
 uint32_t kapazitaet_kb = kapazitaet /= 1024;
 Serial.println(kapazitaet_kb);
 Serial.print("Kapazität (MBytes): ");
 uint32_t kapazitaet_mb = kapazitaet_kb /= 1024;
 Serial.println(kapazitaet_mb);

 Serial.println("\nDie Karte enthält die folgenden :.Dateien: ");
 SdFile root;
 root.openRoot(volume);
 root.ls(LS_R | LS_DATE | LS_SIZE);
 }

 void loop() {}






DataLogger.ino

 #include <SD.h>

 const uint8_t CHIP_SELECT_PIN = 4;
 const uint16_t BAUD_RATE = 9600;

 File logDatei;

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

 if (!SD.begin(CHIP_SELECT_PIN)) {
 Serial.println("SD-Karte konnte nicht initialisiert werden.");
 return;
 }

 logDatei = SD.open("datalog.csv", FILE_WRITE);
 if (!logDatei) {
 Serial.println("Die Log-Datei konnte nicht geöffnet werden.");
 return;
 }
 }

 void loop() {
 const uint8_t MAX_PIN = 3;

 String sensorDaten = "";
 for (uint8_t analogPin = 0; analogPin < MAX_PIN; analogPin++) {
 uint16_t sensor = analogRead(analogPin);
 sensorDaten += String(sensor);
 if (analogPin < MAX_PIN - 1) {
 sensorDaten += ",";
 }
 }

 Serial.println(sensorDaten);
 logDatei.println(sensorDaten);
 logDatei.flush();
 delay(500);
 }





Format für Daten-Logger
Wer Daten auf eine SD-Karte schreibt, muss zuvor ein Datenformat festlegen. Die Auswahl ist groß und hängt davon ab, mit
welcher Anwendung die gesammelten Daten weiterverarbeitet werden.
Als Faustregel gilt, dass Binärdaten nur in Ausnahmefällen in Frage kommen. Eine etwaige Platzersparnis durch die kompaktere Speicherung
rechtfertigt in den seltensten Fällen die damit einhergehenden Nachteile. Binärdaten können nicht mit einem Text-Editor
inspiziert werden, sondern bedürfen spezieller Software, um sie anzusehen. Sie sind oft nicht portabel, weil sie auf verschiedenen
CPU-Architekturen unterschiedlich interpretiert werden.
Text-Formate haben diese Nachteile nicht und lassen sich einfach erzeugen und lesen. Besonders beliebt ist das CSV-Format (Character-
Separated Values), das so gut wie alle Tabellenkalkulationsprogramme und Datenbanken importieren kann.
In einer CSV-Datei werden Daten zeilenweise gespeichert und jede Zeile enthält dieselbe Anzahl an Werten. Benachbarte Werte
werden durch dasselbe Zeichen (meistens ein Komma, Semikolon oder Tabulator-Zeichen) getrennt.
Selbst vermeintlich einfache Formate wie CSV stecken jedoch voller Tücken.
Auf dem Arduino beginnt das mit dem Dezimalpunkt bei Fließkommazahlen.
Die print()-Funktionen verwenden als Dezimal-Trennzeichen nämlich einen Punkt und kein Komma.
Das ist vorteilhaft, wenn man ein Komma als CSV-Trennzeichen verwendet.
Es führt aber zu Problemen, wenn die Landes-Einstellungen der Tabellenkalkulation ein Komma als Dezimal-Trennzeichen erwarten.
Weitere Alternativen sind XML (eXtensible Markup Language) und JSON (JavaScript Object Notation). Beides sind ebenfalls Text-Formate, orientieren sich aber nicht an Zeilen, sondern an Dokumenten.
Um XML- oder JSON-Dokumente zu erzeugen, muss man Daten daher oft vorm Schreiben puffern, und wenn mal irgendetwas schiefgeht, sind die Ergebnis-Dokumente mit hoher Wahrscheinlichkeit kaputt.
Diese Nachteile sind allesamt bekannt und so gibt es mittlerweile sogar eine zeilenorientierte Version von JSON
http://jsonlines.org/




DataLoggerZeitstempel.ino

 #include
 #include "RTClib.h"

const uint8_t CHIP_SELECT_PIN = 10;
 const uint16_t BAUD_RATE = 9600;

File logDatei;
 RTC_DS1307 rtc;

 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.begin(BAUD_RATE);

 if (!rtc.begin()) {
 Serial.println("Konnte keine Uhr finden.");
 return;
 }

 if (!rtc.isrunning()) {
 Serial.println("Die Uhr läuft nicht.");

 }

 SdFile::dateTimeCallback(ermittle_zeitstempel);

 if (!SD.begin(CHIP_SELECT_PIN)) {
 Serial.println("SD-Karte konnte nicht initialisiert werden.");
 return;
 }

 logDatei = SD.open("datalog.csv", FILE_WRITE);
 if (!logDatei) {
 Serial.println("Die Log-Datei konnte nicht geöffnet werden.");
 return;
 }
 }

 void loop() {
 DateTime now = rtc.now();
 char buffer[11];
 sprintf(buffer, "%4d-%02d-%02d", now.year(), now.month(), now.day());
 logDatei.print(buffer);
 logDatei.print(",");
 sprintf(buffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
 logDatei.print(buffer);
 logDatei.print(",");

 String sensorDaten = ermittle_sensor_daten();
 Serial.println(sensorDaten);

 digitalWrite(LED_BUILTIN, HIGH);
 logDatei.println(sensorDaten);
 logDatei.flush();
 digitalWrite(LED_BUILTIN, LOW);
 delay(500);
 }

 String ermittle_sensor_daten() {
 const uint8_t MAX_PIN = 3;

 String sensorDaten = "";
 for (uint8_t analogPin = 0; analogPin < MAX_PIN; analogPin++) {
 uint16_t sensor = analogRead(analogPin);
 sensorDaten += String(sensor);
 if (analogPin < MAX_PIN - 1) {
 sensorDaten += ",";
 }
 }
 return sensorDaten;
 }

 void ermittle_zeitstempel(uint16_t* datum, uint16_t* uhrzeit) {
 DateTime now = rtc.now();
 *datum = FAT_DATE(now.year(), now.month(), now.day());
 *uhrzeit = FAT_TIME(now.hour(), now.minute(), now.second());
 }




2-Kanal Datenlogger für Temperatur °C und Luftfeuchtigkeit r.F.





SaunaMonitor.ino
 #include <SD.h>
 #include "Adafruit_HDC1000.h"
 #include "RTClib.h"

 const uint8_t CHIP_SELECT_PIN = 10;
 const uint16_t BAUD_RATE = 9600;

 File logDatei;
 RTC_DS1307 rtc;
 Adafruit_HDC1000 hdc = Adafruit_HDC1000();

 void setup() {
 pinMode(LED_BUILTIN, OUTPUT);
 Serial.begin(BAUD_RATE);

 if (!hdc.begin(0x43)) {
 Serial.println("Konnte Temperatursensor nicht finden.");
 return;
 }

 hdc.drySensor(); // Braucht 15 Sekunden!

 if (!rtc.begin()) {
 Serial.println("Konnte keine Uhr finden.");
 return;
 }

 if (!rtc.isrunning()) {
 Serial.println("Die Uhr läuft nicht.");
                            // Die folgende Anweisung setzt die Uhrzeit auf die Zeit
                            // zu der das Programm übersetzt wurde:
                            // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

                            // Die folgende Anweisung setzt die Uhrzeit auf einen
                            // festen Zeitpunkt. Der 2. Juli 2017, 15:59:00 wäre:
                            // rtc.adjust(DateTime(2017, 7, 2, 15, 59, 0));
 }

 SdFile::dateTimeCallback(ermittle_zeitstempel);

 if (!SD.begin(CHIP_SELECT_PIN)) {
 Serial.println("SD-Karte konnte nicht initialisiert werden.");
 return;
 }

 logDatei = SD.open("datalog.csv", FILE_WRITE);
 if (!logDatei) {
 Serial.println("Die Log-Datei konnte nicht geöffnet werden.");
 return;
 }
 }

 void loop() {
 DateTime now = rtc.now();
 char buffer[11];
 sprintf(buffer, "%4d-%02d-%02d", now.year(), now.month(), now.day());
 logDatei.print(buffer);
 logDatei.print(",");
 sprintf(buffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
 logDatei.print(buffer);
 logDatei.print(",");

 String sensorDaten = ermittle_sensor_daten();
 Serial.println(sensorDaten);

 digitalWrite(LED_BUILTIN, HIGH);
 logDatei.println(sensorDaten);
 logDatei.flush();
 digitalWrite(LED_BUILTIN, LOW);
 delay(5000);
 }

 void ermittle_zeitstempel(uint16_t* datum, uint16_t* uhrzeit) {
 DateTime now = rtc.now();
 *datum = FAT_DATE(now.year(), now.month(), now.day());
 *uhrzeit = FAT_TIME(now.hour(), now.minute(), now.second());
 }

 String ermittle_sensor_daten() {
 String sensorDaten = "";
 sensorDaten += hdc.readTemperature();
 sensorDaten += ",";
 sensorDaten += hdc.readHumidity();
 return sensorDaten;
 }




AUDIO-PLAYER


AudioStreamer.ino
 #include <SD.h>

 const uint16_t BAUD_RATE = 9600;
 const uint8_t CHIP_SELECT_PIN = 10;
 const char DATEI_NAME[] = "test.wav";

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

 for (uint8_t i = 0; i < 8; i++)
 pinMode(i, OUTPUT);

 if (!SD.begin(CHIP_SELECT_PIN)) {
 Serial.println("SD-Karte konnte nicht :.initialisiert werden.");
 return;
 }

 File audioDatei = SD.open(DATEI_NAME);
 if (!audioDatei) {
 Serial.println("Die Audio-Datei konnte nicht :.geöffnet werden.");
 } else {
 while (audioDatei.available()) {
 PORTD = audioDatei.read();
 delayMicroseconds(60);
 }
 audioDatei.close();
 }
 }

 void loop() {}




WavPlayer.ino
 #include <TMRpcm.h>

 const uint16_t BAUD_RATE = 9600;
 const uint8_t CHIP_SELECT_PIN = 10;
 const char DATEI_NAME[] = "test.wav";

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

 if (!SD.begin(CHIP_SELECT_PIN)) {
 Serial.println("SD-Karte konnte nicht :.initialisiert werden.");
 return;
 }

 TMRpcm player;
 player.speakerPin = 9;
 player.play(DATEI_NAME);
 }

 void loop(){}




Quelle:
Make: Magazin
Postfach 61 04 07, 30604 Hannover
Karl-Wiechert-Allee 10, 30625 Hannover
Telefon: 05 11/53 52-300
Fax:     05 11/53 52-417
mailto:[email protected]
www.make-magazin.de


Maik Schmidt arbeitet seit über 20 Jahren als Softwareentwickler für mittelständische und Großunternehmen.
Außerdem schreibt er Buchkritiken und Artikel für internationale Zeitschriften und hat selbst einige Bücher verfasst.
Unter anderem ist er Autor des Buchs
 „Arduino: A Quick-Start Guide, 2nd.“
ISBN: 978-1-94122-224-9
das bei The Pragmatic Bookshelf erschienen ist und unter dem Titel
 „Arduino – Ein schneller Einstieg in die Microcontroller-Entwicklung“
ISBN: 978-3-86490-126-3
 vom dpunkt-Verlag ins Deutsche übersetzt wurde.




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