Go Down

Topic: Creare Librerie (Read 21004 times) previous topic - next topic

mastraa

Il link alla cookbook si trova in giro, io ce l'ho, ma non so se sia legale e quindi se si possa inserire qui nel forum/sito...ad ogni modo con una piccola ricerca su google lo trovi.
Si chiama Arduino Cookbook della O'reilly.

Grazie comunque!!!

lestofante

Quote
Innanzitutto ho trovato in giro delle librerie che non hanno bisogno di essere inizializzate dal costruttore, si tratta di librerie che non lavorano a classi?


dipende. A colpo d'occhio puoi distuinguere una classe (quindi C++) da una libreria (quindi C) (quindi sì, chiamare "librerie" quelle di arduino è un errore, sono quasi tutte classi) dal fatto che di solito una classe ha un file .cpp che si chiama come il file .h e ne implementa i metodi. Poi se apri il .h e vedi "class" o "interface" da qualche parte, allora sai che hai a che fare con una classe :) )

Dal punto di vista funzionale invece cambia tantissimo; avere un oggetto fa in modo tale che tu possa fare nomeOggetto.funzione(parametro); invece una vera libreria è una raccolta di funzioni che vengono appese (immagina un copia/incolla) al tuo codice, il che vuol dire che hai un sacco di problemi; niente funzioni con lo stesso nome, niente "memorizzazione di stato" per la amancanza di variabili etc..

Quindi una classe può contenere una o più altre classi, o perfino estenderle, mentre una libreria è una grezza raccolta di funzioni.

Di default tutte le classi hanno un costruttore "void", ovvero senza parametri e che non fa nulla. Se vuoi tu puoi sovrascrivere (override) questo costruttore, aggiungendo anche parametri (sovraccaricarlo).

quindi

Code: [Select]


TwoWire::TwoWire(){//override costruttore void
}

TwoWire::TwoWire(int parametro){//sovraccarico costruttore
}


In generale temo ti manchino le basi per riuscire a capire a fondo il tema. Parti dall'idea ad oggetti (C++) o lineare (C) perchè sono due cose fondamewntalmente differenti.

Consiglio di programmareil C puro su pc (copn arduino è pressochè impossibile) e vedrai che le differenze e tantecose le capirai
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

mastraa

Grazie lesto,

quindi detta in parole spicce: si può fare una classe che ti permette di avere molte 'funzionalità' in più. Cioè di chiamare più funzioni con lo stesso nome perché poi sono richiamate dal costruttore di classe ecc. ecc.

Oppure fare un semplice elenco di funzioni (C non l'ho usato molto, però con PHP e Javascript è lo stesso) dove si mettono le funzioni e poi si caricano nello sketch e via. Questa seconda opzione con Arduino non è possibile giusto? Quello che io utilizzo senza istanza (Wire, Serial, SD) è solo perché è già istanziato nella libreria?

Poi andrò chiaramente a cercare qualche guida, ma cerco di fare le cose mirate, anche perché purtroppo il tempo che ho non è molto e in quella, poca, esperienza che ho, mi sono reso conto che apprendo molto di più a pormi i problemi facendo cose anche 'ambiziose' e rispondendomi (anche non partendo dalle basi basi) che prendere una guida, leggerla senza 'giocare' e finire per dover rileggere ogni volta che mi serve una cosa

lestofante

Quote
(C non l'ho usato molto, però con PHP e Javascript è lo stesso)

attento che PHP e JS inseriscono qualche cosa di oggetti, per esempio puoi incapsulare variabilioltre che funzioni e giochetti simili..


Quote
non è possibile giusto


si che è possibile, basta aprire un secondo tab (o più) nell'edito ed inserire le propire funzioni. Non si fa così nel C vero, ma ci avvicianiamo abbastanza. ( l'ide arduino non gioca proprio pulito, per questo consigliavo di fare programmi lato pc)

Quote
Quello che io utilizzo senza istanza (Wire, Serial, SD) è solo perché è già istanziato nella libreria?

esatto, la classe crea un istanza (di solito statica) di se stessa, così tu non rischi di istanzairala due volte e creare casini. Invece la Servo, per esempio, non si auto istanzia, perchè ogni pin è comandabile a sè. Immagina di fare la stessa cosa con le funzioni e basta; non puoi,dovresti essere te a mantenere un array di strutture contenenti i dadi da passare alle funzioni in base a quale pin vuoi comandare.


Se vai nel reference, troverai come scrivere una "libreria" in aruino, che poi è una classe. Ti consiglio di seguirla,
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

mastraa

Grazie mille, ti rompo ancora per una cosa:

quando scrivo una funzione in libreria e inserisco dei parametri anticipati da *nome o &nome che significa?

Credo di aver capito che si tratta di indicare tipo l'indirizzo della variabile da modificare o qualcosa del genere, nel senso che modificando, all'interno della funzione, la variabile 'nome' vado in realtà a fare la modifica alla variabile che ho passato durante lo sketch nella posizione di nome.

E' corretto? cosa cambia per le due sintassi?

lestofante

cosa cambia? il mondo.
Non sto scherzando, la differenza è che stai usando i puntatori, concetto fondamentale non solo del C, ma di TUTTI i linguaggi di programmazione, anche se fanno di tutto per nasconderteli. Molto potenti, e per questo molto facile combinare casini :)

Segui la guida che ho in firma, ti porta ad una guida su HTML.it sul C in italiano ottima per iniziare.
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Maurotec

Il C++ ha introdotto il passaggio di parametri per rifermento o alias tramite l'operatore &.
La confusione deriva dal fatto che & ricava l'indirizzo di una variabile.
L'operatore & usato su un parametro significa passa il riferimento ed è come se passassi il puntatore, cioè non viene fatta una copia locale del parametro.

Passare un puntatore o un riferimento e più rapido, più efficiente. Alle volte non vogliamo modificare il valore, ci basta leggere il contenuto della variabile passata per riferimento o come puntatore, in tal caso si usa anteporre il qualificatore "const", es: (const type &nameVar) o (const type *nameVar).
Ci sono varianti che per essere comprese si devono sperimentare sul pc, es: (type * const nameVar) il puntatore è costante ma il contenuto di nameVar lo posso cambiare senza ricevere errore in fase di compilazione.

Con (const type *nameVar) se provi a cambiare il contenuto della variabile da dentro la funzione ricevi errore in fase di compilazione.

Sono convinto che la difficoltà di comprensione con i puntatore e gli alias deriva dal fatto che non si ha bene chiaro
come è organizzata la RAM, un buon libro C/C++ spiega i puntatori usando delle caselle numerate con indirizzi esadecimali e mostra cosa accade graficamente.

Ciao.

lestofante

Quote
Il C++ ha introdotto

??? il passaggio di puntatori come parametri c'è anche in C
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

gpb01

Solito link "legale per uso personale" da dove reperire un bel libro sull'argomento ... Understanding and Using C Pointers

@ mastraa : studiatelo bene ... ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

mastraa


cosa cambia? il mondo.
Non sto scherzando, la differenza è che stai usando i puntatori, concetto fondamentale non solo del C, ma di TUTTI i linguaggi di programmazione, anche se fanno di tutto per nasconderteli. Molto potenti, e per questo molto facile combinare casini :)

Segui la guida che ho in firma, ti porta ad una guida su HTML.it sul C in italiano ottima per iniziare.


Adesso la guardo, non mi veniva la parola così al posto di puntatori ho messo indirizzo credo  ]:D

lestofante

i puntatori puntando ad un indirizzo (o aria di memoria) quindi il termine non è errato
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

mastraa


i puntatori puntando ad un indirizzo (o aria di memoria) quindi il termine non è errato


Ho letto la guida, ma tra l'altro già ci avevo dato un'occhiata tempo fa e infatti cosa sono i puntatori ce l'ho più o meno chiaro, ora ho chiaro anche quale sia la differenza tra & e *:

* serve per memorizzare il valore della variabile puntata
& serve per memorizzare l'indirizzo della variabile puntata

quello che non riesco a immaginare è cosa succeda passando a una funzione l'uno e l'altro.

Cioè nella guida fa l'esempio di una funzione (swap) che richiede due *puntatori e vengon a passati due &parametri
quindi crea di fatto un puntatore (con *) e io passo l'indirizzo (con &). Giusto?
Su questo non mi è chiarissimo, ma diciamo che ha la sua logica e credo si tratti di fare esperienza.

Io però ho un codice dove il codice della funzione chiede direttamente dei parametri con &, in questo caso cosa fa?

Ad esempio viid funzione (chat pinco, unsigned int &palla){...};

Cosa fa? memorizza solo l'indirizzo del parametro che gli passerò?

e quando dentro alla funzione poi vedo "palla = x+y;" cosa sta facendo? nel senso che io ora in palla ho il valore dell'indirizzo a quanto ho capito dalla guida...


Cioè a me non è che non sia chiaro cos'è un puntatore, piuttosto non capisco cosa succede quando passo dei parametri in questo modo a una funzione :smiley-red:

gpb01

Hai visto il libro che ti ho indicato poco sopra ???  Perché li c'è di tutto e di più !  ]:D

Guglielmo
Search is Your friend ... or I am Your enemy !

Maurotec


Quote
Il C++ ha introdotto

??? il passaggio di puntatori come parametri c'è anche in C


Certo, ciò che non c'è in C ANSI è il passaggio di parametri per rifermento o alias, cioè la seguente riga
è un errore:
Code: [Select]

myFunc(const int &nameVar) {

}

Mentre è valida per C++.


Quote
* serve per memorizzare il valore della variabile puntata
& serve per memorizzare l'indirizzo della variabile puntata


La confusione come ho già scritto prima deriva dal fatto che * e & svolgono compiti differenti in base a come e dove vengono scritti. & Ricava l'indirizzo di una variabile, oppure se usato nella lista dei parametri specifica il passaggio per riferimento o alias, che ti permette di accedere alla variabile da dentro la funzione.

La stessa cosa si può fare con i puntatori, ma per accedere alla variabile puntata devi anteporre *, operatore di risoluzione.

La cosa è molto semplice, quasi banale, tuttavia io compreso mi confondevo.

Come faccio a ricavare l'indirizzo di una variabile?
Uso l'operatore &. es: int *intPtr = &intVar;
Da destra verso sinistra: intVar è una variabile da cui ricavo l'indirizzo che assegno a intPtr che è un puntatore a tipo intero. PS: intPtr è anche una variabile per cui posso ricavare l'indirizzo di intPtr: &intPtr

Come faccio a passare un argomento per riferimento?
Uso l'operatore &

Da dentro la funzione come uso l'argomento passato per riferimento?
Nel modo normale di usare una variabile.

Come ricavo il valore da una variabile puntatore?
Uso * prima della variabile puntatore, per ricavare (leggere) il contenuto della cella di memoria.

Una cella di memoria ha due proprietà:
1) L'indirizzo della cella
2) Il dato conservato nella cella.

Ciao.

lestofante


* serve per memorizzare il valore della variabile puntata
& serve per memorizzare l'indirizzo della variabile puntata


non si "scrivere", ma di "usare".  In oltre sfortunatamente chi ha scritto il C ha deciso di usare il * anche per la dichiarazione

Quote
Certo, ciò che non c'è in C ANSI è il passaggio di parametri per rifermento o alias, cioè la seguente riga

oddio hanno spostato la & dalla chiamata alla funzione... cosa brutta secondo me, non ti accorgi se la tua variabile potrebbe essere modificata dalla funzione.. altri vantaggi?
Guida per principianti http://playground.arduino.cc/Italiano/newbie
Unoffical Telegram group https://t.me/genuino

Go Up