Jeffrey Cross
Jeffrey Cross

Arduino Cookbook-Auszug: Große Datentabellen im Programmspeicher

Wenn Sie jemals ein Arduino-basiertes Projekt mit einer großen Anzahl von Textzeichenfolgen erstellt haben, werden Sie feststellen, dass die Standardausgabe von Arduino's 2K von SRAM sehr einschränkend ist. Eine Lösung besteht darin, den Text stattdessen im Programmspeicher zu speichern, was bei 32 Kb wesentlich größer ist.

Im Frühjahr 2011 arbeitete ich mit den Künstlern Steve Hanson und Elliot Clapp an einem Projekt, das Teil der von Todd Zuniga kuratierten Gruppenausstellung von Apexart war. Steve erstellte einen generativen Fragebogen, der Galeristen befragte und ihnen ihre letzten Worte präsentierte. Eine interaktive Push-Button-Konsole und ein LCD wurden von Elliot (oben abgebildet) gebaut, und wir haben das Ding mit einer kostengünstigen Arduino-Variante von Modern Device gebaut. Das gesamte Projekt ist im Wiki "Make: Projects" dokumentiert.

Steves poetische Last Words nahmen fast 16 KB Speicherplatz in Anspruch, der im Programmspeicher des Arduino gespeichert war. Nachfolgend finden Sie einen Auszug aus dem Arduino Cookbook von Michael Margolis, in dem erklärt wird, wie Sie eine große Datentabelle im Programmspeicher speichern und darauf zugreifen.

17.3 Speichern und Abrufen numerischer Werte im Programmspeicher

Problem

Sie haben viele konstante numerische Daten und möchten diese nicht dem RAM zuordnen.

Lösung

Speichern Sie numerische Variablen im Programmspeicher (dem Flash-Speicher, in dem Arduino-Programme gespeichert werden).

Diese Skizze passt eine verblassende LED an die nichtlineare Empfindlichkeit des menschlichen Sehens an. Es speichert die zu verwendenden Werte in einer Tabelle mit 256 Werten im Programmspeicher statt im RAM.

Die Skizze basiert auf Rezept 7.2; In Kapitel 7 finden Sie einen Verdrahtungsplan und Informationen zum Ansteuern von LEDs. Wenn Sie diese Skizze ausführen, ändert sich die Helligkeit der LED an Pin 5 im Vergleich zu der LED an Pin 3:

/ * ProgmemCurve sketch * verwendet eine Tabelle in Progmem, um eine lineare in eine exponentielle Ausgabe zu konvertieren. * Siehe Rezept 7.2 und Abbildung 7-2 * / #include // für PROGMEM benötigt // Tabelle der Exponentialwerte // für Werte von i zwischen 0 und 255 generiert -> x = round (pow (2.0, i / 32.0) - 1); Konst Byte-Tabelle [] PROGMEM = {0, 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, 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, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 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; // diese LED wird mit Rohwerten gespeist const int adjustLedPin = 5; // diese LED wird vom Tisch int Helligkeit = 0 angesteuert; int Inkrement = 1; void setup () {// Pins, die von analogWrite gesteuert werden, müssen nicht als Ausgänge deklariert werden.} void loop () {if (Helligkeit> 254) {increment = -1; // Countdown nach Erreichen von 255} else if (Helligkeit <1) {increment = 1; // hochzählen, nachdem auf 0 zurückgefallen ist} Helligkeit = Helligkeit + Inkrement; // Inkrement (oder Dekrement-Vorzeichen ist Minus) // Schreibe den Helligkeitswert in die LEDs analogWrite (rawLedPin, Helligkeit); // Dies ist der Rohwert int adjustBrightness = pgm_read_byte (& table [Helligkeit]); // eingestellter Wert analogWrite (adjustedLedPin, adjustBrightness); Verzögerung (10); // 10 ms für jede Schrittänderung bedeutet 2,55 Sekunden, um nach oben oder unten zu blenden.}

Diskussion

Wenn Sie einen komplexen Ausdruck verwenden müssen, um einen Wertebereich zu berechnen, der sich regelmäßig wiederholt, ist es oft besser, die Werte vorzuberechnen und sie in eine Wertetabelle (normalerweise als Array) in den Code aufzunehmen. Dies spart die Zeit, die erforderlich ist, um die Werte wiederholt zu berechnen, wenn der Code ausgeführt wird. Der Nachteil betrifft den Speicherplatz, der erforderlich ist, um diese Werte im RAM abzulegen. RAM ist auf Arduino begrenzt und der viel größere Programmspeicherplatz kann zum Speichern konstanter Werte verwendet werden. Dies ist besonders hilfreich für Skizzen mit großen Zahlenfeldern.

Am oberen Rand der Skizze wird die Tabelle mit dem folgenden Ausdruck definiert:

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

PROGMEM teilt dem Compiler mit, dass die Werte nicht im RAM, sondern im Programmspeicher abgelegt werden sollen. Der Rest des Ausdrucks ähnelt dem Definieren eines herkömmlichen Arrays (siehe Kapitel 2).

Die für die Verwendung von PROGMEM erforderlichen Low-Level-Definitionen sind in einer Datei mit dem Namen pgmspace.h enthalten. Die Skizze enthält Folgendes:

#umfassen

Um die Helligkeit anzupassen, damit das Fade gleichförmig aussieht, fügt dieses Rezept dem LED-Ausgangscode in Rezept 7.2 die folgenden Zeilen hinzu:

int adjustBrightness = pgm_read_byte (& table [Helligkeit]); analogWrite (adjustedLedPin, adjustBrightness);

Die Variable adjustBrightness wird aus einem aus dem Programmspeicher gelesenen Wert gesetzt. Der Ausdruck pgm_read_byte (& table [Helligkeit]); bedeutet, die Adresse des Eintrags im Tabellenfeld an die durch Helligkeit angegebene Indexposition zurückzugeben. Jeder Eintrag in der Tabelle ist ein Byte, eine andere Möglichkeit, diesen Ausdruck zu schreiben, ist:

pgm_read_byte (tabelle + helligkeit);

Wenn nicht klar ist, warum & table [Helligkeit] Tabelle + Helligkeit entspricht, machen Sie sich keine Sorgen. Verwenden Sie den für Sie sinnvolleren Ausdruck.

Ein anderes Beispiel stammt aus Rezept 6.5, in dem eine Tabelle zum Umwandeln eines Infrarotsensormesswerts in eine Entfernung verwendet wurde. Hier ist die Skizze aus diesem Rezept, die für die Verwendung einer Tabelle im Programmspeicher anstelle von RAM konvertiert wurde:

/ * ir-distance_Progmem sketch * druckt die Entfernung und ändert die LED-Blitzrate * abhängig von der Entfernung zum IR-Sensor * verwendet das Programm für Tabelle * / # include // bei Verwendung von Progmem // Tabelleneinträgen sind Entfernungen in Schritten von 250 Millivolt const int TABLE_ENTRIES = 12; const int firstElement = 250; // erster Eintrag ist 250 mV const int Intervall = 250; // Millivolt zwischen jedem Element // Das Folgende ist die Definition der Tabelle im Programmspeicher const int distanceP [TABLE_ENTRIES] PROGMEM = {150,140,130,100,60,50, 40,35,30,25,20,15}; // Diese Funktion liest aus dem Programmspeicher am angegebenen Index int getTableEntry (int index) {int value = pgm_read_word (& distanceP [index]); Rückgabewert; }

Der restliche Code ist dem von Rezept 6.5 ähnlich, mit der Ausnahme, dass die getTableEntry-Funktion verwendet wird, um den Wert aus dem Programmspeicher abzurufen, anstatt auf eine Tabelle im RAM zuzugreifen. Hier ist die überarbeitete getDistance-Funktion aus diesem Rezept:

int getDistance (int mV) {if (mV> Intervall * TABLE_ENTRIES) return getTableEntry (TABLE_ENTRIES-1); // der minimale Abstand else {int index = mV / Intervall; Floatfac = (mV% 250) / (Float) Intervall; return getTableEntry (index) - ((getTableEntry (index) - getTableEntry (index + 1)) * frac); }}


In der Schuppenhalle:

Arduino-Kochbuch Erstellen Sie mit Arduino und diesem Leitfaden eigene Roboter, Spielzeug, Fernbedienungen, Alarme, Detektoren und mehr. Mit Arduino können Künstler und Designer eine Vielzahl erstaunlicher Objekte und Prototypen erstellen, die mit der physischen Welt interagieren. Mit diesem Kochbuch können Sie direkt eintauchen und experimentieren, dank mehr als hundert Tipps und Techniken, unabhängig von Ihrem Können. Hier finden Sie die Beispiele und Ratschläge, die Sie benötigen, um Ihre Projekte sofort zu beginnen, zu erweitern und zu verbessern.

Aktie

Leave A Comment