ARDUINO Kochbuch‎ > ‎

Kapitel 17 deutsch

NEU

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

http://www.linksammlung.info/

http://www.schaltungen.at/

                                                                                             Wels, am 2015-04-26

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 17 engl. (16 Seiten )_1a.pdf
Auf dieser Seite die schlechte (nicht korrigierte) Maschinen-Übesetzung ins Deutsche



Draht = Wire
Stift = Pin
Rezept = Sketch


KAPITEL 17

Erweiterte Codierung und
Speicher Handhabung

17.0 Einführung

Wie Sie mit Ihrem Arduino mehr tun, müssen Sie Ihre Skizzen effizienter zu werden.
Die
Techniken, die in diesem Kapitel können Ihnen helfen, die Leistung zu verbessern und den Code zu reduzieren Größe Ihrer Skizzen.
Wenn Sie brauchen, um Ihre Zeichnung schneller laufen oder benutzen Sie weniger RAM, die
hier Rezepte helfen können.
Die Rezepte sind hier eher technische als die meisten anderen Rezepten
in diesem Buch, weil sie Dinge, die in der Regel von der freundlichen Arduino verborgen sind decken
Wrapper.
Das Arduino Build-Prozess wurde entwickelt, um komplexe Aspekte der C und C ++ zu verbergen, wie sowie die verwendeten Werkzeuge, um eine Skizze in die Bytes, die hochgeladen werden, und führen Sie auf konvertieren ein Arduino Board.
Aber wenn Ihr Projekt Performance und Ressourcenbedarf über
die Fähigkeit der Standard-Arduino-Umgebung, sollten Sie die Rezepte finden hier sinnvoll.
Das Arduino-Board verwendet den Speicher zur Speicherung von Informationen. Es verfügt über drei Arten von Speicher:
Programmspeicher, einen Direktzugriffsspeicher (RAM) und EEPROM.
Jeder hat andere
Eigenschaften und Verwendungen.
Viele der Techniken in diesem Kapitel behandeln, was zu tun, wenn Sie
haben nicht genug von einer Art von Speicher. Programmspeicher (auch als Flash bekannt) ist in dem die ausführbare Skizze Code gespeichert ist.
Der Inhalt des Programmspeichers kann nur durch den Bootloader im Upload geändert werden
Prozess von der Arduino-Software auf Ihrem Computer ausgeführt eingeleitet. Nach dem Upload Prozess abgeschlossen ist, kann der Speicher nicht bis zur nächsten Upload geändert werden.
Es gibt
weit mehr Programmspeicher auf einem Arduino-Board als RAM, so dass es von Vorteil sein können Speichern von Werten, die sich nicht ändern, während der Code ausgeführt wird (zB Konstanten) im Programmspeicher.
Der Bootloader nimmt etwas Platz im Programmspeicher.
Wenn alle anderen Versuche zur Minimierung
der Code, um im Programmspeicher passen gescheitert sind, der Bootloader kann entfernt werden um Platz zu schaffen, sondern eine zusätzliche Hardware-Programmierer wird dann benötigt, um Code zu bekommen auf die Platine.
Seite 583

Wenn Ihr Code ist größer als der Programmspeicher auf dem Chip, die Upload- wird nicht funktionieren und die IDE wird Sie warnen, dass die Skizze ist zu groß, wenn Sie kompilieren.
RAM wird durch den Code verwendet, wie es läuft, um die Werte für die Variablen durch verwendet speichern Sie Ihre skizzieren (einschließlich Variablen in den durch die Skizze verwendet Bibliotheken). RAM ist flüchtig, die bedeutet, dass es durch den Code in Ihre Skizze geändert werden.
Es bedeutet auch, nichts in dieser gespeicherte
Speicher verloren geht, wenn der Strom abgeschaltet wird.
Arduino hat viel weniger RAM als Programm
Speicher.
Wenn Sie aus dem RAM ausgeführt werden, während die Skizze läuft auf dem Board (wie Variablen
erstellt und zerstört, während der Code ausgeführt wird) das Board schlecht benehmen (Absturz). EEPROM (elektrisch löschbarer programmierbarer Nur-Lese-Speicher) ist ein Speicher, Code auf Arduino laufen kann lesen und schreiben, aber es ist nicht-flüchtigen Speicher, die Werte bewahrt auch wenn das Gerät ausgeschaltet ist. EEPROM-Zugriff ist deutlich langsamer als für RAM, so EEPROM ist in der Regel zum Speichern von Konfigurations oder andere Daten, die beim Start gelesen wird verwendet, Informationen aus der vorherigen Sitzung wiederherzustellen.
Um diese Probleme zu verstehen, ist es hilfreich zu verstehen, wie die Arduino IDE bereitet Ihr Code auf den Chip zu gehen und wie Sie die Ergebnisse es produziert zu inspizieren.
Preprocessor
Einige der Rezepte verwenden hier den Präprozessor, um das gewünschte Ergebnis zu erzielen. Vorverarbeitung ist ein Schritt in der ersten Stufe des Build-Prozesses, in dem der Quellcode (Skizze) ist für die Zusammenstellung vorbereitet.
Verschiedene Suchen und Ersetzen-Funktionen durchgeführt werden.
Preprocessor Befehle werden von Zeilen, die mit # beginnen identifiziert.
Sie haben bereits gesehen
in Skizzen, die eine Bibliotheks- # verwenden gehören teilt dem Präprozessor, um den Code von einfügen die Namen Bibliotheksdatei.
Manchmal ist der Präprozessor ist der einzige Weg, um zu erreichen, was ist
benötigt, aber die Syntax ist anders als C und C ++ Code, und es können Fehler einführen, dass
sind subtil und schwer aufzuspüren, so verwenden Sie es mit Sorgfalt.
Siehe auch
Avrfreaks ist eine Website für Software-Ingenieure, die eine gute Quelle für technische Detail ist auf den Controller-Chips von Arduino verwendet:
http://www.avrfreaks.net
Technische Details auf der C-Präprozessor finden Sie unter
http://gcc.gnu.org/onlinedocs/
gcc-2.95.3/cpp_1.html
Die Speicherspezifikationen für alle offiziellen Karten können auf der Arduino
-Website gefunden werden.
http://www.arduino.cc/en/Main/Products?from=Main.Hardware
.
17.1 Verständnis der Arduino Build-Prozess
Problem
Sie wollen sehen, was sich unter der Decke passiert, wenn Sie kompilieren und laden ein Skizze.
Seite 584 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung

Lösung
Sie können wählen, um alle Befehlszeilen Aktivität, die bei der Zusammenstellung stattfindet anzuzeigen oder Hochladen einer Skizze über den Dialog Einstellungen im Arduino 1.0 aufgenommen.
Wählen
Datei → Einstellungen, um das Dialogfeld anzuzeigen, um aktivieren oder deaktivieren Sie die Kontrollkästchen aktivieren ausführliche Ausgabe zu kompilieren oder Upload-Nachrichten.
In Versionen vor 1.0 können Sie bei gedrückter Shift-Taste gedrückt, wenn Sie auf Kompilieren klicken oder Laden.
Die Konsolenbereich im unteren Teil des IDE wird Details der Kompilierung angezeigt
Prozess.
In Versionen vor 1.0, um einen Wert in der Arduino Preferences.txt ändern müssen Sie Datei dieses Detail immer sichtbar zu machen.
Diese Datei sollte in den folgenden Standorten:

Windows XP
C:\Documents and Settings\<USERNAME>\Application Data\Arduino\preferences.txt

Sicherstellen, dass der Arduino IDE nicht läuft (Änderungen vorgenommen, um Preferences.txt somit nicht gespeichert, wenn die IDE läuft).
Öffnen Sie die Datei, und suchen Sie die Zeile build.verbose = false (es ist
nahe dem Ende der Datei).
Ändern Sie false auf true und die Datei speichern.
Diskussion
Wenn Sie auf Kompilieren und Hochladen klicken, eine Menge von Aktivitäten vor, dass in der Regel nicht auf dem Bildschirm angezeigt.
Die Kommandozeilen-Tools, die die Arduino IDE wurde gebaut, um zu verbergen
werden dazu verwendet, kompilieren, linken und laden Sie Ihren Code auf dem Brett.
Erste Skizze Datei (en) in eine geeignete für den Compiler-Datei umgewandelt (avrgcc) herstellen.
Alle Quelldateien in der Skizze Ordner, die keine Dateierweiterung sind
zusammen, um eine Datei zu machen.
Alle Dateien, die in .c oder .cpp enden werden separat erstellt.
Header-Dateien (mit der Erweiterung von H) werden ignoriert, sofern sie nicht ausdrücklich in die mitgelieferte Dateien, die miteinander verbunden sind.
#include <Arduino.h> (WProgram.h in früheren Versionen) am Anfang der Datei hinzu die Header-Datei mit allen Arduino spezifische Codedefinitionen wie gehören
digitalWrite () und analogRead (). Wenn Sie, um den Inhalt zu untersuchen möchten, können Sie die Datei finden kann Windows unter dem Verzeichnis, in dem Arduino installiert wurde; von dort aus können Sie
Navigieren Sie Hardware → Arduino → Kerne → Arduino.
17.1 Das Verständnis der Arduino Build-Prozess | Seite 585



Das Arduino-Verzeichnis-Struktur kann in neue Versionen geändert, so überprüfen
die Dokumentation der von Ihnen verwendeten Version.

Um den Code gültig C ++ zu machen, die Prototypen von Aufgaben in Ihrem Code, angegeben werden, erzeugt nächsten und eingefügt.
Schließlich ist die Einstellung der Pensionsmenü wird verwendet, um Werte einfügen
(aus der erhaltene
boards.txt Datei),
die verschiedenen Konstanten für die Controller-Chips auf dem ausgewählten verwendet definieren
Bord.
Diese Datei wird dann von AVR-GCC, die innerhalb des Arduino Haupt enthalten kompiliert
Download (im Ordner Tools ist).
Der Compiler produziert eine Reihe von Objektdateien (Dateien mit der Erweiterung .o das wird durch den Link-Tool kombiniert werden).
Diese Dateien befinden sich im Verzeichnis / tmp auf Mac und Linux gespeichert.

Auf
Fenster, sie sind in der Applet-Verzeichnis (ein Ordner unter dem Arduino-Installationsverzeichnis).
Die Objektdateien werden dann zusammen, um einen Hex-Datei zu machen, um auch direkt hochladen verbunden.
Avrdude, ein Dienstprogramm für die Übertragung von Dateien auf das Arduino-Controller, wird verwendet, um den Upload die tafel.
Die zur Herstellung des Build-Prozess zu implementieren Werkzeuge können in der Hardware \ Tools gefunden werden
Verzeichnis.
Ein weiteres nützliches Tool für erfahrene Programmierer ist avr-objdump, auch im Ordner Tools.
Damit können Sie sehen, wie der Compiler macht die Skizze in Code, den der Controller-Chip läuft.
Dieses Tool erzeugt eine Demontage Auflistung Ihrer Skizze, die den Objekt-Code zeigt, mit dem Quellcode vermischt.
Es kann auch ein Speicherabbild aller Variablen angezeigt werden
in Ihrer Skizze verwendet.
Um das Tool zu verwenden, kompilieren Sie die Skizze, und navigieren Sie zu dem Ordner,
mit dem Arduino Verteilung.
Dann navigieren Sie zum Ordner mit allen Zwischen
Dateien in den Build-Prozess verwendet werden (wie bereits erläutert).
Die von verwendeten Datei
avr-objdump ist der mit der Verlängerung .elf.
Zum Beispiel, wenn Sie die Blink kompilieren
skizzieren Sie könnten die kompilierte Ausgabe (der Maschinencode) angezeigt werden durch Ausführen der folgenden
in der Befehlszeile:
..\hardware\tools\avr\bin\avr-objdump.exe -S blink.cpp.elf
Es ist bequem, die Ausgabe in eine Datei, die in einem Texteditor gelesen werden kann lenken.
Sie können
tun dies wie folgt:
..\hardware\tools\avr\bin\avr-objdump.exe -S blink.cpp.elf > blink.txt

Seite 586 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung

Diese Version bringt eine Liste der Abschnittsüberschriften (hilfreich für die Bestimmung der Speichernutzung):
..\hardware\tools\avr\bin\avr-objdump.exe -S -h blink.cpp.elf > blink.txt
Sie können eine Batch-Datei, um die Liste in eine Datei auszug erstellen.
Fügen Sie den Pfad
Ihrer Arduino-Installation auf die folgende Zeile und speichern Sie sie auf einem Stapel
Datei:
hardware\tools\avr\bin\avr-objdump.exe -S -h -Tdata %1 > %1%.txt
Siehe Auch
Für Informationen über die Arduino Build-Prozess finden
http://code.google.com/p/arduino/wiki/BuildProcess

http://www.avrfreaks.net/wiki/index.php/Documentation:AVR_GCC

17.2 Bestimmung der Höhe der freien und belegten RAM
Problem
Sie wollen sicher sein, dass Sie nicht von RAM. Eine Skizze wird nicht korrekt ausgeführt werden, wenn nicht genügend Speicherplatz, und das kann schwer zu erkennen sein.
Lösung
Dieses Rezept zeigt Ihnen, wie Sie die Menge des freien Speichers zur Verfügung, um zu bestimmen Ihre Skizze.
Diese Skizze enthält eine Funktion namens memoryFree, die die Menge Berichte
verfügbarer RAM:
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree()); // print the free memory
Serial.print(' '); // print a space
delay(1000);
}
// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;
// function to return the amount of free RAM
int memoryFree()

{
int freeValue;
if((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
return freeValue;
}


17.2 Bestimmung der Höhe der freien und belegten RAM | Seite 587

Diskussion
Die memoryFree Funktion verwendet die Systemvariablen, die Menge an RAM berechnen.
System
Variablen sind normalerweise nicht sichtbar (sie vom Compiler erstellt werden, um zu verwalten interne Ressourcen).
Es ist nicht notwendig, zu verstehen, wie die Funktion arbeitet, um seine Ausgabe zu verwenden.
Die Funktion gibt die Anzahl der Bytes des freien Speichers.
Die Anzahl der Bytes Ihr Code ändert sich der Code ausgeführt wird. Das Wichtigste ist, um sicherzustellen, dass Sie mehr Speicher, als Sie nicht verbrauchen.
Hier sind die wichtigsten Möglichkeiten, RAM-Speicher verbraucht wird:
• Wenn Sie Konstanten initialisieren:
#define ERROR_MESSAGE "an error has occurred"
• Wenn Sie erklären, globale Variablen:
char myMessage[] = "Hello World";
• Wenn Sie einen Funktionsaufruf:

void myFunction(int value)
{
int result;
result = value * 2;
return result;
}


• Wenn Sie dynamisch Speicher zuweisen:
String stringOne = "Arduino String";
Das Arduino String-Klasse verwendet dynamische Speicher, um Platz für Zeichenfolgen zuweisen.
Sie können
finden Sie dies, indem Sie die folgende Zeile an die Spitze des Codes in der Lösung:
String s = "\n";
und die folgenden Zeilen direkt vor der Verzögerung in der Schleife Code:
s = s + "Hello I am Arduino \n";
Serial.println(s); // print the string value


Sie werden sehen, der Speicherwert als die Größe des Strings zu reduzieren wird jedes Mal erhöht durch die Schleife.
Wenn Sie die Skizze lange genug ausführen, wird der Speicher aus-nicht laufen
endlos versuchen, die Größe einer Zeichenkette in einer anderen als einer Testanwendung zu erhöhen.
Seite 588 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung

Schreiben von Code, wie diese, die ein ständig wachsWert schafft, ist ein sicherer Weg zu laufen aus dem Speicher. Sie sollten auch darauf achten, nicht-Code, der dynamisch erzeugt erstellen
eine unterschiedliche Anzahl von Variablen basierend auf einige Parameter, während der Code ausgeführt wird, da es sehr schwierig sein, sicher sein, Sie werden die Speichermöglichkeiten des Boards nicht überschreiten
wenn der Code ausgeführt wird.
Konstanten und globale Variablen werden oft in Bibliotheken erklärt als gut, so können Sie nicht sich bewusst sein, aber sie benutzen immer noch RAM.
Der serielle Bibliothek hat zum Beispiel einen 128
Byte-Array, das globale es für eingehende serielle Daten verwendet.
Dies allein verbraucht ein Achtel
des Gesamtspeichers eines alten Arduino 168 Chip.
Siehe auch
Eine technische Übersicht über die Speichernutzung ist auf
verfügbar
http://www.gnu.org/savannah-checkouts/non-gnu/avr-libc/user-manual/malloc.html


17.3 Speichern und Abrufen von numerischen Werten in Programmspeicher
Problem
Sie haben eine Menge von konstanten numerischen Daten und wollen nicht, dies zu RAM zuweisen.
Lösung
Lagern Sie numerische Variablen im Programmspeicher (Flash-Speicher verwendet werden, um Arduino speichern Programme).
Diese Skizze stellt einen Fading-LED für die nichtlineare Empfindlichkeit des menschlichen Sehens.
Es speichert
die Werte, die in einer Tabelle von 256 Werten in dem Programmspeicher nicht im Arbeitsspeicher zu verwenden.
Die Skizze ist auf Rezept 7.2 Auf der Grundlage; siehe Kapitel 7 für einen Schaltplan und Diskussion auf der Fahrt LEDs.
Ausführen dieser Skizze zu einer glatten Änderung der Helligkeit mit der
LED an Pin 5 im Vergleich zur LED an Pin 3:

/*
* ProgmemCurve sketch
* uses table in program memory to convert linear to exponential output
* See Recipe 7.2 and Figure 7-2
*/

#include <avr/pgmspace.h> // needed for PROGMEM
// table of exponential values
// generated for values of i from 0 to 255 -> x=round( pow( 2.0, i/32.0) - 1);
const byte table[]PROGMEM = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7,
7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10,
10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15,
15, 15, 16, 16, 16, 17, 17, 18, 18, 18, 19, 19, 20, 20, 21, 21,
22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 30, 30,
31, 32, 32, 33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55, 56, 58, 59, 60, 62,
63, 64, 66, 67, 69, 70, 72, 73, 75, 77, 78, 80, 82, 84, 86, 88,
90, 91, 94, 96, 98, 100, 102, 104, 107, 109, 111, 114, 116, 119, 122, 124,
127, 130, 133, 136, 139, 142, 145, 148, 151, 155, 158, 161, 165, 169, 172, 176,
180, 184, 188, 192, 196, 201, 205, 210, 214, 219, 224, 229, 234, 239, 244, 250
};
const int rawLedPin = 3; // this LED is fed with raw values
const int adjustedLedPin = 5; // this LED is driven from table
int brightness = 0;
int increment = 1;
void setup()
{
// pins driven by analogWrite do not need to be declared as outputs
}
void loop()
{
if (brightness > 254)
{
increment = -1; // count down after reaching 255
}
else if (brightness < 1)
{
increment = 1; // count up after dropping back down to 0
}
brightness = brightness + increment; // increment (or decrement sign is minus)
// write the brightness value to the LEDs
analogWrite(rawLedPin, brightness); // this is the raw value
int adjustedBrightness = pgm_read_byte(&table[brightness]); // adjusted value
analogWrite(adjustedLedPin, adjustedBrightness);
delay(10); // 10ms for each step change means 2.55 secs to fade up or down
}




Diskussion
Wenn Sie brauchen, um einen komplexen Ausdruck zu verwenden, um eine Reihe von Werten, die regelmäßig berechnen zu wiederholen, ist es oft besser, die Werte vorzuberechnen und sie in einer Tabelle von Werten,
(Üblicherweise als ein Array) im Code. Dies spart Zeit für die Berechnung der Werte wiederholt, wenn der Code ausgeführt wird.
Der Nachteil betrifft den Speicherbedarf zu Ort
diese Werte im RAM. RAM auf Arduino und der viel größeren Programmspeicher begrenzt
Seite 590 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung

Raum kann verwendet werden, um konstante Werte zu speichern. Dies ist besonders hilfreich für Skizzen, haben große Anordnungen von Zahlen.
An der Spitze der Skizze ist die Tabelle mit den folgenden Ausdruck definiert:

const byte table[]PROGMEM = {
0, . . .


PROGMEM teilt dem Compiler mit, dass die Werte, die im Programmspeicher nicht gespeichert werden als RAM.
Der Rest der Expression ist ähnlich zu der Definition eines herkömmlichen Array
(Siehe Kapitel 2).
Die Low-Level-Definitionen erforderlich, um PROGMEM verwenden werden in einer Datei mit dem Namen enthalten pgmspace.h und die Skizze enthält diese wie folgt:
#include <avr/pgmspace.h>
Um die Helligkeit um die Fade-Look zu vereinheitlichen, fügt dieses Rezept die folgende Zeilen in die LED-Ausgangscode in Rezept 7.2 verwendet:
int adjustedBrightness = pgm_read_byte(&table[brightness]);
analogWrite(adjustedLedPin, adjustedBrightness);

Die Variable adjustedBrightness von einem Wert aus dem Programmspeicher gelesen gesetzt.
Die
Ausdruck pgm_read_byte(&table[brightness]); Mittel, um die Adresse der Rückkehr
Eintrag in der Tabelle Anordnung an der Indexposition von brightness angegeben. Jeder Eintrag in der Tabelle ist ein Byte, also eine weitere Möglichkeit, diesen Ausdruck zu schreiben ist:
pgm_read_byte(table + brightness);
Ist es nicht klar, warum und Tabelle [Helligkeit] entspricht Tisch + Helligkeit, nicht Sorgen; Verwendung je nachdem, was Ausdruck macht mehr Sinn für Sie.
Ein weiteres Beispiel ist von Rezept 6.5, die eine Tabelle zum Konvertieren eines Infrarot verwendet Sensors, der in Abstand. Hier ist die Skizze von diesem Rezept umgewandelt, um eine Tabelle zu verwenden
im Programmspeicher anstatt RAM:

/* ir-distance_Progmem sketch
* prints distance & changes LED flash rate depending on distance from IR sensor
* uses progmem for table
*/
#include <avr/pgmspace.h> // needed when using Progmem
// table entries are distances in steps of 250 millivolts
const int TABLE_ENTRIES = 12;
const int firstElement = 250; // first entry is 250 mV
const int interval = 250; // millivolts between each element
// the following is the definition of the table in Program Memory
const int distanceP[TABLE_ENTRIES] PROGMEM = { 150,140,130,100,60,50,
40,35,30,25,20,15 };
// This function reads from Program Memory at the given index
int getTableEntry(int index)
{

int value = pgm_read_word(&distanceP[index]);
return value;
}



17,3 speichern und abrufen Numerische Werte im Programmspeicher | Seite 591


Der verbleibende Code ähnelt Rezept 6.5, mit der Ausnahme, dass die getTableEntry Funktion verwendet, um den Wert aus dem Programmspeicher, anstatt Zugriff auf eine Tabelle in dem RAM zu erhalten.
Hier
ist die überarbeitete getDistance Funktion von diesem Rezept:

int getDistance(int mV)
{
if( mV > interval * TABLE_ENTRIES )
  return getTableEntry(TABLE_ENTRIES-1); // the minimum distance
  else
  {
  int index = mV / interval;
  float frac = (mV % 250) / (float)interval;
  return getTableEntry(index) - ((getTableEntry(index) -
getTableEntry(index+1)) * frac);
  }
}


Siehe auch
In Rezept 17.4 für die Technik in Arduino 1.0 eingeführt, um Strings in Flash speichern Speicher.

17.4 Speichern und Abrufen von Strings im Programmspeicher
Problem
Sie haben viele Strings und sie verbrauchen zu viel RAM. Sie wollen sich zu bewegen String-Konstanten, wie zum Beispiel Menüführung oder Debugging-Anweisungen, aus dem RAM und in Programmspeicher.
Lösung
Diese Skizze erzeugt einen String im Programmspeicher an und gibt deren Wert an den Serial Monitor mit dem F ("text") in Arduino 1.0 eingeführt Ausdruck.
Die Technik für das Drucken
die Menge des freien RAM wird in Rezept 17.2 beschrieben:

/*
* Write strings using Program memory (Flash)
*/
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree()); // print the free memory
Serial.print(' '); // print a space
Serial.print(F("arduino duemilanove ")); // print the string
delay(1000);
}
// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;
// function to return the amount of free RAM
int memoryFree()
{
int freeValue;
if ((int)__brkval == 0)
freeValue = ((int)&freeValue) - ((int)&__bss_end);
else
freeValue = ((int)&freeValue) - ((int)__brkval);
return freeValue;
}



Seite 592 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung


Diskussion
Strings sind besonders hungrig, wenn sie in den Arbeitsspeicher kommt. Jedes Zeichen wird ein Byte, so es ist leicht, große Teile der RAM verbrauchen, wenn Sie viele Wörter in Zeichenfolgen in Ihrem
Skizze. Einfügen von Text in das F ("text") Ausdruck speichert den Text in der viel größeren
Flash-Speicher anstelle von RAM.
Wenn Sie eine frühere Arduino Mitteilung sind können Sie Text im Programmspeicher noch zu speichern, aber Sie brauchen, um ein wenig mehr Code in Ihre Skizze hinzuzufügen.
Hier ist die gleiche Funktionalität
für Versionen vor 1.0 implementiert:

#include <avr/pgmspace.h> // for progmem
//create a string of 20 characters in progmem
const prog_uchar myText[] PROGMEM = "arduino duemilanove ";
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.print(memoryFree()); // print the free memory
Serial.print(' '); // print a space
printP(myText); // print the string
delay(1000);
}
// function to print a PROGMEM string
void printP(const prog_uchar *str)
{
char c;
while((c = pgm_read_byte(str++)))
Serial.write(c);
}
// variables created by the build process when compiling the sketch
extern int __bss_end;
extern void *__brkval;
// function to return the amount of free RAM
int memoryFree(){
int freeValue;
if((int)__brkval == 0) freeValue = ((int)&freeValue) - ((int)&__bss_end);
else freeValue = ((int)&freeValue) - ((int)__brkval);
return freeValue;
}



17.4 Speichern und Abrufen von Strings im Programm-Speicher | Seite 593

Siehe auch
In Rezept 15.11 ein Beispiel für Flash-Speicher zum Speichern von Web-Seite Strings verwendet.

17.5 Using #define and const Instead of Integers
Problem
Sie wollen RAM-Auslastung, indem Sie dem Compiler mit, dass der Wert konstant ist zu minimieren und optimiert werden.
Lösung
Verwenden Sie const auf Werte, die in der gesamten Skizze konstant zu deklarieren.
Beispielsweise können anstelle von:

int ledPin=13;
use:
const int ledPin=13;


Diskussion
Wir wollen oft einen konstanten Wert in verschiedenen Bereichen der Code zu verwenden. Nur das Schreiben der Anzahl ist eine sehr schlechte Idee.
Wenn Sie später die verwendete Wert ändern möchten, ist es schwierig, herauszufinden,
welche Zahlen in der ganzen Code verstreut müssen auch geändert werden.
Es ist am besten zu nutzen
Nennung von Namen.
Seite 594 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung

Hier sind drei Möglichkeiten, einen Wert, der eine Konstante zu definieren:

int ledPin = 13;       // a variable, but this wastes RAM
const int ledPin = 13; // a const does not use RAM
#define ledPin 13      // using a #define
                       // the preprocessor replaces ledPin with 13
pinMode(ledPin, OUTPUT);


Obwohl die ersten zwei Ausdrücke ähnlich aussehen, erzählt der Begriff const den Compiler nicht um ledPin als gewöhnliche Variable behandeln.
Im Gegensatz zu den normalen int ist keine RAM reserviert
Halten Sie den Wert für die const, da sichergestellt ist, nicht zu ändern.
Der Compiler erzeugen
genau das gleiche Code, als hätten Sie geschrieben:
pinMode(13, OUTPUT);
Sie werden manchmal sehen # define-Konstanten verwendet werden, um bei älteren Arduino-Code definieren, aber const ist eine bessere Wahl als #define.
Dies liegt daran, eine const-Variable hat eine Art, die
ermöglicht dem Compiler zu überprüfen und zu melden, wenn die Variable, die in einer Weise nicht angemessen verwendet für diesen Typ.
Der Compiler wird auch C-Regeln zu respektieren für den Geltungsbereich eines const
variabel.
Ein #define Wert den gesamten Code in der Skizze zu beeinflussen, das ist mehr als sein kann,
Sie bestimmt.
Ein weiterer Vorteil der const ist, dass es vertraut Syntax- # definieren nicht
verwenden das Gleichheitszeichen und kein Semikolon am Ende verwendet.
Siehe auch
Siehe Einleitung Abschnitt in diesem Kapitel, um mehr über den Präprozessor.

17.6 Verwenden von Conditional Compilation
Problem
Sie möchten verschiedene Versionen des Codes, die selektiv zusammengestellt werden können.
Für
Beispiel-Code müssen Sie möglicherweise anders zu arbeiten bei der Fehlersuche oder bei der Ausführung mit verschiedensten Boards.
Lösung
Sie können die bedingte Anweisungen auf dem Präprozessor Ziel verwenden, um zu steuern, wie Ihre Skizze wird gebaut.
Dieses Beispiel von Skizzen in Kapitel 15 umfasst die SPI.h Bibliotheksdatei, die nur ist zur Verfügung und mit Arduino Versionen nach 0018 veröffentlicht benötigt:

#if ARDUINO > 18
#include <SPI.h> // needed for Arduino versions later than 0018
#endif


17.6 Verwenden von Conditional Compilation Übersicht | Seite 595

Das Beispiel mit dem Sketch von Rezept 5.6 zeigt nur einige Debug-Anweisungen wenn DEBUG definiert ist:

/*
Pot_Debug sketch
blink an LED at a rate set by the position of a potentiometer
Uses Serial port for debug if DEBUG is defined
*/
const int potPin = 0; // select the input pin for the potentiometer
const int ledPin = 13; // select the pin for the LED
int val = 0; // variable to store the value coming from the sensor
#define DEBUG
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT); // declare the ledPin as an OUTPUT
}
void loop() {
val = analogRead(potPin); // read the voltage on the pot
digitalWrite(ledPin, HIGH); // turn the ledPin on
delay(val); // blink rate set by pot value
digitalWrite(ledPin, LOW); // turn the ledPin off
delay(val); // turn LED off for same period as it was turned on
#if defined DEBUG
Serial.println(val);
#endif
}



Diskussion
Dieses Rezept benutzt den Präprozessor zu Beginn der Kompilierung verwendet werden, um zu ändern welche Code kompiliert.
Die ersten Beispiel prüft, ob der Wert des konstanten ARDUINO ist
größer als 18, und wenn ja, wird die Datei SPI.h enthalten.
Der Wert des konstanten ARDUINO
wird in den Build-Prozess festgelegt und entspricht dem Arduino-Release-Version.
Die
Syntax dieser Ausdruck nicht die gleiche wie die für das Schreiben einer Skizze verwendet.
Expressions
dass mit dem Symbol # beginnen, werden verarbeitet, bevor der Code kompiliert, sehen die in diesem Kapitel Einführungsabschnitt, um mehr über den Präprozessor.
Sie haben bereits in # include kommen:
#include <library.h>
Die <> Klammern sagen dem Compiler, um die Datei in den Speicherort für Standard suchen Bibliotheken:
#include "header.h"
Der Compiler wird auch in der Skizze Verzeichnis.
Seite 596 | Kapitel 17: Erweiterte Codierung und Speicher Handhabung

Sie können ein bedingtes Kompilieren, basierend auf dem Steuerchip in der IDE ausgewählt ist.
Beispielsweise wird der folgende Code anderen Code als für einen Mega zusammengestellt produzieren Brett, das die zusätzliche analoge Stifte, die es lautet:

/*
* ConditionalCompile sketch
* This sketch recognizes the controller chip using conditional defines
*/
int numberOfSensors;
int val = 0; // variable to store the value coming from the sensor
void setup()
{
Serial.begin(9600);
#if defined(__AVR_ATmega1280__) // defined when selecting Mega in the IDE
numberOfSensors = 16; // the number of analog inputs on the Mega
#else // if not Mega then assume a standard board
numberOfSensors = 6; // analog inputs on a standard Arduino board
#endif
Serial.print("The number of sensors is ");
Serial.println(numberOfSensors);
}
void loop() {
for(int sensor = 0; sensor < numberOfSensors; sensor++)
{
val = analogRead(sensor); // read the sensor value
Serial.println(val); // display the value
}
Serial.println();
delay(1000); // delay a second between readings
}


Siehe auch
Technische Details auf der C-Präprozessor finden Sie unter
http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html

Siehe die Diskussion Abschnitt Rezept 16.4 zum Beispiel für die bedingte Kompilierung verwendet werden, um Unterschiede zwischen Arduino 1.0 und früheren Versionen zu behandeln.

17.6 Verwenden von Conditional Compilation Übersicht | ENDE Seite 597





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

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