Saturday, July 30, 2011

Arduino Vending Machine: 2 - Accepting Dollar Bills


Updated - (8/1/2012)!
Summary
This is a tutorial of how to use an Arduino to count the number of dollar bills accepted by a bill validator (BA-30).

Description
This tutorial is about using an Arduino to count dollars that were accepted by a bill validator. This is a common type of bill validator used in machines that take money and give something (vending machines).  The goal is to connect the bill validator to the Arduino and be able to know when a dollar bill has been accepted.

Specifically, we will use an Arduino to read pulses from a bill validator.  Normally, the pulses read from the bill validator will be in the range of 8000 to 9000.  When we insert a dollar bill into the bill validator and the bill validator accepts the bill, we will be able to read pulses above 12000 from the bill validator.  Given this, we can tell when a bill is accepted.
If (duration > 12000)
{
     billCount++;
}

Before we begin
Divide and Confuse...
In many forums around the web, there is great interest in how to use an Arduino to accept cash.  Unfortunately,  there is very little concrete information about how to it.  What's worse is that these devices, bill validators and coin mechanisms, use different protocols.  Many devices that share a common protocol share the Multi-Drop Bus (MDB) protocol which uses a 9-bit word.  Enough said.

Bill Validator explained
The bill validator takes dollar bills.  For the most part, all it does is take money in paper form, validate it (make sure it is real), store it, and report that one piece of money (of a certain value) has been accepted.  The bill validator is also known as a bill acceptor or that thing that takes dollars (or other appropriate local currency).

The idea for everything is simple, we are just listening for when the bill is accepted.  We are using the Arduino to listen to the bill validator.  The bill validator has all of the logic to know when it has accepted the paper currency.  In the case of this tutorial, we are using the BA-30, made by Coinco.  The nice thing about the BA-30 is that it provides us with two ways to listen to it.  The first is using pulses and the other is using the MDB protocol.  We will be using the pulses.

Safety (always)
"You gotta play it safe around the power lines" - Louie T.L. Bug
Experimenting with the combined equipment of an Arduino, bill validator, and computer can cause harm to you or your equipment under certain situations.  Here's some items to consider for some of the components involved.

Bill Validator
In order to power the bill validator, you will need to hook it up to power from an outlet.  It is relatively simple but if you don't feel comfortable, don't do it.  Find someone that has done something similiar and have them help you.

D.) Other
This is the other category.  This is all meant to be fun.  When experimenting, there may be times you feel uncomfortable or unsafe about doing something in a project.  At times like these, find a person, forum, or group (Arduino forums linked) to ask and make your situation safe at all times.

Steps
Control the ESC/Motor using an Arduino
  1. Setup the bill validator.
  2. Connect the bill validator to Arduino.
  3. Upload your sketch to the Arduino.
  4. Use a dollar and watch for the output.


Begin
1. Setup the bill validator.

Figure 1.1 - The pins

We are going to work with the pins A through F {A,B,C,D,E,F} as these are for pulses.  Disregard the pins G through K as they are for MDB and aren't covered in this tutorial.

As you can see from Figure 1.2, I use a wire harness for the BA30.  You can find them on the internet.  If you are looking for them, search for "BA30 wire harness" or "BA30 coinco wire harness". As long as one end goes to the BA30, you don't really care what the other end goes to.

 First we need power.  Power the BA30 with main (110V) power.  NOTE: Power from an outlet can kill you.  Don't attempt this if you don't know how to be safe.  There is a picture below with all of the pins labeled (Figure 1.1).  This picture is from the kegbot blog at: http://kegbot.blogspot.com/2004/11/coinco-magpro-mag50b-pinout.html Take the line of a power cord and splice the hot into "110VAC Hot" (on the picture it's pin F), and again splice the hot into the "Hot Enabled" (on the picture it's pin E).  Take the line's neutral and splice it into "110VAC Neutral" (on the picture it's pin C).

Figure 1.2 - Sideview with pins labeled




2. Connect the bill validator to the Arduino
According to the diagram in Figure 1.1, the bill validators pin labeled "A" is the "cr-" line.  It is difficult to see but the line is green.  Take this line from the bill validator and put it in the Arduino pin #7 (this is the pin used in the sketch).  The next line we need from the bill validator is labeled "B" or the "cr+" line.  This line needs to tie into the +5v as shown below (Figure 2.1)

Figure 2.1 - Connecting bill validator to Arduino

3. Upload you sketch to the Arduino
The hard part is over.  Upload the following sketch to your Arduino:


/*
* Sean
* globalw2865@gmail.com
* 30JUL2012
* Bill validator/Arduino (second draft)
*/

/*
* RESOURCES:
* http://www.arduino.cc/en/Reference/PulseIn
* http://kegbot.blogspot.com/2004/11/coinco-magpro-mag50b-pinout.html
* http://www.coinco.com/coin/faq/servicematerials/921970_1.pdf
*/

/*
* Description:
* Arduino records and counts dollar bill received from pin 7 (billValidator).
*/

// Constants //
// pin for the bill validator's credit(-) line
const int billValidator = 7;

// Variables //

// recording the duration of pulse (milliseconds)
unsigned long duration;

// holding the total dollars recorded
int dollarCounter = 0;

void setup()
{
  // Pin setups for bill validator and button
  pinMode(billValidator, INPUT);
 
  // Initialize serial ports for communication.
  Serial.begin(9600);
  Serial.println("Waiting for dollar...");
}

void loop()
{
  // get the duration of the pulse
  duration = pulseIn(billValidator, HIGH);
   
  // Receiving a dollar bill will create a pulse
  // with a duration of 150000 - 160000.
  // NOTE: When there is no dollar bill pulse,
  // I will receive a pulse of 8400 - 8600
  // on every loop.
  // Dollar received
  if(duration > 12000)
  {
  // Count dollar
  dollarCounter++;
  // Checking for understanding
  Serial.print("Dollar detected.\n Total: ");
  // Display new dollar count
  Serial.println(dollarCounter);
  }
     
}


4. Use a dollar and watch for the output

First dollar (Figure 4.1)

Figure 4.1


Second dollar (Figure 4.2)

Figure 4.2


5. Done
The tutorial is fairly simple.  Many thanks to anyone who has corrected me.  Also, if anyone is interested in this, you will probably be interested in the posts on the Bounis Blog.  They go into detail on the MDB protocol (well done).




Sunday, July 17, 2011

(Tablet + Elm327) / Bluetooth = cool

Lame title but interesting project. The idea is simple, take the data from your car and display it on something.  The data from your car is in the form of ODB-II protocols.  I started the project by messing around using a product called the Elmscan 5 from www.scantool.net/elmscan-5-usb.html.  With some pretty good success getting the RPM's using the Elmscan5, a laptop, and C#, I wanted to take it just a step further.  No cords, a better screen, and a touch screen would be helpful additions.

Got myself an ODBII reader with Bluetooth from amazon...  I'm not confident in the reader I bought but it has worked at times.  A picture of it is included here.  I'm only buying from scantool as their products are reliable.  At any rate, the ODBII reader with Bluetooth with get the serial data broadcast to us without wires.
 
For the other half, a tablet.  I've been waiting to buy an Android tablet and finally settled on the Toshiba thrive.  The program used to test the ODBII reader was a neat program called "Torque" by Ian Hawkins at torque-bhb.com.  I got the paid version, it is worth the money.  I think the developer did a great job.  I got the engine codes, RPM's, and a variety of other data from the car.

As I do more, there will be more.  Plans are to write for the Elm327 through Bluetooth, on my off time.

Friday, July 8, 2011

Project 1 - Arduino Accepting Coins

I am unable to finish this sketch at the moment.  I have run into trouble listening for the interrupt, pulling the send line to low, and listening on the data line (at 600bps) for binary.  Any assistance, advice, or anything that helps would greatly help.  In the meantime, I can control the solenoids that dispense change using the code below.  Have fun and thank you

Update 11/5/11: The MDB RS-485 is a 9-bit protocol.  It's really not cool.  8 regular bit and a mode bit to make an address or data byte.  This is in addition to the obvious start and stop.  There's not a ton of material to make something read this.  It sounds like one of those do it yourself without reference material.

2/23/12:  Still work in progress, no positive results.

SUMMARY:  This post focuses on one of the many devices that accepts coins, known as the coin mechanism, and how to get it to work with an Arduino.


Material from coinco:

I. Valid Coin
  1. The valid coin status message defines the value of the

valid coin, the status of the coin tube sensors, and the destination of the valid coin (cash box or inventory
tubes).
  1. The changer will attempt to validate coins and transmit

the information to the external controller if the external controller is not requesting information from
the changer (i.e. the accept enable input line is low and
the send input line is high,
see Table 7 Sections I B and
C respectively) and the changer is not in the process of sending information to the external controller (i.e. the interrput output line is high and the data output line is high. See Table 7 Sections II A and B respectively).
  1. If the coin is valid then a single message will be sent to the external controller from the changer as follows:
  1. The interrupt output line will be pulled low by the
changer indicating to the external controller a
message is ready to be transmitted.
  1. The external controller will acknowledge the

interrupt output request within 5 MSEC +/- .5 MSEC
by pulling the send input line low.
  1. The changer will then begin serially transmitting the message within 2 MSEC at 600 BAUD using the data output line. After the transmission of 10 BITS
(approximately 16.66 MSEC) the external controller will pull the send input line high for at least 2 MSEC but not more than 20 MSEC (refer to Figure 6). This completes the single transmission communication
protocol (see Table 8 for status word definitions).
  1. The external controller can request a repeated

transmission if it elects to do so. However, a maximum of 4 repeats is recommended. A repeated
transmission is initiated by the external controller pulling the send input low 2 MSEC minimum to 4 MSEC maximum after the send input line is pulled high, indicating the completion of the previous transmission by the changer as described in pargraph 3C above



Code for TRC-6010:

/*
* Rough draft of arduino sketch used to
* communicate with a coin mechanism.
* Coin mechanism model used is:
* Mars(MEI) TRC-6010 (12-pin plug)
*/


// declare constants for the pins
const int sendPin = 3;
const int interruptPin = 2;
const int dataPin = 5;
const int enablePin = 6;
const int quarterPin = 7;
const int dimePin = 8;
const int nickelPin = 9;
const int resetPin = 11;

// declare variables
int counter = 0; // counter is a means to view the number of interrupts in triggered()
char incoming_char = 0; // to isolate/test coin mech functions

void setup()
{

  // initialize the interrupt
  // set the interrupt
  attachInterrupt(0, triggered, FALLING);
  // so when interrupt zero (digital pin 2) changes state,
  // triggered is fired

  // initialize required lines from arduino to coin mech (OUTPUT)
  pinMode(sendPin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(quarterPin, OUTPUT);
  pinMode(dimePin, OUTPUT);
  pinMode(nickelPin, OUTPUT);
  pinMode(resetPin, OUTPUT);

  // set the pins to proper state
  digitalWrite(sendPin, HIGH);    // HIGH = Waiting
  digitalWrite(enablePin, LOW);   // LOW = Enabled(accept coins)
  digitalWrite(quarterPin, HIGH); // HIGH = Not active
  digitalWrite(dimePin, HIGH);    // HIGH = Not active
  digitalWrite(nickelPin, HIGH);  // HIGH = Not active
  digitalWrite(resetPin, LOW);    // LOW = No reset



  // Initialize serial port communication
  Serial.begin(9600);
  Serial.println("Waiting for interrupt...");
}


void loop()
{


  if (Serial.available())
  {
    incoming_char = Serial.read();
 
    if (incoming_char == '1')
    {
      digitalWrite(quarterPin, LOW);
      Serial.println("quarterPin set to LOW");
      delay(100);
      digitalWrite(quarterPin, HIGH);
      Serial.println("quarterPin set to HIGH");
    }
 
 
    else if (incoming_char == '2')
    {
      digitalWrite(nickelPin, LOW);
      Serial.println("nickelPin set to LOW");
      delay(100);
      digitalWrite(nickelPin, HIGH);
      Serial.println("nickelPin set to HIGH");
    }
 
    else if (incoming_char == '3')
    {
     digitalWrite(dimePin, LOW);
     Serial.println("dimePin set to LOW");
     delay(100);
     digitalWrite(dimePin, HIGH);
     Serial.println("dimePin set to HIGH");
    }
 
    else if (incoming_char == '4')
    {
      digitalWrite(enablePin, LOW);
      Serial.println("enablePin set to LOW = ACTIVE");
    }
 
    else if (incoming_char == '5')
    {
      digitalWrite(enablePin, HIGH);
      Serial.println("enablePin set to HIGH = DISABLED");
    }
 
    else if (incoming_char == '6')
    {
      digitalWrite(resetPin, HIGH);
      Serial.println("Reseting coin mechanism");
      delay(1000);
      digitalWrite(resetPin, LOW);
      Serial.println("Reset complete.");
    }

  }
}

void triggered()
{
  counter++;
  Serial.println(counter);
  digitalWrite(sendPin, LOW);
  delay(4);
  digitalWrite(sendPin, HIGH);
}