Proyecto Monedero

Bueno. Como suponía, el resto de pines no tienen (y lo más importante, no tendrán) influencia en los valores. Se podría haber simplificado más aún, utilizando los pines de un puerto determinado y leyendo el puerto directamente, pero como no tenía seguro el extremo anterior, lo hice un poco más abierto. Más sencillo, incluso, si estuvieras dispuesto a cambiar la nomenclatura de tus leds para quitar los huecos.
Prueba a ver este código. Compila, aunque está sin probar; pero debería hacer algo.

#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// ESTADO DE LOS LED. SI NECESITAMOS MÁS DE 8 HAY QUE CAMBIAR TIPO A INT
byte estaoLeds=0;

struct {
      byte numeroLed;
      int pin;
} leds [] = {
      {3, 41}, {4, 43}, {5, 45}, {7, 47}, {8, 49}, {9, 51}, {10, 53}
};

const byte totalLeds = sizeof(leds)/sizeof(leds[0]);

void setup()
{
      lcd.begin(16, 2);           // Fijamos el numero de caracteres y filas
      lcd.clear();
      lcd.print("    PROBADOR ");  // Aqui va la primera linea con mensaje en espera
      lcd.setCursor(0, 1);    // Ponte en la linea de abajo 1, posicion 5
      lcd.print("   DE MONEDAS "); // Aqui va la segunda linea con mensaje en espera
      delay(2000);
      lcd.clear();

      for(int i=0; i<totalLeds; i++){
            pinMode(leds[i].pin, INPUT);   
      }
}

void loop()
{
      byte nuevoEstadoLeds=0;
      for(int i=0; i<totalLeds; i++){
            // Si el led está en HIGH, establecemos el bit correspondiente en nuevoEstado
            if (digitalRead(leds[i].pin)) {
                  bitSet(nuevoEstadoLeds, i);
            }
      }

      // Si ha cambiado algún bit, refrescamos la pantalla
      if (estaoLeds != nuevoEstadoLeds) {
            estaoLeds = nuevoEstadoLeds;
            refrescaPantalla();
      }
}

void refrescaPantalla(void)
{
      lcd.setCursor(0, 0);
      lcd.print(" SALIDAS ");
      for(int i=0; i<totalLeds; i++){
            if(bitRead(estaoLeds, i))
                  lcd.print( leds[i].numeroLed);
            else
                  lcd.print(" "); 
      }
      lcd.setCursor(0, 1);
      lcd.print("    VALOR ");
      lcd.print(estaoLeds);
      delay(1000);
}

Prueba y comenta.
Saludos.

Surbyte, creo que no habéis entendido que el monedero coge los 12v para su funcionamiento aparte y solo para eso una vez funciona no actúa para nada esos 12v con el Arduino , para dar señales usa los pines gnd y salida que son unos 2 o 3 v

Noter: Luego lo pruebo ahora no tengo PC estoy con móvil , creo que me estás entendiendo perfectamente, donde pongo texto VALOR es para poder poner valor de la moneda según combinación de salidas , en el primer post pongo la combinación que existe . Al encender el aparato: “ PROBADOR “ “ DE MONEDEROS “ Mientras no se introduzcan monedas: “ INSERTE “ “ MONEDAS “ Si se introduce una moneda 0,05 “ SALIDAS 3 4 7 “ “ VALOR 0,05 ctm “ Así me gustaría quedarlo

A ver.. llevamos 21 post intentando entenderte!! Entonces el que no sabe explicarse eres tu.

Dime donde dices que la salida entrega 2 a 3V?

Aun ahi no hay drama en usar los optos, mejor aun ya que con 2V no podras accionar la entrada del arduino. Con 3 vaya y pase, estas en el limite de lo que se llama tensión de entrada minima nivel Alto.

Con 2 o 3 V en las salidas de tu monedor a probar, usas una R de

R = (2-1.5)/10mA = 50 ohms o sea 47 ohms e irá bien.

El resto como ya te indiqué.

Perdónarme por no explicarme bien y sobre todo por no saber nada de nada , llevo unos 7 días con el tema Arduino , antes ni sabia ni que era y me cuesta entender y explicar lo que quiero por mí más alta torpeza. El código que puse que después borré y el que tengo ahora en el hilo es de mucho ver vídeos y sacar pequeños conceptos , algunos de ellos los entiendo y otros no. Gracias por la ayuda y gracias por la paciencia

noter: Prueba y comenta.

NO ME FUNCIONA, al iniciar me da el mensaje de bienvenida y despues me sale : salidas 3457891 valor 127 si introduzco una moneda me borra las salidas correspondientes bien menos la 3 que no hace nada y en la fila de abajo en valor me pone valor y unos datos que no comprendo segun moneda pone de menos a mas 101,111,117,119

¿Quieres decir que las salidas están invertidas? ¿Que en lugar de encender el número correspondiente se apaga? En cuanto a lo del led3, revisa la definición a ver si lo tienes conectado al pin correspondiente. Cada una de las parejas indica el nombre (número) de led y el pin al que va conectado:

      {3, 41}, {4, 43}, {5, 45}, {7, 47}, {8, 49}, {9, 51}, {10, 53}

así que el led3 irá en pin 41, el led 4 en 43, etc. El número que aparece en valor, no te preocupes. Una vez que se representen los pines correctamente en la línea superior, te contaré cómo trabajar con ese valor.

noter: ¿Quieres decir que las salidas están invertidas?

Eso es he cambiado esto y ya funciona menos el 3 que no se que pasa, estan bien la salida a su sitio if(bitRead(estaoLeds, i)) lcd.print( " ") else lcd.print( leds*.numeroLed);*

Prueba a ver de esta otra forma. He cambiado tres cosas:

  • He invertido la lógica (como has hecho tú, pero en la lectura, en lugar de en la impresión).
  • He agregado un espacio más si el número a tapar es el 10 (son dos cifras a borrar).
  • He quitado la pausa, a ver si es la causa de que no aparezca el 3.
#include <LiquidCrystal.h>

LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// ESTADO DE LOS LED. SI NECESITAMOS MÁS DE 8 HAY QUE CAMBIAR TIPO A INT
byte estaoLeds=0;

struct {
      byte numeroLed;
      int pin;
} leds [] = {
      {3, 41}, {4, 43}, {5, 45}, {7, 47}, {8, 49}, {9, 51}, {10, 53}
};

const byte totalLeds = sizeof(leds)/sizeof(leds[0]);

void setup()
{
      lcd.begin(16, 2);           // Fijamos el numero de caracteres y filas
      lcd.clear();
      lcd.print("    PROBADOR ");  // Aqui va la primera linea con mensaje en espera
      lcd.setCursor(0, 1);    // Ponte en la linea de abajo 1, posicion 5
      lcd.print("   DE MONEDAS "); // Aqui va la segunda linea con mensaje en espera
      delay(2000);
      lcd.clear();

      for(int i=0; i<totalLeds; i++){
            pinMode(leds[i].pin, INPUT);   
      }
}

void loop()
{
      byte nuevoEstadoLeds=0;
      for(int i=0; i<totalLeds; i++){
            // Si el led está en LOW, establecemos el bit correspondiente en nuevoEstado
            if (!digitalRead(leds[i].pin)) {
                  bitSet(nuevoEstadoLeds, i);
            }
      }

      // Si ha cambiado algún bit, refrescamos la pantalla
      if (estaoLeds != nuevoEstadoLeds) {
            estaoLeds = nuevoEstadoLeds;
            refrescaPantalla();
      }
}

void refrescaPantalla(void)
{
      lcd.setCursor(0, 0);
      lcd.print("SALIDAS ");
      for(int i=0; i<totalLeds; i++){
            if(bitRead(estaoLeds, i)) {
                  lcd.print( leds[i].numeroLed);
            }
            else {
                  lcd.print(" ");
                  // otro espacio para tapar el 10
                  if (leds[i].numeroLed>=10)
                        lcd.print(" ");
            }
      }
      lcd.setCursor(0, 1);
      lcd.print("VALOR: ");
      lcd.print(estaoLeds);
}

Prueba y cuenta.

noter: Prueba a ver de esta otra forma. He cambiado tres cosas: - He invertido la lógica (como has hecho tú, pero en la lectura, en lugar de en la impresión). - He agregado un espacio más si el número a tapar es el 10 (son dos cifras a borrar). - He quitado la pausa, a ver si es la causa de que no aparezca el 3. nada incluso peor, por quitar la pausa, la salida 10 me da igual que sea 0 si es mas facil, mejor sin pausa

No entiendo tu última respuesta. ¿Puedes detallar un poco más lo que ocurre?

EL 3 sigue sin salir y al quitar la pausa se queda el lcd dando salidas en blanco hasta que meto moneda que da las salidas correctas menos el 3 que no lo da y abajo simpre pone un valor, lo de abajo como me has dicho antes ya lo veremos pero la 3 no sale nunca, a menos que meta muchas veces la misma moneda que rara vez si lo da

No te preocupes pero te das cuenta que no estamos en tu cabeza asi que de haber leído bien las normas, hubieras entendido lo importante que es explicar bien toda la idea y su contexto pero bueno ya se comprende.

Tenemos un monedero alimentado x 12V que realmente a nosotros no nos importa ( a ti si claro). Las salidas a probar/detectar entregan tensiones de entre 2 a 3V. Necesitamos que se visualicen en un LCD. El código hecho por noter seguramente funciona bien.

Esto

struct {
      byte numeroLed;
      int pin;
} leds [] = {
      {3, 41}, {4, 43}, {5, 45}, {7, 47}, {8, 49}, {9, 51}, {10, 53}
};

es una estructura que contiene el número de Led y el Pin con el que se detecta. numeroLed Pin 3 41 4 43 5 45 7 47 8 49 9 51 10 53

Esa estructura se identifica por led y cuenta con dos valores i,j

que van de 0 al máximo entonces el leds[0][0] = 3 y en cambio leds[0][1] = 41 para terminar leds[6][0] = 10 leds[6][1] = 53

eso para que entiendas mejor como funciona la estructura.

se que empece mal explicando, y ya me disculpe y vuelvo a hacerlo.... mas o menos entiendo lo que me dices pero no acabo de entender por que el 3 no llega a salir, y si quito todas las entradas menos esa ( 3 ) si que funciona sola...... espero explicarme bien

Pues te comento, pero primero una pregunta: ¿Cuánto tiempo permanecen los led activados tras detectar una moneda? Creo que el código funciona correctamente. Hace un barrido de los pines de entrada y los anota en valor. Pensé que tal vez lo que ocurría era que cuando se producía el cambio era a mitad de barrido, y por lo tanto sólo se anotaban los cambios en los pines posteriores del barrido. Al estar la pausa de un segundo, se estaría mostrando, por tanto, el valor erróneo durante todo ese segundo. Sin embargo, al quitar la pausa, aunque puede producirse ese mismo error en la primera lectura, inmediatamente se hace otro barrido que debería leer los valores correctos. Me decanto a pensar que puede ser entonces problema hardware. Máxime si estás trabajando con voltajes en el límite de detección (entre 2V-3V no está bien definido el estado de una entrada. HIGH y LOW deberían estar por encima y debajo de esos valores). Además, en contra de la lógica "natural" estamos recibiendo lógica invertida. Aunque eso es fácil de solventar, como hemos visto, si lo has hecho así "sin querer" tal vez tu esquema de conexión no sea el correcto. Intenta explicar un poco más detalladamente tu esquema de conexión y seguro que surbyte u otro forero (yo no, tristemente :-[ ) te podrá asesorar en ello.

Ya lo dije antes. si no usa un adaptador de nivel apropiado, eso no va a funcionar.