ARDUINO Kochbuch‎ > ‎

Kapitel 18 deutsch

NEU

http://sites.schaltungen.at/arduino-kochbuch/kapitel-18-deutsch

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                             Wels, am 2015-05-10

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

DIN A3 oder DIN A4 quer ausdrucken
**********************************************************************************
DIN A4  ausdrucken
*********************************************************

Englischsprachige ORIGINAL-Seiten
715_d_O'REILLY-x_Arduino Kochbuch - Kapitel 18 engl. (38 Seiten )_1a.pdf
Auf dieser Seite die schlechte (nicht korrigierte) Maschinen-Übesetzung ins Deutsche

Untergeordnete Seiten (3):

Draht = Wire
Stift = Pin
Rezept = Sketch

Skizze = Sketch

KAPITEL 18

Mit dem Controller-Chip-Hardware

18.0 Einführung
Das Arduino-Plattform vereinfacht die Programmierung durch die Bereitstellung einfach zu bedienende Funktionsaufrufe bis hin zu komplexen, Low-Level-Hardware-Funktionen zu verstecken.
Manche Anwendungen benötigen, um zu umgehen
die freundlichen Zugriffsfunktionen direkt an Hardware zu bekommen, sei es, weil das der einzige Möglichkeit, die erforderliche Funktionalität zu erhalten, oder weil eine höhere Leistung erforderlich ist.
Diese
Kapitel zeigt, wie Sie Zugang und die Nutzung Hardwarefunktionen, die nicht vollständig ausgesetzt sind durch die dokumentierten Arduino Sprache.

Ändern Registerwerte können das Verhalten einiger Arduino ändern Funktionen (beispielsweise millis).
Die in dieser beschriebenen Low-Level-Funktionen
Kapitel erfordern Sorgfalt, Aufmerksamkeit, und Prüfung, wenn Sie Ihren Code zu wollen
vollständig funktionieren zu können.

Register

Die Register sind Variablen, die auf Hardware Speicherplätze beziehen.
Sie werden durch das verwendete
Chiphardwarefunktionen zum Speichern der Ergebnisse der Hardware-Operationen zu konfigurieren, oder.
Die Inhalte der Register können gelesen und durch Ihre Skizze geschrieben werden.
Ändern Register
-Werte, wie die Hardware betreibt, oder den Zustand von etwas (wie verändern der Ausgang eines pin).
Einige Register stellen einen Zahlenwert (die Anzahl ein Timer
wird) zählen.
Die Register können steuern, oder berichten über Hardware-Status;
zum Beispiel der Status eines Stiftes, oder wenn eine Unterbrechung aufgetreten ist.
Register sind in Code mit ihrem verwiesen
Namen - diese sind im Datenblatt für den Microcontroller dokumentiert.
Einstellung ein
registrieren um ein falscher Wert in der Regel ergibt sich eine Skizze Funktionsweise falsch, so sorgfältig prüfen Sie die Dokumentation, um sicherzustellen, dass Sie richtig mit Register.
599

Interrupts
Interrupts sind Signale, die den Controller-Chip ermöglichen, den normalen Ablauf einer Skizze zu stoppen und Griff eine Aufgabe, die sofortige Aufmerksamkeit, bevor Sie mit, was es war erforderlich tun.
Arduino Kernsoftware verwendet Interrupts, um eingehende Daten von der seriellen hand
Port, um die Zeit für die Verzögerung und Millis Funktionen zu halten und um das Trigger attachInterrupt Funktion.
Bibliotheken, wie Draht-und Servo, Nutzung unterbricht, wenn ein
Ereignis ein, so dass der Code muss nicht ständig überprüfen, ob das Ereignis passiert ist.
Diese ständige Kontrolle, genannt Polling kann die Logik der Skizze zu erschweren.
Interrupts kann ein zuverlässiger Weg, um Signale von sehr kurzer Dauer zu erfassen.
Rezept 18.2
erläutert, wie Interrupts verwenden, um festzustellen, ob ein digitaler Stift seinen Zustand geändert hat.
Zwei oder mehrere Interrupts auftreten, bevor die Bearbeitung des ersten Unterbrechung abgeschlossen ist;
beispielsweise jeweils erzeugt, wenn zwei Schalter gleichzeitig gedrückt und verschiedene Interrupt.
Der Interrupt-Handler für den ersten Schalter muss abgeschlossen sein, bevor
der zweite Interrupt kann loslegen.
Interrupts sollte kurz sein, denn eine Interrupt-
Routine, die zu viel Zeit in Anspruch nimmt kann andere Interrupt-Handler veranlassen, verzögert oder zu verpassen Veranstaltungen.

Arduino Dienste einen Interrupt zu einem Zeitpunkt.
Es unterbricht die anstehenden Unterbrechungen
während sie sich mit einem Interrupt, was geschehen ist. Code, um Unterbrechungen zu handhaben
(Die so genannte Interrupt-Handler, oder Service-Routine zu unterbrechen)
sollte
kurz fassen ein unangemessenes Aufhalten der anstehenden Unterbrechungen zu vermeiden.
Ein Interrupt
Routine, die zu viel Zeit in Anspruch nimmt kann andere Interrupt-Handler zu verursachen Miss-Ereignisse.
Aktivitäten, die eine relativ lange Zeit in Anspruch nehmen, wie zum Beispiel zu blinken
eine LED oder sogar Seriendruck, sollten Sie in einem Alarm vermieden werden
Handler.

Timer
Ein Standard-Arduino-Board hat 3 Hardware-Timer für zeitgesteuerte Aufgaben (Die Mega hat 6).
Die Timer werden in einer Reihe von Arduino Funktionen verwendet:

ARDUINO UNO
Timer0
Used for millis and delay; also analogWrite on pin-5 and pin-6
Timer1
analogWrite functions on pin-9 and pin-10; also driving servos using the Servo library
Timer2
analogWrite functions on pin-3 and pin-11

Die Servo-Bibliothek verwendet den gleichen Timer wie analogWrite an den Pins 9 und 10, so können Sie nicht analogWrite mit diesen Stiften, wenn Sie die Servo-Bibilothek.
Die Mega hat drei zusätzliche 16-Bit-Timer und verwendet unterschiedliche Pin-Nummern mit analogWrite:

600 | Kapitel 18: Verwenden der Controller-Chip-Hardware




ARDUINO MEGA
Timer0
analogWrite functions on pins 4 and 13
Timer1
analogWrite functions on pins 11 and 12
Timer2
analogWrite functions on pins 9 and 10
Timer3
analogWrite functions on pins 2, 3, and 5
Timer4
analogWrite functions on pins 6, 7, and 8
Timer5
analogWrite functions on pins 45 and 46


Timer sind Zähler, die Impulse von einer Zeitquelle, eine so genannte Zeitbasis zählen.
Der Timer Hardware besteht aus 8-bit oder 16-bit Digitalzähler, die programmiert ist, um zu bestimmen, kann der Modus der Timer verwendet, um zu zählen.
Die häufigste Art ist zum Zählen von Impulsen
von der Zeitbasis auf dem Arduino Board, in der Regel 16 MHz aus einem Kristall abgeleitet;
16
MHz Impulse wiederholen alle 62,5 Nanosekunden, und das ist zu schnell für viele Timing-Anwendungen, so dass der Zeitbasisrate wird durch einen Teiler genannt Vorteiler reduziert.
Die Aufteilung der
Zeitbasis von 8 beispielsweise erhöht die Dauer von jeder Zählung zu einem halben Mikrosekunde.
Für Anwendungen, in denen dies noch zu schnell ist, können auch andere prescale Werte verwendet werden (siehe Tabelle 18-1).
Timer-Betrieb wird durch Werte in den Registern gehalten, die gelesen und geschrieben werden können gesteuert von Arduino Code.
Die Werte in diesen Registern stellen Sie den Timer-Frequenz (die Anzahl der
Systemzeitbasis Impulse zwischen jedem Zahl) und die Art der Zählung (up, down, oben und unten, oder durch ein externes Signal).

Hier ist ein Überblick über die Timer-Register (n Timer-Nummer):
Timer Counter Control Register A (TCCRnA)
   Determines the operating mode
Timer Counter Control Register B (TCCRnB)
   Determines the prescale value
Timer Counter Register (TCNTn)
   Contains the timer count
Output Compare Register A (OCRnA)
   Interrupt can be triggered on this count
Output Compare Register B (OCRnB)
   Interrupt can be triggered on this count
Timer/Counter Interrupt Mask Register (TIMSKn)
   Sets the conditions for triggering an interrupt
Timer/Counter 0 Interrupt Flag Register (TIFRn)
   Indicates if the trigger condition has occurred


18.0 Einleitung | 601


Tabelle 18-1 gibt einen Überblick über die verwendeten, um den Timer Präzision gesetzt Bit-Werte.
Einzelheiten
die Funktionen der Register sind in den Rezepturen in denen sie verwendet werden, erläutert.




Tabelle 18-1. Timer prescale Werte (16-MHz-Takt)



Alle Zeiten werden für einen Skalierwert von 64 initialisiert.
Präzision in Nanosekunden gleich der CPU (Zeit für einen CPU-Zyklus) multipliziert ist vom Skalierwert.
Analoge und digitale Pins
Kapitel 5 beschreibt die Standard-Arduino-Funktionen zum Lesen und Schreiben (an / aus) Digital und Analog-Pins.
In diesem Kapitel wird erklärt, wie Sie Stifte schneller als mit der Kontrolle
Arduino Lese- und Schreibfunktionen und Änderungen an analogen Methoden zu verbessern Leistung.
Ein Teil des Codes in diesem Kapitel sind schwieriger zu verstehen als die anderen Rezepturen in diesem Buch, wie es über Arduino Syntax bewegt und näher an der darunterliegenden Hardware.
Diese Rezepte arbeiten direkt mit den knapp genannten Register in dem Chip und den Einsatz Bitverschiebung und Maskierung zu Bits zu manipulieren.
Der Vorteil von dieser Komplexität
ist Leistung und Funktionalität verbessert.

Siehe auch
Übersicht von Hardware-Ressourcen:     http://code.google.com/p/arduino/wiki/HardwareResourceMap
Timer1 (and Timer3)
Bibliothek (library): http://www.arduino.cc/playground/Code/Timer1
Tutorial on timers and PWM:                 http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM
602 | Chapter 18: Using the Controller Chip Hardware



The ATMEL ATmega168
ATmega328 Datenblätter (data sheets):          http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf
ATMEL Application Note auf die Einrichtung und Nutzung Timer         http://www.atmel.com/dyn/resources/prod_documents/DOC2505.PDF
Eine gründliche Zusammenfassung der Informationen rund 8-Bit-Timer:
http://www.cs.mun.ca/~rod/Winter2007/4723/notes/timer0/timer0.html
Diagramme, die Registereinstellungen für Timer-Modi:                         http://web.alfredstate.edu/weimandn/miscellaneous/atmega168_subsystem/atmega168_subsystem_index.html
Wikipedia-Artikel über Interrupts:                                                       http://en.wikipedia.org/wiki/Interrupts



18.1 Speichern von Daten im Permanent EEPROM Speicher
Problem
Sie wollen Werte, die auch dann erhalten werden, wenn das Gerät ausgeschaltet ist zu speichern.
Lösung
Verwenden Sie die EEPROM-Bibliothek zum Lesen und Schreiben Werte in EEPROM-Speicher.
Dieser Sketch
blinkt eine LED mit Werten aus dem EEPROM und ermöglicht die Werte geändert werden mit dem "Serial-Monitor"

_18.1_Speichern_von_Daten_im_Permanent_EEPROM_Speicher_1a.ino

/ *
basierend auf Blink ohne Verzögerung
verwendet EEPROM zum Speichern von blink-Werte
* /
#include <EEPROM.h>

// Diese Werte werden im EEPROM gespeichert
const byte EEPROM_ID = 0x99;   
// Verwendet werden, wenn zu erkennen gültigen Daten in EEPROM
byte ledPin = 13; // the number of the LED pin
int interval = 1000; //
Blink-Intervall, in Millisekunden
// Variablen, die nicht brauchen, um gerettet zu werden


// Titel: 18.1 Speichern von Daten im Permanent EEPROM Speicher// Beschreibung: Verwenden Sie die EEPROM-Bibliothek zum Lesen und Schreiben Werte in EEPROM-Speicher. // Diese Skizzeblinkt eine LED mit Werten aus dem EEPROM und ermöglicht die Werte geändert werden mit dem Serial Monitor:// Autor: Fritz Prenninger// Datum: 2015-04-18// Sketch: 18.1 Speichern von Daten im Permanent EEPROM Speicher_1a.ino// Shield: keines// Controller: Arduino UNO R3// Version: Arduino 1.0.6// Tools: COM4// 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567/*based on Blink without Delay uses EEPROM to store blink values */#include <EEPROM.h>// these values are saved in EEPROMconst byte EEPROM_ID = 0x99; // used to identify if valid data in EEPROMbyte ledPin = 13; // the number of the LED pinint interval = 1000; // interval at which to blink (milliseconds)// variables that do not need to be savedint ledState = LOW; // ledState used to set the LEDlong previousMillis = 0; // will store last time LED was updated//constants used to identify EEPROM addressesconst int ID_ADDR = 0; // the EEPROM address used to store the IDconst int PIN_ADDR = 1; // the EEPROM address used to store the pinconst int INTERVAL_ADDR = 2; // the EEPROM address used to store the intervalvoid setup(){  Serial.begin(9600);  byte id = EEPROM.read(ID_ADDR); // read the first byte from the EEPROM  if( id == EEPROM_ID)  {    // here if the id value read matches the value saved when writing eeprom    Serial.println("Using data from EEPROM");    ledPin = EEPROM.read(PIN_ADDR);    byte hiByte = EEPROM.read(INTERVAL_ADDR);    byte lowByte = EEPROM.read(INTERVAL_ADDR+1);    interval = word(hiByte, lowByte); // see word function in Recipe 3.15  }  else  {    // here if the ID is not found, so write the default data    Serial.println("Writing default data to EEPROM");    EEPROM.write(ID_ADDR,EEPROM_ID); // write the ID to indicate valid data    EEPROM.write(PIN_ADDR, ledPin); // save the pin in eeprom    byte hiByte = highByte(interval);    byte loByte = lowByte(interval);    EEPROM.write(INTERVAL_ADDR, hiByte);    EEPROM.write(INTERVAL_ADDR+1, loByte);  }  Serial.print("Setting pin to ");  Serial.println(ledPin,DEC);  Serial.print("Setting interval to ");  Serial.println(interval);  pinMode(ledPin, OUTPUT);}void loop(){  // this is the same code as the BlinkWithoutDelay example sketch  if (millis() - previousMillis > interval)  {    previousMillis = millis(); // save the last time you blinked the LED    // if the LED is off turn it on and vice versa:    if (ledState == LOW)      ledState = HIGH;    else      ledState = LOW;    digitalWrite(ledPin, ledState); // set LED using value of ledState  }  processSerial();}// function to get duration or pin values from Serial Monitor// value followed by i is interval, p is pin numberint value = 0;void processSerial(){  if( Serial.available())  {    char ch = Serial.read();    if(ch >= '0' && ch <= '9') // is this an ascii digit between 0 and 9?    {      value = (value * 10) + (ch - '0'); // yes, accumulate the value    }    else if (ch == 'i') // is this the interval    {      interval = value;      Serial.print("Setting interval to ");      Serial.println(interval);      byte hiByte = highByte(interval);      byte loByte = lowByte(interval);      EEPROM.write(INTERVAL_ADDR, hiByte);      EEPROM.write(INTERVAL_ADDR+1, loByte);      value = 0; // reset to 0 ready for the next sequence of digits    }    else if (ch == 'p') // is this the pin number    {      ledPin = value;      Serial.print("Setting pin to ");      Serial.println(ledPin,DEC);      pinMode(ledPin, OUTPUT);      EEPROM.write(PIN_ADDR, ledPin); // save the pin in eeprom      value = 0; // reset to 0 ready for the next sequence of digits    }  }}

Öffnen Sie die Serial Monitor. Wie die Skizze beginnt, es sagt Ihnen, ob es mit den Werten zuvor auf EEPROM oder Standardwerte gespeichert, wenn dies das erste Mal, die Skizze wird gestartet.
Sie können die Werte, indem Sie eine Zahl, gefolgt von einem Buchstaben, um die Aktion anzugeben ändern.
Eine Zahl, gefolgt von dem Buchstaben i wechselt die Blinkintervall; eine Zahl, gefolgt von einem p ändert die PIN-Nummer für die LED.

Diskussion
Arduino enthält EEPROM-Speicher, die Werte auch bei eingeschaltetem Gerät gespeichert werden off.
Es gibt 512 Byte EEPROM in einem Standard-Arduino-Board, 4 KB in einer Mega.
Die Skizze verwendet die EEPROM-Bibliothek zum Lesen und Schreiben Werte in EEPROM-Speicher.
Sobald die Bibliothek in der Skizze enthalten, ein EEPROM-Objekt zur Verfügung, greift der speicher.
Die Bibliothek stellt Methoden zum Lesen, Schreiben und klar.
EEPROM.clear () wird in dieser Skizze verwendet, weil es löscht alle EEPROM-Speicher.
Die EEPROM-Bibliothek müssen Sie die Adresse im Speicher, die Sie wollen, um festzulegen lesen oder zu schreiben.
Das heißt, Sie zu verfolgen, wo jeder Wert, so dass schriftliche halten müssen
wenn Sie auf den Wert ist von der richtigen Adresse.
Um einen Wert zu schreiben, EEPROM.write (Adresse, Wert) verwenden Sie.
Die Adresse ist von 0 bis 511
(Auf einem Standard-Arduino-Board), und der Wert ist ein einzelnes Byte.
Zum Lesen, EEPROM.read (Adresse) verwenden Sie.
Das Byte Inhalt dieser Speicheradresse
zurückgegeben.
18.1 Speichern von Daten in Permanent EEPROM-Speicher | 605


Die Skizze speichert drei Werte im EEPROM.
Die erste gespeicherte Wert ist eine ID-Wert, ist
nur im Setup verwendet werden, um festzustellen, ob der EEPROM zuvor mit gültiger geschrieben Daten.
Wenn der gespeicherte Wert mit dem erwarteten Wert übereinstimmt, werden die anderen Variablen gelesen
EEPROM und in der Skizze verwendet.
Wenn es nicht übereinstimmt, hat diese Skizze nicht geführt
dieses Board (sonst wäre die ID geschrieben worden sein), so dass die Standardwerte geschrieben werden, einschließlich der ID-Wert.
Die Skizze überwacht die serielle Schnittstelle und neue empfangenen Werte werden in den EEPROM geschrieben.
Die Skizze speichert die ID-Wert im EEPROM-Adresse 0, die Pin-Nummer in der Adresse 1, und die zwei Bytes für den Intervallstart in Adresse 2.
Die folgende Zeile schreibt die Pin-Nummer
im EEPROM. Die Variable ledPin ist ein Byte, so dass es in einem einzigen EEPROM-Adresse passt:

EEPROM.write(PIN_ADDR, ledPin); // save the pin in eeprom

Da Intervall ist ein int, zwei Byte Speicher benötigt, um den Wert zu speichern:

byte hiByte = highByte(interval);
byte loByte = lowByte(interval);
EEPROM.write(INTERVAL_ADDR, hiByte);
EEPROM.write(INTERVAL_ADDR+1, loByte);


Der vorstehende Code teilt den Wert in zwei Bytes, die in zwei aufeinander folgenden gespeicherten Adressen.
Alle zusätzlichen Variablen, die EEPROM hinzugefügt werden müssten gesetzt werden
in Adressen, die diese beiden Bytes folgen.
Hier ist die verwendet werden, um die int-Variable vom EEPROM wieder aufzubauen Code:

ledPin = EEPROM.read(PIN_ADDR);
byte hiByte = EEPROM.read(INTERVAL_ADDR);
byte lowByte = EEPROM.read(INTERVAL_ADDR+1);
interval = word(hiByte, lowByte);


Siehe Kapitel 3, um mehr über die Verwendung des Wortes Ausdruck eine ganze Zahl von zwei Bytes erstellen.
Für kompliziertere Verwendung von EEPROM, ist es ratsam, um eine Karte von dem, was herauszuziehen gespeichert, wo, um sicherzustellen, dass keine Adresse um mehr als einen Wert verwendet, und das Multibyte Werte nicht überschreiben andere Informationen.

Siehe auch

Rezept 3.14 finden Sie weitere Informationen zum Konvertieren von 16-bit und 32-bit Werte in Byte.


18.2 Verwendung von Prozessalarmen
Problem
Sie wollen, um eine Aktion durchzuführen, wenn ein digitaler Stift Wert ändert und Sie nicht möchten, zu haben, um ständig Überprüfen Sie die pin-Zustand.

606 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Lösung

Dieser Sketch überwacht Impulse an Pin 2 und speichert die Laufzeit in einem Array.
Wenn das
Array gefüllt ist (64 Impulse empfangen wurden), ist die Dauer eines jeden Impulses angezeigt auf der Serial Monitor:

_18.2_Interrupts_Sketch_1a.ino


// Titel: 18.2 Interrupts Sketch// Beschreibung: Verwenden Sie die EEPROM-Bibliothek zum Lesen und Schreiben Werte in EEPROM-Speicher. // Diese Skizzeblinkt eine LED mit Werten aus dem EEPROM und ermöglicht die Werte geändert werden mit dem Serial Monitor:// Autor: Fritz Prenninger// Datum: 2015-04-26// Sketch: 18.2 Interrupts Sketch_1a.ino// Shield: keines// Controller: Arduino UNO R3// Version: Arduino 1.0.6// Tools: COM4// 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567/*Interrupts Sketch siehe Sketch 10.1 Anschlussplan */const int irReceiverPin = 2;    // an pin-2 ist der Empfänger angeschlossenconst int numberOfEntries = 64; // setze diese Zahl auf jeder beliebigen Wertvolatile unsigned long microseconds;volatile byte index = 0;volatile unsigned long results[numberOfEntries];void setup(){  pinMode(irReceiverPin, INPUT);  Serial.begin(9600);  attachInterrupt(0, analyze, CHANGE); //  Encoder auf Interrupt-0  ist pin-2  results[0]=0;}void loop(){  if(index >= numberOfEntries)  {    Serial.println("Durations in Microseconds are:") ;    for( byte i=0; i < numberOfEntries; i++)    {      Serial.println(results[i]);    }    index = 0;   // beginnt mit der Analyse wieder
  }  delay(1000);   // 1 Sekunde Pause}void analyze(){  if(index < numberOfEntries )  {    if(index > 0)    {      results[index] = micros() - microseconds;    }    index = index + 1;  }  microseconds = micros();}

Wenn Sie einen Infrarot-Empfänger-Modul haben, können Sie die Verkabelung in Rezept 10.1 zur Messung die Impulsbreite von einer Infrarot-Fernbedienung.
Sie könnten auch die Verkabelung in verwenden

18.2 Verwendung von Prozessalarmen | 607


Rezept 6.12, um Impulse von einem Drehgeber messen oder schließen Sie einen Schalter auf Pin 2 (siehe Rezept 5,1), mit einem Taster zu testen.

Diskussion
Im Setup der attachInterrupt (0, analysieren, CHANGE); Call ermöglicht die Skizze zu handhaben unterbricht.
Die erste Zahl in der Aufforderung festgelegt, welche die Initialisierung unterbrechen.

Auf einem
Standard-Arduino-Board sind zwei Interrupts zur Verfügung: Nummer 0, die Pin 2 verwendet, und Nummer 1 auf Pin 3.
Der ARDUINO Mega hat vier weitere: Nummer 2, der Stift 21 verwendet, Nummer 3
an Pin 20, Nummer 4 an Pin 19 und Nummer 5 an Pin 18.
Der nächste Parameter legt fest, welche Funktion aufrufen (manchmal auch als ein Interrupt-Handler) wenn die Interrupt-Ereignis eintritt; analysieren in dieser Skizze.
Der letzte Parameter gibt an, welche den Alarm auslösen. CHANGE bedeutet, wann immer die Änderungen Pin-Ebene (geht von niedrig bis hoch, oder absteigend).

Die anderen Optionen sind:

LOW
Wenn der Stift niedrig
RISING
Wenn der Stift geht von niedrig bis hoch
FALLING
Wenn der Stift geht von hoch zu niedrig

Beim Lesen von Code, Interrupts verwendet, bedenken Sie, dass es möglicherweise nicht offensichtlich, wenn sein Werte in der Skizze ändern, weil die Skizze nicht direkt die Interrupt-Handler rufen;
es heißt, wenn die Interrupt-Bedingungen auftreten.
In dieser Skizze, überprüft die Hauptschleife die Indexvariable zu sehen, ob alle Einträge wurden von der Interrupt-Handler gesetzt.
Nichts in Schleife ändert den Wert des Index.

Index
in der Analyse-Funktion, wenn die Interrupt-Bedingung auftritt (Pin 2 Wechsel geändert Zustand).
Der Indexwert wird verwendet, um die Zeit, die seit der letzten Zustandsänderung in den Laden
nächsten Schlitz in der Ergebnis-Reihe.
Die Zeit wird durch Subtrahieren der letzten Zeit die berechnete
Zustand geändert von der aktuellen Zeit in Mikrosekunden.
Die aktuelle Uhrzeit wird gespeichert
wie beim letzten Mal eine Änderung passiert.
(Kapitel 12 beschreibt das Verfahren zum Erhalt von
verstrichene Zeit mit dem millis-Funktion; hier Mikros wird verwendet, um die verstrichene Mikrosekunden erhalten statt Millisekunden.)
Die Variablen, die in einem Alarm-Funktion geändert werden, werden als flüchtig erklärt; diese lässt der Compiler, dass die Werte kann jederzeit (mit einem Interrupt-Handler) zu ändern.
Ohne Verwendung der flüchtigen Stichwort, würde der Compiler kann die Werte zu speichern in Registern, die zufällig von einer Interrupt-Verarbeitung überschrieben werden kann.
Verhindern
Dies teilt das Schlüsselwort volatile den Compiler an, die Werte im RAM zu speichern, statt Register.
Jedes Mal, wenn ein Alarm ausgelöst wird Index inkrementiert und wird die aktuelle Zeit gespeichert.
Die Zeitdifferenz wird berechnet und in dem Array gespeichert werden (mit Ausnahme der ersten Zeit der

608 | Kapitel 18: Verwenden der Controller-Chip-Hardware



Interrupt ausgelöst wird, wenn Index 0). Wenn die maximale Anzahl von Einträgen hat eingetreten ist, der innere Block in Schleife läuft, und er druckt alle Werte an die serielle Schnittstelle.
Der Code bleibt in der while-Schleife am Ende des inneren Blocks, so müssen Sie die Reset müssen Bord, wenn Sie einen anderen Lauf zu tun.

Siehe auch
Rezeptur 6.12 hat ein Beispiel externe Interrupts verwendet, um eine Bewegung in einer Dreh detektieren
Encoder.

18.3 Einstellen Timer Dauer
Problem
Sie wollen etwas in periodischen Abständen zu tun, und Sie wollen nicht, Ihren Code haben ständig überprüft, wenn das Intervall abgelaufen ist.
Sie möchten eine einfache Schnittstelle haben
zur Einstellung der Zeitraum.
Lösung
Der einfachste Weg, um einen Zeitgeber zu verwenden ist durch eine Bibliothek. Die folgende Skizze verwendet das
MsTimer2.h  Bibliothek
http://www.arduino.cc/playground/Main/MsTimer2
 um eine zu generieren
Impuls mit einer Periode, die mit der Serial Monitor eingestellt werden können. Diese Skizze blinkt Pin 13 mit einer Rate, die mit der Serial Monitor festgelegt werden können:

Zeitgeber pulseTimer2_1a.ino

// Titel: Zeitgeber pulseTimer2// Beschreibung: Impuls mit einer Periode, die mit der "Serial-Monitor" eingestellt werden können. // Dieser Sketch bringt an pin-13 die eingebaute LED zum blinken, mit einer Bölinkfrequenz, die am Serial-Monitor festgelegt wird.// Autor: Fritz Prenninger// Datum: 2015-5-01// Sketch: Zeitgeber pulseTimer2_1a.ino// Shield: keines// Controller: Arduino UNO R3// Version: Arduino 1.0.6// Tools: COM4// 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567/*pulseTimer2 Puls einen Stift mit einer Rate von seriellen Eingang eingestellt */#include <MsTimer2.h>const int pulsePin = 13;const int NEWLINE = 10; // ASCII-Wert für Zeilenumbruchint period = 100; // 10 Millisekundenboolean output = HIGH; // Der Zustand des Puls-pinvoid setup(){  pinMode(pulsePin, OUTPUT);  Serial.begin(9600);  MsTimer2::set(period/2, flash);  MsTimer2::start();  period= 0; // Auf Null zurückzusetzen, bereit zum Lesen am seriellen Eingang}void loop(){  if( Serial.available())  {    char ch = Serial.read();    if( isDigit(ch) ) // das ist ein ASCII-Ziffer von 0 bis 9?    {      period = (period * 10) + (ch - '0'); // Ja, accumuliere den WERT    }    else if (ch == NEWLINE) // ist der Charakter der Zeilenumbruch    {      Serial.println(period);      MsTimer2::set(period/2, flash);      MsTimer2::start();      period = 0; // Auf 0 zurückgesetzt, bereit für die nächste Folge von Ziffern    }  }}void flash(){  digitalWrite(pulsePin, output);  output = !output; //  Invertieren der Ausgänge}

Führen Sie dies mit der Serial Monitor Dropdown zum Anfügen eines Zeilenumbruch bei der Ende jeden senden (siehe "Diskussion" auf Seite 15).

Diskussion
Geben Sie Ziffern für den gewünschten Zeitraum in Millisekunden mit Hilfe des Serial Monitor.
Die Skizze
sammelt die Ziffern und teilt den empfangenen Wert von 2, um die Dauer zu berechnen Ein- und Aus-Zuständen (die Periode ist die Summe der Ein-Zeit und Aus-Zeit, so dass die kleinste Wert, den Sie verwenden können, ist 2).
Bedenken Sie, dass eine LED sehr schnell blinkt möglicherweise nicht angezeigt
zu blinken für das menschliche Auge sein.

Diese Bibliothek verwendet Timer2, so dass es den Betrieb der analogWrite auf verhindern Pins 3 und 11.

Diese Bibliothek ermöglicht es Ihnen, Timer2, indem der Zeitablauf und den Namen verwenden der Funktion zu rufen, wenn das Intervall abgelaufen ist:

MsTimer2::set(period/2, flash);
Damit wird der Timer. Der erste Parameter ist die Zeit für den Timer in Millisekunden ausgeführt.
Der zweite Parameter ist die Funktion, die nach der Timer die Ende dieser Zeit
(Die Funktion mit dem Namen Flash in diesem Rezept):
MsTimer2::start();

610 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Wie der Name schon sagt, beginnt Anfang der Timer läuft. Ein weiteres Verfahren, mit dem Namen Anschlag, die Zeit gestoppt.
Wie in Rezept 18.2, die Skizze Code nicht direkt die Funktion aufrufen, um das durchzuführen Aktion.
Die LED ein und aus in den Flash-Funktion, die durch MsTimer2 genannt gedreht
jedes Mal, es an das Ende seines Zeiteinstellung.
Der Code in der Schleife sich mit jedem seriellen
Nachrichten und Änderungen der Timer-Einstellungen auf ihr basiert.
Mit einer Bibliothek, um Timer zu steuern ist viel einfacher, als den direkten Zugriff auf die Register.
Hier ist ein Überblick über das Innenleben dieser Bibliothek: Zeitgeber wirken, indem ständig Zählen auf einen Wert, signalisiert, daß sie den Wert erreicht hat, dann wieder ab.
Jeder Timer hat einen Vorteiler, der die Zählfrequenz bestimmt.
Die Vorteiler teilt
die Systemzeitbasis um einen Faktor, wie 1, 8, 64, 256 oder 1.024.
Je niedriger die prescale
Faktor, desto höher die Zählfrequenz und desto schneller wird die Zeitbasis erreicht ihren Maximalanzahl.
Die Kombination, wie schnell zu zählen, und welchen Wert zählen, um,
gibt die Zeit des Zeitgebers.
Timer2 ist ein 8-Bit-Timer;
Dies bedeutet, es kann bis zu 255 zählen vor dem Start wieder bei 0. (Timer1 und Timer 3, 4, und 5 auf den Mega Einsatz 16 Bit und kann bis zu 65.535 zu zählen.)
Die MsTimer2 Bibliothek verwendet eine prescale Faktor 64. Bei einem 16 MHz Arduino Board, jeder CPU-Zyklus beträgt 62,5 Nanosekunden lang ist, und wenn dies durch die Prescale Faktor dividiert 64, wird jede Zählung des Zeitgebers 4000 Nanosekunden (62,5 * 64 = 4000, der vier ist sein Mikrosekunden).

Denken Sie daran, dass, wenn Sie direkt einen Timer in Ihre Skizze, Einbau Funktionen, die diesen Timer verwenden, wie zum Beispiel analogWrite, möglicherweise nicht mehr richtig.

Siehe auch
Eine einfach zu bedienende Bibliothek für die Verbindung mit Timer2:
http://www.arduino.cc/playground/Main/MsTimer2
Main / MsTimer2
Eine Sammlung von Routinen für die Schnittstellen mit Timer1 (auch Timer3 am Mega):
http://www.arduino.cc/playground/Code/Timer1




18.4 Einstellen Timer Impulsdauer und Laufzeit
Problem
Sie wollen Arduino um Impulse mit einer Dauer und Breite, die Sie angeben erzeugen.

18.4 Einstellen Timer Impulsdauer und Laufzeit | 611



Lösung
Diese Sketch erzeugt Impulse im Frequenzbereich von 1 MHz bis 1 Hz unter Verwendung Timer1 PWM an pin-9

Die folgende Skizze verwendet die Bibliothek TimerOne.h 

Zeitgeber TimerOne_1a.ino
// Titel: Zeitgeber TimerOne// Beschreibung: Diese Sketch erzeugt Impulse im Frequenzbereich // von 1 MHz bis 1 Hz unter Verwendung Timer1PWM an pin-9// Autor: Fritz Prenninger// Datum: 2015-05-01// Sketch: Zeitgeber TimerOne_1a.ino// Shield: keines// Controller: Arduino UNO R3// Version: Arduino 1.0.6// Tools: COM4// 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567#include <TimerOne.h>#define pwmRegister OCR1A // die logische Stift kann zu 0CR1B eingestellt werdenconst int outPin = 9; // der physische Stiftlong period = 10000; // die Zeit in Mikrosekundenlong pulseWidth = 1000; // Breite eines Pulses in Mikrosekundenint prescale[] = {  0,1,8,64,256,1024}; // der Bereich der prescale WERTEvoid setup(){  Serial.begin(9600);  pinMode(outPin, OUTPUT);  Timer1.initialize(period); // Timer 1 mit 1000 Mikrosekunden initialisieren  setPulseWidth(pulseWidth);}void loop(){}bool setPulseWidth(long microseconds){  bool ret = false;  int prescaleValue = prescale[Timer1.clockSelectBits];  // calculate time per counter tick in nanoseconds  long precision = (F_CPU / 128000) * prescaleValue ;  period = precision * ICR1 / 1000; // Zeit in Mikrosekunden  if( microseconds < period)  {    int duty = map(microseconds, 0,period, 0,1024);    if( duty < 1)      duty = 1;    if(microseconds > 0 && duty < RESOLUTION)    {      Timer1.pwm(outPin, duty);      ret = true;    }  }  return ret;}
612 | Kapitel 18: Verwenden der Controller-Chip-Hardware



Diskussion
Sie stellen die Impulsperiode auf einen Wert zwischen 1 bis 1.000.000 Mikrosekunden, indem Sie die Wert der Periode an der Spitze der Skizze.
Sie können die Impulsbreite auf einen beliebigen Wert im Set
Mikrosekunden, dass weniger als die Zeit, indem der Wert von pulsewidth.
Die Skizze verwendet die Timer1-Bibliothek von
http://www.arduino.cc/playground/Code/Timer1
.
Timer1 ist ein 16-Bit-Timer (zählt von 0 bis 65.535). Es ist der gleiche Timer verwendet
analogWrite den Pins 9 und 10 zu steuern (so dass Sie nicht verwenden können, diese Bibliothek und analogWrite auf diese Stifte zur gleichen Zeit).
Die Sketch erzeugt einen Impuls an Pin 9 mit einer Periode und
Pulsbreite von den Werten of the variables named period and pulseWidth.
Wenn du Pin 10 statt Stift 9 verwenden möchten, können Sie die folgende Änderung vornehmen:

#define pwmRegister 0CR1B // the logical pin
const int outPin = 10; // the physical pin - OCRIB is pin 10


OCR1A und OCR1B sind Konstanten, die in der von der Arduino Kern enthalten Code definiert werden Software (OCR steht für Ausgangsvergleichs-Register).
Viele verschiedene Hardware-Register
in der Arduino-Hardware in der Regel nicht durch eine Skizze (die freundliche Arduino erforderlich
Befehle verstecken die eigentliche Registernamen). Aber, wenn Sie Zugriff auf die Hardware direkt an Funktionalität nicht von Arduino-Befehle zur Verfügung gestellt zu bekommen, müssen diese Register zugegriffen werden soll.
Alle Details zu den Registern in der Atmel Datenblatt für den Chip.
Die Skizze in dieses Rezepts Lösung verwendet die folgenden Register:

ICR1 (Input Vergleichen registrieren Timer1) bestimmt die Periode des Impulses.
Diese
Register enthält einen 16-Bit-Wert, der als maximaler Zählwert für den Zeitgeber verwendet wird.
Wann
die Zeitgeberzählung erreicht dieser Wert wird zurückgesetzt und startet wieder bei 0.
In
die Skizze in dieses Rezepts Lösung, wenn jeder Zählung dauert 1 Mikrosekunde und die ICR1 Wert wird auf 1000 gesetzt ist, ist die Dauer jedes Zählzyklus 1000 Mikrosekunden.

OCR1A (oder OCR1B je nachdem, welchen Stift die Sie verwenden möchten) ist der Ausgang vergleichen Registrieren Sie sich für Timer1.
Wenn der Zeitgeberzählerstand diesen Wert erreicht (und der Timer wird in PWM
Modus wie hier), wird der Ausgangspin gesetzt Nieder diese werden bestimmt die Impulsbreite.
Zum Beispiel, wenn jede Zählung erfolgt eine Mikrosekunde und die ICR1 Wert wird auf 1000 gesetzt und OCR1A auf 100 gesetzt ist, wird der Ausgangspin HOCH für 100 Mikrosekunden und LOW für 900 sein
Mikrosekunden (die Gesamtdauer beträgt 1000 Mikrosekunden).

Die Dauer jeder Zählung vom Arduino Controller Zeitbasis bestimmt
Frequenz (typischerweise 16 MHz) und die Vorskalierwert.
Der Skalierwert ist der Wert, der die
Zeitbasis wird durch unterteilt. Beispielsweise mit einem Skalierwert 64 wird die Zeitbasis sein 4 Mikrosekunden.

Der Timer1 Bibliothek hat viele nützliche Funktionen, finden Sie in der Playground Artikel für Details -but es nicht ermöglichen die Einstellung einer spezifischen Pulsbreite.
Diese Funktionalität ist
ergänzt durch die Funktion mit dem Namen setPulseWidth.

Diese Funktion verwendet einen Wert von ICR1, den Zeitraum zu bestimmen:

18.4 Einstellen Timer Impulsdauer und Laufzeit | 613



int prescaleValue = prescale[Timer1.clockSelectBits];

Die Vorskalierwert wird durch eine Variable in der Bibliothek mit dem Namen clockSelectBits gesetzt.
Diese Variable
einen Wert zwischen 1 und enthält 7-dies wird als Index in das Array verwendet prescale um die aktuelle prescale Faktor zu erhalten.
Die Dauer für jede Zahl (Präzision) wird durch Multiplikation der Vorskalierwert berechnet um die Dauer eines Zeitbasiszyklus:

// time per counter tick in ns
long precision = (F_CPU / 128000) * prescaleValue ;


Die Periode ist die Präzision-fachen Wert des ICR1 registrieren; es ist von 1000 bis aufgeteilt geben die Dauer in Mikrosekunden:

period = precision * ICR1 / 1000; //
Zeit in Mikrosekunden

Der Timer1 Bibliothek verfügt über eine Funktion namens pwm, die das Tastverhältnis eingegeben werden erwartet als ein Verhältnis von einem Wert ausgedrückt von 1 bis 1.023
 (wobei 1 die kleinste Puls und 1.023
die längste).
Dieser Wert wird mit dem Arduino Karte Funktion, um die Skalierung berechnet
Mikrosekunden für die Zeit gegeben in einen proportionalen Wert der Zeit, die reicht von 1 bis 1023:

int duty = map(microseconds, 0,period, 1,1023);

Siehe auch
Siehe "Siehe auch" auf Seite 602 finden Sie Links zu Datenblättern und anderen Hinweise für Timer.

18.5 Erstellen eines Impulsgeber
Problem
Sie möchten Impulse von Arduino erzeugen und steuern die Eigenschaften aus der Serial Monitor.

Lösung
Dies ist eine erweiterte Version des Rezept 18.4, die die Frequenz, Periode, Puls ermöglicht Breite und Arbeitszyklus, von der seriellen Schnittstelle eingestellt werden:

Zeitgeber Frequenz Periode Puls TimerOne_1a.ino
// Titel: Zeitgeber Frequenz Periode Puls TimerOne// Beschreibung: Dies ist eine erweiterte Version des Rezept 18.4, // die die Frequenz, Periode, Puls ermöglichtBreite und Arbeitszyklus, // von der seriellen Schnittstelle eingestellt werden:// Autor: Fritz Prenninger// Datum: 2015-05-01// Sketch: Zeitgeber Frequenz Periode Puls TimerOne_1a.ino// Shield: keines// Controller: Arduino UNO R3// Version: Arduino 1.0.6// Tools: COM4// 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567#include <TimerOne.h>const char SET_PERIOD_HEADER = 'p';const char SET_FREQUENCY_HEADER = 'f';const char SET_PULSE_WIDTH_HEADER = 'w';const char SET_DUTY_CYCLE_HEADER = 'c';#define pwmRegister OCR1A // die logische Stift kann zu OCR1B eingestellt werdenconst int outPin = 9; // der physische Stift ist pin-9

long period = 1000; // die Zeit in Mikrosekundenint duty = 512; // duty Bereich von 0 to 1024 ist 512 beträgt 50% Einschaltdauerint prescale[] = { 0,1,8,64,256,1024}; // der Bereich der prescale Wertevoid setup(){ Serial.begin(9600); pinMode(outPin, OUTPUT); Timer1.initialize(period); // Timer1 mit 1000 Mikro initialisieren Timer1.pwm(9, duty); // Setup PWM auf pin-9, 50% Tastverhältnis}void loop(){ processSerial();}void processSerial(){ static long val = 0; if ( Serial.available()) { char ch = Serial.read(); if(ch >= '0' && ch <= '9') // ch ist eine Zahl? { val = val * 10 + ch - '0'; // Ja, accumuliere den WERT } else if(ch == SET_PERIOD_HEADER) { period = val; Serial.print("Setting period to "); Serial.println(period); Timer1.setPeriod(period); Timer1.setPwmDuty(outPin, duty); // nicht das Tastverhältnis ändern show(); val = 0; } else if(ch == SET_FREQUENCY_HEADER)


{ if(val > 0) { Serial.print("Setting frequency to "); Serial.println(val); period = 1000000 / val; Timer1.setPeriod(period); Timer1.setPwmDuty(outPin, duty); // don't change the duty cycle } show(); val = 0; } else if(ch == SET_PULSE_WIDTH_HEADER) { if( setPulseWidth(val) ) { Serial.print("Setting Pulse width to "); Serial.println(val); } else Serial.println("Pulse width too long for current period"); show(); val = 0; } else if(ch == SET_DUTY_CYCLE_HEADER) { if( val >0 && val < 100) { Serial.print("Setting Duty Cycle to "); Serial.println(val); duty = map(val,1,99, 1, ICR1); pwmRegister = duty; show(); } val = 0; } }}bool setPulseWidth(long microseconds){ bool ret = false; int prescaleValue = prescale[Timer1.clockSelectBits]; // calculate time per tick in ns long precision = (F_CPU / 128000) * prescaleValue ; period = precision * ICR1 / 1000; // period in microseconds if( microseconds < period) { duty = map(microseconds, 0,period, 0,1024); if( duty < 1) duty = 1; if(microseconds > 0 && duty < RESOLUTION) { Timer1.pwm(outPin, duty); ret = true; } } return ret;}void show(){ Serial.print("The period is "); Serial.println(period); Serial.print("Duty cycle is "); // pwmRegister is ICR1A or ICR1B



Serial.print( map( pwmRegister, 0,ICR1, 1,99)); Serial.println("%"); Serial.println();}


Diskussion
Diese Skizze ist auf Rezept 18.4 basiert, mit dem Zusatz von Seriennummer, um Befehle zu interpretieren zu empfangen und die Frequenz, Periode, Impulsdauer und Einschaltdauer Prozent.
Kapitel 4 erläutert die Technik verwendet, um die Variable val, die dann verwendet wird, zu akkumulieren für den gewünschten Parameter, bezogen auf die Befehlsbuchstaben.
Sie können diese Funktion hinzufügen, wenn Sie Anweisungen an die serielle Schnittstelle drucken möchten:

void instructions()
{
Serial.println("Send values followed by one of the following tags:");
Serial.println(" p - sets period in microseconds");
Serial.println(" f - sets frequency in Hz");
Serial.println(" w - sets pulse width in microseconds");
Serial.println(" c - sets duty cycle in %");
Serial.println("\n(duty cycle can have one decimal place)\n");
}





Siehe auch
Rezept 18.4
Siehe "Siehe auch" auf Seite 602 finden Sie Links zu Datenblättern und anderen Hinweise für Timer.

18.6 Ändern einer Timer-PWM-Frequenz
Problem
Sie müssen sich erhöhen oder verringern die Pulsweitenmodulation (PWM) Frequenz verwendet mit analogWrite (siehe Kapitel 7).
Zum Beispiel können Sie mit analogWrite sind mit einer Steuer
Motordrehzahl und es gibt ein hörbares Brummen, da die PWM-Frequenz zu hoch ist, oder Sie sind Multiplexing LEDs und das Licht ist uneben, weil PWM-Frequenz zu niedrig ist.

Lösung

Sie können die PWM-Frequenz durch Ändern einer Registerwert einstellen. Die Registerwerte und die damit verbundenen Frequenzen sind in Tabelle 18-2 gezeigt.

Tabelle 18-2. Einstellwerte für PWM





Alle Frequenzen werden in Hertz und gehen von einem 16 MHz-System-Zeitbasis.
Der Standard prescale
Faktor 64 ist fett gedruckt.
Diese Skizze können Sie eine Timer-Frequenz von der Serial Monitor auswählen.
Geben Sie ein
stelligen 1-7 mit dem Wert in der linken Spalte der Tabelle 18-2 und folgen dieser mit Charakter für eine Timer0, b für Timer1, und c für Timer2:


const byte mask = B11111000; //
Maskenbits that are not prescale WERT
int prescale = 0;

void setup()
{
Serial.begin(9600);
analogWrite(3,128);
analogWrite(5,128);
analogWrite(6,128);
analogWrite(9,128);
analogWrite(10,128);
analogWrite(11,128);
}

void loop()
{
  if ( Serial.available())
  {
    char ch = Serial.read();
    if(ch >= '0' && ch <= '9') //
ch ist eine Zahl?
    {
    prescale = ch - '0';
    }
    else if(ch == 'a') // timer 0;
    {
    TCCR0B = (TCCR0B & mask) | prescale;
    }
    else if(ch == 'b') // timer 1;
    {
    TCCR1B = (TCCR1B & mask) | prescale;
    }
    else if(ch == 'c') // timer 2;
    {
      TCCR2B = (TCCR2B & mask) | prescale;
    }
  }
}





Vermeiden, dass die Frequenz des Timer0 (zum analogWrite Stifte 5 eingesetzt und 6), weil es zu falschen Zeitpunkt führen mit Verzögerung und millis.

Diskussion
Wenn Sie nur noch LEDs zu den analogen Pins in dieser Skizze angeschlossen, werden Sie nicht sehen, merkliche Veränderung der Helligkeit, wie Sie die PWM-Drehzahl ändern.
Sie ändern
die Geschwindigkeit, wie sie drehen sich ein und aus, nicht das Verhältnis der Ein / Aus-Zeit.
Wenn dies unklar ist,
finden Sie in der Einleitung zu Kapitel 7, um mehr über PWM.
Sie ändern die PWM-Frequenz eines Timers durch Setzen des TCCRnB Register, wobei n die Registernummer.
Auf einem Mega Pension haben Sie auch TCCR3B, TCCR4B und TCCR5B für Timer
3 bis 5.

Alle analogen Ausgang (PWM) Stifte auf einem Zeitgeber mit derselben Frequenz arbeiten, so dass ändernden Timerfrequenz wird alle Ausgangspins für diesen Timer beeinflussen.

Siehe auch
Siehe "Siehe auch" auf Seite 602 finden Sie Links zu Datenblättern und anderen Hinweise für Timer.

18.6 Ändern einer Timer-PWM-Frequenz | 619






18.7 Zählimpulse
Problem
Sie wollen die Anzahl der Impulse auf einem Stift auftreten zählen. Sie wollen diese Anzahl zu sein vollständig in Hardware ohne Software-Bearbeitungszeit gemacht verbraucht.

Lösung
Verwenden Sie den Impulszähler in die Timer1-Hardware gebaut:

/*
* HardwareCounting sketch
*
* uses pin 5 on 168/328
*/
const int hardwareCounterPin = 5; //
Eingangsstift auf interne Timer fest
const int ledPin = 13;
const int samplePeriod = 1000;    //
Die Probenzeit in Millisekunden
unsigned int count;
void setup()
{
Serial.begin(9600);
pinMode(ledPin,OUTPUT);
                                  // Hardwarezähler-Setup (siehe ATmega Datenblatt für weitere Details)
TCCR1A=0;                         //
Timer / Zähler-Steuerregister A zurückgesetzt}
void loop()
{
digitalWrite(ledPin, LOW);
delay(samplePeriod);
digitalWrite(ledPin, HIGH);
                                 
// Die Auszählung beginnen
bitSet(TCCR1B ,CS12);             //
Zähler Taktquelle externen Pin
bitSet(TCCR1B ,CS11);             //
Clock bei steigender Flanke
delay(samplePeriod);
                                  // Stoppen der Stoppuhr
TCCR1B = 0;
count = TCNT1;
TCNT1 = 0;                        //
Die Hardware-Zähler zurückzusetzen
if(count > 0)
Serial.println(count);
}



Diskussion
Sie können diesen Entwurf, indem Sie den seriellen Test erhalten (Pin 0) mit dem Eingang (Pin 5 auf einem Standard-Arduino-Board).
Jedes Zeichen gesendet sollte eine Erhöhung der zeigen

620 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Vorzähler die spezifische Erhöhung hängt von der Anzahl von Impulsen benötigt wird, um die darstellen ASCII-Wert der Zeichen
(bedenken Sie, dass die Serienzeichen befinden sich zwischen eingeklemmt
Start und Stopp-Impulse).
Einige interessante Zeichenmuster sind:

'u' = 01010101
'3' = 00110011
'~' = 01111110
'@' = 01000000



Wenn Sie zwei Arduino-Boards haben, können Sie eine der Pulsgenerator Skizzen aus ausführen vorherige Rezepte in diesem Kapitel und verbinden Sie den Impulsausgang (Pin 9) mit dem Eingang.
Die
Pulsgenerator verwendet auch Timer1 (die nur 16-Bit-Timer auf einem Standard-Arduino-Board) so können Sie die Funktionalität mit einem einzigen Board zu verbinden.

Hardware Impulszählung verwendet einen Stift, der intern in der verdrahtet Hardware und kann nicht verändert werden.
Verwenden Sie auf einem Standard-Arduino Pin 5
Bord.
Die Mega verwendet Zeitgl5, die an Pin 47 ist;
ändern TCCR1A zu
TCCR5A und TCCR1B zu TCCR5B,

Des Timers TCCR1B Register steuert die Zählung Verhalten, die Einstellung so 0 stoppt die Zählung.
Die in der Schleife Kode Werte ermöglichen Zählung in der ansteigenden Flanke der Impulse für die Eingangs-Pin. TCNT1 ist die Timer1-Register in der Arduino Kern-Code, der sammelt erklärt der Zählwert.
In loop wird der aktuelle Zählerstand einmal pro Sekunde gedruckt. Wenn keine Impulse von detektierten Stift 5 werden die Werte 0 sein.

Siehe auch
Die FrequencyCounter Bibliothek mit der Methode in diesem Rezept beschrieben:
http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library/

Siehe "Siehe auch" auf Seite 602 finden Sie Links zu Datenblättern und anderen Hinweise für Timer.


18.8 Measuring Pulses More Accurately
Problem
Sie wollen die Zeit zwischen Impulsen oder die Dauer der ein oder aus zu messen eines Impulses.
Sie benötigen diese so genau wie möglich, so dass Sie nicht möchten, dass jede Verzögerung durch
Aufruf einer Interrupt-Handler (wie in Rezept 18.2), da dies die Messungen beeinflussen.

Lösung
Verwenden Sie die Hardware-Pulsmessfähigkeit in die Timer1-Hardware gebaut:

Pulszeit messen - Sie fahren kmh_1a.ino
// Titel: Pulszeit messen - Sie fahren kmh// Beschreibung: Zeit zwischen 2 Impulsen oder die Zeit zwischen EIN und AUS eines Impulses  messen // Impulsdauer genau messen // Autor: Fritz Prenninger// Datum: 2015-05-01// Sketch: Pulszeit messen - Sie fahren kmh_1a.ino// Shield: keines// Controller: Arduino UNO R3// Version: Arduino 1.0.6// Tools: COM4// 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567/*InputCapture Timer verwendet Hardware, um Impulse an Pin 8 auf ATMEL ATmega168 oder AZTmega328 messen *//* Einige interessante ASCII Bit-Muster: u 01010101 3 00110011 ~ 01111110 @ 01000000 */const int inputCapturePin = 8;                  // Eingangs-pin fixed auf internem Timerconst int ledPin = 13;                          // eingebaute LED an pin-13const int prescale = 8;                         // Prescale Faktor (each tick 0.5 us @16MHz)const byte prescaleBits = B010;                 // siehe Tabelle 18-1 bzw. Datenblatt                                                // calculate time per counter tick in nsconst long precision = (1000000/(F_CPU/1000)) * prescale ;const int numberOfEntries = 64;                 // die maximale Anzahl von Impulsen zu messenconst int gateSamplePeriod = 1000;              // the sample period in millisecondsvolatile byte index = 0;                        //  Index der gespeicherten Messwertevolatile byte gate = 0;                         // 0 deaktiviert Erfassung, 1 aktiviertvolatile unsigned int results[numberOfEntries]; //  beachten Sie, das ist 16bit-Wert                                                // ICR InterruptvektorISR(TIMER1_CAPT_vect){  TCNT1 = 0;                                     // Den Zähler zurückzusetzen  if(gate)  {    if( index != 0 || bitRead(TCCR1B ,ICES1) == true) // auf steigende Flanke warten    {                                                 // fallende Flanke wurde erkannt       if(index < numberOfEntries)      {        results[index] = ICR1;          // speichere the input capture value        index++;      }    }  }  TCCR1B ^= _BV(ICES1);                 // Toggle-Bit to trigger on the other edge}void setup() {  Serial.begin(9600);  pinMode(ledPin, OUTPUT);  pinMode(inputCapturePin, INPUT);       // ICP Stift (Digitalstift 8 auf Arduino) als Eingabe  TCCR1A = 0 ; // Normale Zählmodus  TCCR1B = prescaleBits ;                // setze das  prescale bits  TCCR1B |= _BV(ICES1);                  //  Input Capture aktivieren  bitSet(TIMSK1,ICIE1);                  //  Freigabeeingang Erfassung Interrupt für Timer 1    Serial.println("pulses are sampled while LED is lit");  Serial.print( precision);              // Report Dauer der einzelnen Häkchen in Mikrosekunden  Serial.println(" microseconds per tick");}// Diese Schleife gibt die Anzahl der Impulse in der letzten Sekunde // und zeigt min und die max. Impulsbreitenvoid loop(){  digitalWrite(ledPin, LOW);  delay(gateSamplePeriod);  digitalWrite(ledPin, HIGH);  gate = 1;                               // enable sampling  delay(gateSamplePeriod);  gate = 0;                               // disable sampling  if(index > 0)  {    Serial.println("Durations in Microseconds are:") ;    for( byte i=0; i < numberOfEntries; i++)    {      long duration;      duration = results[i] * precision;   // Pulsdauer in Nanosekunden      if(duration >0)        Serial.println(duration / 1000);   // Dauer in Mikrosekunden    }    index = 0;  }}


Diskussion
Diese Skizze wird ein Timer-Anlage genannt Eingangserfassung, um die Dauer eines Impulses zu messen.
Nur 16-Bit-Timer unterstützt diese Funktion und das funktioniert nur mit Pin 8 auf einem Standard Arduino UNO Board.

Eingang Capture verwendet einen Stift, die intern innerhalb der Hardware verdrahtet und kann nicht verändert werden.
FEHLER in dieser Zeile > Verwenden Sie auf einem Standard-Arduino-Board und Pin Pin 8
48 auf einem Mega (mit Zeitgl5 statt Timer1).

Da Eingangserfassung vollständig in dem Controller-Chip-Hardware implementiert, keine Zeit in Interruptverarbeitung verschwendet, so dass diese Technik genauer ist für sehr kurze Pulse
(Weniger als zehn Mikrosekunden).
Die Skizze wird ein Gate-Variable, die Messungen (wenn ungleich Null) alle anderen ermöglicht Sekunde.
Die LED leuchtet, um anzuzeigen, dass die Messung aktiv ist.
Die Input-Capture-Unterbrechungsroutine speichert die Impulsdauern von bis zu 64 Impulsübergängen.
Die Kante, die den Timer Messung löst wird durch die ICES1 Bit des fest TCCR1B Geberregister.

18.8 Mess Impulse genauer | 623



Die Linie:

TCCR1B ^= _BV(ICES1);

schaltet die Kante, die die Prozedur auslöst, so dass die Dauer der hohen und niedrigen Impulse gemessen.
Wenn die Zählung geht höher als der Maximalwert für den Timer, können Sie Überlauf überwachen eine Variable, um den Zählbereich zu erweitern erhöhen.
Die folgenden Code-Schritten
eine Variable namens Lauf jedesmal, wenn der Zähler überläuft:

volatile int overflows = 0;
/* Überlau-Interrupt-Vector */
ISR(TIMER1_OVF_vect) //
hier, wenn kein Eingangsimpuls erkannt{
overflows++; //
Schrittzahl-Überlauf
}
Change the code in setup as follows:
TIMSK1 = _BV(ICIE1); //
Freigabeeingang Erfassung Interrupt für Timer 1
TIMSK1 |= _BV(TOIE1); //
Fügen Sie diese Zeile, um Überlaufunterbrechungsfreigabe

Siehe auch
Siehe "Siehe auch" auf Seite 602 finden Sie Links zu Datenblättern und anderen Hinweise für Timer.


18.9 Measuring Analog Values Quickly
Problem
Sie möchten einen Analogwert so schnell wie möglich zu lesen, ohne die Genauigkeit.
Lösung
Sie können die analogRead Abtastrate indem Registerwerte, die bestimmen, zu erhöhen die Sampling-Frequenz:


const int sensorPin = 0; // pin the receiver is connected to
const int numberOfEntries = 100;
unsigned long microseconds;
unsigned long duration;
int results[numberOfEntries];
void setup()
{
Serial.begin(9600);
// standard analogRead performance (prescale = 128)
microseconds = micros();
for(int i = 0; i < numberOfEntries; i++)
{
results[i] = analogRead(sensorPin);
}
duration = micros() - microseconds;
Serial.print(numberOfEntries);
Serial.print(" readings took ");
Serial.println(duration);
// running with high speed clock (set prescale to 16)
bitClear(ADCSRA,ADPS0) ;
bitClear(ADCSRA,ADPS1) ;
bitSet(ADCSRA,ADPS2) ;
microseconds = micros();
for(int i = 0; i < numberOfEntries; i++)
{
results[i] = analogRead(sensorPin);
}
duration = micros() - microseconds;
Serial.print(numberOfEntries);
Serial.print(" readings took ");
Serial.println(duration);
}
void loop()
{
}




Ausführen der Skizze auf einem 16 MHz Arduino wird ähnlich wie die folgende Ausgabe:

100 readings took 11308
100 readings took 1704



Diskussion
analogRead dauert ca. 110 Mikrosekunden, um eine Messung durchzuführen. Dies kann nicht schnell sein genug für eine rasche Änderung der Werte, wie die Erfassung der höheren Bereich von Audiofrequenzen.
Die Skizze misst die Zeit in Mikrosekunden für die Standard analogRead und dann passt die von der Analog-Digital-Wandler (ADC) verwendet Zeitbasis durchzuführen die Umwandlung schneller.
Mit einem 16 MHz Board wird die Zeitbasis Rate von erhöhten
125 kHz bis 1 MHz.
Der tatsächliche Leistungsverbesserung ist geringfügig kleiner als 8
Zeiten, denn es gibt einige Overhead in der Arduino analogRead Funktion, die nicht durch die Zeitbasisänderung verbessert.
Die Verringerung der Zeit von 113 Mikrosekunden bis 17
Mikrosekundn ist eine signifikante Verbesserung.

Die ADCSRA Register wird verwendet, um den ADC zu konfigurieren, und die Bits in der Skizze eingestellt
(ADPS0, ADPS1 und ADPS2) stellen Sie die ADC-Taktteiler 16.
Siehe auch
Atmel hat eine Applikationsschrift, die eine ausführliche Erklärung der Leistung bietet Aspekte der ADC:
http://www.atmel.com/dyn/resources/prod_documents/DOC2559.PDF

18.9 Messanalogwerte schnell | 625



18.10 Reduzierung Batterieverbrauch
Problem
Sie wollen die Leistung von Ihrer Anwendung verwendet durch Abschalten Arduino reduzieren bis eine Zeitspanne verstrichen ist oder bis ein externes Ereignis stattfindet.
Lösung
Diese Lösung verwendet eine Bibliothek mit Arduino-Guru Peter Ritter. Sie können die Bibliothek downloaden von
http://code.google.com/p/narcoleptic/:


#include <Narcoleptic.h>
void setup() {
pinMode(2,INPUT);
digitalWrite(2,HIGH);
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
}
void loop() {
int a;
//
Merlin die Katze dösen ... Schließen digitalen Pin 2 an Masse, um ihn aufzuwecken.
Narcoleptic.delay(500); // During this time power consumption is minimized
while (digitalRead(2) == LOW) {
// Wake up CPU. Unfortunately, Merlin does not like waking up.
// Swipe claws left
digitalWrite(13,HIGH);
delay(50);
// Swipe claws right
digitalWrite(13,LOW);
delay(50);      // Verzögerung 50ms
}
// 
Merlin die Katze geht schlafen ...}





Diskussion
Ein Standard-Arduino-Board würde eine 9-Volt-Alkalibatterie in ein paar Wochen heruntergekommen
(Die Duemilanove zieht in der Regel mehr als 25 Milliampere [mA], ohne ein externes
Geräte, die angeschlossen werden können).
Sie können diesen Verbrauch um die Hälfte zu reduzieren, wenn Sie
verwenden Sie ein Brett, das nicht über einen integrierten USB-Schnittstellen-Chip, wie der Arduino Mini, LilyPad, Fio, oder in einem der modernen Geräte Bare Bones Boards, die den Einsatz erforderlich eine externe USB-Schnittstelle für das Hochladen Skizzen. Deutlich höhere Energieeinsparungen kann erreicht werden, wenn Ihre Anwendung kann der Betrieb für einen Zeitraum von zeit- auszusetzen
626 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Arduino Hardware kann für eine vorgegebene Zeitspanne oder bis ein Stift Änderungen eingeschläfert werden Zustand, und dies reduziert den Stromverbrauch des Chips auf weniger als ein onehundredth von 1 Prozent (von etwa 15 mA auf etwa 0,001 mA) während des Schlafes.
Die in diesem Rezept verwendet Bibliothek bietet einfachen Zugriff auf die Hardware-Schlaf-Funktion.
Die
Schlafzeit kann von 16 bis 8.000 Millisekunden (acht Sekunden) betragen.
Um länger schlafen
Zeiten, können Sie die Verzögerungsintervalle wiederholen, bis Sie den Zeitraum, die Sie wollen:


void longDelay(long milliseconds)
{
   while(milliseconds > 0)
   {
     if(milliseconds > 8000)
     {
       milliseconds -= 8000;
       Narcoleptic.delay(8000);
     }
     else
     {
       Narcoleptic.delay(milliseconds);
       break;
     }
   }
}




Ruhemodus können den Stromverbrauch des Controller-Chips zu reduzieren, aber wenn Sie sind suchen, um so lange wie möglich auf einer Batterie laufen, sollten Sie Stromverbrauch zu minimieren durch externe Komponenten wie ineffiziente Spannungsregler, Pull-up oder Pull-Down- Widerstände, LEDs und andere Komponenten, die Strom ziehen, wenn der Chip in schlafmodus.

Siehe auch
Finden Sie in der Hardware-Seite Arduino für Verknüpfungen zu Informationen über die LilyPad und Fio Platten:
http://www.arduino.cc/en/Main/Hardware
Ein Beispiel für die sehr geringe Leistungsaufnahme Betrieb finden
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/






18.11 Einstellung Digitale Pins Schnell
Problem
Sie müssen festlegen oder klar digitalen Stifte viel schneller als von der Arduino digitale aktiviert Schreibbefehl.

18.11 Einstellen der digitalen Pins Schnell | 627


Lösung
Arduino digital bietet eine sichere und einfach zu bedienende Methode Setzen und Löschen Stifte, aber es ist mehr als 30 mal langsamer als direkt auf die Controller-Hardware.
Sie können klare Stifte durch direktes Setzen Bits auf den Hardware-Register, die gesetzt sind und Steuerung digitaler Stifte.
Diese Skizze verwendet direkte Hardware-I / O, um Morse-Code (das Wort Arduino) einen AM senden Radio auf etwa 1 MHz abgestimmt.
Die hier verwendete Technik ist 30 mal schneller als
Arduino digitalWrite:

/*
* Morse sketch
*
* Direct port I/O used to send AM radio carrier at 1MHz
*/
const int sendPin = 2;
const byte WPM = 12;                       //
Sendegeschwindigkeit in Wörtern pro Minute
const long repeatCount = 1200000 / WPM;    //
Zahl bestimmt Punkt / Strich-Dauer
const byte dot = 1;
const byte dash = 3;
const byte gap = 3;
const byte wordGap = 7;
byte letter = 0; // the letter to send
char *arduino = ".- .-. -.. ..- .. -. ---";
void setup()
{
pinMode(sendPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
sendMorse(arduino);
delay(2000);
}
void sendMorse(char * string)
{
letter = 0 ;
while(string[letter]!= 0)
{
if(string[letter] == '.')
{
sendDot();
}
else if(string[letter] == '-')
{
sendDash();
}
else if(string[letter] == ' ')
{
sendGap();
}
else if(string[letter] == 0)
{
sendWordGap();
}
letter = letter+1;
}
}
void sendDot()
{
transmitCarrier( dot * repeatCount);
sendGap();
}
void sendDash()
{
transmitCarrier( dash * repeatCount);
sendGap();
}
void sendGap()
{
transmitNoCarrier( gap * repeatCount);
}
void sendWordGap()
{
transmitNoCarrier( wordGap * repeatCount);
}
void transmitCarrier(long count)
{
while(count--)
{
bitSet(PORTD, sendPin);
bitSet(PORTD, sendPin);
bitSet(PORTD, sendPin);
bitSet(PORTD, sendPin);
bitClear(PORTD, sendPin);
}
}
void transmitNoCarrier(long count)
{
while(count--)
{
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
bitClear(PORTD, sendPin);
}
}



Verbinden Sie ein Ende einem Stück Draht an Pin 2 und das andere Ende in der Nähe der Antenne eines Mittelwellen-AM-Radio zu 1 MHz (1000 kHz) abgestimmt.

Diskussion
Die Skizze erzeugt ein 1 MHz Signal an Punkt-Strich-Sounds, die sein können, produzieren von einem AM-Radio auf diese Frequenz abgestimmt übermittelt.
Die Frequenz wird durch das bestimmt
Dauer der BitSet und BITCLEAR Befehle, die den Stift HIGH und LOW gesetzt zu erzeugen das Funksignal.
BitSet und BITCLEAR nicht funktioniert, sind sie Makros.

Makros Ersatz
ein Ausdruck für einen ausführbaren Code, in diesem Fall ein Code, der ein einziges Bit ändert im Register PORTD durch den Wert der sendPin gegeben.
Digitalen Pins 0 bis 7 werden von dem Register mit dem Namen PORTD gesteuert. Jedes Bit in PORTD entspricht einem digitalen Stift. Pins 8 bis 13 sind auf Register PORTB und Stiften 14 durch 19 sind auf PORTA.
Die Skizze verwendet die BitSet und BITCLEAR Befehle zum Setzen und Löschen
Bits auf dem Port (siehe Rezept 3.12).
Jedes Register unterstützt bis zu acht Bits (wenn auch nicht
Alle Bits entsprechen Pins Arduino).
Wenn Sie Arduino Pin 13 statt Stift verwenden möchten
2, müssen Sie festgelegt und klar PORTB wie folgt:

const int sendPin = 13;

bitSet(PORTB, sendPin - 8);
bitClear(PORTB, sendPin - 8);


Sie subtrahieren 8 von dem Wert des Stiftes, weil das Bit 0 des PORTB Register Pin 8, Bit 1 ist Pin 9 und so weiter, bis Bit 5 Stellnockens 13.
Setzen und Löschen Bits mit Bitset wird in einer einzigen Anweisung des Arduino gemacht Controller.
Auf einem 16 MHz Arduino, also 62,5 Nanosekunden.

Dies ist etwa 30x
schneller als mit digital.
Die Sendefunktionen in der Skizze tatsächlich brauchen mehr Zeit aktualisiert und prüft die Zählvariable als es braucht, um eingestellt und deaktivieren Sie die Register-Bits, die, warum der ist transmitCarrier Funktion hat vier BitSet Befehle und nur eine BITCLEAR Befehls die zusätzlichen BITCLEAR Befehle werden nicht wegen der Zeit brauchte braucht, um zu aktualisieren, und überprüfen Sie die Zählvariable.


18,12 Hochladen Sketches Mit einem Programmer
Problem
Sie möchten Skizzen mit einem Programmierer statt des Bootloaders zu laden. Vielleicht
Sie wollen die kürzeste Ladezeit, oder Sie nicht eine serielle Verbindung zu Ihrem Com- haben

630 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Computer für Urladen, oder Sie, um den Raum in der Regel für die reservierte verwenden möchten Bootloader, den Programmspeicher zur Verfügung, um die Skizze zu erhöhen.

Lösung

Schließen Sie eine externe In-System-Programmierer (ISP) mit dem Arduino Programmier ICSP (In-Circuit Serial Programming) Anschluss.
Programmierer für die Verwendung mit Arduino bestimmt
einen 6-poligen Kabel, das an den 6-poligen Stecker ICSP legt, wie in Abbildung 18-1 gezeigt.
Darauf achten, dass Pin 1 vom Programmierer (in der Regel mit anderen Farbe als der markierte andere Drähte) angeschlossen ist, um auf dem ICSP-Anschluss Pin 1.
Der Programmierer kann
ein Schalter oder Jumper, es zu ermöglichen, das Arduino-Board anzutreiben; lesen Sie die Anweisungen zur Ihre Programmierer, um sicherzustellen, dass der Arduino korrekt versorgt.

Abbildung 18-1. Anschließen eines Programmierer Arduino



Wählen Sie ein Programmierer aus dem Menü Extras. (AVRISP, AVRISPII, USBtinyISP, Parallel Programmierer oder Arduino als ISP) und überprüfen Sie, dass Sie die richtige Arduino haben Vorstand gewählt.
Wählen Sie im Menü Datei die Option hochladen Mit Programmer durchführen
der Upload.

Diskussion
Es gibt eine Anzahl von unterschiedlichen Programmierern möglich, von teuren Geräten gerichtet an professionelle Entwickler, die verschiedene Debugging-Optionen bieten, um Low-Cost-Eigenbau Kits oder Programmieren eines zusätzlichen Arduino um diese Funktion auszuführen.
Der Programmierer
kann eine native USB-Gerät zu sein, oder als eine serielle Schnittstelle angezeigt.
Überprüfen Sie die Dokumentation für
Ihr Gerät zu sehen, welche Art es ist, und ob Sie den Treiber dafür zu installieren.

Die seriellen Rx und Tx LEDs auf der Arduino nicht beim Upload flackern
da der Programmierer nicht über die serielle Schnittstelle Hardware.
18,12 Hochladen Sketches Mit einem Programmierer | 631


Hochladen mit einem Programmiergerät entfernt die Bootloader-Code aus dem Chip.
Dies befreit
bis der Raum der Bootloader nimmt und gibt ein wenig mehr Raum für Ihre Skizze Code.

Siehe auch
Code, um eine Arduino in eine ISP-Programmer umwandeln kann in der Skizze Beispiel gefunden werden Namen ArduinoISP.
Die Kommentare in der Skizze beschreibt die Verbindungen zu verwenden.
In Rezept 18.13.
Geeignete Hardware-Programmierer sind:
• USBtinyISP
• Atmel avrisp2
• CrispAVR_USB STK500

18.13 Austausch der Arduino Bootloader
Problem
Sie wollen den Bootloader zu ersetzen. Vielleicht können Sie das Motherboard, um Programme hochzuladen nicht bekommen und vermuten, dass der Bootloader nicht funktioniert.
Oder Sie wollen einen alten Bootloader ersetzen möchten
mit einem mit höherer Leistung oder verschiedene Funktionen.
Lösung
Schließen Sie ein Programmierer, und wählen Sie sie aus, wie in Rezept 18.12 behandelt.
Überprüfen Sie
das richtige Board ausgewählt, und klicken Sie auf "Burn Bootloader" aus dem Menü Extras.
Eine Meldung wird in der IDE angezeigt, die besagt "Burning Bootloader auf I / O Karte (dies kann eine Minute), ... "Programmierer mit Status-LEDs sollte, dass der Bootloader angeben wird an die Tafel geschrieben.
Sie sollten die LED angeschlossen bis 13 Flash die Pin zu sehen
Brett ist so programmiert (Stift 13 passiert, zu einem der ICSP-Signal-Pins angeschlossen sein).
Wenn alles gut geht, sollten Sie eine Meldung bekommen "Fertig Laden Bootloader."
Trennen Sie das Programmiergerät und versuchen Upload-Code durch die IDE, um sicherzustellen, ist es Arbeiten.
Diskussion
Der Bootloader ist ein kleines Programm, das auf dem Chip ausgeführt wird und kurz überprüft jedes Mal die Chip-Leistungen bis zu festzustellen, ob die IDE-Upload-Code versucht, den Vorstand.
Wenn ja, die
Bootloader übernimmt und ersetzt den Code auf dem Chip mit neuer Code hochgeladen über die serielle Schnittstelle.
Wenn der Bootloader ist eine Anforderung zum Hochladen nicht erkennen kann, überlässt es
Kontrolle der Skizze Code bereits auf dem Brett.
Wenn Sie eine serielle Programmierer verwendet haben, müssen Sie die serielle Schnittstelle zurück zu schalten die richtige für Ihr Arduino Board, wie in Rezept 1.4 beschrieben.

632 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Siehe auch
Optiloader, von Bill Westfield halten, ist eine andere Art zu aktualisieren oder installieren Sie den Bootloader.
Es verwendet ein Arduino als ISP-Programmer angeschlossen, aber alle Bootloader in der Arduino Sketch-Code enthalten. Das bedeutet, ein Arduino mit Optiloader kann programmieren Sie einen anderen Chip automatisch, wenn die Spannung eingeschaltet, keine externe Computer benötigt. Der Code identifiziert den Chip und lädt den Bootloader korrekt darauf.

18,14 Programmieren Sie den Uno, eine Mutter USB-Gerät emulieren
Problem
Sie möchten Ihre Arduino Uno, um wie eine native USB-Gerät und nicht als Serien erscheinen Port, wie beispielsweise eine MIDI-USB-Gerät direkt mit Musikprogramme kommunizieren auf Ihrem Computer.
Lösung
Ersetzen Sie den Code auf der Uno USB-Controller läuft (ATmega8U2) Chip, so dass sie kommuniziert mit dem Computer als native USB-Gerät und nicht als serielle Schnittstelle.
a FEHLER
Wenn die Neuprogrammierung nicht sorgfältig durchgeführt oder eine andere Firmware verwendet, das keine der DFU-Firmware können Sie das Boot zu holen in einen Zustand, in dem Sie einen externen Programmierer, es mit ein Problem lösen müssen
ein Befehlszeilenprogramm namens avrdude. Wenn Sie nicht mit Lauf vertraut sind Kommandozeilen-Tools, sollten Sie sorgfältig, bevor Sie sich denken,
dieses Reze

a

Beginnen Sie mit der Programmierung der Uno-Board mit der Skizze werden, die der 8U2 sprechen wird, wie
sobald Sie die 8U2 umprogrammiert haben es schwieriger sein wird, um die Skizze zu ändern.
http:// Jagd Darran Hunt geeigneten Code für diese, die Sie aus downloaden geschrieben

http://hunt.net.nz/users/darran/weblog/52882/attachments/1baa3/midi_usb_demo.pde

 (zu der Zeit des Schreibens, verwendet diese Skizze des alten .pde Erweiterung, aber es ist kompatibel mit Arduino 1.0).
Laden Sie dieses an die Uno in der IDE auf die übliche Weise.
Diese Skizze wird Befehle an die 8U2, die sie sagen, welche MIDI-Befehle zurück in die schicken Computer.
Laden Sie den Code, um den Chip von 8U2

http://hunt.net.nz/users/darran/weblog/52882/attachments/e780e/Arduino-usbmidi-0.2.hex

Sie müssen auch Programmier-Software, die auf dem Chip 8U2 sprechen kann:
Auf Windows-Installieren Sie die Atmel Flip-Programm:
http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3886

18,14 Programmieren Sie die Uno, eine Mutter USB-Gerät emulieren | 633




Stellen Sie die 8U2 in seine umprogrammieren Modus: Wenn Ihr Uno hat die 6-poligen Stecker vom 8U2 Chip mit Stiften bestückt, dann müssen Sie nur kurz die linke Paar von Stiften (am nächsten an den USB-Anschluss) zusammen, um den Chip in den DFU-Modus zu schalten.

Die erste Uno-Boards (Revision 1) nicht über einen Widerstand benötigt, um zurückzusetzen die 8U2.
Wenn Sie nicht in der Lage, um das Board zurückgesetzt sind, folgen Sie den Anweisungen
bei
http://arduino.cc/en/Hacking/DFUProgramming8U2

Auf halbem Weg
Die Seite beschreibt, was zu tun, wenn Ihre Karte benötigt eine externe zu haben
Widerstand hinzugefügt Zurücksetzen des 8U2 Chip zu aktivieren.

Auf Windows
Wenn die Platte in den DFU-Modus zum ersten Mal gesagt, das Suchen neuer Hardware Assistent erscheint.
Wenn das Board installiert, ohne Fehler dann weiter.
Wenn der Hardware-Installation fehlschlägt (in der gleichen Weise die Uno-Installation der Fall ist), dann müssen Sie gehen in den Geräte-Manager und markieren Sie den Eintrag für Arduino DFU (es wird ein gelbes haben Warndreieck daneben), der rechten Maustaste und wählen Sie Treiber aktualisieren.
Navigieren Sie zu der
Flip 3.4.3 Ordner Programme / Atmel und wählen Sie den USB-Ordner.
Die Fahrer
sollte jetzt erfolgreich zu installieren. Starten Sie den Flip-Programm.
Wählen Sie den Gerätetyp AT90USB82 aus dem Dropdown-Menü aus (es ist der einzige aktive Option, wenn Sie zuerst das Programm).
Klicken Sie auf das Symbol einer Blei und wählen Sie USB.
Wenn Sie die Fehlermeldung AtLibUsbDfu.dll nicht gefunden haben die Treiber nicht installiert.
Folgen Sie den Anweisungen oben.
Klicken Sie auf die Schaltfläche EEPROM Schaltfläche am unteren Rand des Fensters und offene Arduino-usbmidi-0.2.hex.
Wählen Sie Ausführen links neben dieser Schaltfläche, und das Programm sollte
gehen durch den Zyklus über der Taste aufgeführt: Löschen, Programmieren, Verifizieren.
Ziehen Sie die
Board und stecken Sie es wieder und es zeigen sich als MIDI-Gerät auf Ihrem Computer.

634 | Kapitel 18: Verwenden der Controller-Chip-Hardware


Diskussion
Sobald die 8U2 umprogrammiert wird, die Nachrichten, die an den Computer gesendet werden, sind noch immer von der Skizze läuft kontrolliert an der Haupt-Chip, aber Ihr Computer sieht den Arduino Brett als MIDI-Gerät statt einer seriellen Schnittstelle.
Die Skizze läuft auf der Haupt-Chip
bestimmt, was wird an Ihren Computer gesendet, so dass Arduino auf Schalter reagieren und Sensoren zu kontrollieren, was gespielt wird.
Die IDE wird nicht die Standard-Bootloader, wenn die 8U2 wurde neu programmiert wie in diesem Rezept beschrieben, so um die Skizze zu einer externen Programmiergerät ändern
(Siehe Rezept 18.12).
Wenn Sie Ihre 8U2 in seinen ursprünglichen Zustand zurückkehren möchten, können Sie die erforderliche HEX erhalten

Datei in
https://github.com/arduino/Arduino/tree/master/hardware/arduino/firmwares
Setzen Sie dieses auf dem 8U2 mit dem oben beschriebenen Verfahren, aber mit diesem Hex-Datei statt der MIDI einem.
Wenn Sie andere Firmware verwendet haben, die den DFU-Loader (nicht alle Firmware nicht enthält im Internet sind es), oder etwas gefunden schief gegangen ist und das Board wird nicht gehen in den DFU-Modus, dann müssen Sie einen externen Programmierer verwenden, um die zu ersetzen Firmware.
Dies muss von der Kommandozeile mit dem Upload-Dienstprogramm namens AVRdude erfolgen
(Es kann nicht mit dem Arduino IDE durchgeführt werden).

Damit der folgende Befehl funktioniert, müssen Sie die Versorgung vollständigen Pfad zu avrdude, nicht nur den Namen. avrdude befindet sich im Inneren Ihrer Arduino-Programmordner:
Arduino.app / Contents / Resources / Java / Hardware /
Werkzeuge / avr / bin auf einem Mac; Hardware / tools / avr / bin im Inneren des Arduino-Ordner unter Windows.
(Sie können auch diesen Ort in den PATH-Umgebungs hinzuzufügen;
Für Ihr Betriebssystem für Google "set path Umwelt"
Details.)

In der Befehlszeile aus dem Ordner, in dem Hex-Datei befindet, führen Sie den folgenden

Befehl:
Für dien ARDUINO UNO
avrdude -p at90usb82 -F -P usb -c avrispmkii -U flash:w:UNO-dfu_and_usbse
rial_combined.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U
lock:w:0x0F:m


18,14 Programmieren Sie die Uno, eine Mutter USB-Gerät emulieren | 635

Für den ARDUINO Mega 2560
avrdude -p at90usb82 -F -P usb -c avrispmkii -U flash:w:MEGA-dfu_and_usbse
rial_combined.hex -U lfuse:w:0xFF:m -U hfuse:w:0xD9:m -U efuse:w:0xF4:m -U
lock:w:0x0F:m


Sollte Ihr Programmiergerät ist ein serielles Gerät, anstatt USB, müssen Sie ändern -P Usb an die serielle Schnittstelle festlegen (zB P \\ \ COM19 unter Windows;. -P / Dev / tty.usbserial-XXXXXX auf Mac
(überprüfen Sie die serielle Schnittstelle Menü Arduino für den Namen es
erscheint als, und welche Werte XXXXXX sind).
Stellen Sie die -c avrispmkii basierend auf der Art der
Programmierer haben. Weitere Informationen dazu finden Sie Rezept 18.12.

Siehe auch
In Rezept 18.12.
Darran Hunts ATmega8U2 Blog: http://hunt.net.nz/users/darran/
Aktualisieren der Atmega8U2 auf einer Uno oder Mega2560 mit DFU:
http://arduino.cc/en/
Hacking / DFUProgramming8U2
Die Teensy und Teensy ++ Boards können USB-HID-Geräte emulieren
http://www.pjrc.com/
teensy/
Der Arduino Leonardo Board unterstützt Emulation der USB-HID-Geräte. Leonardo hatte
nicht freigegeben, wenn das Buch gedruckt wurde; Überprüfen Sie die Seite Arduino Hardware
zu sehen, wenn es verfügbar ist:
http://www.arduino.cc/en/Main/hardware
In Rezept 9.6 für die konventionelle Art, MIDI von Arduino steuern.
Ein Tutorial für den Low-Level-Programmiertool avrdude:
http://www.ladyada.net/make/usbtinyisp/avrdude.html


636 | Kapitel 18: Verwenden der Controller-Chip-Hardware

DIN A4 ausdrucken
*********************************************************

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