Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**********************************************************
- the untappd kegerator
- 2012, Jeff Karpinski.
- No copyright or warranty, express or implied.
- Use as you see fit! Make it your own!
- Revision history
- 2012.06.24 1.0 Initial code
- 2012.06.27 1.1 wait, what? millis() returns a DOUBLE word?!?!
- **********************************************************/
- #include <SPI.h>
- #include <Ethernet.h>
- #include <avr/eeprom.h>
- #define FLOWTAP1PIN 2
- #define FLOWTAP2PIN 3
- #define TAP1LED 4
- #define TAP2LED 5
- #define OVERRIDEPIN 6
- //ethernet stuff - set as appropriate
- byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
- IPAddress myip(192, 168, 0, 11);
- IPAddress mygw(192, 168, 0, 254);
- IPAddress untappdip(184, 106, 111, 128);
- //untappd stuff
- const String untappdapikey = "XXXXXXXXXXXXXXXXX"; //you must apply to Untappd for this
- const String untappdauth = "XXXXXXXXXXXXXXXXX"; //Base64 encoding of username:md5hashedpassword
- const String untappdgmtoffset = "-7"; //your GMT offset (for correct checkin times)
- volatile uint8_t lastflowtap1state; //saved high/low state from flow meters
- volatile uint8_t lastflowtap2state;
- volatile uint16_t ratetimer = 0; //simple counter to determine 1 second lapsed
- volatile uint16_t tap1pulsecount = 0; // number of flow sensor rotations in 1 second
- volatile uint16_t tap2pulsecount = 0;
- volatile uint16_t tap1flowrate = 0; //rpm
- volatile uint16_t tap2flowrate = 0;
- volatile uint32_t pouredTime = 0; //saved time of last pour in ms
- volatile uint8_t justpoured = 0; //flag to prevent multiple checkins from top-offs
- String command = ""; //http data returned
- EthernetServer server(80);
- EthernetClient untappd;
- // Interrupt is called once a millisecond
- SIGNAL(TIMER0_COMPA_vect) {
- ratetimer++;
- if (ratetimer == 1000) { // 1 second has lapsed - calc RPMs
- ratetimer = 0;
- tap1flowrate = tap1pulsecount * 60;
- tap2flowrate = tap2pulsecount * 60;
- tap1pulsecount = 0;
- tap2pulsecount = 0;
- }
- uint8_t x = digitalRead(FLOWTAP1PIN);
- if (x != lastflowtap1state) {
- lastflowtap1state = x;
- if (x == HIGH) tap1pulsecount++;
- }
- x = digitalRead(FLOWTAP2PIN);
- if (x != lastflowtap2state) {
- lastflowtap2state = x;
- if (x == HIGH) tap2pulsecount++;
- }
- }
- void useInterrupt(boolean v) {
- if (v) {
- OCR0A = 0xAF;
- TIMSK0 |= _BV(OCIE0A);
- } else {
- TIMSK0 &= ~_BV(OCIE0A);
- }
- }
- // string to integer converter
- uint32_t satoi(String data) {
- uint32_t r = 0;
- char str[data.length()];
- data.toCharArray(str,data.length());
- int len = strlen(str);
- for(int i=0; i<len; i++){
- if ( str[i] < 0x3a && str[i] > 0x2f){ //Check if this digit is a number
- r = r * 10;
- r += (str[i]-0x30);
- } else break; // non-numeric - bail and send what we got so far
- }
- return r;
- }
- // perform Untappd api checkin call
- void checkIn(uint32_t bid) {
- if (untappd.connect(untappdip, 80)) {
- untappd.print("POST /v3/checkin?key=");
- untappd.print(untappdapikey);
- untappd.println(" HTTP/1.1");
- untappd.println("Host: api.untappd.com");
- untappd.print("Authorization: Basic ");
- untappd.println(untappdauth);
- untappd.println("Content-Type: application/x-www-form-urlencoded");
- untappd.println("Content-Length: 64");
- untappd.println();
- untappd.print("gmt_offset=");
- untappd.print(untappdgmtoffset);
- untappd.print("&shout=Checkin via the Untappd Kegerator&bid=");
- untappd.println(bid);
- } else { //failed to connect. blink out the error and clear pour
- for (int i = 0; i < 11 ; i++) {
- digitalWrite(TAP1LED, LOW);
- digitalWrite(TAP2LED, HIGH);
- delay(50);
- digitalWrite(TAP2LED, LOW);
- digitalWrite(TAP1LED, HIGH);
- delay(50);
- }
- digitalWrite(TAP1LED, LOW);
- digitalWrite(TAP2LED, LOW);
- justpoured = 0;
- }
- while (untappd.connected()) { //gobble up return data from server
- if (untappd.available()) { //room for improvement here - we're just assuming checkin went through
- char c = untappd.read();
- //Serial.print(c); // for debugging server response
- }
- }
- // close the connection:
- untappd.stop();
- }
- void setup() {
- //Serial.begin(9600); // for debugging server response
- Ethernet.begin(mac, myip, mygw, mygw);
- server.begin();
- pinMode(FLOWTAP1PIN, INPUT);
- digitalWrite(FLOWTAP1PIN, HIGH);
- lastflowtap1state = digitalRead(FLOWTAP1PIN);
- pinMode(FLOWTAP2PIN, INPUT);
- digitalWrite(FLOWTAP2PIN, HIGH);
- lastflowtap2state = digitalRead(FLOWTAP2PIN);
- useInterrupt(true);
- pinMode(OVERRIDEPIN, INPUT);
- digitalWrite(OVERRIDEPIN, HIGH);
- pinMode(TAP1LED, OUTPUT);
- pinMode(TAP2LED, OUTPUT);
- }
- void loop() {
- EthernetClient client = server.available();
- if (client) { //someone wants to change BIDs
- // an http request ends with a blank line
- boolean currentLineIsBlank = true;
- while (client.connected()) {
- if (client.available()) {
- char c = client.read();
- // if you've gotten to the end of the line (received a newline
- // character) and the line is blank, the http request has ended,
- // so you can send a reply
- if (c == '\n' && currentLineIsBlank) {
- // send a standard http response header
- client.println("HTTP/1.1 200 OK");
- client.println("Content-Type: text/html");
- client.println();
- // webpage title
- client.println("<center><p><h1>Untappd kegerator v1.1</h1></p><center><hr><br />");
- // form
- client.println("<form method=get name=form>");
- client.print("Tap #1 BID: <input type=text name=tap1 value=");
- client.print(eeprom_read_dword((uint32_t*)0));
- client.println(" maxlength=6 /><br />");
- client.print("Tap #2 BID: <input type=text name=tap2 value=");
- client.print(eeprom_read_dword((uint32_t*)4));
- client.println(" maxlength=6 /><br />");
- client.println("<input type=submit value=Submit />");
- client.println("</form><br />");
- // webpage footer
- client.println("<hr><center><a href=http://untappd.com>Untappd home</a><br />");
- break;
- }
- if (c == '\n') {
- // you're starting a new line
- currentLineIsBlank = true;
- // see if we got updated BID values & save to EEPROM
- for (int i = 0; i < command.length() ; i++) {
- if (command.substring(i,i+4) == "tap1") {
- eeprom_write_dword((uint32_t*)0,satoi(command.substring(i+5)));
- break;
- }
- }
- for (int i = 0; i < command.length() ; i++) {
- if (command.substring(i,i+4) == "tap2") {
- eeprom_write_dword((uint32_t*)4,satoi(command.substring(i+5)));
- break;
- }
- }
- command = "";
- }
- else if (c != '\r') {
- // you've gotten a character on the current line
- currentLineIsBlank = false;
- command += c;
- }
- }
- }
- // give the web browser time to receive the data
- delay(1);
- // close the connection:
- client.stop();
- }
- if (digitalRead(OVERRIDEPIN) == LOW) { //override button pressed - suppress checkins
- justpoured = 1;
- digitalWrite(TAP1LED, HIGH);
- digitalWrite(TAP2LED, HIGH);
- pouredTime = millis();
- }
- if (justpoured) { //pour recently happened (or override on)
- uint32_t timePassed = millis() - pouredTime;
- if (timePassed > 300000) { //5 min
- justpoured = 0;
- digitalWrite(TAP1LED, LOW);
- digitalWrite(TAP2LED, LOW);
- }
- } else {
- if (tap1flowrate > 60) { //tap 1 pouring - check it in!
- justpoured = 1;
- pouredTime = millis();
- digitalWrite(TAP1LED, HIGH);
- checkIn(eeprom_read_dword((uint32_t*)0));
- }
- if (tap2flowrate > 60) { //tap 2 pouring - check it in!
- justpoured = 1;
- pouredTime = millis();
- digitalWrite(TAP2LED, HIGH);
- checkIn(eeprom_read_dword((uint32_t*)4));
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement