I foråret 2011 arbejdede jeg på et projekt med kunstnere Steve Hanson og Elliot Clapp, der var en del af Apexarts "Lad det ende som denne" gruppeshow, kurateret af Todd Zuniga. Steve lavede et generativt spørgeskema, der spurgte gallerihandlere og præsenterede dem med deres sidste ord. En interaktiv push-button-konsol og LCD blev bygget af Elliot (billedet ovenfor) og vi byggede sagen ved at bruge en billig Arduino-variant fra Modern Device. Det komplette projekt er dokumenteret i Make: Projects wiki.
Steve's poetiske sidste ord tog næsten 16K hukommelse op, som blev opbevaret i Arduino's programmagasin. Nedenfor er et uddrag fra Arduino Cookbook af Michael Margolis, der forklarer, hvordan man gemmer og får adgang til et stort databord i programhukommelsen.
Du har mange konstante numeriske data og vil ikke allokere dette til RAM.
Gem numeriske variabler i programhukommelsen (flashhukommelsen, der bruges til at gemme Arduino-programmer).
Denne skitse justerer en fading LED for den ikke-lineære følsomhed af menneskesyn. Den lagrer værdierne, der skal bruges i en tabel med 256 værdier i programhukommelsen i stedet for RAM.
Skissen er baseret på Opskrift 7.2; se kapitel 7 for et ledningsdiagram og diskussion om kørelys. At køre denne skitse resulterer i en jævn ændring i lysstyrken med LED på pin 5 i forhold til LED på pin 3:
/ * ProgmemCurve sketch * bruger tabel i Progmem til at konvertere lineær til eksponentiel output * Se Opskrift 7.2 og Figur 7-2 * / #include
Når du skal bruge et komplekst udtryk til at beregne en række værdier, der regelmæssigt gentages, er det ofte bedre at forudregulere værdierne og inkludere dem i en tabel af værdier (normalt som et array) i koden. Dette sparer tid for at beregne værdierne gentagne gange, når koden kører. Ulempen vedrører den hukommelse, der er nødvendig for at placere disse værdier i RAM. RAM er begrænset på Arduino, og det meget større programhukommelsesrum kan bruges til at gemme konstante værdier. Dette er især nyttigt for skitser, der har store arrayer af tal.
Øverst på skissen er tabellen defineret med følgende udtryk:
const byte bord [] PROGMEM = {0,. . .
PROGMEM fortæller kompilatoren, at værdierne skal lagres i programhukommelsen i stedet for RAM. Resten af udtrykket svarer til at definere en konventionel matrix (se kapitel 2).
De lavniveaudefinitioner, der er nødvendige for at bruge PROGMEM, er indeholdt i en fil ved navn pgmspace.h, og skissen indeholder dette som følger:
#omfatte
For at justere lysstyrken for at gøre blækket ensartet, tilføjer denne opskrift følgende linjer til LED-udgangskoden, der anvendes i opskrift 7.2:
int adjustedBrightness = pgm_read_byte (& bord [lysstyrke]); analogWrite (justeretLedPin, justeretBrightness);
Den variable justeretBrightness er indstillet fra en værdi, der læses fra programhukommelsen. Udtrykket pgm_read_byte (& table [brightness]); betyder at returnere adressen til posten i tabelmatrixen ved indekspositionen angivet ved lysstyrke. Hver indtastning i tabellen er en byte, så en anden måde at skrive dette udtryk på er:
pgm_read_byte (tabel + lysstyrke);
Hvis det ikke er klart, hvorfor & bord [lysstyrke] svarer til tabel + lysstyrke, så rolig; Brug hvilket udtryk der giver dig større mening.
Et andet eksempel er fra Opskrift 6.5, som brugte et bord til at konvertere en infrarød sensor til afstand. Her er skitsen fra denne opskrift konverteret til at bruge et bord i programhukommelsen i stedet for RAM:
/ * ir-distance_Progmem skitse * udskriver distance og ændringer LED flash hastighed * afhængig af afstand fra IR sensor * bruger progmem til tabel * / #include
Den resterende kode svarer til Opskrift 6.5, bortset fra at getTableEntry-funktionen bruges til at hente værdien fra programhukommelsen i stedet for at få adgang til en tabel i RAM. Her er den reviderede getDistance-funktion fra denne opskrift:
int getDistance (int mV) {hvis (mV> interval * TABLE_ENTRIES) returnerer getTableEntry (TABLE_ENTRIES-1); // den mindste afstand ellers {int indeks = mV / interval; float frac = (mV% 250) / (float) interval; return getTableEntry (indeks) - ((getTableEntry (indeks) - getTableEntry (indeks + 1)) * frac); }}