interfacciamento con Gettoniera comestero RM5 contamonete

ciao a tutti,
dopo mesi che non mi dedicavo ad aurduino (nozioni very low level) ho vouluto cimentarmi in questo progetto:
comunicare con una classica gettoniera da distributore automatico.
la mia è questa
http://www.comesterogroup.it/pr-gett-gene-evolution.asp
e qui sotto il suo manuale
http://www.comesterogroup.it/pdf/prodotti/01getto/elettronica/rm5-evol/rm5-00/manuale/man-rm5-ita.pdf

io l'ho programmata con relativo sw come validatore (capitolo 8.1 del manuale)

in breve,
ad ogni canale / pin viene viene associato un valore di moneta letto,
e questo pin passa da un livello alto ad uno basso e ci resta per il tempo preimpostato dal sw (mio caso 50ms)
leggendo questo stato basso sul relativo canale si puo determinare il n di monete lette per ogni valore.

a tal proposito ho cercato di sviluppare uno sketch di base solo per la lettura delle monete.
il mio problema è sebbene a grandi linee funzioni fa comunque diversi errori di conteggio
ho provato a fare un sacco di modifiche per migliorare l'accuratezza ma al momento questo qui sotto è quello che mi ha dato migliori risultati:

utilizzato**Arduino 2009

//contamonete

// gettoniera impostata come validatore: per ogni moneta accettata (chX) invia un livello basso per x millisecondi, impostati in gett
niera 50 ms

int ch1 = 7; 
int ch2 = 8;
int ch3 = 9;
int ch4 = 10;
int ch5 = 3;
int ch6 = 4;

int cm = 0;
int cm1 = 0;
int cm2 = 0;
int cm3 = 0;
int cm4 = 0;
int cm5 = 0;
float val1;
float val2;
float val3;
int val4;
int val5;
float somma;


unsigned long test1;
unsigned long test2;
unsigned long test3;
unsigned long test4;
unsigned long test5;
long previousMillis1 = 0;  // w
long previousMillis2 = 0;
long previousMillis3 = 0;
long previousMillis4 = 0;
long previousMillis5 = 0;

long interval = 40;           // 

void setup()
{
  pinMode(ch1, INPUT);//0,1
  pinMode(ch2, INPUT);//0,2
  pinMode(ch3, INPUT);//0,5
  pinMode(ch4, INPUT);//1,0
  pinMode(ch5, INPUT);//2,0

  val1 = 0;
  val2 = 0;
  val3 = 0;
  val4 = 0;
  val5 = 0;
  somma = 0;
  //  pinMode(ch6, INPUT);



  Serial.begin(9600);	// opens serial port, sets data rate to 9600 bps

}

void loop()

{
  unsigned long currentMillis = millis();




  test1 = digitalRead(ch1); // controllo che il canale dei 10 cent va 0
  if( currentMillis - previousMillis1 > interval) { //temporizzazione per evitare false letture

    if ( test1== 0 ){
      //delay (50);
      val1 = val1 + 0.1; //somma i vaolri delle monete
      cm1 = cm1++;        //conta il numero di monete per ogni canale
      previousMillis1 = currentMillis;
    }
  }
  test2 = digitalRead(ch2);

  if(currentMillis - previousMillis2 > interval) {
    if ( test2== 0 ){ 
      //delay (40);
      val2 = val2 + 0.2;
      cm2= cm2++;
      previousMillis2 = currentMillis; 
    }
  }
  test3 = digitalRead(ch3);


  if(currentMillis - previousMillis3 > interval) {
    if ( test3== 0 ){  

      //delay (40);
      val3 = val3  + 0.5;
      cm3= cm3++;
      previousMillis3 = currentMillis;
    }
  }
  test4 = digitalRead(ch4);

  if(currentMillis - previousMillis4 > interval) {
    if ( test4== 0 ){ 
      //delay (40);
      val4 =  val4 + 1;
      cm4= cm4++;
      previousMillis4 = currentMillis; 
    }
  }
  test5 = digitalRead(ch5);


  if(currentMillis - previousMillis5 > interval) {
    if ( test5== 0 ){
      //delay (40);
      val5 = val5 + 2;
      cm5= cm5++;
      previousMillis5 = currentMillis; 
    }
  }
  somma = (val1 + val2 + val3 + val4 + val5);

  Serial.println ("somma");
  Serial.println (somma);
  Serial.println ("Valore per moneta");
  Serial.println (val1);
  Serial.println (val2);
  Serial.println (val3);
  Serial.println (val4);
  Serial.println (val5);
  Serial.println ("n monete per tipo");
  Serial.println (cm1);
  Serial.println (cm2);
  Serial.println (cm3);
  Serial.println (cm4);
  Serial.println (cm5);


}

nella mia inesperienza penso di aver abusato di variabili.

qualchuno potrebbe aiutarmi ad aumentare l'affidabilitè della lettura?

inizialmente volevo interfacciarla via seriale (ho i protocolli rs232, basta chiederli) ma sebbene da terminale fossi riuscito a comunicare con la gettoniera, con arduino non sono riuscito a gestire la seconda seiriale NewsoftwareSerial e allora ho abbandoanto il progetto.

considerato il il costo contenuto (20 30 euro usata su ebay) ritengo che lo sviluppo di un progetto arduino per questa gettoniera potrebbe tornare utile a molti.

spero vivamente che qualcuno possa aiutarmi :slight_smile:
grazie
andrea

Volevo aggiungere che inizialmente avevo utilizzato l'istruzione "pulsein" ma mi è sembrato che si verificassero troppi delay.
forse l'ho utilizzato nel modo scorretto
ciao ciao
andrea

ok ...
vedo che non interessa...
peccato :roll_eyes:

Il fatto che nessuno risponda non significa che non sono interessati ma , almeno per quanto mi riguarda, da un lato forse non sono in grado di aiutarti e dall'altro non ho capito bene la tua domanda.

Spiegami meglio, ma la gettoniera da un segnale diverso a seconda del diametro/peso della moneta? E' tarata gia' di suo sugli €?

Ciao,

Fab.

ciao f.schiano,

la gettoniera, come dici tu, li ha memorizzati valori delle monete.
ogni valore 0,1 0,2 0,5 1 e 2 è associato ad un canale. il canale è alla fine fisicamente un pin di un connettore di comuniczaione.
nello specifico, se inseriamo una moneta da 1 euro, il pin 10 del connettore (ch4) passa da un livello logico 1 a 0 per circa xx ms (questo valore è impostabile, io l'ho settato a 50 ms)
similmente se insersco una moneta da 0,1 euro, la moneta viene riconosciuta e a sua volta mette a 0 il pin 7 (ch1) xx ms
questo è il sistema piu semplice a mio avviso per identificare le monete.
ci sono altri sistemi di comunicazione ma questi prevedono treni di impulsi che vanno misurati in tempo, usicte binarie basate su un unico pin etc...(tralascio i protocolli MDB Executive o ccTalk che li trovo complessi sebbene quelli piu usati)
l'alternativa come dicevo al primo post è la seriale che sarebbe alquanto piu semplice ma in questo caso non sono capace di mandare i comandi da serial monitor (per testare) verso una porta virtuale al quale collego la gettoniera.... e tanto meno visualizzare i dati di risposta della gettoniera su serial monitor...

spero di essermi spiegato meglio
ciao ciao

Ok. Quindi hai provato tutte le monete e le riconosce tranquillamente? Mandando a LOW il pin apposito giusto?

Ora spiegami cosa vorresti fare!

Ciao,

Fab.

Wonder:
ci sono altri sistemi di comunicazione ma questi prevedono treni di impulsi che vanno misurati in tempo, usicte binarie basate su un unico pin etc...

Ciao , tempo addietro, nel 2003-2004 :smiley: sviluppai un progetto di una stazione per consentire il gioco tramite playstation2 a pagamento.
Il metodo per caricare il credito era proprio una RM5 (p.s. se non erro in cantina ne ho ancora un paio).
Il progetto non era basato su arduino bensi sui miei amati (e compianti) microprocessori Microchip, nello specifico dei 16f628a.
Io ho utilizzato la modalità a treno d'impulsi e ti garantisco che è tutt'altro che complicato da far funzionare, anzi se me lo permetti, mi sa che la modalità più complessa da far funzionare l'hai scelta tu!

Come l'ho utilizzata io serve un solo pin, e leggi i fronti di salita (o meglio discesa) del treno di impulsi generati all'inserimento della moneta e sei apposto.
Stà poi a te programmare adeguatamente la gettoniera(ma come vedo hai il manuale e come vedi è semplicissimo programmarla), in maniera tale che se inserisci ad esempio 50cent, ti genera 5 impulsi, se inserisci un euro 10 impulsi e così via...
L'evoluzione di questo progetto poi in seguito mi ha portato a utilizzare anche i riconoscitori di banconote, ma questo è un altro discorso!

Saluti!

Niki hai codice a disposizione? O comunque un po' di documentazione? E' una cosa interessante e potrebbe aiutare Wonder!

f.schiano:
Ok. Quindi hai provato tutte le monete e le riconosce tranquillamente? Mandando a LOW il pin apposito giusto?

Ora spiegami cosa vorresti fare!

Ciao,

Fab.

Quello che voglio fare è semplicemente adottare arduino come automazione di qualsiasi genere a seguito di un pagamento.
dall'erogazione di prodotti alla gestione di un certo tempo di attivazione e cosi via

E cosa non ti funziona? O cosa non riesci ad implementare?

Dai che ce la facciamo a capire quello che ti serve :slight_smile:

x f.shiano

si me li manda giu e nel programma che ho sviluppato anche li legge... il problema che riscontro è la lettura errata,
diverse volte inserndo di seguito 10 15 monete di taglio diverso mi salta il conteggio di qualche moneta di un certo taglio o magari me ne aggiunge 1 o 2 in piu in un altro taglio.

xniki,
sono al corrente che esiste il conteggio di impulsi ma dalla mia esperienza siccome le ho installate nella mia lavagettone,
gli impulsi cambiano di lunghezza in funzione del valore della moneta... forse ho frainteso non lo nego...
e comunque mi sembra una lettura abbastanza lenta quella in questione perchè per contare 3 euro circa si deve attendere diversi secondi prima che transiti tutto il treno di impulsi. ci tenevo a realizzare qualcosa di piu immediato...
certo ambivo alla comunicazione seriale ma i tentativi fatti mi hanno messo in crisi e allora ho optato x qualcosa piu alla mia portata.

Se diminuisci/aumenti quell'intervallo di 50ms cosa succede?

Ciao,

Fab.

f.schiano:
Se diminuisci/aumenti quell'intervallo di 50ms cosa succede?

Ciao,

Fab.

i 50 milli si posso impostare sulla gettoniera da un minimo di 10 a un max di 2 secondi (consigliato 10 - 630 ms)
io li ho messi prima a 100 poi a 50 ma gli errori si verificano comunque
d'altra parte invece ho usato delle temporizzazioni nello schetch nella speranza di creare una finestra di tempo che mi garantisca il pin low mentre il progamma va in lettura dello stato (non so se è corretto quello che ho fatto) variando queto intervallo di attesa mi cambia solo il tipo di errore di lettura magari piu in difetto o magari qulache conteggio di troppo.
ho notato che l'errore si manifesta di piu con monete da 10 20 cent inserite una dietro l'altra. (n monete massime accettetate dalla rm5 son 3 al secondo)

siccome tutto questo è un workaround alla mia mancata conoscnza della comunicazione seriale,
qualcuno sa dirimi come mandare da serial monitor un comando hex 00 0d verso una seconda seriale virtuale e da questa leggere 2 byte (valore della moneta) e visuliazzarli in serial monitor?

mi sembra che mi sto complicando la vita con queste false letture quando magari sapendo usare la seriale sarebbe tutto piu semplice.
garantisco che ci ho provato a fare tentativi ma non ne è usicto niente

f.schiano:
Niki hai codice a disposizione? O comunque un po' di documentazione? E' una cosa interessante e potrebbe aiutare Wonder!

Effettivamente da qualche parte il codice ce l'ho , ed era pure fatto in C , quindi...
Anzi no, tanto ero niubbo (ma lo sono ancora è, non fraintendete) che usai picbasic =(

Comunque la cosa era assai semplice, leggevo lo stato logico del pin collegato alla gettoniera con debounce di 100ms
Ad ogni lettura a livello logico basso corrispondeva un impulso della gettoniera, in quella installazione gestivo solo monete da 50cent, 1 euro e 2 euro, 50 centesimi = 1 impulso , 1 euro 2 impulsi, 2 euro 4 implusi .
Nella peggiore ipotesi dei 2 euro impiega c.a. 400ms per leggere tutto il treno.Impostando diversamente la gettoniera ed il debounce si può anche scendere, ma mi sembrano tempi accettabili per un riconoscitore di denaro!

Sicuramente posso dirti che hai frainteso come funziona la modalità multiimpulso,i tempi che hai ipotizzato sono veramente biblici.

Scusa se mi permetto ancora wonder ma mi sembra veramente (come hai anche tu stesso ammesso) che ti stai veramente complicando tanto la vita per nulla!

niki77:

f.schiano:
Niki hai codice a disposizione? O comunque un po' di documentazione? E' una cosa interessante e potrebbe aiutare Wonder!

Comunque la cosa era assai semplice, leggevo lo stato logico del pin collegato alla gettoniera con debounce di 100ms
Ad ogni lettura a livello logico basso corrispondeva un impulso della gettoniera, in quella installazione gestivo solo monete da 50cent, 1 euro e 2 euro, 50 centesimi = 1 impulso , 1 euro 2 impulsi, 2 euro 4 implusi .
Nella peggiore ipotesi dei 2 euro impiega c.a. 400ms per leggere tutto il treno.Impostando diversamente la gettoniera ed il debounce si può anche scendere, ma mi sembrano tempi accettabili per un riconoscitore di denaro!

Sicuramente posso dirti che hai frainteso come funziona la modalità multiimpulso,i tempi che hai ipotizzato sono veramente biblici.

E probalile che abbia frainteso o non la chiamiamo allo stesso modo.
le differenze di tempo possono anche essere dovute all'unità di misura, mi sembra giusto che se usi 50 Cent e l'unita di conteggio è quella sono 400 ms
nel mio caso invece l'unità di misura è 10 cent e l'accetttazione di una moneta di 2 euro dura almeno 2 sec con la modalità che usi tu
probabilmente non è la stessa che sto verificando io perchè in una configurazione con scheda I/O=originale (relè che si eccita ad ogni impulso) una moneta da 2 euro viene acquisita in 6 sec.

niki77:
Scusa se mi permetto ancora wonder ma mi sembra veramente (come hai anche tu stesso ammesso) che ti stai veramente complicando tanto la vita per nulla!

si me la sto complicando sicuramente perchè in origine volevo la comunicazione rs232 dove il dato che la gettoniera sputa è quello e non va interpretato.

se mi aiutate a risolvere il problema di comunicazione seriale elimino anche tutti i dubbi su come interfacciarmi alla gettoniera.

qui sotto il codice di base
è un esempio base dove in teoria trasferisco i dati seriali da serial monitor verso gettoniera e viceversa.

#include <SoftwareSerial.h>
#include <icrmacros.h>



SoftwareSerial mySerial(6, 7);

int inByte = 0; 
int outByte = 0;
void setup() {
 
  Serial.begin(9600);
  mySerial.begin(9600);

}

void loop() {
  // read from port 0, send to port 1:
  if (Serial.available()) {
    int outByte = Serial.read();
  //  Serial.println("comando");
    mySerial.print(outByte,HEX); 

  }
  // read from port 1, send to port 0:
 if (mySerial.available()) {
    int inByte = mySerial.read();
    Serial.println("Risp. gettoniera");
    Serial.print( inByte,HEX); 
  }
}

beh non funziona proprio
quello che deve fare è questo:
da serial monitor spedendo il comando 00 1D metto la gettoniera in attesa moneta.
quando la moneta viene letta, la gettoniera dovrebbe rispondere con 2 byte in esadecimale con il valore della moneta.

già con il solo comando 00 la gettoniera dovrebbe risponde con 00 00 (verificato con un terminale e una connessione diretta tra rs232 pc e gettoniera)
da serial monitor tramite arduino ho provato a inserire 00, 0, 0x00, (0x00) ma non ottengo mai una risposta dalla gettoniera.

ditemi dove sto sbagliando per favore perchè sta cosa mi sta facendo andare fuori di testa

ciao ciao

Forse ho capito cosa non funziona , ma prendilo con le pinze!

A parte tutto il tuo ragionamento contorto che stai facendo che non voglio approfondire, forse il problema risiede sul fatto che tu scrivendo da serial monitor 00, col codice che hai poi non vai ad inviare il valore hex di 00, ma bensi 30 30 (che dovrebbe essere il valore ascii dei caratteri 0) e se cosi fosse la gettoniera è normale che non ti risponde.
Prova a modificare il codice forzando poi l'invio alla gettoniera di un byte 0 e vedi cosa succede.

#include <SoftwareSerial.h>
#include <icrmacros.h>



SoftwareSerial mySerial(6, 7);

int inByte = 0; 
int outByte = 0;
void setup() {
 
  Serial.begin(9600);
  mySerial.begin(9600);

}

void loop() {
  // read from port 0, send to port 1:
  if (Serial.available()) {
    int outByte = Serial.read();
    outByte = 0;
  //  Serial.println("comando");
    mySerial.print(outByte,HEX); 

  }
  // read from port 1, send to port 0:
 if (mySerial.available()) {
    int inByte = mySerial.read();
    Serial.println("Risp. gettoniera");
    Serial.print( inByte,HEX); 
  }
}

niki77:
Forse ho capito cosa non funziona , ma prendilo con le pinze!

A parte tutto il tuo ragionamento contorto che stai facendo che non voglio approfondire, forse il problema risiede sul fatto che tu scrivendo da serial monitor 00, col codice che hai poi non vai ad inviare il valore hex di 00, ma bensi 30 30 (che dovrebbe essere il valore ascii dei caratteri 0) e se cosi fosse la gettoniera è normale che non ti risponde.
Prova a modificare il codice forzando poi l'invio alla gettoniera di un byte 0 e vedi cosa succede.

#include <SoftwareSerial.h>

#include <icrmacros.h>

SoftwareSerial mySerial(6, 7);

int inByte = 0;
int outByte = 0;
void setup() {

Serial.begin(9600);
 mySerial.begin(9600);

}

void loop() {
 // read from port 0, send to port 1:
 if (Serial.available()) {
   int outByte = Serial.read();
   outByte = 0;
 //  Serial.println("comando");
   mySerial.print(outByte,HEX);

}
 // read from port 1, send to port 0:
if (mySerial.available()) {
   int inByte = mySerial.read();
   Serial.println("Risp. gettoniera");
   Serial.print( inByte,HEX);
 }
}

ho provato a fare come dici tu... nessun risultato positivo
se ho capito la tua modifica, qualsiasi cosa scrivo in serila monitor, viene trasmesso uno 0 alla gettoniera.

per scrupolo ho anche eliminato il cavo di connessione originale della gettoniera che è provvisto di max232 e mi sono collegato direttamente dai pin 6 7 di arduino ai pin rx tx della gettoniera
il collegamento che ho fatto in entrambi i casi sono i classici rx arduino >tx gett / tx arduino> rx gett. + ground.
mannaggia che inghippo

Bhe, pensandoci bene in effetti con serial.print la cosa non dovrebbe essere cambiata molto.

la cosa più corretta sarebbe usare Serial.write(0) , in questa maniera hai la certezza che viene inviato il byte 0 alla seriale.

Serial.print() secondo la documentazione recita : Prints data to the serial port as human-readable ASCII text.

Quindi in sostanza non va bene.

Parlo empiricamente basandomi sulla teoria, perchè in pratica al momento sono impossibilitato dal provare.

niki77:
Bhe, pensandoci bene in effetti con serial.print la cosa non dovrebbe essere cambiata molto.

la cosa più corretta sarebbe usare Serial.write(0) , in questa maniera hai la certezza che viene inviato il byte 0 alla seriale.

Serial.print() secondo la documentazione recita : Prints data to the serial port as human-readable ASCII text.

Quindi in sostanza non va bene.

Parlo empiricamente basandomi sulla teoria, perchè in pratica al momento sono impossibilitato dal provare.

anche io avevo provato il serial.write ma questo da un problema con compilazione, pare che non accetti valori di 2 byte,
ti allego l'errore compilando con serial.write

sketch_dec14a.cpp: In function ‘void loop()’:
sketch_dec14a:23: error: call of overloaded ‘write(int)’ is ambiguous
/home/pic/arduino-1.0/libraries/SoftwareSerial/SoftwareSerial.h:92: note: candidates are: virtual size_t SoftwareSerial::write(uint8_t)
/home/pic/arduino-1.0/hardware/arduino/cores/arduino/Print.h:49: note: size_t Print::write(const char*)