Kodėl Arduino kodas nesikompiliuoja

Kai kompiuteris nesupanta jūsų kodo

Sėdite prie kompiuterio, jau valandą rašote Arduino kodą, spaudžiate tą mėlyną rodyklės mygtuką ir… klaida. Vėl. Ir dar kartą. Kompiliavimo klaidos gali išvesti iš kantrybės net patyrusius programuotojus, o pradedantiesiems kartais atrodo, kad Arduino tiesiog nekenčia jų asmeniškai. Tačiau realybė daug paprastesnė – Arduino IDE tiesiog labai griežtai laikosi tam tikrų taisyklių, ir kai kurios iš jų nėra tokios akivaizdžios, kaip galėtų atrodo.

Kompiliavimo procesas – tai vertimas iš žmogui suprantamos programavimo kalbos į mašininį kodą, kurį mikroschema gali vykdyti. Jei šiame vertime atsiranda nesklandumų, viskas sustoja. Gera žinia ta, kad beveik visos klaidos patenka į kelias pagrindines kategorijas, ir kai suprasite, ko ieškoti, problemų sprendimas taps daug greitesnis.

Sintaksės klaidos – kai pamiršti kablelius ir kabutes

Pati dažniausia kompiliavimo nesėkmių priežastis – sintaksės klaidos. C++ kalba, kuria rašomas Arduino kodas, yra labai griežta dėl skyrybos ženklų. Kiekviena eilutė turi baigtis kabliataškiu, kiekviena atidaryta skliaustų pora turi būti uždaryta, o kabučių tipai turi atitikti.

Klasikinis pavyzdys – pamirštas kabliataškis eilutės pabaigoje:

„`cpp
int ledPin = 13
digitalWrite(ledPin, HIGH);
„`

Kompiliatorius iškart skundžiasi, nors kartais klaidos pranešimas nurodo į kitą eilutę, ne į tą, kurioje tikroji problema. Tai atsitinka todėl, kad kompiliatorius bando suprasti kodą toliau ir tik vėliau supranta, kad kažkas ne taip.

Kita dažna problema – neteisingai suporuotos figūrinės skliaustai. Funkcijos, ciklai, sąlygos – visi jie naudoja `{}` skliaustus, ir kai jų daug, lengva pasimesti. Profesionalūs programuotojai naudoja įtraukas (indentaciją), kad matytų kodo struktūrą, bet Arduino IDE ne visada automatiškai jas tvarko idealiai.

Bibliotekų ir priklausomybių galvosūkiai

Arduino ekosistema gyvuoja dėl tūkstančių bibliotekų, kurias kūrė entuziastai visame pasaulyje. Tačiau čia ir slypi problema – ne visos bibliotekos yra gerai prižiūrimos, ne visos dera tarpusavyje, ir ne visos veikia su visomis plokštėmis.

Kai matote klaidą „No such file or directory” arba panašią, dažniausiai tai reiškia, kad:

– Biblioteka neįdiegta arba įdiegta neteisingai
– Bibliotekos pavadinimas `#include` direktyvoje parašytas su klaidomis
– Biblioteka nesuderinama su pasirinkta plokšte
– Yra kelios tos pačios bibliotekos versijos, ir IDE pasirenka ne tą

Bibliotekų tvarkyklė (Library Manager) Arduino IDE padeda, bet ne visada išsprendžia visas problemas. Kartais reikia rankiniu būdu ištrinti seną bibliotekos versiją iš `libraries` aplanko jūsų dokumentuose. Kartais dvi skirtingos bibliotekos turi failus su tais pačiais pavadinimais – tada prasideda tikras chaosas.

Ypač įdomu būna su populiariomis bibliotekomis kaip „Wire.h” arba „SPI.h”, kurios jau įtrauktos į Arduino branduolį. Jei bandote įdiegti jų papildomą kopiją, gali kilti konfliktų.

Plokštės pasirinkimas ir procesorių skirtumai

Arduino pasaulyje yra dešimtys skirtingų plokščių – nuo klasikinės Uno iki galingų ESP32 ar STM32 variantų. Kiekviena turi skirtingą procesorių, skirtingą atmintį, skirtingas galimybes. Kodas, puikiai veikiantis Mega plokštėje, gali atsisakyti kompiliuotis Nano.

Viena iš subtiliausių problemų – atmintis. Arduino Uno turi vos 32KB programos atminties ir 2KB RAM. Jei jūsų kodas per didelis arba naudoja per daug kintamųjų, kompiliatorius gali išmesti klaidą „Sketch too big” arba „Not enough memory”. Tai ypač aktualu, kai naudojate daug teksto eilučių – jos ryja atmintį neįtikėtinu greičiu.

Kai kurios funkcijos ir bibliotekos veikia tik su specifiniais procesoriais. Pavyzdžiui, `analogWrite()` funkcija veikia skirtingai ESP8266 ir klasikinėse Arduino plokštėse. Jei kopijuojate kodą iš interneto, visada patikrinkite, kuriai plokštei jis buvo skirtas.

Kintamųjų tipai ir jų nesutapimai

C++ yra stipriai tipizuota kalba, o tai reiškia, kad kiekvienas kintamasis turi turėti aiškų tipą – `int`, `float`, `char`, `boolean` ir t.t. Pradedantieji dažnai susipainioja, nes Arduino IDE kartais automatiškai konvertuoja tipus, o kartais – ne.

Tipinė problema:

„`cpp
int sensorValue = analogRead(A0);
float voltage = sensorValue * (5.0 / 1023.0);
String message = „Įtampa: ” + voltage;
„`

Paskutinė eilutė sukels klaidą, nes negalite tiesiog sudėti `String` ir `float`. Reikia konvertuoti: `String(voltage)`.

Dar viena gudrybė – sveikųjų skaičių dalyba. Jei parašysite `int result = 5 / 2;`, gausite 2, ne 2.5, nes abu skaičiai yra sveikieji. Reikia bent vieno padaryti slankiuoju: `float result = 5.0 / 2;`.

Ypač klastinga situacija su `unsigned` ir `signed` tipais. Jei atimate iš `unsigned int` ir rezultatas tampa neigiamas, gausite labai didelį teigiamą skaičių dėl perpildymo. Kompiliatorius kartais įspės, kartais – ne.

Funkcijų deklaravimas ir matomumo sritys

Arduino IDE turi vieną įdomią savybę – ji automatiškai generuoja funkcijų prototipus. Tai reiškia, kad dažniausiai galite rašyti funkcijas bet kokia tvarka, ir viskas veiks. Bet ne visada.

Jei funkcija naudoja sudėtingus parametrus arba grąžina ne standartinius tipus, automatinis prototipų generavimas gali suklupti. Tada reikia pačiam parašyti funkcijos prototipą failo pradžioje:

„`cpp
void myComplexFunction(int array[], int size);

void setup() {
// kodas
}

void myComplexFunction(int array[], int size) {
// funkcijos realizacija
}
„`

Kita problema – globalūs ir lokalūs kintamieji. Jei deklaruojate kintamąjį funkcijos viduje, jis nebus matomas už jos ribų. Pradedantieji kartais bando pasiekti `setup()` funkcijoje sukurtą kintamąjį iš `loop()` – ir gauna klaidą „not declared in this scope”.

Komentarų ir specialiųjų simbolių spąstai

Komentarai turėtų būti saugūs – juk kompiliatorius jų ignoruoja, tiesa? Beveik visada taip ir yra, bet yra keletas išimčių. Jei naudojate vieneilinio komentaro ženklą `//`, o eilutė baigiasi specialiuoju simboliu kaip `\`, kompiliatorius gali pamaišyti ir „pakomentuoti” kitą eilutę.

Dar įdomiau su daugiaeiliniu komentaru `/* */`. Jei pamiršite uždaryti komentarą arba turite įdėtinį komentarą, kodas gali tapti neįskaitomas kompiliatoriui:

„`cpp
/* Tai komentaras
/* Bandau įdėti kitą komentarą */
Ši eilutė vis dar komentare! */
„`

Lietuviškos raidės ir kiti ne-ASCII simboliai taip pat gali sukelti problemų, ypač senesniuose Arduino IDE versijose. Jei jūsų komentarai ar teksto eilutės turi ąžuolėlius ir įžuolėlius, geriau naudoti naujausią IDE versiją arba išvis vengti jų kritiniuose kodo fragmentuose.

Versijų nesuderinamumas ir IDE ypatumai

Arduino IDE evoliucionuoja, ir ne visada į gerąją pusę (bent jau suderinamumo prasme). Kodas, puikiai veikęs IDE 1.8.x versijoje, gali atsisakyti kompiliuotis naujojoje 2.x versijoje. Tai dažniausiai susiję su tuo, kaip tvarkomas bibliotekų įtraukimas ir kompiliavimo proceso smulkmenos.

Viena iš didžiausių problemų – board manager’io versijos. Kai atnaujinate plokštės palaikymo paketą (pavyzdžiui, ESP32 ar STM32), gali pasikeisti kompiliatoriaus versija, ir staiga kodas, veikęs metus, nebepraslenka pro kompiliatorių. Ypač tai aktualu profesionaliems projektams – geriau užfiksuoti konkrečias versijas ir jų nelįsti be rimto reikalo.

Dar viena subtilybė – operacinė sistema. Kai kurios bibliotekos skirtingai veikia Windows, Mac ir Linux aplinkose. Kelių simbolių skirtumai, failų sistemų ypatumai – visa tai gali lemti, kad kodas veikia jūsų draugo kompiuteryje, bet ne jūsų.

Kai viskas atrodo gerai, bet vis tiek neveikia

Kartais susiduri su situacija, kai kodas atrodo tobulas, visos kablelės vietose, bibliotekos įdiegtos, plokštė pasirinkta teisingai, bet kompiliatorius vis tiek skundžiasi. Tada laikas išbandyti kelis „branduolinius” sprendimus.

Pirmas dalykas – išvalyti kompiliavimo laikinuosius failus. Arduino IDE kaupią laikinus failus aplanke, ir kartais jie sugenda. Uždarykite IDE, raskite laikinųjų failų aplanką (dažniausiai `/tmp` Linux/Mac arba `%TEMP%` Windows) ir ištrinkite viską, kas prasideda „arduino”. Po to paleiskite IDE iš naujo.

Antras triukas – pabandyti kompiliuoti paprasčiausią „Blink” pavyzdį. Jei net jis neveikia, problema tikrai ne jūsų kode, o aplinkoje. Gali reikėti iš naujo įdiegti Arduino IDE arba plokštės palaikymo paketus.

Trečias variantas – pažiūrėti į išsamią kompiliavimo išvestį. Arduino IDE pagal nutylėjimą rodo tik pagrindines klaidas, bet galite įjungti „verbose” režimą per nustatymus. Tada pamatysite visą kompiliavimo procesą – kurios bibliotekos įtraukiamos, kokie parametrai naudojami. Dažnai būtent čia slypi atsakymas.

Ir paskutinis patarimas, kuris skamba banaliai, bet veikia nuostabiai dažnai – tiesiog perkraukite kompiuterį. Kartais Arduino IDE „užstringa” keistoje būsenoje, ir tik pilnas perkrovimas viską išsprendžia.

Kompiliavimo klaidos – tai ne Arduino kerštas už kažką. Tai tiesiog griežtas, bet nuoseklus būdas pasakyti, kad kažkas neatitinka taisyklių. Kai suprasite pagrindines klaidų kategorijas ir išmoksite skaityti kompiliatoriaus pranešimus (nors jie kartais būna kriptiniai), debugging’as taps daug malonesniu procesu. O kartais net įdomiu – kaip galvosūkių sprendimas, tik su daugiau blyksinčių LED’ų pabaigoje.

Поділіться: XFacebookPinterestLinkedin