
Arduino on teinud pöörde elektroonikamaailmas tänu funktsionaalsete prototüüpide ja projektide loomise lihtsusele. Neile, kes soovivad programmeerimisega sammu edasi minna ja ressursse optimeerida, koodi puhtana hoida ja tõhusust suurendada, makrosid saada peamiseks tööriistaks.
Selles artiklis käsitleme üksikasjalikult selle kasutamist makrod Arduinos: mis need on, kuidas neid kasutatakse, nende eelised ja piirangud. Ja me teeme seda, kogudes parimatest veebis saadaolevatest ressurssidest kõige põhjalikuma ja kasulikuma teabe, mis on selgelt ja kaasaegselt ümber kirjutatud, et olla tõeliselt praktiline.
Mis on Arduino makrod?
Makrod on eelprotsessori direktiivid keeles C/C++, mis võimaldavad teil teksti enne koodi kompileerimist asendada. Selle asemel, et täita käske nagu traditsiooniline funktsioon, töötab makro lähteteksti osade asendamisega, millel on otsene mõju lõpliku binaarkoodi genereerimisele.
Eeltöötleja See töötab enne tegelikku koostamist ja vastutab nende asenduste rakendamise eest. Arduinos võimaldab see alates defineerida konstandid, kaasake faile tingimuslikult või looge isegi väikesed võrgufunktsioonid mis säästavad aega ja mälu.
Põhinäide: määratlus nagu #define LED_PIN 13 põhjustab kogu koodi automaatse asendamise LED_PIN poolt 13 enne koostamist.
See võib tunduda triviaalne, kuid see pakub a võimas viis paindlikuma ja hooldatavama koodi kirjutamiseks.
Makrode kasutamise eelised
Makrode rakendamine Arduino projektides võib pakkuda mitmeid konkreetseid eeliseid:
- Parandage koodi loetavust: Sümboolseid nimetusi taaskasutades on lihtsam mõista iga elemendi eesmärki.
- Toimivuse optimeerimine: Kui funktsioonikutseid ei genereerita, saavad makrod toiminguid kiiremini täita.
- Vähendage RAM-i kasutamist: eriti kasulik piiratud ressursiga tahvlitel, näiteks Arduino UNO.
- Lubab tingimuslikke kohandusi: Olenevalt kasutatava Arduino plaadi tüübist on võimalik koostada erinevaid koodifragmente.
Põhimakrod: #define kasutamine
Direktiiv #defineeri See on enim kasutatud. Seda kasutatakse mõlema jaoks defineerida konstantsed väärtused kudumata luua süstitud automaatseid funktsioone koostamise eelsel ajal.
Näide 1: määrake tihvt
#define PINLED 13
void setup() {
pinMode(PINLED, OUTPUT);
}
void loop() {
digitalWrite(PINLED, HIGH);
delay(500);
digitalWrite(PINLED, LOW);
delay(500);
}
Näide 2: makro sisemise funktsioonina
int itemCounter = 0;
#define COUNT_ITEM() do { itemCounter++; } while(0)
void setup() {
Serial.begin(9600);
COUNT_ITEM();
COUNT_ITEM();
}
void loop() {
Serial.println(itemCounter);
}
Nagu näete, mustri kasutamine tee { … } while(0) tagab, et makro käitub ohutult, isegi kui seda kasutatakse tingimusstruktuurides.
## operaator ja makro konkatenatsioon
Operaator ## on võimas eeltöötlustööriist. mis võimaldab identifikaatorite liitmist. See on väga kasulik, kui soovite muutujate nimesid dünaamiliselt genereerida.
Praktiline näide:
#define GENERAR_VARIABLE(no) \
int var##no = no;
void setup() {
GENERAR_VARIABLE(3); // crea int var3 = 3
}
Oluline hoiatus: See operaator ei ühildu kõigi Arduino plaadimudelitega võrdselt. Näiteks võib see Uno või Esplora puhul hästi töötada, kuid Mega puhul ebaõnnestuda. Samuti ei saa makrode loomist teiste makrode sisse pesastada, kasutades otse ##.
Makrod ja mälu säästmine
Arduino makrode kasutamise üks peamisi eeliseid on RAM-mälu säästmine. Arduino mahutavus on piiratud, seega võib tekstistringide otse RAM-i laadimine muutuda oluliseks probleemiks.
Täiustatud tehnika selle vältimiseks hõlmab kasutamist FORCE_INLINE ja laadige stringid programmimälust (PROGMEM):
#include <HardwareSerial.h>
#define MYSERIAL Serial
#define FORCE_INLINE __attribute__((always_inline)) inline
FORCE_INLINE void printFromFlash(const char *str) {
char ch = pgm_read_byte(str);
while (ch) {
MYSERIAL.write(ch);
ch = pgm_read_byte(++str);
}
}
#define SERIAL_LOG(x) (MYSERIAL.print(x))
#define SERIAL_LOGLN(x) (MYSERIAL.println(x))
Nende makrode kasutamine võib eristada, kas projekt töötab või mitte, eriti ekraanide või mitme anduriga rakendustes.
Funktsioonidega kombineeritud makrod
Makrod võivad hõlbustada ka funktsioonide dünaamilist kutsumist parameetrina edastatud tüübi alusel. Selge ja üsna graafiline näide on:
#define FUNC_LENTA(tipo) \
{ funcion_##tipo##_lenta(); }
#define FUNC_RAPIDA(tipo) \
{ funcion_##tipo##_rapida(); }
void funcion_caminar_lenta() {
Serial.println("Andando despacio");
}
void funcion_caminar_rapida() {
Serial.println("Andando rápido");
}
void setup() {
Serial.begin(9600);
FUNC_LENTA(caminar);
}
void loop() {
FUNC_RAPIDA(caminar);
}
Tänu operaatorile ## ja makrodele saame vältida struktuuride kordamist ja tsentraliseerida dünaamilist loogikat..
Väljundparameetritega makrod
Väikeste objektide või konversioonide kapseldamiseks on võimalik kasutada ka makrosid:
#define BOOL_OUT() (bool){false}
#define NUM_OUT(a,b) (float){a+b}
#define STR_OUT(msg) (String){msg}
void loop() {
Serial.println(BOOL_OUT());
Serial.println(NUM_OUT(1.2, 3.4));
Serial.println(STR_OUT("Mensaje"));
}
Head tavad ja ettevaatusabinõud makrode kasutamisel
Makrode liigne või hooletu kasutamine võib põhjustada raskesti siluvad vead. Näiteks tehes valesid asendusi või määratledes nimesid, mis põrkavad kokku väliste teekide nimedega.
Mõned põhireeglid probleemide vältimiseks:
- Vältige tarbetuid tühikuid või reavahesid makro sees.
- Ärge lisage kommentaare keerulistes makrodes, mis kasutavad mitut rida.
- Kasutage ainulaadseid nimesid või eesliidetega (nt projekti nimi), et vältida konflikte.
- Asenda makrod reaalsete konstantide või funktsioonidega igal võimalusel. Kaasaegne C++ võimaldab puhtamaid ja ohutumaid alternatiive.
Teisest küljest võib makrode liigne kasutamine vähendada koodi selgust. Eesmärk peaks olema tõhususe ja modulaarsuse parandamine, ilma et see kahjustaks hooldatavust.
Tingimuslikud direktiivid ja adaptiivne koostamine
Üks kõige praktilisemaid funktsioone skaleeritavates projektides on makrode kasutamine to tinglikult genereerida kood, midagi väga kasulikku, kui soovite, et sama sketš töötaks erinevatel tahvlitel.
Tüüpiline näide:
#ifdef ARDUINO_MEGA
#define LEDPIN 53
#else
#define LEDPIN 13
#endif
See on kasulik ka silumise juhtimiseks või kompilaatoriteadete kuvamiseks #pragma sõnum või isegi tekitada teatud tingimustel vigu #viga.
Sisemised kompilaatori makrod
AVR-i GCC eelprotsessor (kasutatakse Arduinos) sisaldab mitmeid spetsiaalsed makrod, mis pakuvad süsteemiteavet, väga kasulik arenduse ajal:
- __LINE__: praeguse rea number.
- __FILE__: praeguse faili nimi.
- __TIME__ ja __DATE__: koostamise aeg ja kuupäev.
- __func__: praeguse funktsiooni nimi.
Need võimaldavad versioonikontrolli, logistruktuure ning hõlbustavad hooldust ja vigade jälgimist ilma põhikoodi tungimata.
Makrod pakuvad võimsat ja paindlikku viisi Arduino projektide struktureerimiseks. Need võimaldavad teil määratleda konstante, säästa mälu, kohandada koodi olenevalt täitmiskeskkonnast ja luua korduvkasutatavaid plokke ilma ridu dubleerimata. Muidugi nõuavad need distsipliini, selgust ja teadmisi, et vältida peeneid vigu või loetavuse kaotust. Õige kasutamise korral on need keskmise taseme ja edasijõudnutele arendajatele hindamatuks väärtuseks.