Jump to content

Arduino code for ITC Note Acceptor


Recommended Posts

Hi Guys

I have hooked up an ITC note acceptor to MFME through a Leonardo Arduino Board, but am only getting so far as I have never coded C++.

Here is the code I am using, which works perfectly for pressing the letter 'z' on a keyboard - after a certain amount in notes have been inserted.  In my case 5x20 Baht,  2x50 or 1x100.

What I am trying to do is generate an 'x' for 20 Baht, 'Y' for 50 Baht and a 'z' for 100 Baht.

Here is the code below (taken from GitHub and edited accordingly).

-----------------------------------------------------------------------------------------------------------------------

 #include <Keyboard.h>
/*

  This program expects pulses of logic high coming from a bill acceptor into pin 0 on an arduino leonardo.
  It counts the number of pulses, pretends to be a usb keyboard and sends an F3 keypress when enough total pulses have been received to pay for a service.

*/

// The pin on the arduino where CREDIT (-) [Common] is connected
#define INPIN (9)

int cents_per_pulse; // how many cents per pulse. for most bill acceptors this is 100 or $1 per pulse, but it can often be configured and coin acceptors will be different
int min_pulse_width; // the minimum pulse width to acccept
int max_pulse_width; // the maximum pulse width to accept
int debounce_speed; // ignore changes in input line state that happen faster than this
int pulse_count; // how many pulses have been received so far in this pulse train
int cents_received; // Counts how many cents have been received
int cost_of_service; // Trigger service when this number of cents have been received
unsigned long pulse_duration; // how long was the last pulse
unsigned long pulse_begin; // when did the last pulse begin
unsigned long pulse_end; // if they pulse was within min and max pulse width, when did it end
unsigned long curtime; // what is the current time
int post_pulse_pause; // how long to wait after last pulse before sending pulse count
int pulse_state; // what is the current input line state (1 for high, 0 for low)
int last_state; // what was the last input line state


void setup() {
  pinMode(INPIN, INPUT); // Pin 0 is the pin where the pulse output from the bill acceptor is connected. Change it 
 // Serial.begin(115200); // You can comment all the Keyboard lines and uncomment all the serial lines to make it print to serial instead (useful for debugging)
  Keyboard.begin();
  pulse_begin = 0;
  last_state = 0;
  min_pulse_width = 40;
  max_pulse_width = 60;
  debounce_speed = 4;
  post_pulse_pause = 300;
  cents_per_pulse = 100;
  pulse_end = 0;
  pulse_count = 0;
  cents_received = 0;
  cost_of_service = 1000;
}

void loop() {
  pulse_state = digitalRead(INPIN);
  curtime = millis();
  if((pulse_state == 1) && (last_state == 0)) { // this means we entered a new pulse
    pulse_begin = curtime; // save the begin time of the pulse
    last_state = 1; // set the previous state
  } else if((pulse_state == 0) && (last_state == 1)) { // this means a pulse just ended
    pulse_duration = curtime - pulse_begin; // calculate pulse duration
    if(pulse_duration > debounce_speed) { // ensure that we don't change state for very short (false) pulses (this is called debouncing)
      last_state = 0;
    }
    if((pulse_duration > min_pulse_width) && (pulse_duration < max_pulse_width)) { // check if the pulse width is between the minimum and maximum
      pulse_end = curtime; // save the end time of the pulse
      pulse_count++; // increment the pulse counter
    }
  }
  
  if((pulse_end > 0) && (curtime - pulse_end > post_pulse_pause)) { // check if we've waited long enough that we don't expect any further pulses to be forthcoming

    cents_received += pulse_count * cents_per_pulse;
    if(cents_received >= cost_of_service) { // check if enough money has been paid for the service
     // Serial.print(pulse_count);
     // Serial.println();  
     Keyboard.write('z'); // Send a z keypress
      cents_received = 0; // reset cents_received so it's ready for next payment
    }    

    pulse_end = 0;
    pulse_count = 0;
  }

}

---------------------------------------------------------------------------------------------------------------------------------

Does anybody have any idea how to improve the code on this, to generate keypresses for different notes? 

Hopefully others will be able to use this to add note acceptors to their MFME cabs in the future.

Thanks in advance guys:)
 

Treat every day like your last, because one day it will be!

Link to comment
Share on other sites

here is what i tried, note i don't use c++ often (blue moon level rareness but the main idea is you need a switch statement) i added a suffix of '//++'.to lines changed by me so you can see what im trying.

note:

i assumed the pulses sent is in increments of 1000, if this is wrong you will need to change each case to the correct pulse count expected for that note as well as the 'min_cost_of_service' and 'max_cost_of_service' (min_cost_of_service = pulse count for £5 and max_cost_of_service = £50)

 #include <Keyboard.h>
/*

  This program expects pulses of logic high coming from a bill acceptor into pin 0 on an arduino leonardo.
  It counts the number of pulses, pretends to be a usb keyboard and sends an F3 keypress when enough total pulses have been received to pay for a service.

*/

// The pin on the arduino where CREDIT (-) [Common] is connected
#define INPIN (9)

int cents_per_pulse; // how many cents per pulse. for most bill acceptors this is 100 or $1 per pulse, but it can often be configured and coin acceptors will be different
int min_pulse_width; // the minimum pulse width to acccept
int max_pulse_width; // the maximum pulse width to accept
int debounce_speed; // ignore changes in input line state that happen faster than this
int pulse_count; // how many pulses have been received so far in this pulse train
//int cents_received; // Counts how many cents have been received//++
int cost_of_service; // Trigger service when this number of cents have been received
unsigned long pulse_duration; // how long was the last pulse
unsigned long pulse_begin; // when did the last pulse begin
unsigned long pulse_end; // if they pulse was within min and max pulse width, when did it end
unsigned long curtime; // what is the current time
int post_pulse_pause; // how long to wait after last pulse before sending pulse count
int pulse_state; // what is the current input line state (1 for high, 0 for low)
int last_state; // what was the last input line state

int min_cost_of_service; // Trigger service when this minimal number of cents have been received. //++
int max_cost_of_service; //++
void setup() {
  pinMode(INPIN, INPUT); // Pin 0 is the pin where the pulse output from the bill acceptor is connected. Change it 
 // Serial.begin(115200); // You can comment all the Keyboard lines and uncomment all the serial lines to make it print to serial instead (useful for debugging)
  Keyboard.begin();
  pulse_begin = 0;
  last_state = 0;
  min_pulse_width = 40;
  max_pulse_width = 60;
  debounce_speed = 4;
  post_pulse_pause = 300;
  cents_per_pulse = 100;
  pulse_end = 0;
  pulse_count = 0;
  //cents_received = 0;//++
  cost_of_service = 1000;
  
  min_cost_of_service = 1000; //++
  max_cost_of_service = 4000;
}

void loop() {
  pulse_state = digitalRead(INPIN);
  curtime = millis();
  if((pulse_state == 1) && (last_state == 0)) { // this means we entered a new pulse
    pulse_begin = curtime; // save the begin time of the pulse
    last_state = 1; // set the previous state
  } else if((pulse_state == 0) && (last_state == 1)) { // this means a pulse just ended
    pulse_duration = curtime - pulse_begin; // calculate pulse duration
    if(pulse_duration > debounce_speed) { // ensure that we don't change state for very short (false) pulses (this is called debouncing)
      last_state = 0;
    }
    if((pulse_duration > min_pulse_width) && (pulse_duration < max_pulse_width)) { // check if the pulse width is between the minimum and maximum
      pulse_end = curtime; // save the end time of the pulse
      pulse_count++; // increment the pulse counter
    }
  }
  
  if((pulse_end > 0) && (curtime - pulse_end > post_pulse_pause)) { // check if we've waited long enough that we don't expect any further pulses to be forthcoming

    //cents_received += pulse_count * cents_per_pulse;//++
    //if(cents_received >= cost_of_service) { // check if enough money has been paid for the service//++
	if(pulse_count >= min_cost_of_service && pulse_count <= max_cost_of_service) {//++
     // Serial.print(pulse_count);
     // Serial.println();  
     //Keyboard.write('z'); // Send a z keypress//++
		switch(pulse_count) { //++
		  case 1000: //++
			// £5, 1000 pulses. //++
			Keyboard.write('a'); //++
			break; //++
		  case 2000: //++
			// £10 2000 pulses. //++
			Keyboard.write('b'); //++
			break; //++
		  case 3000: //++
			// £20 3000 pulses. //++
			Keyboard.write('c'); //++
			break; //++
		  case 4000: //++
			// £50 4000 pulses. //++
			Keyboard.write('d'); //++
			break; //++
		}
      //cents_received = 0; // reset cents_received so it's ready for next payment//++
    }    

    pulse_end = 0;
    pulse_count = 0;
  }

}

 

  • Thanks 1
Link to comment
Share on other sites

Posted (edited)

Thanks Ross:)

Hopefully this should help anyone who wants to add a cheap (ITC Pulse) note changer to their MFME cabinet!

I will reprogram my board with this code shortly and see what happens:). All I have to do now is change the service amounts (Notes here are lower value than UK) and the keys to x,y,z so they do not conflict with any known MFME shortcuts.

Thanks again for the input!

 

Edited by Amusements

Treat every day like your last, because one day it will be!

Link to comment
Share on other sites

Posted (edited)

Quick update.

The code above works great for the UK notes, and with some small changes it will work for any currency:)

 

For Thai Bahts this is what I am now using.

[code]
/*

  This program expects pulses of logic high coming from a bill acceptor into pin 9 on an arduino leonardo.
  It counts the number of pulses, then pretends to be a usb keyboard and sends x,y,z keypress's when corrisponding pulses have been received to pay for credit.

*/

// The pin on the arduino where CREDIT (-) [Common] is connected
#include <Keyboard.h>
#define INPIN (9)
int cents_per_pulse; // how many cents per pulse. for most bill acceptors this is 100 or $1 per pulse, but it can often be configured and coin acceptors will be different
int min_pulse_width; // the minimum pulse width to acccept
int max_pulse_width; // the maximum pulse width to accept
int debounce_speed; // ignore changes in input line state that happen faster than this
int pulse_count; // how many pulses have been received so far in this pulse train
int cost_of_service; // Trigger service when this number of cents have been received
unsigned long pulse_duration; // how long was the last pulse
unsigned long pulse_begin; // when did the last pulse begin
unsigned long pulse_end; // if they pulse was within min and max pulse width, when did it end
unsigned long curtime; // what is the current time
int post_pulse_pause; // how long to wait after last pulse before sending pulse count
int pulse_state; // what is the current input line state (1 for high, 0 for low)
int last_state; // what was the last input line state
int min_cost_of_service; // Trigger service when this minimal number of cents have been received. //++
int max_cost_of_service; //++

void setup() {
  pinMode(INPIN, INPUT); // Pin 0 is the pin where the pulse output from the bill acceptor is connected. Change it 
  // Serial.begin(115200); // You can comment all the Keyboard lines and uncomment all the serial lines to make it print to serial instead (useful for debugging)
  Keyboard.begin();
  pulse_begin = 0;
  last_state = 0;
  min_pulse_width = 40;
  max_pulse_width = 60;
  debounce_speed = 4;
  post_pulse_pause = 300;
  cents_per_pulse = 100;
  pulse_end = 0;
  pulse_count = 0;
  cost_of_service = 1;
  min_cost_of_service = 2; //++
  max_cost_of_service = 10;
}

void loop() {
  pulse_state = digitalRead(INPIN);
  curtime = millis();
  if((pulse_state == 1) && (last_state == 0)) { // this means we entered a new pulse
    pulse_begin = curtime; // save the begin time of the pulse
    last_state = 1; // set the previous state
  } else if((pulse_state == 0) && (last_state == 1)) { // this means a pulse just ended
    pulse_duration = curtime - pulse_begin; // calculate pulse duration
    if(pulse_duration > debounce_speed) { // ensure that we don't change state for very short (false) pulses (this is called debouncing)
      last_state = 0;
    }
    if((pulse_duration > min_pulse_width) && (pulse_duration < max_pulse_width)) { // check if the pulse width is between the minimum and maximum
      pulse_end = curtime; // save the end time of the pulse
      pulse_count++; // increment the pulse counter
    }
  }
  
  if((pulse_end > 0) && (curtime - pulse_end > post_pulse_pause)) { // check if we've waited long enough that we don't expect any further pulses to be forthcoming
  if(pulse_count >= min_cost_of_service && pulse_count <= max_cost_of_service) {//++
 // Serial.print(pulse_count);
 // Serial.println();  
    switch(pulse_count) { //++
      case 2: //++
      // 20Baht, 2 pulses. //++
      Keyboard.write('x'); //++
      break; //++
      case 5: //++
      // 50Baht 5 pulses. //++
      Keyboard.write('y'); //++
      break; //++
      case 10: //++
      // 100Baht 10 pulses. //++
      Keyboard.write('z'); //++
      break; //++
    }
    }    
    pulse_end = 0;
    pulse_count = 0;
  }
}
[/code]

 

Edited by Amusements
removed 500Bahts for a q press (not needed)
  • Like 1

Treat every day like your last, because one day it will be!

Link to comment
Share on other sites

 Share

×
×
  • Create New...