Topic permanente di programmazione newbie

Nel mio lunghissimo post avevo anche messo:

leo72:
Basta un if con un triplo controllo all'interno di un for. Mettiamo che firma[..] contenga la firma digitale letta dal micro e archivioFirme[..][..] le firme memorizzate:

boolean trovato=false;

for (byte i=0; i<num_firme; i++) {
 if ((firma[0]==archivioFirme[i][0]) && (firma[1]==archivioFirme[i][1]) && (firma[2]==archivioFirme[i][2])) {
   .....codice per firma trovata....
   trovato=true;
   break;
 }
}
if (!trovato) {
 ....micro non riconosciuto...
}



"trovato" è false all'uscita del ciclo for se non è stato trovato nessun corrispondente modello nell'archivio

Quindi un semplice flag per verificare che l'uscita dal ciclo di controllo delle signature sia avvenuto recuperando un modello oppure no.
Se ora tu estrai la definizione di "byte i" dal for e la metti come variabile esterna, all'uscita del ciclo for, "i" contiene l'indice del modello che puoi poi usare per estrarre i dati dalle altre tabelle.

leo72:
Nel mio lunghissimo post avevo anche messo:

Scusa Leo, ma in questo caso dissento totalmente dalla tua soluzione.
Prima di tutto scansioni tutto l'array sempre, tempo cpu sprecato, e poi a Michele serve un indice per trovare tutti i parametri, la mia soluzione non solo è più elegante, più compatta ed efficiente, si ferma non appena trova il modello di micro e ritorna il relativo indice.

astrobeed:
Prima di tutto scansioni tutto l'array sempre, tempo cpu sprecato

a Michele serve un indice per trovare tutti i parametri, la mia soluzione non solo è più elegante, più compatta ed efficiente, si ferma non appena trova il modello di micro e ritorna il relativo indice.

Questo è un discorso relativo perché si hanno da passare in rassegna 10/20 modelli non di più. Si sprecano risorse ma parliamo di un ciclo che non sempre arriverà fino alle ultime posizioni dell'array dei micro. Inoltre non scansiono l'intero array ma mi fermo quando trovo una corrispondenza. Lo stesso fa il tuo ciclo for, perché esce solo nel momento in cui trova il micro, non prima.

Se la variabile viene messa fuori dal ciclo, nel momento in cui esce dal for conserva la posizione del micro trovato, quindi l'indice della corrispondenza trovata.

Poi è ovvio: ogni scarrafone è bello a mamma sua :wink:

Non vorrei dire una boiata, ma la Ricerca Dicotomica vi dice niente ? :grin:
Credo che non darebbe nessun problema durante l'implementazione ne durante il funzionamento..

Buongiorno, è doverosa la premessa che dovete sempre tener presente leggendo il titolo del Topic :blush:
Quindi io accetto e rispetto ogni suggerimento e davvero ringrazio di cuore chiunque mi dia una mano, poi ho due priorità: "comprendere" il suggerimento in quanto lo dovrò poi spiegare, ed "impossessarmi" di esso in quanto certamente devo manipolarlo; inoltre i tempi sono stretti quindi magari capita che prendo una soluzione tecnicamente meno favorevole di un'altra, ma se la capisco e funziona per me è un grande balzo avanti come state comprendendo; ancora, ovvio che se oltre a spiegarmi mi postate un code copia/incolla mi ci butto a pesce, salvo poi a chiedere spiegazioni. Ieri con grande fatica :sweat_smile: sono riuscito ad arrivare al punto che ho scritto nell'ultimo post, ora mi sembra giusto, prima di andare al lavoro (ma spero di sbrigarmi presto) postare la soluzione adottata, che mi sembra semplice e chiara, e che ora non so nemmeno più di chi è figlia, avendola perlatro "snaturata" tutta con interventi da newbie, che ora vi faranno imprecare, ma che funzionano, e per me, almeno per ora, tanto basta. Il prossimo passaggio consiste secondo me nel creare un 4° array con 6 righe e tre colonne nel quale memorizzo i sei valori del 4° byte dell'array "fuses" ed i corrispondenti valori di EFUSE si/no e programming mode HVSP/HVPP/HVP13; oppure con un semplice select case, da aggiungere alla base del code che vi sto postando, ottengo lo stesso risultato, ditemi Voi; una volta in possesso dei dati per la programmazione devo passare all'ultimo stadio, che è quello della scrittura dei fuses e poi ho finito; resta da immplementare l'erase, ma mi verrà semplice una volta ristrutturato il software, come sto facendo, man mano che procedo.

#define  TOT            4
char atmel [TOT] [20] = {      {"ATtiny13"},
                               {"ATtiny25"},
                               {"ATtiny45"} 
          {"NON IN TABELLA"}    
}; 

byte signature [TOT] [3] = {   {0x1E,0x90,0x07},
                               {""},
                               {""}
			};

byte fuses [TOT] [4] =    {    {0x6A,0xFF,0xFF,0x00},
				{0x62,0xD9,0xFF,0x04},
                               {0x62,0xDF,0xFF,0x05}
			};

IN LOOP:

// arrivati a questo punto sono in possesso della sola signature del micro

unsigned char indice;
    unsigned char LFUSE;
    unsigned char HFUSE;
    unsigned char EFUSE;
    unsigned char FLAGS;
    char modello[TOT],i;
    delay(500);
    indice = cfr_signature(read_signature2,read_signature3);
    if (indice < TOT)
      {
       for(i=0;i<20;i++) modello[i] = atmel[indice] [i];
       LFUSE = fuses[indice] [0];
       HFUSE = fuses[indice] [1];
       EFUSE = fuses[indice] [2];
       FLAGS = fuses[indice] [3];
      }  
    else for(i=0;i<20;i++) modello[TOT] = atmel[indice] [i];


NELLA SEZIONE FUNCTIONS & VOIDS

unsigned char cfr_signature(unsigned char byte2, unsigned char byte3)
{
char i;
unsigned int temp1, temp2;

temp1 = (unsigned int)(byte2 << 8) + byte3;

for (i=0;i<TOT;i++)
 {
  temp2 = (unsigned int) (signature[i] [1] <<8) + signature[i] [2];
  if (temp1 == temp2) return i; // esce dalla funzione con il valore dell'indice
 }
i = TOT-1; // corrispondenza non trovata, i assume l'ultimo valore dell'array "NON IN TABELLA"
return i; 
}

@ ratto93: per quanto mi riguarda non so di che parli :~

ratto93:
,Non vorrei dire una boiata, :grin:

Si l'hai detta :slight_smile:
La ricerca dicotomica è applicabile solo se hai una lista ordinata, in senso crescente o decrescente, il che implica l'uso di un sort oppure obbligare Michele ad un lavoraccio per mettere tutte le signature in ordine, se gli fai questa proposta come minimo telefona alla tua scuola e ti fa bocciare in anticipo :grin:
Dato che parliamo di array di piccole dimensioni, non penso andrà mai oltre i cento elementi, non è che ci sono tutti questi grandi vantaggi nell'applicare algoritmi di ricerca particolari, la banale scansione con stop sul match va più che bene.

astrobeed:

ratto93:
, ma la Ricerca Dicotomica vi dice niente ? :grin:

Si l'hai detta :slight_smile:
La ricerca dicotomica è applicabile solo se hai una lista ordinata, in senso crescente o decrescente, il che implica l'uso di un sort oppure obbligare Michele ad un lavoraccio per mettere tutte le signature in ordine, se gli fai questa proposta come minimo telefona alla tua scuola e ti fa bocciare in anticipo :grin:
Dato che parliamo di array di piccole dimensioni, non penso andrà mai oltre i cento elementi, non è che ci sono tutti questi grandi vantaggi nell'applicare algoritmi di ricerca particolari, la banale scansione con stop sul match va più che bene.

Allora usiamo lo Gnome sort per ordinare la lista :stuck_out_tongue:

astrobeed:

ratto93:
,Non vorrei dire una boiata, :grin:

Si l'hai detta :slight_smile:
La ricerca dicotomica è applicabile solo se hai una lista ordinata, in senso crescente o decrescente, il che implica l'uso di un sort oppure obbligare Michele ad un lavoraccio per mettere tutte le signature in ordine, se gli fai questa proposta come minimo telefona alla tua scuola e ti fa bocciare in anticipo :grin:
Dato che parliamo di array di piccole dimensioni, non penso andrà mai oltre i cento elementi, non è che ci sono tutti questi grandi vantaggi nell'applicare algoritmi di ricerca particolari, la banale scansione con stop sul match va più che bene.

Ratto, puoi smettere di lavorare alla tua tesina, non serve più, almeno per quest'anno ]:smiley:
Scherzi a parte io li sto già inserendo in ordine, ma in base alla Tabella che ho preparato circa i 25 controllori programmabili con certezza, con questo strumento. I successivi in serimenti saranno fatti in coda agli array.

Sì, concordo col fatto che è inutile cercare algoritmi particolari, perché VI confermo che la ricerca è immediata, anzi un ritardo è introdotto da un delay che Astro non mi ha spiegato, subito dopo la dichiarazione delle variabili.

@ Leo buono per quando implementerò le zoccolature qfn & co e programmeremo qualche migliaio di micro :grin:

Ragazzi, non faccio programmazione strutturata da 2 anni e ne abbiamo fatta anche poca quindi non prendetevela più di tanto :*

Per di più se sono già in ordine, può funzionare :zipper_mouth_face:
Mi riservo comunque il beneficio di dire boiate :stuck_out_tongue_closed_eyes:

menniti:
anzi un ritardo è introdotto da un delay che Astro non mi ha spiegato, subito dopo la dichiarazione delle variabili.

Il delay è solo per non bombardare la seriale con una marea di dati, dato che per l'esempio ho inserito tutto nella loop giusto per non farti vedere una marea di righe correre a velocità luce sul serial monitor ho messo quel ritardo.

ratto93:
Mi riservo comunque il beneficio di dire boiate :stuck_out_tongue_closed_eyes:

E noi quello di cazziarti quando le dici :smiley: :grin: :smiley:

astrobeed:

menniti:
anzi un ritardo è introdotto da un delay che Astro non mi ha spiegato, subito dopo la dichiarazione delle variabili.

Il delay è solo per non bombardare la seriale con una marea di dati, dato che per l'esempio ho inserito tutto nella loop giusto per non farti vedere una marea di righe correre a velocità luce sul serial monitor ho messo quel ritardo.

Allora lo posso togliere, visto che la seriale l'attivo solo dopo che ho tutti i dati e non mentre li leggo. Grazie.
Ora vorrei solo un paio di chiarimenti sulla funzione:
temp1 = (unsigned int)(byte2 << 8) + byte3; in temp1 metti la somma o l'unione dei bue byte? A che serve "<<8"?
Il resto mi è chiaro, fai ciclicamente la stessa cosa con temp2 prendendo i dati dall'array e confrontandoli con quelli di temp1, quando coincidono esci e riporti l'indice.

menniti:
tutti i dati e non mentre li leggo. Grazie.
Ora vorrei solo un paio di chiarimenti sulla funzione:
temp1 = (unsigned int)(byte2 << 8) + byte3;

Spiegazione estesa di cosa fa questa riga in C:

temp1 = (unsigned int)(byte2 << 8) + byte3;

Temp1 è definita come variabile di tipo unsigned int, cioè un intero senza segno in grado di rappresentare un numero compreso tra 0 e 65535.
byte2 e byte3 sono due variabili unsigned char, aka byte in wiring, la riga altro non fa che sommare assieme i due valori per ottenere un numero intero a 16 bit, per farlo è necessario moltiplicare per 256 il primo valore in modo da spostarlo 8 bit avanti, il modo più semplice, e rapido, per farlo è utilizzare l'operatore shift verso sinistra, il "<< 8".
In pratica byte2 viene letteralmente spostato di 8 bit trasformandolo da un valore unsigned char in un unsigned int, p.e. se byte2 vale 0xAA dopo l'operazione di shift vale 0xAA00, però dato che il dato è definito come unsigned char, cioè solo otto bit, è indispensabile dire al linguaggio che la variabile viene promossa a unsigned int e questo si fa tramite il casting, cioè il "(unsigned int)" prima di byte2.
Un volta che byte2 è diventato un 16bit possiamo sommargli byte3 per ottenere un valore a 16 bit univoco che rappresenta i due byte, p.e. se byte2 = 0xAA e byte3 = 0x25 dopo lo shift e il casting abbiamo 0xAA00 e dopo la somma di byte3 abbiamo 0xAA25.
La stessa cosa viene fatta durante il confronto utilizzando i dati della matrice comparandoli con il valore precedentemente calcolato.

Azz, m'hai appena regalato un quarto di pagina d'articolo XD no, scherzo, però visto che devo fare didattica credo non sia male soffermarsi su qualche tecnica particolare dello sketch; sei stato chiarissimo, grazie!

Leggo il byte FLAGS dall'array con il comando FLAGS = fuses[indice] [3];
ogni byte per me significano due variabili distinte in combinazione, pensavo che il seguente codice le assegnasse regolarmente, invece su serial non mi esce altro che un quadratino bianco, sia per l'una che per l'altra variabile (sono globali tipo "BYTE"):

switch (FLAGS) { 
  case 0x00:
    BURN_EFUSE = 0; 
    mode = HVSP;
    break;
  case 0x01:
    BURN_EFUSE = 0; 
    mode = HVPP;
    break;
  case 0x02:
    BURN_EFUSE = 0; 
    mode = HVP13;
    break; 
  case 0x03:
    BURN_EFUSE = 1; 
    mode = HVSP;
    break;
  case 0x04:
    BURN_EFUSE = 1; 
    mode = HVPP;
    break;
  case 0x05:
    BURN_EFUSE = 1; 
    mode = HVP13;
    break; 
  }

menniti:
Leggo il byte FLAGS dall'array con il comando FLAGS = fuses[indice] [3];
ogni byte per me significano due variabili distinte in combinazione, pensavo che il seguente codice le assegnasse regolarmente, invece su serial non mi esce altro che un quadratino bianco, sia per l'una che per l'altra variabile (sono globali tipo "BYTE"):

Dipende da come le fai visualizzare, usa l'estensione HEX nella serial print cosi vedi esattamente il contenuto in formato esadecimale.

Hai ragione, in esadecimale BURN_EFUSE mi dà 0 o 1 correttamente; mode invece mi dà 0,1 o 2, cioè le differenze corrispondono ma da dove li prende questi tre valori numerici che io non ho dato da nessuna parte? per vedere i valori testuali attribuiti come devo fare?
Anche perché dopo visualizzati li devo usare per decidere quali routine lanciare per le varie fasi della programmazione.

menniti:
Hai ragione, in esadecimale BURN_EFUSE mi dà 0 o 1 correttamente; mode invece mi dà 0,1 o 2, cioè le differenze corrispondono ma da dove li prende questi tre valori numerici che io non ho dato da nessuna parte?

???
Sei tu che assegni un valore a mode, "mode = HVP13;", da qualche parte avrai predefinito HVP13, HVPP, HVSP e in base a queste definizioni mode viene inizializzato di conseguenza.

è questo vero.....
enum modelist { HVSP, HVPP, HVP13 };
che assegna 1, 2, 3?
ma ora ti chiedo, nella prosecuzione dello sketch li ritiene equivalenti 1/HVSP, ecc.?
Cioè se io dopo aver caricato un flags in cui mode = 1 (quindi = HVSP), faccio una cosa del genere:
if mode = HVSP
me lo dà come "vero"? altrimenti sono fott.....

menniti:
Cioè se io dopo aver caricato un flags in cui mode = 1 (quindi = HVSP), faccio una cosa del genere:
if mode = HVSP
me lo dà come "vero"? altrimenti sono fott.....

Se in mode hai caricato HVSP, precedentemente predefinito con un certo valore, p.e. #define HVSP 1, e poi fai "if (mode == HVSP)" ovviamente ottieni un match.