29 abril 2022

Cambiadora AMYC Global Change. Con NV10 traga. Apaño. BILLETERO NV10 POR LUMINA.

 PARA REPASAR, y fuentes de información: La máquina de cambio se compone, a grandes rasgos, de un lector de billetes (originalmente un LUMINA de Money Controls -hoy extinguida-) que por ser raro, no dispongo de repuesto y se convierte en complicada la gestión de reprogramaciones y actualizaciones para billetes nuevos. Por eso, hace ya un tiempo (años), se ha cambiado por un NV10 de Innovative Technologies. Un transformador toroidal alimenta a 24Vac a la placa principal (Macmoney Newmac/5). En ella está la regulación de alimentación y el control. Añade dos placas externas, una para controlar un pequeño display, y otra de I/O con pulsadores para manejar la configuración y enchufar el billetero. Esta controla dos hoppers tipo U de Azkoyen. 

 

Billetero LUMINA de Money Controls (original)
 

Billetero NV10 de Innovative Technologies (modificación)

 

En principio, la adaptación no tiene demasiada complicación. El Lumina usa, en este caso, el protocolo paralelo, y el NV10 también soporta ese protocolo. Así, que solo se trata de modificar la sujeción a la máquina, y cablear los pines correspondientes del NV10 (ver página 10 del manual del NV10) directamente a los pines apropiados del Lumina (ver página 6 del manual del Lumina). Y, sin más complicaciones, ¡ha funcionado bien varios años...!


Conexión al billetero CN6


EL PROBLEMA:

Desde hace unas semanas la máquina traga de vez en cuando algún billete. Se le cambia el billetero NV10 y se rehace el cableado de la conexión de éste. Pero el problema sigue. Así que se retira para taller.

En el taller, en test, observo algo curioso. Siempre que traga el billete parece patinar un poco. O cuando yo, con la mano, sujeto el billete para no dejarlo pasar fácilmente, el billete pasa, pero la máquina no lo da por aceptado. 

Así, que con un analizador lógico barato, y desde el magnífico entorno Open Source de análisis de señal Sigrok ,me dispongo a intentar estudiar las señales del NV10 y descubrir qué pasa.  


Estudio de señales y timing entre billetero y máquina


ANALIZANDO PROCESO DE ACEPTACIÓN CORRECTO:

Según el análisis de la documentación del selector de billetes NV10, el proceso de aceptación en esta máquina (protocolo paralelo) sería como sigue (Ver FOTOaceptación):

Las señales de crédito (pines del 1 al 4 del NV10) permanecen, en reposo, a nivel alto. Cuando introduces un billete, que el NV10 reconoce, baja la linea correspondiente al billete en cuestión (en el ejemplo billete de 5€=linea D0) durante 100ms.

La linea Escrow (pin 10) se usa para poder rechazar o aceptar el billete. Si la mantenemos a nivel alto, aceptará  siempre. Si la ponemos a nivel bajo antes de la aceptación, una vez leído un billete, e indicado con una primera  bajada de 100ms de la línea correspondiente, el NV10 espera hasta 30 segundos, a que la línea Escrow se suba a nivel alto. Así indicamos que queremos aceptar el billete. El billete pasará al interior y el NV10 volverá a confirmar todo el proceso de aceptación volviendo a bajar el pin Accept correspondiente. 

Se puede provocar la devolución del billete subiendo a nivel alto la línea Inhibit  correspondiente antes de la aceptación total. O inhibiendo todas las lineas Inhibit, hacer que devuelva todo y que el billetero permanezca inactivo.


(FOTOaceptación) D0,D1,D2=Accept1,3,2*; D3,D4,D5=Inhibit1,2,3; D7=Escrow


En la "FOTOaceptación" y "FOTOaceptaciónBIS", se pueden observar las señales involucradas en un proceso de aceptación correcto, real, con esta máquina. Obsérvese que la máquina cambiadora inhibe la entrada de billetes mientras los hoppers están pagando (D4 y D5 a nivel alto un rato después de aceptar). 

Nótese también, que no tengo monitorizado la linea Accept4 e inhibit4 porque "mi analizador lógico" sólo tiene 8 lineas de datos, así que he inhibido, e ignorado, el billete de 50€ para las pruebas. (*)También había cometido un error y están intercambiados de su forma lógica los pines D1 y D2 que deberían haber sido Accept2 y Accept3, pero no. Nótese el pie de "FOTOaceptación". Siento estos errores y la mala edición de las fotos. Fue todo un proceso que ahora, acabado, pretendo documentar, con lo que conservo. Pero cuando empecé no pretendía hacer esta entrada.


(FOTOaceptaciónBIS) Aceptación correcta de 5,10,y 20€


NO ENTIENDO EL PROBLEMA:

 Aquí, en la siguiente imagen, enseño monitorizadas otras señales, en donde sí, esta vez, la máquina se traga billetes. El primer billete de 5 euros y el tercero de 20 euros. El segundo billete de 10 euros es aceptado correctamente.

 

Traga billete de 5, acepta de 10, y vuelve a tragar de 20€


Aquí sucede algo que no acabo de entender, y que me gustaría, si alguien tiene alguna idea, me la comentase...

Cuando el billete, después de ordenar aceptarlo (escrow a High) por alguna razón patina, la máquina, no sé como (¿sugerencias?) lo detecta. Baja escrow justo el tiempo que el billete patina o lo mantengo sujeto a propósito. Y además sube las líneas de inhibición para ordenar rechazarlo. Pero el billete ya ha pasado, y el NV10 no es capaz de hacer caso. Acaba dando el segundo pulso de confirmación de aceptación, pero la máquina ya no le hace caso. 


MIS HIPÓTESIS DEL FALLO:

He pensado varias ideas de porque podría estar fallando.

Probé con varios NV10. Con algunos mejor que con otros, pero con todos traga a veces.

Pensé en un fallo de alimentación. Que cuando el billete se atasca o patina, el consumo del billetero sea mayor y no sean estables los niveles lógicos. De hecho he revisado alimentación y cambiado condensadores para subir unas décimas la tensión de +12Vdc. Todo sin conseguir resultados. 

Además, con todo, parece una respuesta intencionada de la máquina de cambio, puesto que se eleva el nivel de las líneas de inhibición para rechazar el billete. Pero, ¿cómo puede detectar esto la máquina si el billetero, funcionando en paralelo, y según el manual, no se lo comunica de ninguna manera?

Valoré que sea por el timing de las señales. Si el billete patina, tardará más de lo debido en entrar. Algo que la máquina sí puede medir. Pero las lineas de inhibición suben antes de que todo el billete entre. La linea de escrow permanece baja todo el tiempo y el exacto que el billete permanece atascado o patinando. Es decir, la máquina se da cuenta antes de que billete entre.

He consultado, y me sugieren que el problema no tiene solución. Que la máquina no adapta bien con los NV10. Y puesto que los Lumina se consideran obsoletos, la única opción es un kit de adaptación para otro modelo que no tengo. Es decir, que gastes  en un kit y en otro billetero...

Por curiosidad, reinstalo el Lumina viejo (original de la máquina) que no acepta billetes nuevos,  pero sí viejos. Y la observación, es que el billete entra mas suave que en el NV10, pero que si lo sujeto o freno lo suficiente, el mismo proceso, con las señales, se repite, y el billete también se lo traga.

 Acabo convencido de que la máquina tiene algún sistema de seguridad por software o hardware que no integra bien con el NV10. Sobre todo cuando ya no es  nuevo y no va fino. 

Pero la solución del kit me da una idea: puedo intentar hacerlo yo. 

No parece una cosa difícil. Con un Arduino puedo leer y aceptar primero el billete, siguiendo el protocolo estricto que marca el manual;  y cuando lo tenga dentro, pasarle, a la máquina, las señales apropiadas para que interprete la aceptación, ya sin "patinaje" ni "atasco" posible.  


A LA FAENA:

Así que me puse a la faena. Todo muy prototipo, sin intención de que fuese muy reproducible. Pero como finalmente ha salido factible y satisfactorio, he limpiado un poco el código (mi nivel de programación es limitada) y dejo por aquí mis notas, fotos y cositas (algunas algo cutres) para recordar, si hace falta en un futuro, volver a ello. O como siempre, por si a alguien más le sirve como aprendizaje. También valoraría, si alguien sabe como la máquina detecta la mala entrada del billete, algún comentario.

 

 

Pruebas y programación de Arduino como kit intermedio de adaptación

 

He usado un Arduino Nano. Las señales IN/OUT vistas desde el punto de vista del Arduno las he organizado como sigue:

 

------------------------------------------------------------------

DESDE CONECTOR NV10

IN                                                        OUT

D9 (pin12)-----ACCEPT1

D10(pin13)----ACCEPT2   

D11(pin14)----ACCEPT3

D12(pin15)----ACCEPT4

                       INHIBIT1---D4(pin7)

                       INHIBIT2---D5(pin8)

                       INHIBIT3---D6(pin9)

                       INHIBIT4---D7(pin10)

 

                       ESCROW---D8(pin11)

 

DESDE EL CONECTOR "A" LA MAQUINA 

IN                                                        OUT

                         ACCEPT1---D0(pin2)

                         ACCEPT2---D1(pin1)

                         ACCEPT3---D2(pin5)

                         ACCEPT4---D3(pin6)

D14-A0(pin19)--INHIBIT1

D15-A1(pin20)--INHIBIT2

D16-A2(pin21)--INHIBIT3

D17-A3(pin22)--INHIBIT4

 

D18-A4(pin23)--ESCROW

                        


                          LED---------D13(pin16,conectado internamente)

D19-A5(pin24); A6(pin25); A7(pin26)---Conectados a masa para prevenir ruido.

---------------------------------------------------------------

Aquí el esquema eléctrico de las conexiones. Puede descargarse aquí.

Esquema electrico del adaptador


 

Y aquí dejo el código. Puede descargarse también aquí.




/////////////////////////////////
// Sancos v0.3 28-01-2022      //
// Para adaptar poner un NV10  //
// en cambiadora AMYC MacMoney //
// GlobalChange, con original  //
// Lumina de Money Controls    //
//                             //
// El NV10 a pelo, si no va    //
// fino, cuando patina, la     //
// maquina por algun motivo    //
// baja señal de escrow y sube //
// inhabilitaciones. Y traga el//
// billete.                    //
//                             //
// Con Arduino manejaré NV10   //
// y luego pasaré los datos y  //
// timing directamente a la    //
// maquina sin funcionamiento  //
// ya del billetero            //
/////////////////////////////////
#define ARDUINO_NANO // Uso Nano. Cambiar si otro


#ifdef ARDUINO_NANO  //Añadir si otro
  #define ACCEPT1_NV10 9
  #define ACCEPT2_NV10 10
  #define ACCEPT3_NV10 11
  #define ACCEPT4_NV10 12
  #define INHIBIT1_NV10 4
  #define INHIBIT2_NV10 5
  #define INHIBIT3_NV10 6
  #define INHIBIT4_NV10 7
  #define ESCROW_NV10 8

  #define ACCEPT1_MAQ 0
  #define ACCEPT2_MAQ 1
  #define ACCEPT3_MAQ 2
  #define ACCEPT4_MAQ 3
  #define INHIBIT1_MAQ 14
  #define INHIBIT2_MAQ 15
  #define INHIBIT3_MAQ 16
  #define INHIBIT4_MAQ 17
  #define ESCROW_MAQ 18

  #define LED 13
#endif

void setup()
{
  pinMode(ACCEPT1_NV10,INPUT_PULLUP); //Accepts desde el NV10
  pinMode(ACCEPT2_NV10,INPUT_PULLUP);
  pinMode(ACCEPT3_NV10,INPUT_PULLUP);
  pinMode(ACCEPT4_NV10,INPUT_PULLUP);
  pinMode(INHIBIT1_MAQ,INPUT_PULLUP); //Inhibits desde maquina
  pinMode(INHIBIT2_MAQ,INPUT_PULLUP);
  pinMode(INHIBIT3_MAQ,INPUT_PULLUP);
  pinMode(INHIBIT4_MAQ,INPUT_PULLUP); 
  pinMode(ESCROW_MAQ,INPUT_PULLUP);   //Escrow desde maquina

  pinMode(ACCEPT1_MAQ,OUTPUT);  // Accepts hacia la maquina
  pinMode(ACCEPT2_MAQ,OUTPUT);  
  pinMode(ACCEPT3_MAQ,OUTPUT); 
  pinMode(ACCEPT4_MAQ,OUTPUT); 
  pinMode(INHIBIT1_NV10,OUTPUT);  // Inhibits hacia el NV10
  pinMode(INHIBIT2_NV10,OUTPUT);  
  pinMode(INHIBIT3_NV10,OUTPUT); 
  pinMode(INHIBIT4_NV10,OUTPUT); 
  pinMode(ESCROW_NV10,OUTPUT);    // 'ESCROW' hacia el NV10
  
  pinMode(LED,OUTPUT); // LED del arduino indicaciones de estado 
  digitalWrite(LED,LOW);
}

void loop()
{
  int billete;
 
  billete=DetectarBillete();
  if (billete)
    {
      if (ConfirmarBillete(billete)) TranspasoAMaquina(billete);        
    }
}




/*************************************/
/*            FUNCIONES              */
/*************************************/

int DetectarBillete()
{
  /*
   * Estado de reposo
   * NV10 espera a que "aparezca" un billete
   * ESCROW low, INHIBITS segun indique maquina
   * ACCEPTs a maquina HIGH
   * Pendiente de algun ACCEPT en NV10
   */
  int quelineaLOW;

  digitalWrite(INHIBIT1_NV10,digitalRead(INHIBIT1_MAQ)); // Acepta billetes
  digitalWrite(INHIBIT2_NV10,digitalRead(INHIBIT2_MAQ)); // según cambiadora
  digitalWrite(INHIBIT3_NV10,digitalRead(INHIBIT3_MAQ));
  digitalWrite(INHIBIT4_NV10,digitalRead(INHIBIT4_MAQ));
  digitalWrite(ACCEPT1_MAQ,HIGH); //Aseguro no datos a maquina
  digitalWrite(ACCEPT2_MAQ,HIGH); //mientras leo billetero
  digitalWrite(ACCEPT3_MAQ,HIGH);
  digitalWrite(ACCEPT4_MAQ,HIGH);

  digitalWrite(ESCROW_NV10,LOW);   //En disposicion usar ESCROW 
  quelineaLOW=LeerBill();
  return quelineaLOW;
}


int ConfirmarBillete(int billete_en_entrada)
{
  /*Un billete ha sido detectado en la entrada
   *Aceptarlo y pendiente de confirmar que entra a cajon
   */
  unsigned long tiempo; 
  tiempo=millis();
  
  digitalWrite(ESCROW_NV10,HIGH);  //Acepto billete
    do
      {
        /* 
         *  Perder tiempo hasta que se 
         *  confirme aceptacion billete
         *  LeerBill()=al billete_en_entrada de la lectura anterior
         */
      }
    while ((billete_en_entrada != LeerBill()) && ((millis()-tiempo) < 6000));
    if ((millis()-tiempo)>5999)
      {
        billete_en_entrada=0; //Algo paso, no valido
        digitalWrite(INHIBIT1_NV10,HIGH);   // Inhibiciones 
        digitalWrite(INHIBIT2_NV10,HIGH);   // todas HIGH. 
        digitalWrite(INHIBIT3_NV10,HIGH);   // Devuelve
        digitalWrite(INHIBIT4_NV10,HIGH);
        digitalWrite(LED,HIGH); //Marca error
        delay(31000);  //Mas de 30seg sin confirmacion NV10 intenta devolver
        digitalWrite(LED,LOW);
      }
  return (billete_en_entrada);  //paso billete admitido o 0 si fallo
      
}


int TranspasoAMaquina(int transBill)
{
  /*    
   * Inhibimos NV10 mientras    
   * transpasamos valor a maquina
   */
   int linAccept=0;

   digitalWrite(INHIBIT1_NV10,HIGH); //Inhibir NV10
   digitalWrite(INHIBIT2_NV10,HIGH);
   digitalWrite(INHIBIT3_NV10,HIGH);
   digitalWrite(INHIBIT4_NV10,HIGH);

   linAccept=transBill-1; // Calcula pin
   // Accept1-Pin0; ... Accept4-Pin3
   digitalWrite(linAccept,LOW); //Envio pulso billete
   delay(100);
   digitalWrite(linAccept,HIGH);
   
   do
   {
     //Esperar maquina accepte (ESCROW HIGH)
   }while (digitalRead(ESCROW_MAQ) == LOW);

   delay(1000); //simulo retraso entrar billete

   digitalWrite(linAccept,LOW); //Otro pulso confirma billete
   delay(100);
   digitalWrite(linAccept,HIGH);

   do
   {
     //Esperar maquina confirme aceptacion (ESCROW LOW)
   }while (digitalRead(ESCROW_MAQ) == HIGH);

   
   // Espero a volver el tiempo que tarda en pagar monedas
   delay(1500*(1<<linAccept)); //Aprox. 300ms por moneda
   //uso operacion de bits porque en C no funcion potencia
  
   return 0; //Proceso acabado.
}


int LeerBill()
{
        // leer lineas ACCEPT NV10, 
        // asegura pulso largo (activo LOW)
        // pasa valor 0(si no LOW) 1,2,3,4 (segun linea LOW)
    int linea[4]={ACCEPT1_NV10,ACCEPT2_NV10,ACCEPT3_NV10,ACCEPT4_NV10};    
    int lectura,i;

    for (int i = 0;i<=3;i=i+1)
    {
      lectura=digitalRead(linea[i]);
       if (lectura == LOW)
         {
           delay(50);
           if (lectura == digitalRead(linea[i]))
           //Si pulso largo
             {
              do
                {
                 // Pulso LOW, esperar a que HIGH
                }
              while (lectura == digitalRead(linea[i]));
              delay(10);
              return (i+1); // Pulso ACCEPT1  
             }
           else
             {
               //Pulso demasiado corto   
             }
         }
  
    }

    return 0; //No hubo pulso o fue corto
}
   


Para hacerlo físicamente he utilizado una stripboard porque solo se trata de un prototipo que no cuento reproducir. Una stripboard tiene los pads unidos en tiras. Uso un taladro para cortar las pistas en ciertos puntos (en mi esquemita particular "X" rojas) y con un cuter divido algunas pistas, perpendicularmente, para colocar los conectores IDC (líneas discontinuas rojas).

Mi esquemita stripboard para entenderme yo


Y su correspondiente acabado



Al voltear izquierda es derecha...


Y aquí ya, con el resultado final, colocación y pruebas a fondo....

Testeando todo con billete de 5€

Resultado final