Smart Beer

My first project using an Arduino micro-controller. Detect when my glass is getting low on beer and then send a message indicating I need a refill! The message can be sent using either Cisco Spark (demoed in the below video) or Twitter.



Yes, I'm using a straw with beer. Don't judge. How else am I supposed to do this on camera? Maybe the next version it will be integrated in the glass...

There was some issue with fluctuating sensor readings. Perhaps the beer had too much carbonation which affected the analog water sensor (it worked much better in plain water). Maybe I'll try again with wine next time.

Electrical Connections

Fairly straightforward here.

Arduino Code

This is also using an Ethernet shield attached to the base Arduino board. However since the ethernet shield cannot natively handle HTTPS (!) the code is calling a local web server which in turn will proxy the specific request to either Twitter or Cisco Spark to actually post the message securely.
#include <SPI.h> #include <Ethernet.h> #include <HttpClient.h> // Enter a MAC address for your controller byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; // Initialize the Ethernet client library EthernetClient client; bool messageSent1; bool messageSent2; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); pinMode(9,OUTPUT); Serial.println("Starting ethernet"); Ethernet.begin(mac); messageSent1 = false; messageSent2 = false; Serial.println("Setup complete"); } void loop() { switch (Ethernet.maintain()) { case 1: //renewed fail Serial.println("Error: renewed fail"); break; case 2: //renewed success Serial.println("Renewed success"); break; case 3: //rebind fail Serial.println("Error: rebind fail"); break; case 4: //rebind success Serial.println("Rebind success"); break; default: break; } /* 0mm - 480 5mm - 530 10mm - 615 15mm - 660 20mm - 680 25mm - 690 30mm - 700 35mm - 705 40mm - 710 */ Serial.print("Analog signal: "); Serial.println(analogRead(A0)); delay(100); if (analogRead(A0) < 650) { digitalWrite(9,HIGH); if (!messageSent2) { String msg = "I need a refill!"; sendSpark(msg); messageSent2 = true; } } else if (analogRead(A0) < 700) { if (!messageSent1) { String msg = "Oh no, my drink is getting low!"; sendSpark(msg); messageSent1 = true; } } else { digitalWrite(9,LOW); } } void checkIP() { Serial.println("checking IP"); String localIP = DisplayAddress(Ethernet.localIP()); if (localIP == "255.255.255.255") { Serial.println(" no ip"); } else { Serial.println(" have ip"); } } void printIPAddress() { Serial.print("My IP address: "); for (byte thisByte = 0; thisByte < 4; thisByte++) { // print the value of each byte of the IP address: Serial.print(Ethernet.localIP()[thisByte], DEC); Serial.print("."); } Serial.println(); } String DisplayAddress(IPAddress address) { return String(address[0]) + "." + String(address[1]) + "." + String(address[2]) + "." + String(address[3]); } //client function to send/receive GET request data. void sendSpark(String message) { message = URLEncode(message); Serial.println("sending message"); String getparams = "GET /serve.php?app=arduino&function=1&msg=" + message + " HTTP/1.0"; Serial.println(getparams); if (client.connect("192.168.1.130", 80)) { //starts client connection, checks for connection Serial.println("connected"); client.println(getparams); //download text client.println(); //end of get request } else { Serial.println("connection failed"); //error message if no client connect Serial.println(); } while(client.connected() && !client.available()) delay(1); //waits for data while (client.connected() || client.available()) { //connected or data available char c = client.read(); //gets byte from ethernet buffer Serial.print(c); //prints byte to serial monitor } Serial.println("Spark message sent"); client.stop(); //stop client } //client function to send/receive GET request data. void sendTweet(String message) { message = URLEncode(message); Serial.println("sending message"); String getparams = "GET /serve.php?app=arduino&function=1&msg=" + message + " HTTP/1.0"; if (client.connect("192.168.1.130", 80)) { //starts client connection, checks for connection Serial.println("connected"); client.println(getparams); //download text client.println(); //end of get request } else { Serial.println("connection failed"); //error message if no client connect Serial.println(); } while(client.connected() && !client.available()) delay(1); //waits for data while (client.connected() || client.available()) { //connected or data available char c = client.read(); //gets byte from ethernet buffer Serial.print(c); //prints byte to serial monitor } Serial.println("Tweet sent"); client.stop(); //stop client } String URLEncode(String originalMessage) { const char* msg = originalMessage.c_str(); const char *hex = "0123456789abcdef"; String encodedMsg = ""; while (*msg!='\0'){ if( ('a' <= *msg && *msg <= 'z') || ('A' <= *msg && *msg <= 'Z') || ('0' <= *msg && *msg <= '9') ) { encodedMsg += *msg; } else { encodedMsg += '%'; encodedMsg += hex[*msg >> 4]; encodedMsg += hex[*msg & 15]; } msg++; } return encodedMsg; }