Project tutorial
IoT for Coins

IoT for Coins © CC BY

Need to organize your coins? Get some help with this project.

  • 10,210 views
  • 1 comment
  • 49 respects

Components and supplies

Necessary tools and machines

Lasercutter
Laser cutter (generic)
3drag
3D Printer (generic)
09507 01
Soldering iron (generic)
Hy gluegun
Hot glue gun (generic)
Dremel Rotary tool

Apps and online services

About this project

Preview

IoT for Coins

I made an IoT APP for coin with sorter, with a lot of inspiration on Math and Physics, I made this because as maker I need an interactive way to make profit when going out to show projects, this can be a great add up for arcades, faires, or fashioned music player.

The chocolate Genuino Easter egg is a small reward you get if you manage to open the small door.

Install Arduino Software

You will need the Arduino IDE to program the Arduino, wich is the main program for this project.

Go to Arduino Download page

Install the Arduino/Genuino MKR1000

The Arduino/Genuino MKR1000 usually isn´t installed with the default IDE, so you will need to download and install the board, to do this follow these simple instructions.

Tools > Board > Board Manager... > MKR1000 > Install

At this point you can connect your Arduno MKR1000 to your computer, and upload the blink example to verify that you got connection. The LED for the Arduino MKR is on PIN 6.

You can use This Blink example.

void setup() {
     pinMode(6, OUTPUT);
   }
void loop() {
 digitalWrite(6, HIGH);
 delay(1000); 
 digitalWrite(6, LOW);    
 delay(1000);            
}

Using the Windows Remote Arduino Control

Go to Windows 10 Store and type Arduino, and download Windows Remote Arduino Control.

To use Windows Remote Arduino Experience you need to upload the Stardard firmata example.

Files > Examples > Firmata> StandardFirmata and play with Window 10 app

The standard Firmata works via USB @57600 

You can play with this handy APP time to time, specially to test sensors or pinouts without writing a lot of code.

WiFi

You will need to install some libraries so you can use the WiFi and the Microsoft Azure IOT, the default WiFi library doesn't work on the MKR1000

Scketch > Include Library > Manage Libraries ...

Install the Wifi101 and Azure IoT libraries.

To connect the WiFi use the Wifi101 Example, just keep in mind that you have to put your network settings on the Arduino IDE.

To get some fun, you need to find the following lines and overwrite to fit your network. sometimes if no pasword required (open network) you can put a bank password and still works.

char ssid[] = "yourNetwork";      // your network SSID (name)
char pass[] = "secretPassword";   // your network password

For the Windows Remote Arduino Experience you need to use the Standard Firmata WiFi and do some small changes. besides Network and password.

Find and uncomment the following line. You must have only one uncommented  option of 3. 

#define WIFI_101

On the Windows Arduino Remote Experience will ask you for IP and port, you can uncomment the following line to get your IP on the Genuino MKR1000, but by doing this, maybe you need to open the serial port before using Windows aRduino Experience... The port in this Firmata is 3030.

//#define SERIAL_DEBUG

AZURE IoT

Get an Microsoft Azure IoT account, i suggest you to do it with a Microsoft e-mail.

Get Azure Account

Once you created your suscription, look for a suscription token... don't share the number.

For the program, use the red maked, and the host name to publish. and the one on the right is your host page.

On Arduino IDE use the client to post on Azure as follows

   client.println("POST /tables/NameOFProject HTTP/1.1");
   //Host page name
   client.println("Host: internetofthingsservice.azure-mobile.net");
   //Token name
   client.println("X-ZUMO-APPLICATION: TokenMustbeSecretAllTimes456789");
   client.println("Content-Type: application/json");
   client.println("Content-Length: 97");
   client.println();
   client.println(bodyMessage);

On Body Message You put all the sensors and values you want.

Now with Microsoft Visual studio community can add more detailed data, there you work the GUI you want to show.

Download Visual Studio Community.

The design is simple, you just measure the coins you got, and you can open the door by solving math.

Now we will focus on the hardware setup.

Shield for the Genuino MKR1000

I like to use clamps and screws for projects so i decided to ask for a company to make a shield for me... and looks cool, mainly because not everything cames as jumpers, but wires are a lot more common.

Power Supply

Coin Acceptor works at 12V, Arduino/Genuino MKR1000 is 5V tolerant and the GLCD works at 3.3V so i used a computer ATX wich has a lot of different voltage levels, to make it work you need to put a little bridge as shown, between Enable (usually Green wire) to GROUND (any black wire).

This project uses 3 types of voltage, so i took the 12V (Yellow Wire), 5V (Red Wire) and 3.3V (Orange Wire) and GROUND (Black Wire). There are multiple same color wires but don-t worry it should work with 1 of each kind.

Get some generic extensions, wich are chea and keeps your ATX as it.

The shield for Arduino/Genuino MKR1000

The Coin Acceptor

Calibrate the coin acceptor.

I suggest to watch this video.

How to calibrate a coin acceptor

The coin acceptor i got can save up to 4 types of coins, you can tell by the label it has on the blue stamp.

Set the coin values as the coin, it will save you some code.

To read the pulses of the coin acceptor use the following instruction:

duration = pulseIn(CoinPin, HIGH);
 if(duration > 0){
   cash++;
   }else {
       if (t != cash) {
         Serial.println(cash);
           t = cash;
       }
   }

Print your mechanical coin sorter

Coin sorter for mexican pesos.

You can also use the customizer, there are a lot of avaible coin models, in case your coin type is not listed, you can print the one I created at Thingiverse Customizer:

Click here to print your coin sorter

Once you have printed your coin sorter, you can decorate it, you can find the sticker Cad at the files for this project.

The sound

Small sounds to make project a little more interesting, specially when accepting the coin.

How to connect ansimple audio amplifier on Arduino Zero

You must be careful where you connect the SD, because it doesn´t use the standard pins, it changes board to board. Genuino MKR1000 uses pins 8 to 12.

You can only play '.wav' files by now, you got 2 options:

  • Rename your tune/song to "test.wav"
  • Change the following code to fit
 File myFile = SD.open("test.wav");
 if (!myFile) {
   Serial.println("error opening test.wav");
   while (true);
 }

You can get a lot of different tunes on the following websites.

Freesound

Soundbible

Make sure you got 2 different SD card reader and multiple SD cards of different sizes, somehow this code is not perfect.

You can do all this or you can simply generate PMW tunes.

The Door Locker

Not everyone should open the coin aceptor so i put an web based coin acceptor

it needs a small power amplificator.

Now with the power amplificator you can play with it on Arduino IDE, you just need a Digital Output.

void loop() {
 digitalWrite(13, HIGH);   // OPEN
 delay(1000);              // wait for a second
 digitalWrite(13, LOW);    // CLOSED
 delay(1000);              // wait for a second
}

The GLCD

I wanted a little more than the clasic 12X2 LCD, so i decided to use Adafruit GLCD, for this case the library it is not on the manage librariesfrom arduino, so you need to download it from GitHub, the following steps are to make a power logic level, wich makes a 5V go down to 3.3V, this also could be done with resistors.

Wiring and important information for GLCD

I strongly suggest you to test on protoboard before cutom circuit boards.

Use the examples to test the GLCD, it has very handy ideas.

The code is somehow simliar to a normal LCD 12x2, but since it´s not that wide used needs a lot of imagination to code.

#include "ST7565.h"
ST7565 glcd(9, 8, 7, 6, 5);
void setup()   {                
 glcd.drawstring(0, 0, "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation");
 glcd.display();
 delay(2000);
 glcd.clear();
}

It can only use chars, so you need a lot of separators and complicated cleanup.

What does the GLCD prints?

  • Name of the project
  • IP Adress --- so you can view it online
  • Current cash collected.
  • Some dot art

The E-ink

When it cames to talk about IoT devices, you need to know where to connect, but it somehow gets complicated, so I decided to simplify the life of the users with and incredible E-ink display, i decided to use Badger wich is very friendly to certain point, since it's E-ink you can change it when in need, wich can be very handy for Iot Applications.

First we get an image using a QR generator

Click here to create your own QR code.

Once you got your QR code, you need to upload it to the Badger, you will need an GUI to get a special format WIF (Wyolum Image format) 

Upload images to Badger

Then you can either use an SD card or upload it via FTDI, i used the SD shortcut.

Now you can use any QR scan to simplify the life on your project.

Case

The main idea is to be open source so i put and acrylic frame so everyone can see the project, i didn't  used any CAD software to segign it, i just went somehow freestyle, and little by little the case was done, almost all the cuts are linear, so maybe can be donde to old school tecnique.

First you must measure the total dimensions you will need.

I printed some corner on 3D to keep aligned the case from start to end, and it gave a cool visual effect.

This is how it looks fully assembled, and clean.

Thanks for watching, hope to see more.

Code

IoT for CoinsArduino
The hybrid program for Azure via POST and arduino
// Erik Moran 
// IoT for Coins
//
// PINout
// pin 3 - Coin 
//
// pin 6 - GLCD
// pin 7 - GLCD
// pin 8 - GLCD
// pin 9 - GLCD
// pin 10 - GLCD
//
// pin 2 - r
// pin 1 - g
// pin 0 - b
//
// pin 5 - Locker
//
// pin 4 - Chip slct
// pin 10 - mosi /SD
// pin 8 - miso /SD
// pin 9 -sck /SD
//
// pin A1- Random seed.
//
// pin A0 - Buzzer-Sound
//

#include <SD.h>
#include <SPI.h>
#include <AudioZero.h>
#include <WiFi101.h>
#include "ST7565.h"

// Internet password
char ssid[] = "Network Name";     //  your network SSID (name) 
char pass[] = "Password";    // your network password
int keyIndex = 0;                 // your network key Index number (needed only for WEP)

int status = WL_IDLE_STATUS;
WiFiServer server(80);
String IP;

// Coin Acceptor
const int CoinPin = 3;     // the number of the pushbutton pin
int cash = 0;
int t = 0;

//Graphic Liquid Cristal display - GLCD
ST7565 glcd(10, 9, 8, 7, 6);
char Val[5]; 

unsigned long duration;

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status
int buttonState1 = 0;   

int vx;//variable x
int vy;//resultado
int vc;//constante
int vl;//A
int re;//respuesta del usuario
int st = 0;
//2 1 0 pines r g b
int pr = 2;
int pg = 1;
int pb = 0;

int locker = 5;

void setup() {
  Serial.begin(9600);
  
  pinMode(CoinPin, INPUT);

// GLCD background color
  pinMode(pr, OUTPUT);
  pinMode(pg, OUTPUT);
  pinMode(pb, OUTPUT);

  digitalWrite(pr, LOW);
  digitalWrite(pg, LOW);
  digitalWrite(pb, LOW);

  pinMode(locker, OUTPUT); //locker

  glcd.begin(0x18);
  //pon algo de IOT
  // delay(2000);
  glcd.clear(); 

  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    while (true);       // don't continue
  }

  // attempt to connect to Wifi network:
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }
  server.begin();                           // start the web server on port 80
  printWifiStatus();                        // you're connected now, so print out the status

  randomSeed(analogRead(1));
  genera_ec();//inicializa pw
}

void loop() {

// Read the pulse for coin
  duration = pulseIn(CoinPin, HIGH);
  if(duration > 0){
    cash++;
    }else {
        if (t != cash) {
          Serial.println(cash);
            t = cash;
        }
    }

  sprintf(Val, "%d", cash);

  char IPc[24];
  IP.toCharArray(IPc, 24);

  glcd.drawstring(0, 0, IPc);
  glcd.drawstring(0, 1, "IOT for Coins");
  glcd.drawstring(0, 2, "You have:");
  glcd.drawstring(0, 3, Val);
  glcd.display();
  //delay(2000);
  glcd.clear();
 
 // Serial.println(duration);

  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            
            client.print("<link rel=\"shortcut icon\" href=\"http://www.example.com/my_empty_resource\" />");
            client.print("<script src=\"//code.jquery.com/jquery-1.12.0.min.js\"></script>");
            client.print("<style>body {text-align: center; font-size: 18px; color: #333; text-shadow: 0px 0px 3px #ccc; font-family: Verdana;}</style>");

            client.print("Current cash:<br>");
            client.print(cash);

            client.print("<br/><br/>");
            if(vx != 1) client.print(vl);
            client.print("x");//vx
            if(vc < 0) {
              client.print("");
            } else {
              client.print(" + ");
            }
            client.print(vc);
            client.print(" = ");
            client.print(vy);
            client.print("<br/>x = <input type='text' id='respuesta' value=''/>");
            client.print("<input type='button' id='enviar' value='enviar'/>");

            /*
            client.print("<script>$(\"#respuesta\").keyup(function (e) {if (e.keyCode == 13) {window.location='http://'+self.location.hostname+'/'+String.fromCharCode(parseInt($(\"#respuesta\").val())+65);}});</script>");
            client.print("<script>$(\"#enviar\").click(function (e) {window.location='http://'self.location.hostname+'/'+String.fromCharCode(parseInt($(\"#respuesta\").val())+65);});</script>");
            */
            client.print("<script>$(\"#respuesta\").keyup(function (e) {if (e.keyCode == 13) {window.location='http://'+self.location.hostname+'/'+(parseInt($(\"#respuesta\").val())+65);}});</script>");
            client.print("<script>$(\"#enviar\").click(function (e) {window.location='http://'self.location.hostname+'/'+(parseInt($(\"#respuesta\").val())+65);});</script>");
            client.print("<script>$(\"#respuesta\").focus();</script>");

            // The HTTP response ends with another blank line:
            client.println();
            digitalWrite(pg, LOW);
            digitalWrite(locker, LOW);//abre locker
            // break out of the while loop:
            break;//!!!
          }
          else {      // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        }
        else if (c != '\r') {    // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was correct or wrong.
        if (currentLine.endsWith("GET /HH")) {
          digitalWrite(locker, HIGH);            
        }
        if (currentLine.endsWith("GET /LL")) {
          digitalWrite(locker, LOW);            
        }
        if (currentLine.endsWith("GET /"+String(vx+65))) {
        //if (currentLine.endsWith("GET /"+int(vx))) {
            st = 1;
            genera_ec();
            digitalWrite(pg, HIGH);
            digitalWrite(locker, HIGH);//abre locker
          }
          if (currentLine.endsWith("GET /NN")) {
            st = 1;
            genera_ec();
          }
          if (currentLine.endsWith("GET /RR")) {
            client.print("<br/>*<br/>");
            client.print(vx);
            client.print("<br/>*<br/>");
            client.print(String(vx+65));
            client.println();
            
            //digitalWrite(pg, HIGH);
            //digitalWrite(locker, HIGH);//abre locker
          }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
 
}


String DisplayAddress(IPAddress address)
{
 return String(address[0]) + "." + 
        String(address[1]) + "." + 
        String(address[2]) + "." + 
        String(address[3]);
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
  IP = DisplayAddress(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  // print where to go in a browser:
  Serial.print("To see this page in action, open a browser to http://");
  Serial.println(ip);
}



void genera_ec() {
  vx = random(0, 9);
  vc = random(-20, 20);
  vl = random(1,5);
  vy = (vl*vx)+vc;
  re = 0;
}
GLCD library
This is the library for the GLCD from Adafruit.

Custom parts and enclosures

Corner for 3D print
Print 4, made for 3mm acrylic.
I created this one for 3D printing, for both screens i use
Door lock
3D print and use for 3mm Acrylic
Coin Separator for mexican pesos
Coin sorter customized for mexican pesos.
Vynil sticker
Stickr for Schoredinger bank
CORTE.dxf

Schematics

Image for the schematic
This is the wiring for this project ---> Use MKR1000 instead of YUN
Iotforcoins
IoT for Coins
Schematic for this project.
IoT%20for%20Coins.fzz

Comments

Author

Photo
Erik Moran
  • 1 project
  • 10 followers

Additional contributors

Published on

April 1, 2016

Members who respect this project

Interaktiv1912475 792704737425815 138752803 n10408674 10153452711554057 4965803323759327740 n11755075 938403819539167 7064064151652121375 nCmDefault330ohms10857894 934370856581578 5526446785117607631 n

and 41 others

See similar projects
you might like

Similar projects you might like

GPS Datalogger, Spatial Analysis, and Azure IoT Hub.

Project tutorial by Shawn Cruise

  • 21,525 views
  • 4 comments
  • 79 respects

TIA Weak Artificial Intelligence IoT Assistant

Project tutorial by Adam Milton-Barker

  • 4,438 views
  • 0 comments
  • 23 respects

IoT PCR: Low Cost DNA Replication Connected to the Internet.

Project showcase by kemfic

  • 10,511 views
  • 0 comments
  • 32 respects

Modular Smart-Home IoT Node

Project showcase by Team id-IOT

  • 5,521 views
  • 2 comments
  • 24 respects

Thundercatch IoT Network

Project tutorial by Christos Chatzigeorgiou

  • 3,625 views
  • 1 comment
  • 10 respects
Add projectSign up / Login