Spørsmål:
Bibliotek LiquidCrystal_I2C fungerer ikke i andre klasser (komposisjon)
Natalia Kelim Thiel
2016-04-16 00:56:03 UTC
view on stackexchange narkive permalink

God ettermiddag, jeg prøver å bruke en klasse for å effektivisere skriften på LCD-skjermen. I denne klassen har jeg et privat attributt (det er en peker, vet ikke hvordan jeg kaller ham) kalt LiquidCrystal_I2C * _lcd , jeg instanserer det i konstruktøren, så langt så bra, men når jeg ringer til _lcd-> begynner (20, 4) koden nedenfor blir ikke utført, men ingen feil vises.

Display.h:

  klasse Display {public: Display (); ... privat: LiquidCrystal_I2C * _lcd; ...}  

Display.cpp:

  ... Display :: Display () {_lcd = new LiquidCrystal_I2C (0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIV); _lcd->begin (20, 4);} ...  

Program.ino

  #include "Display.h" Display lcd; void setup ( ) {Serial.begin (9600);} void loop () {Serial.println ("test"); delay (3000);}  

Bare jeg la merke til feilen da jeg så at Serial.println ("test"); ikke kjørte. Hvis jeg kommenterer _lcd->begin (20, 4); alt fungerer.

Jeg testet å skrive alt i Program.ino og jobbet, har ingenting å gjøre med forbindelser eller noe, bare ikke bruk konseptet med komposisjon i denne klassen.

Kan noen hjelpe meg? Og beklager engelskmennene, jeg er fra Brasil. Takk.

Forstår du begrepet * statisk tilgang * i klasser?
Hvis det er som Java, forstår jeg det
Det er stort sett det samme, ja. Å få tilgang til medlemsvariabler med Display :: foran dem får tilgang til de statiske klassemedlemmene, ikke objektet lokale medlemmer. Jeg er ganske overrasket over at den faktisk ble samlet slik.
Jeg fjernet skjermen ::, men fungerer fortsatt ikke.
Er det nå: `_lcd = new LiquidCrystal_I2C (0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);` `_lcd-> begin (20, 4);`
@Majenko statiske variabler i C ++ må erklæres statiske. Bare å sette Display :: foran dem, ville ikke gjøre dem om fra forekomstvariabler til klassevariabler.
@JayEye Det var derfor jeg spurte om det virkelig ble samlet.
Har det. Beklager. // flere tegn så jeg kan legge ut en kommentar :)
En svar:
JayEye
2016-04-18 02:16:58 UTC
view on stackexchange narkive permalink

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

Det fungerer! Takk = D Og beklager forsinkelsen, jeg var uten internett ...
Nok en fornøyd kunde :)


Denne spørsmålet ble automatisk oversatt fra engelsk.Det opprinnelige innholdet er tilgjengelig på stackexchange, som vi takker for cc by-sa 3.0-lisensen den distribueres under.
Loading...