Woodbuntu’s Monitoring Software

Given that my recently created (and blogged about) home theater PC is functionally a piece of furniture, the last thing we need is to be constantly checking on it. Rather, the machine should manage itself, and notify us (the users) when updates or intervention is needed.  As such I played around with my favorite scripting language to make some monitoring tools.

Python!

Using a very very very simple python script, I am able to read in a file and send the contents to a list of recipients. Once that was built, we needed a way to create the file for each email including html formatting. Another simple python script which reads in updates lists and status files to create an html file which can then be sent by the original tool.  The last step was automating the process. A few bash scripts placed in the automatically called locations (init.d, cron) can consolidate the necessary information to a file which can be passed through the python scripts.

actual received email

I should log on and update the end tale!

The result is a daily email or two (perhaps I will consolidate the daily emails in to one soon!) alerting us of any power-cycles, updates, or necessary changes needed.    There is support for a few extra features which I have not implemented yet, but will soon (read: eventually).  These tools can be used for many things I have not thought of I’m sure, so I made them highly generic. The builder can accept any type flags you want to define, so its behavior can be expanded without limit. The sender can send any file desired with a customizable subject in the command line. Both tools are written fairly clearly in the hopes of use for new and different things to suit each need.  The code is available in the usual spot here and is intended for linux systems.  I must clarify that these tools have only been tested on the end table PC, so excuse any compatibility errors.

To install, simply download the repository, edit the sender with the To, From, and Auth fields of your choosing, then run the install.sh as root.

Hope you get some use out of this tool, and as always, raise a glass and code on.

yes really

Functional Furniture

This year will be an eventful one for me. I graduate in December, so a lot of changes are coming up fast. The first is a non-school apartment for this semesters lodging. This apartment is the first in which I have space, resources, and the inspiration to really make it my own. I will be living with my girlfriend (English Major Eats) and another computer scientist friend, so the space planning has been a balance of nerdy features, and a woman’s touch. This has been exceedingly difficult. If the other computer scientist and I had our way, the entire apartment would be plastered in motherboards, configured in to the world’s most terrifying hadoop cluster/wall paper. However, the least nerdy of our trio has requested a bit of style, and since she’s so cute, we will oblige.

</rambling>

So how does this warrant a tech blog post? I can fell your frustration and antici…

.

.

.

.

pation. I present to you, THE END TABLE.

THE END TABLE

It may look like an ordinary beat up end table I purchased from Goodwill, because it totally is. But you have to look at its POTENTIAL. If you are having trouble picturing what this could be, let me help you paint a picture. We have a projector which we will be using in the apartment. It is going to live on a ceiling mount, shining at a large screen on the opposite  wall. Up the wall behind the projector will be the wires for each source to the projector. We have an Xbox360, a blu-ray player, a PS3(hacked), and would like some way to project a browser, code, or anything else achievable through a PC. What if all those things could live in the same place? What if the end table WAS  the PC?

 

yes really

I call her WOODBUNTU

Now you are seeing my vision. I started with some leftover PC parts, a beat up end table, and a trip to Microcenter and Home depot, and ended with THIS:

The ratty old end table was sanded, polished, and refinished, then cut, slashed, and hacked all to hell to make room for a motherboard, PSU, graphics card, SSD, and BIG ASS FAN. The 200mm Blue LED fan was the first addition, since it required cutting a very large hole. The motherboard is mounted on standoffs drilled in to the floor, and the PSU is secured to the back via 2 screws. Some serious cable management is needed, but all in all, I am happy with my functional end table.

After mounting all the hardware inside, I used a quick install USB to load the 120GB SSD with Kubuntu, and immediately install the netflix-desktop app and XBMC (with PleXBMC). These apps will let us stream media content from any computer on the local network, in addition to a variety of internet video sources directly to the projector FROM OUR END TABLE.

The goal of this project was to hide our geekiness inside something unassuming (much like the average adventure in to public places). I would say we succeeded, because unless you like to inspect furniture for tiny red power buttons, you are unlikely to suspect this table on which you are setting your beer is the powerhouse HTPC it truly is.

So as I contemplate 100 other cool things to do to this endtable before moving it in to our apartment, I will be setting my beer on my computer case, but always with a coaster.

As always, raise a glass and code on.

IT WORKS!!!!

All condensed in to 2 boxes

The pi bar circuitry

As of today, the pi bar circuitry is complete. Using a few protoboards, I was able to mock up a test signal and dispense liquid from multiple buckets! The next stage is to complete our laser sensor and build the frame. However, in the next few days, I have 3 projects due so I am a little swamped. Hopefully I can find time to keep you updated as I build, but it is likely the next update will be a completed project.

In other news, my birthday is this weekend so I will be a bit preoccupied and unable to make much progress. However, I swear to you it will be done by thursday (partially because it is due then…).  If you are in the Atlanta area and want to come see the more fun, less electronics side of the Drunken Developer, come out to little 5 on Saturday the 19th, where my friends and I will be bar-crawling, ending at the Brewpub Cafe. Come say hi and we can discuss robot bartenders and other such fun.

As always, raise a glass and code on.

Lasers!

Ever watched an old spy movie? I’m talking your classic heists: expensive loot, black tights, ski masks, and the inevitable laser security grid. What if you could own one of those for yourself? For my bartenderbot project (which I am now affectionately calling pi bar) I have been tasked with creating a novel sensor. Since the nature of the product leads to inebriated users, the system needs to be fairly idiot-proof. As such, I am creating a laser security grid for cups.

Bzzzzzzzzzzzzzzzzzzzzz

Beware the laser array

Cup Security

The cups used in this application have a fairly limited size range. The code hard-scales recipes to max out at 12  oz to prevent overflow on Solo cups and shakers, and the smallest drink that makes much sense is 1 oz. As such, we can make some assumptions regarding our cups volume from another property, like height.  This laser security array will read that height (approximately) and give us a best guess of cup size. It is in no way precise, but it will hopefully prevent drunken users from pouring a 12 oz Long Island Iced Tea in to a 1 oz shot glass.

So where do lasers come in to this? EVERYWHERE.  The new design for the cup platform will look like the museum floor around the priceless sculpture centerpiece.  One side of the platform now consists of a  small project box with 3 inconspicuous metal washers sticking out of the side at various heights. The other side looks identical, minus the washers. Instead there are small holes in the box, with no visible parts.

 

WHAT’S IN THE BOX?!

The super secret dark boxes contain 2 cardboard sheets, keeping the insides as dark as possible. This is important for the tiny light dependent resistors (LDRs) nestled in the back. The LDRs are wired to 5V, through a simple comparator to grab an amount of light from their resistance levels. These resistors supply 25 MegaOhms of resistance in relative darkness, and close to 0 Ohms in direct light. I think you can see where this is going. When there is no cup on the platform, all three lasers hit the LDRs head on, supplying our detector circuit with the information we need to determine a cup’s presence. When at least one is blocked, we know SOMETHING is in the way. Using this, we can tell approximately how tall our vessel is to be! 3 lasers allows us to detect a shot glass, low ball and highball.  We are ignoring specialty glasses like martini glasses and margarita glasses for now for simplicity. But this can’t solve all our problems. You see, glasses are often made of glass. Glass is used in many applications for its ability to NOT block light.  So how does the system handles glasses?

 

Thresholding

LDRs are not binary. They are analog (which is another whole problem which will probably get its own blog post once I solve it), meaning they have a large range of resistance, dependent on the AMOUNT of light, rather than the presence. So when a laser passes through a glass, as long as it is weakened, it will be OK. Since glasses are often made of glass >1 micron thick, the scattering of light due to the change in the speed of light is quite noticeable.  Pinholes on the sensor box will allow directed, uninterrupted laser to hit the LDRs head on, but scattered light will hit with much less intensity. A circuit can be used to measure the voltage drop from the increased resistance and “call it” at a certain point. That point is called a threshold. This threshold will need to be experimentally determined due to the near infinite variety of drinking vessels.

 

Project Progress

The laser array has eaten up a fair amount of my time, but this weekend should be a productive one for the pi bar. The design has been created, so a rudimentary parts list is ready for shopping. Once a large amount of PVC and lumber can be acquired, the machine should begin to take shape. I hope to be posting a blog entry with a frame soon, so keep tuned, and keep coding.

Spring Break Pokemon Games

Hey everybody, I’m back! The past few weeks have been a whirlwind of school work and emergencies which finally let up just in time for spring break. Because of my limited time, I was not able to work on my recipe manager or the BartenderBot (much) but I promise I come prepared.  I had mentioned before that I had a tradition of programming digital versions of my favorite drinking games over spring break. Last break I coded Horse Races, and the one before that I made Circle of Death, both of which have a post earlier. This time, I made….

The Pokemon Drinking Game

Most of you know that I love Pokemon, drinking, and programming, so this just made sense. The game itself was designed as a board game some time ago by a user named “raith”. The game has seen many modifications, eventually resulting in the Pokemon Drinking Game 2.0, a circular board based game with many drinks, complicated rules, and a guaranteed good time. The numerous rules to keep track of made this game quite difficult while intoxicated (which occurs about 1/4 of the way through). My version lets the computer worry about movement and turns and instead farms out only the drinking.

Watch the dots move....

The game in mid-play

Making it Work

This game has so many complex rules, movements, turn skips, and history checks that the vast majority of my planned architecture was useless. Unlike a project for school, or work, or fun, this project was for use within the week. As such, clean-code got thrown out in favor of making it work. That is not to say I will not revisit it and clean it up, but for the time being, it is pretty ugly.  Here’s where we sit. There are 3 java packages involved, and they should be clearly named.

Backend – This package contains the control class which controls (duh) everything about game logic, along with any necessary models.

Tiles – There were so many custom tiles needed for weird behaviors, I made a new package of just those custom Tile models.

UI – This houses the GameFrame, which displays the playable part of the game.

These packages do not necessary adhere to their strict responsibilities, but once again, speed and function were emphasized. The Control class is a rather monolithic class, keeping track of all turns, players, tiles, and UI text and screens. All other models are used to store relevant data and have a few important methods. The most important is the Tile class’s landed() function. This method takes a Player (provided by the control when a player lands on a tile) and operates on that player upon the call. This aids in skipped turns or forced moves, along with several more complicated consequences in the specialized tiles.

Help

Unlike any of my other posts, I am pleading to you for help. As I’ve described, the code is ugly, but the far bigger issue is that there are logic failures. The game “plays” and will track you to the end (though the victory image has not been added) but some of the tiles exhibit unwanted behaviors. I am aware of at least one tile where a re-roll results in a move, one which sets the next turn’s movement modifier incorrectly, and a couple other bugs, but they are rather hard to pin down where they occur.

So how you, the reader, the drinker, the good time guy can do to help is play. I have hosted the code in its usual spot on my github (here), and it is free to be grabbed and compiled. If you could play through the game and keep a list of bugs you find, I would love to finish off making this game work. Leave some bug reports in the comments, message me, or if you know me, come up and let me know where you saw problems.  Once the logic is working, I will chip away at the design and appearance until I am satisfied.

As always, code on, and thank you for your help.

Architecture: More Than Drawing Buildings

Chances are, if you are in the habit of speaking to programmers, you will hear someone referred to as an “Architect”. Surely, This person is not the designer of the building, still deeply involved with the company inhabiting it. Surely of all the places in a corporation in which to place such a person, the development team would not be the first choice.  And yet, no dev team would be complete without at least one architect.In case you haven’t figured it out, the architects I am referring to deal with the code architecture. Their job parallels that of a traditional architect in all ways but the medium. Where a traditional architect explores viable designs for the building appearance, the code architect is concerned with the appearance of the code. Just as the traditional architect can draw from Gothic, Renaissance, or Modern structures,  a code architect uses design patterns to match the desired appearance of the code. Design patterns should be familiar to those who have perused code banks before. Patterns such as the Factory Pattern, Singleton Pattern, and  FlyWeight Pattern (more here) are the frameworks off of which code architects build the structure of their application. These applications may have a unique structure by the end, but often include large sections adhering to one or more patterns.

Why do I care?

I am in a unique situation for this question. As a student, I have seen and written MANY poorly architectured programs. I am myself guilty of the monolithic class, every violations of SOLID principles known to man and beast, and cyclical dependencies galore. What sets me apart is that I have seen the error of my ways. At my first development job, I got to work with a veteran of code architecture. He encouraged me to separate concerns, abstract business logic away from models, and write an enterprise software that was maintainable and scalable. The difference in my code was astounding. No longer did I have multi-thousand line classes. No longer need I worry about changing constructors or variable names. The architecture allowed me to create concrete references, set it and forget it.

But… That’s a lot of work…

I know the pain. For instance in my current project I am designing a Pantry Manager/Recipe box/Meal Planner. If I want to make a new button on the UI that saves an item to the pantry I must follow a checklist:

My Recipe Box Architecture

My Recipe Box Architecture

  1. Create Class (in this case some thing like pantryItemModel in the Models Project)
  2. Create method in the relevant Manager (in this case the PantryManager in the Manager Project)
  3. Add method definition to Manager Interface (IPantryManager in the Interfaces Project)
  4. Create method in relevant Data Access Object (DAO) class  (PantryDAO in the Data Project)
  5. Add method definition to the DAO Interface (IPantryDAO in the Interfaces Project)

God forbid I need a new manager or DAO, because then I have to alter the Manager and DAO Factories in the FactoryProject. As you can see, the method call is passed down the chain. This seems unnecessary at a first glance; why not just write the method from the DAO in the UI? It is all about scalability. When the project grows, it is likely to change. The data fetching and saving however is likely to remain constant. By abstracting the business logic away from the data logic, changes can be made on the front end which use the same methods from further back. The structure also allows for project isolation, wherein no class knows about anything but what is needed for its function.

How could this benefit me?

Once the checklist above is complete for all data fetches and saves, the benefits become clear. Now when I want to save a new item in the pantry, I simply gather the form data into a new PantryItemModel, and pass that up the chain with something like this:

//domain call
private void savePantryItem(PantryItemModel pantryItem){
IPantryManager manager = ManagerFactory.getPantryManager();
manager.savePantryItem(pantryItem);
}

With a set of domain calls for each user control, I can rule the WORL- ahem. I mean: I can rapidly code the UI and all gather all necessary data for display or saving. A couple long nights of setting up the architecture turns all the business logic and tweaking in to a few hours work. Mistakes happen, bosses change their minds and clients complain. Isn’t it better to change the wallpaper, rather than rebuild the wall?

Blog Stuff

I would like to formally apologize for my drop-off in posts lately, and let you know whats next. My bartenderbot project has hit a brick wall in the form of limited time. The next step is the construction of the frame for testing, and until I can find the time to hit up Home Depot for some resources, and then construct said resources, the project remains on my shelf. As such, the desire to code has manifested itself in the form of my Recipe manager thingy (which needs a name BTW) so updates on that are coming soon. Until then, grab a drink and code on.

Data Structures

Hey guys, sorry I’m a little late with an update and grasping at straws here for a topic, but I have a good excuse. For those of you who don’t know, Atlanta froze over a couple weeks ago.  Instead of being a responsible student, I let my inner child out and spent my week in the snow instead of doing work. As such, I fell behind and had to do 3 projects this week. Also, I have been doing interviews in all my free time, so I’ve got interview questions on the brain.

Strings. Always Strings.

In every single interview, the coding problem involved string manipulation. After the first interview, I intensively studied the string functions. However, after figuring out more intuitive solutions to most of the problems I learned the real important concept is Data Structures. The majority of programmers will solve a problem using a list or an array first, operating explicitly on strings or lists of strings. This allows the code to be understood easily, while still solving the problem. Problem is that they are usually not optimized at all. Using a data structure can exploit the behaviors of the structure, thus increasing efficiency while decreasing readability. For instance. My example data structure will be a hash table. I will demonstrate the verbose problem solution, and the optimized solution.

The Problem

Given a list of words, organize the words into groups by anagram.

Example :

in: [act, cat, tar, banana, rat]

out: [[act cat],[tar,rat],[banana]]

The verbose method of solving this problem involves iterating over each word and each group (nested) to discover where a word fits, or if you need a new group. This takes a very long time, but is easily readable with clear loops and order.

Readable code for anagram grouping

Readable code for anagram grouping

Its not fast, its not elegant, but it is functional.  On the contrary, a solution using a hash map is functional, fast, but very confusing at a glance. A hashmap uses a method called “hash()” to create an indexed key for data. In this case, creating a hash function which is based off of the component letters of a word allows us to map all words of the same hash value (same letters) into a single group. By exploiting the behaviour of the hash table, we can “chain” all these mapped words into lists, then return all non empty lists. With a mapping and lookup time of O(1) and a hashing time of O(n), we have a very fast function.

Moral

The moral of this post is to never let yourself be contained. A problem often has many sides, some of which could save time and resources. Programming is all about finding the unity between a problem and the desired solution in the language of logic and math. While humans are especially gifted at pattern recognition, it takes a special kind to see the reasoning behind the patterns, and teach a computer to recognize them. Sometimes a String problem is not String problem at all.

Fun with Decoders

When I posted a picture of my BartenderBot project in an earlier post, I received a comment inquiring as to the small number of pins I was using on the pi to control 8 valves. I promised a full post, and by golly I will stick by that promise. The secret of this magical pin reduction is a decoder (also called a DeMultiplexer or a DeMux).

What’s a DeMux?

Toggling a single input

Toggling a single input

A DeMux is a combinational logic circuit. It takes in a set number of “selector” bits and one “enable” bit. The output is a number of pins determined by the maximum number expressed in the number of selector bits (more on that later) where only the one corresponding to the selection is toggled when the enable bit is toggled.

Think of the number of outputs as a binary string. For instance to represent 8 unique numbers in binary, you need log base 2 of the output, which is 3. Three bits can express numbers 0-7, so choosing a binary string who’s value is equal to one of those numbers “selects” that output. Using this, you can turn on any number of inputs (n) with log base 2 selector bits and 1 enable bit.

Quick Example: If you want to turn on the third valve, we need to turn on output 2. So, we set our selector bits to 010 ( append as many zeroes as necessary to the left of that number to fill all selector bits).  Then, we turn on the enable bit.

Programming with a DeMux

Code to provide input to the DeMux

Code to provide input to the DeMux

As the astute among you may have noticed, the DeMux requires a very specific input pattern. The non-decoder method of turning on an output, one pin would be wired to each device and turned on only when the device is needed. With a DeMux, we must share pins across several valves. For instance, every odd output must turn on the least significant bit of the selector. One also must remember that in programming (and the DeMux) number series begin at zeroes, while in typical ordering, numbers start at one.  By simply subtracting 1 from the valve number and converting the result to a binary string, the states of each selector pin can be determined. The basic principle is to iterate through the binary string generated from (valveNum-1). Pins[i].state = (binaryString.charAt(i) == 1).

The pins themselves are controlled by a Java plugin called Pi4J, which allows Java objects to be made which update the GPIO pins on the pi during operation. As you have seen, the objects have fairly simple behaviour. The pins can be set on or off, true or false, high or low (all to the same end), can be pulsed, and (unused in this project so far) can listen for input.

All Together Now

Let’s tie it all together now. A recipe requires 2 oz Vodka (valve 1), 1 oz Peach Schnapps (valve 6), and 9 oz Orange juice (valve 8). For easy math, let’s assume 1 oz takes 1 s.  The recipe sends each instruction to the hardware controller, which turns on the following pins in the correct order:

GPIO17 | GPIO27 | GPIO22 | GPIO23    (time) ->  GPIO17 | GPIO27 | GPIO22 | GPIO23

0001 (2 sec) -> 0000

1011 (1 sec) -> 1010

1111 (9 sec) -> 1110

The DeMux described earlier feeds the relay board and behaves as expected. The obvious drawback here is the “One-hot” behaviour, which means only one valve can pour at a time, but for simplicity, reduced pin numbers, and no risk of backflow the benefits outweigh the disadvantages. I hope this has been a thorough explanation of Decoders, and I hope any interested parties can now make full use of these wonderful IC’s.

Blast from the past, My first coding project

I’m going to be honest here, I’m updating for the poor HR representatives that have to look at this blog for research after reading my resume at the GT career fair. In order to give some personality to this mysterious author who’s thoughts you read so diligently, I have decided to write about my first real coding project!A little background, when I graduated high school, I KNEW I wanted to do Aerospace Engineering. Until orientation at GT (we call it FASET) at which point I decided I KNEW I wanted to do BioChemistry. I believed that new path was the one for me until I took a wonderful class in Computer Science. At that point, I was sure that I had been hasty before, so I waited an entire semester before realizing that this time I REALLY KNEW. So what magical class was so powerful as to make me change majors again and stick with it?

It was Jython

For the uninitiated, Jython is a special blend of the programming language “Python” and some common java libraries. This allows beginner programmers (like myself at the time) to create very clean object-oriented python code in a neat IDE with a console,  and makes visual animations easy.

Jython code in the JES IDE

Jython code in the JES IDE

Jython was my first experience in coding, and it saw my first “Hello World” program, very basic number programming, image manipulations, and eventually animations.  The final project of this class used a unique aspect of Jython called “Turtles”.  You see, in the parallel version of this class which was required for CS majors, the end of the class involved controlling small robots with attached pens around in a pattern. These robots were called ScribblerBots, but they were relatively expensive. Instead, our class made use of the visual libraries provided by java to create small turtles in a picture. The turtles could then be commanded just like the robots, moving and drawing lines, but they could also be used for animation.  By using an array of turtles, each with a certain job, the turtles could change the background to create animation, they could change colors to act as an animated object themselves, or they could drop images on to the screen to create new visual objects.

Our Final Assignment

We were expected to use everything we learned throughout the year to create an animation which satisfied several requirements. As best I can remember them, the minimum  requirements were:

  • Use at least 4 different turtles on the screen at the same time
  • Make at least one turtle change color and size
  • Make a turtle draw, move, stop drawing, and move again
  • Use a randomizer to change at least one attribute of one turtle.  (I went a little crazy on this one)

Beyond those requirements, the assignment was very free form, and we were encouraged to be creative. I took it to heart.

What Horror Hath I Wrought?

Screenshot of the animation

Screenshot of the animation

Pokémon. Registered copyright or trademark or whatever, but let’s be real, it was Pokémon. My goal was to recreate a Pokémon trainer encounter and subsequent battle. For those that have a JES environment (get it here) you can download my code and watch it with full randomness at the usual place. Feel free to download and parse it to see how it works, but remember this is my first real coding work.

For those who have no interest or capability to parse the code and execute it natively, I have a screen recording of the execution.

I hope you enjoy the movie and stay tuned for more!

BartenderBot, As Promised

The Pi Bar

Don't touch

Pi Bar in its current state

If you have read my previous posts, you already know I have been working on a BartenderBot and not much else. If this is your first post to read, I have news for you: I’m building a BartenderBot! The picture doesn’t look like much, so let me break it down for you.

What Is It?

This is a robotic bartender that will dispense simple drinks automatically. One of my hobbies is bartending and mixology, so fusing that hobby with my passion for making things just seemed right.  The idea began as the desire for a robotic dispenser, mixer, and recipe book, and is well underway.

Hardware

Raspberry pi

Raspberry pi

The whole thing is run by a Raspberry pi. These boards are amazing, and for ~40 bucks you can have your own tiny fully-functional computer and control board. In my case I run Raspbian (a debian linux distro built for Raspberry pi) on the pi for full functionality. More on the OS and software in a minute. For now, just know that the software sends commands to General Purpse Input/Output (GPIO) pins on the pi. These pins are jumped to a 3-to-8 demultiplexer. For those of you who are not familiar with this circuit, it takes in 3 selector bits to represent numbers 0-7, and one enable bit to turn on the output selected by the other 3 bits. This allows me to turn 4 pins in to signals with no worry of simultaneous dispensing. From the deMux board the signals travel to a 16-channel 12V relay board.

Relay Board

Relay Board

This awesome Sainsmart board allows me to switch 16 (though I’m only using 8) valves which required 12V/500 mA each using 4 pins on a 3.3V pi! A single 12VDC power source is connected to the board in the form of an AC/DC converter and the power is distributed only to the active relay as chosen by the input pins. The board also prevents back EMF from frying my pi by using opto-isolators, so you know, that’s nice.

Software

The custom drink screen, displaying the recipe for a Sex on the Beach

The custom drink screen, displaying the recipe for a Sex on the Beach

Now, a computer with the power to control fancy dispensers is not very useful if the user has no control over the computer. As I mentioned earlier, the pi has a full linux OS on it, and that could in fact be used to control the machine. However, through a small poll of my friends it was determined that no one wanted to type “echo 1 >gpio(xx)/value” every time they wanted to turn on a valve. Instead, I have coded a Java program which manages premade recipes, a custom drink creator, and a settings screen to change which recipes can be made.  The Java program is loaded on to the pi as a jar, and runs at startup, initializing the pins and displaying a custom UI. The UI can be exited via a secret button, but for the most part, the UI should be the only local interface to the pi. My hope is to add a touchscreen which can be used to make drinks without a mouse or keybord, so the entire UI is made touchscreen-friendly.

 

What’s Next?

I am currently taking a class in which I am required to prototype a machine for a semester-long project, and have decided to make this my project. As such, I will be adding features to meet requirements, but will also have access to way more sophisticated equipment than my home prototyping lab. Hopefully by the end of February I will have base functionality and a frame, but I will be adding sensors, beautifying the UI, and refining the program until April. I will post again once I have a functional prototype, and any Atlanta are alcohol/robot enthusiasts should come give it a test drive.