E' possibile ottenere un pdf del Reference e l'elenco totale dei comandi?

In questi giorni, finito finalmente l'hw del mio progetto sono alle prese con la parte sw, mia bestiola nera (come se non lo fosse anche l'hw :D). Tempo fa, grazie al lavoro di un americano scaricai e stampai i comandi del Reference, ma era un lavoro aggiornato al 2008, e d'altra parte io non riesco a studiare a video, ho bisogno del cartaceo. Ieri cercavo un aggiornamento ed ho trovato un file di 912 pagine, ma tutte contornate dallma grafica del Forum di Arduino e di cui circa 300 sono costituite dalla sola grafica di Arduino ed altrettante dalla pagina di accesso al Forum. Pensare di stare lì ad eliminare singolarmente 5-600 pagine e poi stampare le rimanenti con tanto di quel grigio attorno da spararmi un toner mi sembra davvero uno spreco di tempo e risorse.
Domanda 1: ma esiste un modo per ottenere la stampa del Reference in formato testo, senza fronzoli né grafica? e se non esiste perché non lo si prevede? Io capisco che lo strumento sia in continua evoluzione, ma se decido di stamparlo l'onere è mio no? Cosa costerebbe implementare un tasto stampa riepilogativo?
Approfondendo un saggio consiglio di Leo ho scoperto per puro caso che i comandi presenti nel reference sono circa 1/3 di quelli in realtà riconosciuti ed applicati dall'IDE. P.es. sapevo che "C è nemico delle stringhe" eppure ho trovato un comando strlen(stringa) che restituisce la lunghezza di una stringa, in pratica l'equivalente del Lenght() del mio adorato qbasic. Ho un manuale su C++, piuttosto abbondante, m più volte ho letto che non tutti i comnadi sono supportati.
Domanda 2: esiste un elenco completo dei comandi utilizzabili con l'IDE, magari un bel pdf fatto tipo Reference?
abbiate pazienza :~

Il reference riguarda esclusivamente le funzioni/classi di wiring, che in realtà è poca roba, quello che ti serve un un buon testo sul C ANSI, p.e. strlen() è una funzione standard del C e non di Arduino.
Poi ci sono tutte le funzioni estese (sono in più rispetto a quelle standard del C) di libreria delle avrlibc, tutte disponibili e sono veramente tante, purtroppo per queste non credo esista un pdf.

Allora inizio a cercare un testo sul C ANSI. P.es. ciò che mi sta facendo perdere la testa è la scarsissima precisione del float e sulla double è scritto chiaramente che è presente per compatibilità ma è identica alla float. Alllora ho pensato che in realtà io le letture le faccio su INTERI (10 cifre espresse in Hz), volendo poter leggere le frequenze anche in k e M, invece di fare una divisione x1000.0 o per 1000000.0, mi basterebbe infilare un "." al posto giusto e manterrei la precisione all'Hz anche nelle letture di valori in GHz. Quindi trasformo l'INT in string, leggo la lunghezza, ed in base alla scala attuale e quella di destinazione aggiungo il "." dopo la 3a o 6a cifra a partire da dx, aggiungendo "0" davanti se necessario (penso alla lettura di 1Hz sulla scala kHz, p.es.). Con le funzioni del Qbasic avrei impiegato un secondo, qui non c'è soluzione :disappointed_relieved:

Per avrlibc c'è la doc in html online, html scaricabile o pdf scaricabile:
http://www.nongnu.org/avr-libc/
Ma lo sai che è in inglese, come fai a leggere un cartaceo in inglese?

Per la cosa della stringa penso che la classe String faccia al caso tuo, ci sarà sicuramente la possibilità di unire più stringhe
con l'operatore +. Eventualmente volessi fare tutto con le funzioni avr-libc la cosa è fattibile ma stabilisci prima come vuoi usare questa ipotetica funzione e cosa deve fare.

Ciao.

Ciao Mauro, tu non te ne sei accorto, ma ormai ci conosciamo da due anni, ed io in questo tempo, poiché sono uno che ama studiare, non sono stato con le mani in mano. Preso atto da quelle discussioni iniziali che non c'era niente da fare per avere materiale in Italiano, ho iniziato a studiare un bel libro di Grammatica Inglese ed oggi sono in grado di comprendere senza aiuto l'80% del testo che leggo; naturalmente un grosso passo in avanti l'ho fatto dovendo studiare i datasheet per i miei progetti e certamente non posso negare l'uso di Google Translator ma, a differenza di allora, oggi lo uso come vocabolario e non come traduttore, visto che puntualmente modifico abbondantemente la traduzione che mi fa (e ciò vale anche quando devo scrivere a qualcuno in inglese)
Quindi il cartaceo mi serve per localizzare ciò che mi può essere utile, poi tramite translator faccio la traduzione completa ed infine, con un po' di pazienza e vocabolario alla mano, se proprio mi serve, arrivo ad una traduzione più che soddisfacente, in cui spesso cambio interi periodi trasformandoli in Italiano vero, quello posso dire di conoscerlo molto bene, senza timore di smentita.
Naturalmente le mie conoscenze si fermano alla traduzione ed a qualcosa di scrittura, e d'altra parte se non vado da qualcuno che parla l'Ingese non potrò mai imparare a comprendere e parlare, ma questo per me significherebbe impiegare troppo tempo, e non ce l'ho.
Quindi grazie per il link, ora cerco di capire se con la Classe String posso risolvere. Naturalmente ben vengano suggerimenti di chi è pratico. Ciò che vorrei fare è questo:

  • Ho un numero di xx cifre (da 1 a 10).
  • Lo trasformo in una stringa di almeno 4 caratteri (se le cifre sono in meno, aggiungendo "0" davanti) se devo visualizzare kHz oppure in una stringa di almeno 7 caratteri se devo visualizzare MHz.
  • Separo la stringa in due parti: la seconda parte 3 o 6 caratteri, la prima parte ciò che resta
  • Creo una nuova stringa così: "prima parte" + "." + "seconda parte"
    In QBasic con Lenght, Left, Middle e Right avrei risolto in un secondo, temo che qui non sia così facile, per ora ho trovato solo strlen

Secondo me quello che ti serve è una piccola funzione che ti scali il valore in base alle tue esigenze.
Potresti creare una classe che ragiona in questo modo

parteintera = converti.intero(unsigned long, scala) // dove per scala metti KILO, MEGA, GIGA CHE VARREBBERO 3, 6 E 9. si possono usare dei define
partedecimale = converti.decimale(unsigned long, scala)

il metodo non dove fare altro che contare le cifre del numero originale e dividerla nei due campi.

In questo modo non modifichi il valore di partenza ma hai le due parti da mostrare su display o su seriale.
Credo non ti serva l'oggetto String.

Chiedo ovviamente l'aiuto degli utenti del forum. :blush:
Io le classi ancora non le ho bene affrontate. :sweat_smile:

per stampare ad esempio su lcd faresti

lcd.print(converti.intero(unsigned long, scala));
lcd.print(".");
lcd.print(converti.decimale(unsigned long, scala));

Manca solo tutto il resto del codice... :grin:

EDIT2: Mi correggo.... basterebbe anche una funzione con passaggio di tre parametri.

lcd.print(converti(INTERO, unsigned long, scala));
lcd.print(".");
lcd.print(converti(DECIMALE, unsigned long, scala));

Buonasera,
forse questo link, e la relativa libreria, potrebbero risolvere i tuoi problemi con numeri piuttosto "grossi" : http://arduino.cc/forum/index.php/topic,85692.0.html ... o almeno spero :wink:

Guglielmo

:sweat_smile: io parlo di stringhe perché quelle le so manipolare, se esistono altri etodi diretti sulle cifre per me è uguale; non capisco come trasformare un numero a 6 cifre in un numero a 3 cifre, moltiplicando quest'ultimo per mille mi ricaverei i decimali.
Es. lettura 123456Hz da convertire in kHz (123.456kHz)
Se riesco ad estrapolare 123 (interi) lo moltiplico x 1000 (123000) e lo sottraggo all'originale ottenendo i decimali (123456-123000=456); ma da qui in avanti sempre di stringa dovrei lavorare, la verità è che non ho capito molto della tua idea :smiley:

@ Guglielmo: grazie! mi sembra estremamente interessante, anche se forse eccessivo per ciò che devo fare io, provo a dargli un'occhiata :slight_smile:

Devo uscire... continuo dopo

#define INTERO (byte)0
#define DECIMALE (byte)1
#define KILO (byte)3
#define MEGA (byte)6
#define GIGA (byte)9

void setup() {
  delay(1000);
  Serial.begin(9600);
}

void loop() {
  Serial.print(convert(INTERO, 112347293, MEGA));
  Serial.print(".");
  Serial.print(convert(DECIMALE, 45235424, KILO));
  delay(10000);
}

unsigned long convert(byte t, unsigned long n, byte s)
{
  byte len = 0;
  unsigned long x = n;
  do {
    x /= 10;
    len++; 
  }
  while (x != 0);
  // len contiene il numero di cifre del numero
  if (len < s) .....

    if (t = INTERO)
  {

    return n;
  }
  else
    if (t = DECIMALE)
    {

      return n;
    }
    else return 0;
}

Quello che vuoi fare è molto semplice da mettere in pratica, ti sconsiglio caldamente di utilizzare la classe string perché è molto pesante da gestire ed è vorace di ram, anzi più in generale evitare sempre l'uso del C++ sulle piccole MCU.
Domani ti passo io il codice, ben spiegato, per quello che vuoi fare partendo da un valore long int, tutto realizzato con le normali funzioni per la gestione delle stringhe del C ANSI, lo posterò in questo topic così rimane disponibile per chi ha problemi simili, sono abbastanza comuni e mi capita di vedere soluzioni che fanno venire la pelle d'oca :grin:

Una cosa semplice semplice...

unsigned long frequenza;
char stringa[20];
void setup() {
    Serial.begin(19200);
    delay(2000);
    
    frequenza = 1234567890;
}


void loop() {
    byte lunghezza;
    byte scala;
    //converto in stringa un unsigned long
    ltoa(frequenza, stringa, 10);
    
    //stampo l'unsigned long
    Serial.print("Frequenza: ");
    Serial.println(frequenza, DEC);
    
    //stampo la sua conversione in stringa
    Serial.print("Convertito in: ");
    Serial.println(stringa);
    
    //stampo la lunghezza in caratteri
    lunghezza = strlen(stringa);
    Serial.print("Lunghezza stringa: ");
    Serial.println(strlen(stringa), DEC);
    
    scala = 3; //kHz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" kHz");
    
    scala = 6; //MHz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" MHz");
    
    scala = 9; //GHz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" GHz");

    for(;;);
}


void stampaFrequenza(byte _scala, byte _lunghezza) {
    byte punto;
    if (_scala <= _lunghezza) {
        punto = 255;
    } else {
        punto = _lunghezza - _scala;
    }
    for (byte i = 0; i < _lunghezza; i++) {
        if (i == punto) {
            Serial.print(".");
        }
        Serial.print(stringa[i]);
    } 
}

Come vedi, ci prendiamo la lunghezza della stringa, ottenuta dal numero convertito con ltoa ("L"toa, perché usiamo i long) e poi mettiamo il punto decimale a seconda della scala.
C'è solo da sistemare la parte che parsa la frequenza passata alla funzione che mette il punto per trattare il caso in cui la frequenza sia inferiore alla scala usata, così da mettere gli "0" prima del numero (es.: 0.001234)

Grande LEO!!!
Allora ho provato il tuo codice, ho dovuto implementare qualcosina nella void perché mi serve gestire i casi in cui ile cifre siano poche e ci sia bisogno di anteporre degli "0". Il seguente codice è il tuo modificato. funziona perfettamente da 1 a 10 cifre e tutti i miei problemi sono risolti:

unsigned long frq;
char frequenza[20];
void setup() {
    Serial.begin(9600);
    delay(2000);
    
    frq = 1234567891;
}


void loop() {
    byte lunghezza;
    byte scala;
    //converto in stringa un unsigned long
    ltoa(frq, frequenza, 10);
    
    //stampo l'unsigned long
    Serial.print("Frequenza: ");
    Serial.println(frq, DEC);
    
    //stampo la sua conversione in stringa
    Serial.print("Convertito in: ");
    Serial.println(String(frequenza));
    
    //stampo la lunghezza in caratteri
    lunghezza = strlen(frequenza);
    Serial.print("Lunghezza stringa: ");
    Serial.println(strlen(frequenza), DEC);
    
    scala = 0; //Hz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" Hz");
    
    scala = 3; //kHz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" kHz");
    
    scala = 6; //MHz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" MHz");
    
    scala = 9; //GHz
    stampaFrequenza(scala, lunghezza);
    Serial.println(" GHz");

    for(;;);
}


void stampaFrequenza(byte _scala, byte _lunghezza) {
    byte punto;
    if (_scala >= _lunghezza) {
        Serial.print("0.");
        for (byte i = 0; i < _scala - _lunghezza; i++) {
          Serial.print("0");
        } 
    } 
    else {
        punto = _lunghezza - _scala;
    }
    for (byte i = 0; i < _lunghezza; i++) {
        if (i == punto) {
            Serial.print(".");
        }
        Serial.print(frequenza[i]);
    } 
}

Ho provato ad eliminare i caratteri "_" posti davanti alle variabili nella void e funziona tutto ugualmente, poi mi spiegherai che significano, ma tieni conto che questo codice dovrà essere implementato nel più ampio firmware che ho già scritto, quindi certamente ogni variabile sarà di tipo globale, sempre che ci sia un legame con ciò.
Ti ringrazio di cuore, domani proverò l'implementazione e farò i test necessari, la soluzione è semplice ed economica, non so se Astro pensava a qualcosa del genere, vedremo poi cosa ci dirà.

Un chiarimento, sul manuale avr-libc trovo:

• char * ltoa (long int __val, char *__s, int __radix)
• char * utoa (unsigned int __val, char *__s, int __radix)
• char * ultoa (unsigned long int __val, char *__s, int __radix)

poiché hai dichiarato unsigned long frq;
è possibile che si debba usare

ultoa

invece di

ltoa

?
Considera che nel mio caso il max valore trattato sarà 1.100.000.000.

  1. I segni "_" davanti alle variabili della funzione stampaFrequenza li avevo messi per differenziare visivamente le variabili locali usate nella funzione. Potevo mettere "ciccio1" e "ciccio2" al posto di "_scala" e "_frequenza", era la stessa cosa.
  2. sì, usa ultoa, è meglio.

Sono contento che qualcuno abbia migliorato il mio aborto di funzione. :grin: :disappointed_relieved:

Grazie Leo, ti devo un Ovetto Kinder, gli auguri te li faccio domani, ma anche domenica.

Paolo: ogni contributo ha il suo valore, Ovetto anche a te XD

Girando su internet mi è capitato di trovare un buon PDF sui comandi di Arduino.
Nello stesso PDF si cita come libera traduzione del reference.

http://www.itisvoltafr.it/~marsella/

Nella pagina c'e' a destra un link "PROGRAMMARE ARDUINO" per scaricare il pdf (sotto a "MATERIALI 3AE")

Grazie, l'avevo trovato anch'io ieri sera questo pdf, è ben fatto, più o meno come quello che avevo scaricato tempo fa, per di più è in italiano, grande cosa! Ma spero sempre che qualcuno dei capi mi possa dire che implementeranno la stampa del reference originale.

Allora ragazzi, tutto bene, col codice di Leo ed alcune piccole modifiche (gestione degli 0 iniziali) ho risolto alla grande il mio problema, in questo momento il mio display visualizza 0.000000001 GHz cioè 1solo Hz sulla portata dei GHz, fenomenale!
Grazie Leo, sei un grande.
Buona Pasqua a te e a tutti gli amici del Forum, ma comunque io sono qui....

Ma con Doxygen non si può ottenere il manuale partendo dal core di Arduino? Mi sembra che possa esportare in Latex.