Hucha inteligente cuenta monedas
Introducción
Los motivos que nos llevaron a iniciar este proyecto fue que nos hemos dado cuenta de que las huchas están pasando de moda y, de esta manera, se podrían reinventar.
La idea principal de esta hucha es que te ayude a llevar la cuenta del dinero que vas depositando, pero tiene algunas peculiaridades como que está pensada para ahorrar. Como veremos más adelante, cuando la abramos el contador se reiniciará a cero, por lo tanto, evita posibles tentaciones de coger dinero.
Desde el enfoque del usuario, el esquema general de la hucha se basa en una pantalla led que nos indica qué monedas hemos introducido, así como el total y un sensor ultrasónico que detecta si le hemos puesto la mano para abrirla. Internamente también hace uso de una rampa con agujeros para poder clasificarlas, sensores infrarrojos para detectar las monedas que caen, y un servomotor para poder mover la puerta.
Reparto de tareas
En este aspecto, prácticamente todo lo que hemos hecho ha sido de manera conjunta quitando días puntuales en los que alguno ha trabajado por su cuenta en casa.
El tiempo que hemos empleado supera las 30 horas, que aunque pueden parecer muchas, han sido las necesarias por los problemas que os contaremos a continuación.
Presupuesto
Módulo LCD I2C 16×2 | 7,88€ |
40 cables extensiones | 3,25€ |
Caja de madera | 11,95€ |
Imprimir billetes falsos | 0,96€ |
Sensor infrarrojos FC-51 x10 | 7,99€ |
Cámara OV7670* | 6,99€ |
Sensor de color TCS3200* | 11,49€ |
TOTAL | 32,03€ |
Materiales
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/71KVyWDHkaL._AC_SY450_.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/71pgX9Hhv8L._SX342_.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/81svn3QK-L._AC_SY355_.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/sensor-fc-51-detector-obstaculos-por-infrarrojos-para-arduino.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/p_6_8_1_681-40-CABLES-MACHO-HEMBRA-10cm-jumpers-dupont-254-arduino.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image_1024.jpeg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image-15.png)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image-17.png)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image-18-1024x866.png)
Necesidad que resuelve
La idea principal de esta hucha es que te ayude a llevar la cuenta del dinero que vas depositando, pero tiene algunas peculiaridades:
- Está pensada para ahorrar. Como veremos más adelante, cuando la abramos el contador se reiniciará a cero, por lo tanto, evita posibles tentaciones de coger dinero.
- Las huchas se están pasando de moda y esta es una manera de reinventarlas.
Problemas
A lo largo del transcurso de la práctica nos fueron surgiendo varios problemas que nos hicieron cambiar el enfoque del proyecto.
Primera idea: Hucha cuenta-monedas con ML
En primer lugar queríamos hacer una hucha que reconociera las monedas mediante Machine Learning. Investigando, vimos que la placa de Arduino Uno R3 no tiene la suficiente potencia como para procesar imágenes desde ahí. Entonces, compramos una cámara OV7670 con el objetivo de enviarle las imágenes al ordenador y que desde ahí se hiciera el procesado.
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image6-edited-1024x1024.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image2-edited.png)
Al seguir varios tutoriales, ya que no queríamos desechar la idea tan rápido, vimos uno que incluso dejaba verlo en color. Este fue el que mejor nos funcionó – algo se conseguía ver. Pero al montar el circuito y ver cómo era la imagen, no se conseguía distinguir nada, por lo que decidimos no seguir con esta idea porque era invertir tiempo en vano.
Segunda idea: Hucha cuenta-billetes con colorímetro
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image1-2-edited-1024x1024.jpg)
Después de esto, decidimos contar billetes en vez de monedas. Para esto, queríamos usar un colorímetro con el fin de leer el color de los billetes. Compramos un colorímetro TCS3200 y lo configuramos para que nos imprimiera por el monitor de Arduino los valores que leía, para luego así establecer los rangos y clasificar los billetes.
No funcionó, ya que el colorímetro siempre nos daba resultados muy cercanos a colores verdes, aunque le pusiéramos un objeto completamente rojo, así que volvimos a desechar la idea.
Tercera idea: Hucha cuenta-monedas con una rampa
Al final nos decidimos por hacerlo a la vieja usanza, usando una rampa con agujeros. Como las monedas tienen tamaños muy parecidos y las diferencias son milimétricas, pensamos en encargárselo a una tienda de impresión 3D. Lo que nos entregaron tuvo varios problemas como se puede ver.
Decidimos hacerla con un contrachapado, haciendo los agujeros y limando hasta que entrasen bien.
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image8-1-768x1024.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image7-edited-1024x1024.jpg)
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image4-edited-1024x1024.jpg)
Problemas con la detección de las monedas
Cuando nos propusimos detectar las monedas que caían utilizando los infrarrojos, encontramos un obstáculo importante: la velocidad de las monedas era demasiado rápida para ser detectada por los sensores.
Intentamos utilizar interrupciones para resolver el problema, usando el método attachInterrupt(), lo cual funcionaba perfectamente. Sin embargo, descubrimos que Arduino Uno solo las controla en los pines 2 y 3, lo cual no era compatible con los que necesitábamos.
Finalmente, investigando dimos con la librería digitalWriteFast que nos permitió realizar las lecturas con mayor rapidez.
Circuito
![](https://blogs.etsii.urjc.es/dseytr/wp-content/uploads/sites/8/2023/05/image5-1-1024x547.png)
Código
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <digitalWriteFast.h>
const int irSensor1 = 2;
const int irSensor2 = 4;
const int irSensor3 = 8;
const int irSensor4 = 10;
const int irSensor5 = 7;
const int irSensor6 = 9;
Servo servoMotor;
const int Trigger = 6;
const int Echo = 5;
#define SERVO_PIN 12
LiquidCrystal_I2C lcd(0x27, 16, 2);
float count = 0.00;
bool open = false;
En primer lugar, incluimos las cuatro librerías que nos hacen falta, definimos todos los pines necesarios e inicializamos las constantes globales que vamos a usar.
void setup(){
Serial.begin(9600);
servoMotor.attach(SERVO_PIN);
pinMode(Trigger, OUTPUT);
pinMode(Echo, INPUT);
digitalWrite(Trigger, LOW);
servoMotor.write(0);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Bienvenido!");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Total: ");
lcd.setCursor(7, 0);
lcd.print(count);
}
A continuación, en la función setup, que solo se ejecutará una vez al comienzo de la ejecución, inicializamos la pantalla LCD, el servo motor y el sensor ultrasonido. Mostramos por la pantalla un mensaje de que se mantiene tres segundos y cambiamos al contador.
void loop(){
if (Serial.available() > 0) {
int valor = Serial.read();
if (valor == 'c') {
count = 0;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
}
int state1 = digitalReadFast(irSensor1);
int state2 = digitalReadFast(irSensor2);
int state3 = digitalReadFast(irSensor3);
int state4 = digitalReadFast(irSensor4);
int state5 = digitalReadFast(irSensor5);
int state6 = digitalReadFast(irSensor6);
if (state1 == LOW) {
count = count + 0.1;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
if (state2 == LOW) {
count = count + 0.05;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
if (state3 == LOW) {
count = count + 0.2;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
if (state4 == LOW) {
count = count + 1;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
if (state5 == LOW) {
count = count + 0.5;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
if (state6 == LOW) {
count = count + 2;
lcd.setCursor(7, 0);
lcd.print(count);
delay(1000);
}
long duration;
int distance;
digitalWrite(Trigger, HIGH);
delayMicroseconds(10);
digitalWrite(Trigger, LOW);
duration = pulseIn(Echo, HIGH);
distance = duration * 0.034 / 2;
if (distance < 10 and !open) {
count = 0;
lcd.setCursor(7, 0);
lcd.print(count);
open = true;
servoMotor.write(80);
delay(1000);
}
else if (distance < 10 and open) {
open = false;
servoMotor.write(0);
delay(1000);
}
delay(500);
}
Por último, la función loop que la dividiremos en tres:
- Primero un condicional if, que nos permite resetear el contador por teclado cuando la placa está conectada a un ordenador, en caso de estar conectada a una pila nunca se ejecutaría, al leer el carácter «c» el contador se pone a cero.
- Después tenemos la lectura de cada uno de los seis sensores infrarrojos y sus correspondientes condicionales, en los que si alguno detecta un valor «LOW» entraría por él, sumaría el valor correspondiente al contador, mostraría por la pantalla LCD la moneda detectada y actualizaría el total.
- Finalmente, la parte del código correspondiente al sensor ultrasonidos y al servo motor. Enviamos pulsos ultrasónicos y se leen continuamente los valores que recibimos, los transformamos a distancia con la fórmula y si esta es menor de 10 centímetros hacemos girar el servo motor 80 grados. Para identificar el estado de la tapa tenemos la variable «open», si la tapa estuviera abierta (open = true), la cerraríamos, de lo contrario (open = false), la abriríamos.
Posibles mejoras
- Las implementaciones que nos han dado problemas.
- Meter una alarma sonora que se reproduzca una melodía cuando se llegue a múltiplos de 100 por ejemplo.
- Agregar un teclado y poder configurar tu la cantidad de dinero que quieres poner como objetivo.
- Adaptar el contenedor donde caen las monedas y agregar un botón que al pulsarlo activase un servo motor que levantaría la base haciendo que cayesen las monedas fuera de la hucha para poder sacarlas.