Arduino and BV20 Bill Acceptor/Validator

Hi.

I made this topic to seek some advice. I'm having an horrendous time trying to make the BV20 bill acceptor from Innovative Technologies work with Arduino Mega 2560. I'm an experienced programmer new to electronics, and I'm just accepting the fact that I won't be able to do this on my own (I did try a lot...).

The BV20 is a bill acceptor/validator, same kind of device you can find in most vending machines worldwide. You insert a bill into the device, it checks it to see if it's real money, and if it is, it sends a signal to a microcontroller informing the credit.

The one I'm using sends the signal through a pulse stream, using one single pin to do it. This is the logical info available from the device manufacturer:

INPUTS
Logic Low: 0V to +0.5V.
Logic High: +3.7V to +12V.

OUTPUTS WITH 2K2 PULL UP
Logic Low: 0.6V.
Logic High: Pull up hostage of host interface.

MAXIMUM CURRENT SINK
50mA per output.

The full manual can be found here: http://kriss-sport.com/dl-files/bv20_operations_manual_20101126.pdf. The info I presented is in the 5th page.

The device outputs a 50ms LOW pulse, followed by a 50ms HIGH for each dollar in a bill (so if I insert a $5 bill it sends a 50ms LOW pulse with a 50ms HIGH interval between each pulse five times).

If I put a led between the pulse pin and the arduino i can (barely) see it blinking the pulses when i insert a bill, so I know the device is working and recognizing the bills, but the arduino keep receiving 0's and 1's randomly.

I've tried every kind of assembly imaginable to make the arduino read the pulses correctly, but it was a complete failure. To be honest, I've used the pulseIn() function with moderate success. If I connect the pulse pin directly into the arduino input pin and use this code:

void setup()
{
    Serial.begin(9600);
    pinMode(2, INPUT);   
    pulseCount = 0;
}

void loop() {
    int x = pulseIn(2,LOW);
        if (x >= 500) {
            Serial.println(x);                  
        }
}

I will get some readings of "x" above 500 when a bill is inserted. But that will output anything from 500 to 1200 an inconsistent number of times, independently of the bill. So I can't tell the difference between a $1 and a $5 bill inserted.

I'm trying to make these two work together for weeks now. I'm desperate and I need help. I know it can't be hard to accomplish. Someone can help me out?

Thanks in advance.

Joe,
Firstly try increasing the speed at which the Arduino sends serial information, so up the baud rate, say to 115200.
I have an idea that your pulses are being missed while the serial function is busy

Paul

Hi,
your hardware setup should be:

//                  o +5V
//                  |
//                  R = 2200 ohm               
//                  |
//   BV out o-------+-------o Arduino in
//

and I suggest you try to monitor the digital edges count:

volatile int gCount = 0;
unsigned long gMillisCounter;

void setup()
{
  Serial.begin(9600);
  attachInterrupt(0, pulseCounter, FALLING); // On digital pin 2
  gMillisCounter = millis();
}

void loop()
{
  // Print gCount every 3 seconds
  if( (signed long)( millis() - gMillisCounter ) >= 0)
  {    
    gMillisCounter += 3000;
    
    Serial.println(gCount);   
  }
}

void pulseCounter()
{
  gCount ++;
}

ea123, thanks for the reply. Did the wiring you recommended and copied the code in Arduino. After I inserted a $5 bill that's what I got in Serial Monitor:

-2726
12526
20487
31807
-21701
-7533
5954
18410
31594
-20286
-7357
5292
16138

One line every 3 seconds.

What went wrong?

Rockwallaby: thanks for the reply too. That's what I did after your advice:

int pulseCount = 0;

void setup() {
    Serial.begin(115200);
    pinMode(2, INPUT);   
}

void loop() {
    int x = pulseIn(2,LOW);
    
        if (x >= 500) {
            pulseCount = pulseCount + x;                
        }
        
    if (millis() % 3000 == 0) {
        Serial.println(pulseCount);
    }     
}

but i'm still getting inconsistent readings out on Serial Monitor. Can't tell the difference between the pulses sent by the bills. Two things surprises me. The first is that the pulseIn() function works with microseconds, not miliseconds, so a 50ms pulse should be recognized just when pulseIn >= 50000, but in my case it just recognizes pulses between 500 and 1200 only. The second thing is that the serial monitor outputs the pulses even BEFORE the device finished sending it to them (i mean, the device is still busy sending the info but the serial monitor already showed its full range of pulses). I'm probably not getting the pulses right.

The first is that the pulseIn() function works with microseconds

and returns an unsigned long, which you are trying (unsuccessfully) to shoehorn into an int.

After I inserted a $5 bill that's what I got in Serial Monitor:

Code:
-2726
12526
20487
31807
-21701
-7533
5954
18410
31594
-20286
-7357
5292
16138

One line every 3 seconds.

these numbers probably are due to the fact that a lot of interrupts are received and the gCount variable reachs the maximum (32767) and rolls over with negative numbers. Have you got an oscilloscope to verify the output line of your device?

ea123, you're correct, changing the type from int to long gives me this output:

0
264757
536961
810508
1084856
1359367
1634125
1908568

So the negative numbers were a type problem. But the thing is it keeps adding a line every 3 seconds even when i don't insert a bill. The signal is always falling, all the time.

I changed the hardware setup and put the pulse wire directly into the arduino input (pin 2). The signal keeps falling too. Here's the output on serial monitor:

16
1044757
2088158
3112505
4138586
5160061
6171990

Then I put back the original hardware setup with the pull up and changed the interrupt from FALLING to RISING. Same thing, outputs a large amount of rising in the signal. Here's the serial monitor:

0
272457
543522
810879
1081617
1351859
1619289
1883967

Lastly, tried changing from RISING to LOW. Same thing, a lot of interrupts even when a bill is not inserted. Here's the output:

0
162041
323906
485392
647142
809346

Rechecked again the hardware setup, and is exactly like the diagram you drew.

What's going on?

Thanks in advance.

PaulS, thanks for the observation. You're absolutely correct. After changing the type of "x" to unsigned long i start receiving readings from above 6000 microseconds, but still far away from the 50 ms. Here's the new code:

unsigned long y;

void setup()
{
    Serial.begin(115200);
    pinMode(2, INPUT);   
   }

void loop() {
    unsigned long x = pulseIn(2,LOW);
        if (x >= 500) {
            y = y + x;
        }
        
        if (millis() % 3000 == 0) {
         Serial.println(y); 
       
        }
        
}

What's more important, there's no noticeable difference in the amount or duration of the pulses between different bills.

Have you considered writing a small bit of code to act as the BV20 so you can test your code.
For example, a routine that will say, output on another pin some pulses with the correct timing delays and and then a longer delay pause.

Initial delay
Send 5 pulses out to pin x with 50mSec on time and 50mSec off time
end of bill delay, say 5 seconds
repeat pulse train for another bill.

Then you will be able to see how your code works.

I had a thought that if the BV20 output was a relay contact than you would have contact bounce issues, but I believe it is transistor logic.

PS, of course for the above test, you will need to tie your output pin of the test routine back to the input pin 2.

Paul

Another idea worth considering maybe is to connect the BV20 to your Arduino via the serial interface.
The BV20 documentation talks about this possibility on page 20, except below.

5.5 SERIAL INPUT/OUTPUT – SIO
To use Serial Input/Output mode The SIO interface must be programmed into the
validator via the Configuration Cards (See Appendix D – Configuration Cards) or via the ITL
BNV Currency Manager Program.
Serial Input/Output (SIO) is a simple serial protocol compatible with the same interface on
NV4 to NV10. It is not recommended for use on new designs due to the possibility of noise
effecting the communication. We recommend the use of a serial protocol with error
checking such as SSP. The BV20 does not support the Simple Serial Data Out Only mode
as available on the NV4 and earlier models.

I am assuming that using the serial interface will allow you to gather more information much more easily with less code on your Arduino.
Thoughts ?

rockwallaby . . . hopping about in the sunshine

I tried the serial protocol. But as said earlier, I'm very new to electronics.

I connected the BV20 output to arduino pin 0 (Rx pin) and wrote this code:

void setup()
{
  Serial.begin(9600);
 }

void loop()
{
  if( Serial.available() > 0)
  {    
    Serial.println(Serial.read());   
  }
}

When I put a bill in the validator, nothing outputs in the serial monitor.

It is good that you tried the serial.

But did you check that the BV20 is configured for the correct serial settings that will match up to the Arduino, using BV20 setup software.
For example check the BV20 is set to 9600 baud.

Also, try formatting the data in your print statement as HEX, eg Serial.print(data, HEX), that way you'll see any character even if non-printable.

Also, change your Serial.println to just print, take the 'ln' off to help you see the data better if it is just characters.
If your serial window is too small, you may miss any characters that are received.

You did also connect the ground of the BV20 to your Arduino ground too?

Finally! It works perfectly now.

rockwallaby:
You did also connect the ground of the BV20 to your Arduino ground too?

That was the issue. I had the ground of BV20 connected to the ground of its power supply (a 12v source). I know this is very foolish, but not that obvious for a newcomer like me.

I connected it to the ground of arduino and now everything works perfectly.

Thanks a lot rockwallaby and the others for the advices.

This is the code I used to make BV20 work with Arduino on serial protocol:

void setup()
{
  Serial.begin(9600);
 }

void loop()
{
  if( Serial.available() > 0)
  {    
    Serial.println(Serial.read()); // prints the result to Serial Monitor  
  }
}

The hardware setup was the same posted by ea123

ea123:

//                  o +5V

//                  |
//                  R = 2200 ohm              
//                  |
//   BV out o-------+-------o Arduino in
//

Im having issues in the connections can you send me the exact and complete connection of the bv20 and of the arduino?

Arduino uno and BV20 set SIO 300 Baud rate cannot read from serial .But Mega 2560 work fine

I have a doubt that how can you recognise different kind of notes that a bv20 is accepting and it's value. For every. If I am paying 10 dollars instead of 50 dollar then how can this machine recognise it. Please help me because I want to use this machine in my vending machine.

Hi, Have you tried changing the setting on LOW pulse output. Increase this to 100ms. You can access this with a use of IF17, DA1 or DA2 device and ITL validator manager or its equivalent , or Configuration by Cards. You can find this in Alibaba.

Please us know if this work.

Hi all, is there someone still working on the BV20 valitator? I am facing issues with the mechanical connections and the code design.

I upload the last code probe, but still doesn´t work.

Does anybody can help me?

Best regards.