Mest sannsynlig årsak
Du treffer et lumsk problem som til og med erfarne C ++ programmerere ofte savner: rekkefølgen på initialisering av globale variabler. I ditt tilfelle initialiseres Display lcd
( ie, konstruktøren kalles) før main ()
og deretter setup ()
utføres. Imidlertid er du nesten helt sikkert #include
i det biblioteket som erklærer LiquidCrystal_I2C
-klassen, sannsynligvis Wire.h
, og så videre. I mange av disse klassene defineres også en global variabel av den typen for å gjøre det lettere å få tilgang til ting. For eksempel er Serial
(som i Serial.println ("foo")
) virkelig en global variabel av riktig type, uansett hvilken seriell implementering din spesielle kjerne bruker.
Problemet du treffer er at C ++ -standarden ikke garanterer utførelsesrekkefølgen til konstruktørene av globale variabler. Rekkefølgen er en gjenstand av kompilatoren, rekkefølgen som objektfiler ble koblet til, og sannsynligvis månens fase :)
Det som (nesten helt sikkert) skjer er at konstruktøren for klasse Display blir kalt, som initialiserer LCD og i2c-bussen, og så kaller noe annet enten LCD-konstruktøren eller i2c-konstruktøren og ødelegger ting.
OK, "hvordan fikser jeg dette?" Jeg hører deg spør. Enkelt: gjør den globale lcd-variabelen til en peker , og tildel forekomsten i start ()
, slik:
#include "Display .h "Skjerm * lcd; ugyldig oppsett () {Serial.begin (9600); lcd = ny skjerm (); // stuff} void loop () {// more stuff lcd->some_method (some_argument); // enda flere ting}
Nå er du garantert at koden din vil være den siste som berører initialiseringskoder som kan påvirke skjermen eller bussen. Bare fortsett å få tilgang til class Display
-metodene gjennom pekeren.
En mindre sannsynlig årsak
Det er fortsatt mulig at konstruktørene dine blir utført i riktig rekkefølge, men maskinvaren din liker ikke å bli initialisert to ganger (men test det uansett!), så du må kanskje finne ut hvordan du tilbakestiller maskinvaren slik at du kan initialiser den på nytt. Hvis jeg forstår innleggingen din riktig, går sløyfen aldri, noe som betyr at en ny initialisering antagelig enten forårsaker et unntak (som du ikke ville sett med mindre du hadde en slags ekstra feilsøkingskanal; i tilfelle ESP8266, for eksempel at ville være den eneste utgangen Serial1
-porten, og til og med da må du slå på feilsøking eksplisitt. Hver kjerne har sine egne feilsøkings ting, jeg glemmer hva den virkelige Arduino gjør.)
Håper dette hjelper.
/ ji