self service bar Program help

The project is a self service bar ...the customer pay's let's say £10 + deposit for card . The RFID reader on the bar reads the card if there is any credit left
on the card pin 13 gives 5v to relay that opens selenoid to allow beer to be dispensed .the customer would press a button on the bar they have filled there pint that would send 5v to pin 10 that would close selenoid and look for next card .when there is no credit left pin 13 will go low closing the selenoid . this works fine as long as I don't loose power to arduino as this would reset
all cards to there original value and I would be giving beer away .
but that is not my main problem . what I would like to do is have more than one self service bar and to be able to read card at any bar and know what credit is left on card

I would be very grateful of any help anyone could offer…..

this code reads a RFID card and adds one to count every time it gets a pulse from flow meter until the count reaches
the value of "maxcount" then it prints no credit left . if at any time pin 10 gets 5v the program returns to the bailout line in the program . the next time
this card is detected the count will continue where it left off ....

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
// Take note of the pin numbers
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);




static int lastState = 0;
static int count = 0 ;   //number of pulses for each card
static int countb = 0 ;





byte data[5];  //For holding the ID we receive
int val = 0;
byte jeremy[5] = {
  0x3E,0x00,0xFC,0xBD,0x88};
byte david[5]  = {
  0x45,0x00,0x6A,0x8B,0x9B};
int outputPin = 1;     //names pins
int inputPin =2;

int breakPin =5;
int maxCount ;     //number of pulse's before this card shuts off
int timeout = 0 ;


//int newcard =
void setup()
{


  //lcd.setCursor(0,7);
  // Print a message to the LCD.

  // lcd.setCursor(0, 1);
  //lcd.print(" Mad Dave's Bar");

  Serial.begin(19200);     //just for now so i can see what's going on 
  Serial.print(0xFF,BYTE);  //Header
  Serial.print(0x01,BYTE);  //Reserved
  Serial.print(0x09,BYTE);  //Length (Command + Data)
  Serial.print(0x87,BYTE);  //Command (0x87 sets auto mode behavior
  Serial.print(0x01,BYTE);  //Data 1: Enable Auto-Read
  Serial.print(0x03,BYTE);  //Data 2: Mode – Parity decoded – Manchester RF/64
  Serial.print(0x02,BYTE);  //Data 3: Total number of block to be read (2)
  Serial.print(0x00,BYTE);  //Data 4: No password expected
  Serial.print(0x10,BYTE);  //Data 5: Password byte 1
  Serial.print(0x20,BYTE);  //Data 6: Password byte 2
  Serial.print(0x30,BYTE);  //Data 7: Password byte 3
  Serial.print(0x40,BYTE);  //Data 8: Password byte 4
  Serial.print(0x37,BYTE);  //Checksum

  delay(500);
  Serial.flush();
  Serial.println();



  pinMode(outputPin,OUTPUT);
  pinMode(inputPin, INPUT);     //make's pin 10 input pin 
  pinMode(breakPin, INPUT);      //this is used to breakout of while loop




}

void loop()




{
bailout: // this is for the goto statment ( sorry but i can not thing of any other way but goto )
  digitalWrite (outputPin, LOW);
  lcd.begin(16, 2);
  lcd.print("Waiting for Card ");
  val = Serial.read();
  while (val != 0xff)
  {  //On Successful read, first byte will always be 0xFF
    val = Serial.read();
    delay(1000);
  }

  //we already read the header (0xff)
  Serial.read();              // reserved
  Serial.read();              // length
  Serial.read();              // command (indicates tag data)
  data[0] = Serial.read();    // we read data 1
  data[1] = Serial.read();    // we read data 2
  data[2] = Serial.read();    // we read data 3
  data[3] = Serial.read();    // we read data 4
  data[4] = Serial.read();    // we read data 5
  Serial.read();              // checksum

  // Indentify RFID Card
  boolean j_card = true;
  boolean d_card = true;
  Serial.print("Card found ");
  for (int i=0; i<5; i++)
  {
    if (data[i] < 16) Serial.print("0");
    //Serial.print(data[i], HEX);

    //cross-check

    if (data[i] != david[i]) d_card = false;
  }








  digitalWrite (outputPin, HIGH);

  if (d_card)     


  {

    Serial.println("Credit On Card  ");



    while(digitalRead(5))

    {


      int maxCount =20;
      if (count > maxCount)     //when count gets to the set number sends 5v to pin 13
      { 
        Serial.println("NO CREDIT LEFT REMOVE CARD");
        digitalWrite(outputPin, LOW);   // power to relay to shut flow 
        goto bailout; 

      } 


      digitalWrite (outputPin, HIGH);
      int newState = digitalRead(inputPin);  //pulse from flow meter


      if (newState != lastState)     //detect change

      {


        count ++;    //adds one to count




        lastState = newState;


      }  
    }       


  }

  // looks for next card number
  //The program will repeat the for the next card but change count to countb and maxcount to maxcountb and so on


}

first CTRL-T cleans up the layout of your code in the IDE (please use that)

  • make a central (credit)server that holds the credits per user
  • the arduino's are clients from that server
  • they check for credits and if there are enough they withdraw a credit and open the tap.

A= Arduino S = Server

[scenario 1]
A: detect user
A2S: has user credits?
S2A: yes
A2S: give me one
S2A: here it is (==> credits[user]--)
A2S: thank you
A: open solenoid
A: close solenoid

[scenario 2]
A: detect user
A2S: has user credits?
S2A: no
A2S: OK
A: play "I am sorry.mp3"

does this help?

Maddave - can you clarify - I assume that you have changed the original concept of giving each customer a box with an arduino in it to just giving them an RFID token, correct?

Assuming that, Rob's solution would be required even for a single remote bar - somehow, you have to let the arduino controlling the solenoid know how much credit each RFID card has, so you need a database and a network, at least in concept - their actual implementation could be very basic.

Yes the idea as changed from a box to a RFID card ... Are you saying robs idea would work or not if so can some one tel me how to do it ... Thanks for your replys just hope I can work this out

That could definetly work,
have an arduino at each station that communicates to a central arduino or even computer
each station would read the rfid, send to central, and if it recieves a go ahead work the solenoid
the central would need to have a database of rfid numbers and associated credits, if there's not too many stations you could use an arduino mega which has more memory and more hardware serial ports,
If the bars are like in a different building it would make things somewhat more complex because then you need to bring in a way to bridge the database, maybe a computer server the arduinos can talk to over internet
If the bars are close enou have no central server but each arduino remember credits and tell the others any changes
ornot even a central server but shared memory, that they all can read or write
You could even set up each station with a keypad and lcd to add credit on the fly or check a balance,
Code wise it should not be to hard, just implementing various aspects into one program

but it does not sound like an especialy hard or expensive project

Thanks for your reply all the bars will be close by ........ so I just need to work out how to get the ardino's to talk to each other .... Could any one point me in the rite direction to learn how to do this ................ thanks for your help

Ethernet library ?
Server - Ethernet - Arduino Reference -
Client - Ethernet - Arduino Reference -

Look into the serial library, and the instructions and demos for it
I don't think you'll need the ethernet if they are close,
all you really need to do in the communication is send numbers from an rfid tag and receive a go ahead or not

Short example
//after recieves the rfid tag number on station side
serial.print(rfidnumber);

// on central
if(serial.available > 0){
//some code to translate ascii back into character using serial.read();
// then compare number to credits on account
If(credits > 0){
serial.print("ok");
credits = credits - 1;
}
if(credits < 1){
serial.print("no");
}

//on station
if(serial.available > 0){
//some code to translate back into ascii string "allowed"
}
if(allowed == "ok"){
//code to open and close solenoid and serve
//optional code to display remaining credits etc
allowed = "ready"; // change string to something so it doesn't keep serving lol
}
if(allowed. == "no"){
//maybe so e code to to display that there are no credits
}

Look at what sort of info the rfid tag will give you, the amount of data transfered on serial will depend on that as well as any other needs you have
also you will need a way to associate tag numbers with credits, stored perhaps in an array
and probably will want a way to add new tags and credits, and check balances

credits = credits - 1;

You know, there is a reason why the language used to program the Arduino is called C++, rather than C=C+1.

thanks for your reply i have got another arduino coming it should be here wednesday i will have a play with the code then and let you know how i get on .... once again thanks for your help

I know, It could be streamlined like making some ifs in one line etc
or credits --; but for simplicities sake it makes more sense to a learner

Just a quick question…. how many serial inputs/outputs is there on the maga …..if I understand this I would need 1 input per station… is that rite ??

Man, you are lazy. Do your own research.
http://arduino.cc/en/Main/ArduinoBoardMega2560

The ATmega2560 provides four hardware UARTs for TTL (5V) serial communication.

maddave:
Yes the idea as changed from a box to a RFID card ... Are you saying robs idea would work or not if so can some one tel me how to do it ... Thanks for your replys just hope I can work this out

What I would do is build each Arduino as a simple I/O device. It would have functions to:

  1. detect the presence of a card, and report that on network
  2. receive instructions to allow dispensing beer from the beer
  3. time the dispensing of beer (so you know how much has flowed through) and report on the network
  4. report on level of beer in keg (so you know when it's time to refill which unit) and report on the network

I would then build a simple, central system that manages between 1 and beer dispensers. This would be built using something like a WRAP or HARP box or perhaps a cheap "netbook" (that comes with keyboard, display, and hard drive). Probably running Linux, for a cheap system. This system should have UI that:

  1. displays amount of beer from each connected dispenser
  2. displays transactions from cards as they come in
  3. stores and updates the amount of value related to each card
  4. lets the operator add money stored to a particular card (you probably want a reader right by the system for this purpose)
  5. lets you export transactions and information about the system (beer consumption, etc) for later accounting
  6. receives requests for beer from the nodes
  7. if there's enough credit, send back a "dispense" message; else send back a "no credit" message (for display to the user of the beer tap)
  8. if some beer tap reports trouble, make this clear on the display

Note that netbooks can be had for about $200 new, and a lot less used. Add an Ethernet switch/hub, and an Arduino with Ethernet per tap, and you should have a pretty cost effective system.

Networked programming is hard, though (distributed systems have many failure modes!) and interacting with the real world (dispensing beer) is messy, so you're probably also in for an interesting time making it all work :slight_smile: Sounds like a fun project!

  1. time the dispensing of beer (so you know how much has flowed through) and report on the network
  2. report on level of beer in keg (so you know when it's time to refill which unit) and report on the network

He has a flow meter that takes care of point 3, and indirectly point 4, in that if the beer solenoid is open and the flow meter reads nothing, the keg is apparently empty.

You seem to have covered everything else. In addition though, it would be nice if there was a way to interface the netbook to the POS system - it will be a little awkward if you have to ring up the cash in one device and then go to the netbook to make corresponding entries. I assume the POS stuff is proprietary though. The other piece that bothers me is netbook failure - I'd want a backup somewhere, at least one that knows how many credits each card has, so in the event of failure, you can still issue refunds (or beer) to the punters.

wildbill:
He has a flow meter that takes care of point 3, and indirectly point 4

Yes, I missed that -- makes that part easier!

In addition though, it would be nice if there was a way to interface the netbook to the POS system

Yup! Although most cash registers really don't know how to send a message to "please update the database to add X credits for card Y" so in reality, I think most users of such a system wouldn't benefit.
In fact, you'd probably be better off making the netbook be the POS system :wink:

Regarding backups, if the cards store value across nights, I would agree. If the system is available only for a night (say, it's a rental or similar), and goes down, unless you keep a second netbook on hand with ability to restore from (near-real-time) backups, the backups of the cards won't help much. If the idea is that this is for a party rental store or whatever, then I'd probably want to ruggedize everything and have a "hot backup" just in case. Cost becomes a factor, too.

Man, this sounds like fun. I wish I was the one building this system :slight_smile: :slight_smile: