Cercare un valore all'interno di un elenco

Ciao, volevo sapere se c'è un modo più rapido senza dover fare tutta una serie di "IF"
in pratica ho un elenco di valori es:
byte pippo = 01
byte pluto = 02
byte paperino = 03
byte topolino = 04
byte banny = 05

ricevo dalla seriale una stringa di dati (byte), devo confrontare il quarto byte con l'elenco per sapere cosa mi sta dicendo, quindi se ricevo 03 so che devo eseguire la funzione paperino, per questo chiedevo se c'era un modo più rapido oltre a IF visto che i valori da confrontare sono 30.
Grazie

Mi viene in mente array di puntatori a funzioni
Mai usato, imparo anch'io..

maurizio_B:
Ciao, volevo sapere se c'è un modo più rapido senza dover fare tutta una serie di "IF"

Certo. I valori non li metti nelle variabili singole come hai fatto, ma in un array e cicli su quello per capire quale hai ricevuto.
Esempio:

#define MAX_VALORI 6 // Qui ci metterai 30...
byte valori[] = { 1, 4, 32, 6, 12, 7 }; // Qui i 30 valori..
byte ricevuto = -1;
   ...
  if (ricevuto >= 0) {
    for(int i=0; i<MAX_VALORI; i++)
      if ( ricevuto == valori[i] )
        // fai quello che devi fare

Questo non è esattamente quello che intendevo io, in questo modo eseguo una funzione se il dato ricevuto è presente nell'array.
Io sto facendo un polling di stato verso un hopper rendiresto, nella risposta che ricevo, il 5° byte corrisponde allo stato, es:
0x21 = non è operativo
0x37 = ha terminato di erogare il resto
0x0A = la bocca di uscita monete è ostruita

quindi, se ricevo 0x37 visualizzo nel display "Ritirare il resto", se ricevo 0x0A, con un altro comando tento di liberarla ecc.
Ora ho fatto una funzione di controllo con all'interno tutti gli IF necessari, butto dentro il byte da controllare ed esegue la funzione corrispondente, mi chiedevo se c'era qualche altro modo per farlo senza utilizzare tutti questi if.

  1. Usare lo switch/case

  2. usare il metodo che ti hanno detto utilizzando due array ... il primo contiene i "valori", il secondo, nello stesso ordine, contiene i "messaggi". Cerchi il "valore" e in un solo colpo, usando lo stesso indice, hai il "messaggio" da visualizzare.

Personalmente utilizzerei il metodo 2 (... magari in accoppiata a PROGMEM per risparmiare la SRAM).

Guglielmo

OK, array di puntatori a funzione, ho provato funziona, scusa il gioco di parole
per pura leggibilità dichiari un tipo con una typedef
typedef void (* nomedeltipo)(void);
che significa che nomedeltipo è puntatore (la stellina) a funzione void che ha argomento void

poi prima del setup dichiari un array lungo una bytetata (neologismo che vuol dire tanti elementi quanti sono i possibili valori di un byte)
dicevo un array di puntatori a funzioni, una cosa del tipo

nomedeltipo listafunzioni[];

che crea l'array vuoto (i puntatori vuoti sono null, ricorda)

poi crei le fuznioni void argomento void che ti servono

poi nella setup inizializzi l'array con le funzioni

se 0X02 deve stampare farai
listafunzioni[0x02]=nomedellafuznionechestampa;

poi alla ricezione del byte ti basta eseguire la funzione corrispondente

listafunzioninumeroricevuto;

le parentesiapertechiuse " chiamano" la funzione puntata dal puntatore di fuznione nellennesimo elemento dell'array

ecco perchè AmOdio il "C"..........

PS, per evitare fraintendimenti, come con quell'altro della ruota che girava:
lo ho provato, non venirmi dire che non va!

gpb01:

  1. Usare lo switch/case

  2. usare il metodo che ti hanno detto utilizzando due array ... il primo contiene i "valori", il secondo, nello stesso ordine, contiene i "messaggi". Cerchi il "valore" e in un solo colpo, usando lo stesso indice, hai il "messaggio" da visualizzare.

Personalmente utilizzerei il metodo 2 (... magari in accoppiata a PROGMEM per risparmiare la SRAM).

Guglielmo

se le operazione fossero tutte omologhe lo avrei consigliato anch'io
siccome non tutte sono stampe, alcune accensioni, altre interventi varii, temo che con due array non si possibile

Standardoil:
siccome non tutte sono stampe, alcune accensioni, altre interventi varii, temo che con due array non si possibile

Dal suo messaggio #3 avevo capito che fossero solo messaggi da dare sul display ::slight_smile:
E' chiaro che se invece deve anche eseguire "azioni" la cosa si complica ...

Guglielmo

Io sto facendo un polling di stato verso un hopper rendiresto, nella risposta che ricevo, il 5° byte corrisponde allo stato, es:

hopper CCTalk ? che hopper è marca e modello.

generalmente si cicla su due comandi durante l' erogazione

Header 166 - Request hopper status

Header 163 - Test hopper

il comando 163 restitusce 0 se non ci sono errori quindi solo se != 0 verifichi i singoli bit di errore.

il comando 166 restituisce (eventi - da erogare) - (lultimo comando (erogate - da erogare)) errore

se l' hopper è azkoyen i codici saranno diversi perchè non usano comandi standard e anche i messaggi di ritorno sono diversi ma comunque la tecnica è la stessa.

Standardoil:
OK, array di puntatori a funzione, ho provato funziona, scusa il gioco di parole
per pura leggibilità dichiari un tipo con una typedef
typedef void (* nomedeltipo)(void);
che significa che nomedeltipo è puntatore (la stellina) a funzione void che ha argomento void

poi prima del setup dichiari un array lungo una bytetata (neologismo che vuol dire tanti elementi quanti sono i possibili valori di un byte)
dicevo un array di puntatori a funzioni, una cosa del tipo

Ok.. ci provo
Grazie

PaoloF_60:
Hopper CCTalk INNOVATIVE TECNOLOGY senza selettore di monete in quanto svolge solamente il compito di restituire il credito residuo presente all'interno delle fidelity card

Casomai butta giù uno scheletro. Che poi si va avanti

Ma stai parlando di uno smart hopper ? ITL

perchè se è questo il protocollo usato potrebbe essere CC2

quindi il comando di verifica status è il 29

Se parliamo di questo penso che case e if siano appropriate.

PaoloF_60:
Ma stai parlando di uno smart hopper ? ITL

SMART Hopper

perchè se è questo il protocollo usato potrebbe essere CC2

https://www.aus.at/download/GA863%201_2_4_CC_talk2.pdf

quindi il comando di verifica status è il 29

Se parliamo di questo penso che case e if siano appropriate.

Grazie..
Si proprio lui

Se conosci un po' il basic ti allego un pezzo con la gestione dei comandi proprietari ITL.
Puoi usarla come traccia.

Tieni presente fra l' altro che prima che lo status diventi IDLE si deve attendere che termini
la procedura di Reset Hardware dello Smart Hopper. Solo quando è nello stato IDLE accetta
comandi dopo l' invio del comando lo status va continuamente monitorato affinchè il dispositivo rimanga attivo. A volte può capitare che risponda con due codici consecutivi alla richiesta di status.

Posso anche fornirti il programma se hai un sistema Windows. Tutta la comunicazione è monitorata e visualizzata in una finestra.Devi solo avere un' interfaccia usb-cctalk o rs 232-cctalk.

Code.txt (27.6 KB)

Cctalk Interface_SCH.pdf (17.2 KB)

PaoloF_60:
Se conosci un po' il basic ti allego un pezzo con la gestione dei comandi proprietari ITL.
Puoi usarla come traccia.

Tieni presente fra l' altro che prima che lo status diventi IDLE si deve attendere che termini
la procedura di Reset Hardware dello Smart Hopper. Solo quando è nello stato IDLE accetta
comandi dopo l' invio del comando lo status va continuamente monitorato affinchè il dispositivo rimanga attivo. A volte può capitare che risponda con due codici consecutivi alla richiesta di status.

Posso anche fornirti il programma se hai un sistema Windows. Tutta la comunicazione è monitorata e visualizzata in una finestra.Devi solo avere un' interfaccia usb-cctalk o rs 232-cctalk.

Sei veramente gentile, GRAZIE
Si mi piacerebbe provare il tuo programmino, gia che che ci sono, vorrei chiederti, per caso quale sia il bit di configurazione del registro zero del parametro 0x1E (Set Payout Options)? dal manuale sarebbe il primo bit
0 = free pay - 1 = hight value split, la innovative dice che ce n'è un terzo "hight efficiecy split" ma non capisco come configurarlo.
I due configurabili dal bit 0, non vanno molto bene, ho fatto un test inserendo una moneta da 2 euro 4 da 1 euro poi diverse miste negli altri formati, ho richiesto un resto di 2 euro, con la modalità "0" mi ha buttato fuori una manciata di monetine senza considerare i 2 euro o 1 euro, nella modalità "1" partendo dalla moneta più grande che lui sa di avere, gira e trita per un bel po fino a quando non la trova poi passa alla moneta più piccola ecc. in questo caso ha dato poche monete ma ci ha messo un sacco di tempo ad erogare, pare che con questa terza opzione abbiano ottimizzato l'algoritmo di erogazione.

http://ge.tt/2kpucEp2

da qui puoi scaricarlo

ho aggiunto il sorgente

http://ge.tt/7s0GeEp2

una volta scaricato e installato al primo avvio ti chiede la porta di comunicazione da usare

dall' elenco comandi fai un simple pol on all devise comando 0

quindi selezioni il dispositivo nella lista dispositivi

e quindi get denomination ammount comando 26
puoi impostare il numero di pezzi facendo doppio click nei rispettivi campi

non ho ancora scritto un help

per il bit di configurazione di cui parli non ti so dire bisognerebbe sapere se è stato implememntato da quale versione firmware sia attivo. E eventualmente trovare un manuale del protocollo aggiornato.

Tieni presente che d' altra parte quando hai così poche monete è normale che ci metta del tempo
a cercare la moneta da 2 euro fra tutte le altre è anche una questione meccanica.

Gli algoritmi di erogazione presumibilmente cercano di bilanciare la quantità di monete presenti
all' interno dell' hopper nel tentativo di non esaurire i tagli più piccoli.

Ho trovato qualcosa circa quel bit del registro option nelle specifiche ssp altro protocollo di ITL
è probabile che funzionino anche all' interno del protocollo CC2. In allegato una pagine del
protocollo ssp con il registro in questione.

SSP_Manual.pdf (30.8 KB)

PaoloF_60:
Ho trovato qualcosa circa quel bit del registro option nelle specifiche ssp altro protocollo di ITL
è probabile che funzionino anche all' interno del protocollo CC2. In allegato una pagine del
protocollo ssp con il registro in questione.

Non so come ringraziarti per il programma.

Per quanto riguarda il registro di configurazione, ho anch'io il manuale SSP ma purtroppo con quella configurazione non funziona in CC2, me lo ha confermato anche l'ufficio tecnico della ITL italia, con CC2 funziona solamente con le due modalità configurabili con il bit 0

Ok Comunque io utilizzerei il metodo di pagamento con il valore piu alto per primo e le evevntuali prove
le dovresti fare con un numero minimo di monete all' interno che so almeno 10 pezzi per taglio.

Poi dovresti mantenere il carico bilanciato o con la gestione delle monete entranti o se agisci solo sull' hopper con float by denomination. Puoi sempre gestire tu il pagamento con payout by denomination.

Per quanto riguarda il programma, mi dispiace che non sia molto commentato e sia un po' pasticciato
in quanto ho aggiunto dispositivi e procedure man mano che ne ho avuto bisogno e devo ancora
completare alcune procedure o la gestione di alcuni dispositivi. Devo ad esempio predisporre per
la crittografia del protocollo che inserirò come DLL per questioni di impegno di riservatezza come già fatto
per la crittografia del pagamento con hopper encrypted.