Archive for June, 2009

Intelligent Drink Dispenser – Software Design

Posted in Uncategorized on June 21st, 2009 by Nick – 1 Comment

The other major half of the Intelligent Drink Dispenser project was the software side of things. As with the hardware, there were some things we had to consider when beginning the design of things. What language should we use? Should this be a GUI application or web application? If we go with a GUI application, what operating system should we target?

We decided that since we only had a semester to get everything done, we needed a framework to take care of the more nitty-gritty stuff. We eventually decided to go with the Django web framework, which uses the Python programming language. Python is a language we all knew and Jon and I had used Django in the past. Also, since our ‘final product’ would be highly based on a client-server model, it makes sense to go with a web app since the server can be in a central location with many clients connecting to it.

The most important thing to us was the fact that Django abstracts the database into models for us. No having to mess around with raw SQL, we just run some queries and get our data from the models as if they’re just plain ol’ objects. After some thought, we came up with our models and their relationships:

Django Models

The development of the application was fairly straight-forward. It was just a standard Django app after all. The interesting part was interfacing with the hardware.

If you remember from my post talking about the hardware side, we used an FTDI UM232 USB-to-serial converter. Lucky for us, there’s a Linux kernel module which represents this device as a virtual serial port, which made our jobs a whole lot easier since there’s existing serial libraries for Python (like pyserial). We ended up just writing a couple of functions, one to read the RFID tag from the serial port, and one that takes in a Drink id and then communicates to the microcontroller to pour it. The microcontroller’s fairly dumb, just taking a number and turning that pin on, or turning all of the pins off if a non-valid character is sent, as you can see in the pourDrink function:

def pourDrink(id, serialPort=DEVICE):
  """Pours the drink given by the specified ID"""

  # Seconds per mL of the motors, found experimentally
  # These should be in the database or a config file instead of hardcoded...
  secondsPerML = []
  secondsPerML.append(9.858/350.0)  # Pump 0
  secondsPerML.append(9.858/350.0)  # Pump 1
  secondsPerML.append(6.385/210.0)  # Pump 2

  components = DrinkComponent.objects.filter(drink=id)

  for c in components:
    stock = IngredientStock.objects.filter(ingredient=c.ingredient)
    total = 0

    for s in stock:
      total += s.amount

    if total < c.amount:
      raise UnableToPour("Not enough " + c.ingredient.name + " to pour drink!")

  port = serial.Serial(serialPort, 2400)
  if not port.isOpen():
    raise UnableToPour("Unable to open serial port!")

  for c in components:
    stock = IngredientStock.objects.filter(ingredient=c.ingredient)
    leftToPour = c.amount

    startTime = time.time()

    for s in stock:
      port.write(str(s.slot))
      if leftToPour < s.amount:
        time.sleep(secondsPerML[s.slot]*leftToPour)
        s.amount = s.amount - leftToPour
        s.save()

        break
      else:
        time.sleep(secondsPerML[s.slot]*(s.amount - 30))
        leftToPour = leftToPour - s.amount - 30

        s.amount = 0
        s.save()

    print "Time to pour:" + str(time.time() - startTime)

  port.write("\n")
  port.close()

Not exactly the most precise in terms of pouring accuracy, but it gets the job done as a prototype. As for the rest of the code, there’s not too much else that’s very interesting. I may release the code at some point in the future.

Intelligent Drink Dispenser Details

Posted in Uncategorized on June 21st, 2009 by Nick – 3 Comments

I said that I’d post details on my Intelligent Drink Dispenser project “soon”. That was over a month ago. Whoops. I blame my new internship for that.

For those of you not in the know, the Intelligent Drink Dispenser was my senior design project at Missouri University of Science and Technology (which will forever in my heart be University of Missouri-Rolla). It’s basically a smart drink dispenser that’s capable of mixing, charging customers, telling the bar/restaurant owner when they need to refill the machine, etc.

If you don’t feel like reading the details and just want to look at the pretty pictures, you can check out my Picasa album or watch the Youtube video.

The theoretical process is that the customer would go to order a drink, and since they’re a new customer, they’d have to be entered into the system by the person running the machine (bartender, or waiting staff). They would have their name and credit card information taken, and would then be assigned a drinking vessel based on the first drink they were wanting to order. Multiple vessels could also be assigned to the same person. Once the customer is setup and is ready to purchase their drink, they set the fluid vessel on the marked reader area on the dispenser. The system then recognizes the vessel, who it belongs to, asks the customer for the last four digits of their credit card, and then asks the customer which drink they’d like to order. The customer then chooses what drink they’d like to have, the system double-checks that the vessel is the right size, and pours it.

Security and privacy was one of the major goals of the project. The only information stored about the user is their name, a secure hash of their credit card number, the last four digits of ther card, and their drink order history.

The project itself can pretty much be split into two major components: hardware and software. I would probably say the hardware is more interesting and posed more challenges for us. The first thing is how the heck do you pour the fluid? If you take into consideration that we only had a $300 budget for the whole shebang, it’s not an easy task. The way that the professionals do it is with Carbon Dioxide-powered pumps, which are controlled by electronic valves and supplied by a tank and pressure regulator. Three pumps, valves, and the feed system would cost us well over $300. Our original idea was to use 24 VDC sprinkler valves, but that idea failed because the sprinkler valves by their nature require back-pressure to operate. We came up with the idea of using windshield washer pumps made for cars. Since this was supposed to be a prototype, we didn’t have to worry about our components being food-grade. That, coupled with the fact that the pumps operate on 12V DC and are relatively inexpensive ($15-25 a pop), that’s what we went with for our design.

The rest of the hardware design was fairly straightfoward. We used an 8051 microcontroller to control everything, an FTDI UM232 to handle the PC communications and a Parallax RFID reader to read the tags that are on the bottom of the drinking vessels. The serial communication is pretty interesting since the USB-to-serial device has only one serial port but two devices to talk to (the RFID reader, and the PC). Our solution was to have the receive line go to the RFID reader (to the PC), and have the transmit line go to the 8051 (from the PC). This meant that our 8051 couldn’t talk back, so we had to hope that things were working right. Additionally, Richard developed a simple serial language for the 8051. If the 8051 received an ASCII 0 through 7, it would turn on that pin on the port we were using. This could easily be modified to operate with all the ports on the 8051 to control 24 pumps, or even with some addressing logic to control a huge number of pumps.

Below is our hardware schematic, which should give you some idea of how it’s all connected.

IDD Final Hardware Design

(click for full size image)

In my next post, I’ll be talking about the software design. Stay tuned!