Advertisement
Guest User

Untitled

a guest
Jun 28th, 2012
572
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.03 KB | None | 0 0
  1. /**********************************************************
  2. the untappd kegerator
  3.  
  4. 2012, Jeff Karpinski.
  5. No copyright or warranty, express or implied.
  6. Use as you see fit! Make it your own!
  7.  
  8. Revision history
  9. 2012.06.24 1.0 Initial code
  10. 2012.06.27 1.1 wait, what? millis() returns a DOUBLE word?!?!
  11. **********************************************************/
  12. #include <SPI.h>
  13. #include <Ethernet.h>
  14. #include <avr/eeprom.h>
  15.  
  16. #define FLOWTAP1PIN 2
  17. #define FLOWTAP2PIN 3
  18. #define TAP1LED 4
  19. #define TAP2LED 5
  20. #define OVERRIDEPIN 6
  21.  
  22. //ethernet stuff - set as appropriate
  23. byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
  24. IPAddress myip(192, 168, 0, 11);
  25. IPAddress mygw(192, 168, 0, 254);
  26. IPAddress untappdip(184, 106, 111, 128);
  27.  
  28. //untappd stuff
  29. const String untappdapikey = "XXXXXXXXXXXXXXXXX"; //you must apply to Untappd for this
  30. const String untappdauth = "XXXXXXXXXXXXXXXXX"; //Base64 encoding of username:md5hashedpassword
  31. const String untappdgmtoffset = "-7"; //your GMT offset (for correct checkin times)
  32.  
  33. volatile uint8_t lastflowtap1state; //saved high/low state from flow meters
  34. volatile uint8_t lastflowtap2state;
  35. volatile uint16_t ratetimer = 0; //simple counter to determine 1 second lapsed
  36. volatile uint16_t tap1pulsecount = 0; // number of flow sensor rotations in 1 second
  37. volatile uint16_t tap2pulsecount = 0;
  38. volatile uint16_t tap1flowrate = 0; //rpm
  39. volatile uint16_t tap2flowrate = 0;
  40. volatile uint32_t pouredTime = 0; //saved time of last pour in ms
  41. volatile uint8_t justpoured = 0; //flag to prevent multiple checkins from top-offs
  42. String command = ""; //http data returned
  43.  
  44. EthernetServer server(80);
  45. EthernetClient untappd;
  46.  
  47. // Interrupt is called once a millisecond
  48. SIGNAL(TIMER0_COMPA_vect) {
  49. ratetimer++;
  50. if (ratetimer == 1000) { // 1 second has lapsed - calc RPMs
  51. ratetimer = 0;
  52. tap1flowrate = tap1pulsecount * 60;
  53. tap2flowrate = tap2pulsecount * 60;
  54. tap1pulsecount = 0;
  55. tap2pulsecount = 0;
  56. }
  57. uint8_t x = digitalRead(FLOWTAP1PIN);
  58. if (x != lastflowtap1state) {
  59. lastflowtap1state = x;
  60. if (x == HIGH) tap1pulsecount++;
  61. }
  62. x = digitalRead(FLOWTAP2PIN);
  63. if (x != lastflowtap2state) {
  64. lastflowtap2state = x;
  65. if (x == HIGH) tap2pulsecount++;
  66. }
  67. }
  68.  
  69. void useInterrupt(boolean v) {
  70. if (v) {
  71. OCR0A = 0xAF;
  72. TIMSK0 |= _BV(OCIE0A);
  73. } else {
  74. TIMSK0 &= ~_BV(OCIE0A);
  75. }
  76. }
  77.  
  78. // string to integer converter
  79. uint32_t satoi(String data) {
  80. uint32_t r = 0;
  81. char str[data.length()];
  82. data.toCharArray(str,data.length());
  83. int len = strlen(str);
  84. for(int i=0; i<len; i++){
  85. if ( str[i] < 0x3a && str[i] > 0x2f){ //Check if this digit is a number
  86. r = r * 10;
  87. r += (str[i]-0x30);
  88. } else break; // non-numeric - bail and send what we got so far
  89. }
  90. return r;
  91. }
  92.  
  93. // perform Untappd api checkin call
  94. void checkIn(uint32_t bid) {
  95. if (untappd.connect(untappdip, 80)) {
  96. untappd.print("POST /v3/checkin?key=");
  97. untappd.print(untappdapikey);
  98. untappd.println(" HTTP/1.1");
  99. untappd.println("Host: api.untappd.com");
  100. untappd.print("Authorization: Basic ");
  101. untappd.println(untappdauth);
  102. untappd.println("Content-Type: application/x-www-form-urlencoded");
  103. untappd.println("Content-Length: 64");
  104. untappd.println();
  105. untappd.print("gmt_offset=");
  106. untappd.print(untappdgmtoffset);
  107. untappd.print("&shout=Checkin via the Untappd Kegerator&bid=");
  108. untappd.println(bid);
  109. } else { //failed to connect. blink out the error and clear pour
  110. for (int i = 0; i < 11 ; i++) {
  111. digitalWrite(TAP1LED, LOW);
  112. digitalWrite(TAP2LED, HIGH);
  113. delay(50);
  114. digitalWrite(TAP2LED, LOW);
  115. digitalWrite(TAP1LED, HIGH);
  116. delay(50);
  117. }
  118. digitalWrite(TAP1LED, LOW);
  119. digitalWrite(TAP2LED, LOW);
  120. justpoured = 0;
  121. }
  122. while (untappd.connected()) { //gobble up return data from server
  123. if (untappd.available()) { //room for improvement here - we're just assuming checkin went through
  124. char c = untappd.read();
  125. //Serial.print(c); // for debugging server response
  126. }
  127. }
  128. // close the connection:
  129. untappd.stop();
  130. }
  131.  
  132. void setup() {
  133. //Serial.begin(9600); // for debugging server response
  134. Ethernet.begin(mac, myip, mygw, mygw);
  135. server.begin();
  136. pinMode(FLOWTAP1PIN, INPUT);
  137. digitalWrite(FLOWTAP1PIN, HIGH);
  138. lastflowtap1state = digitalRead(FLOWTAP1PIN);
  139. pinMode(FLOWTAP2PIN, INPUT);
  140. digitalWrite(FLOWTAP2PIN, HIGH);
  141. lastflowtap2state = digitalRead(FLOWTAP2PIN);
  142. useInterrupt(true);
  143. pinMode(OVERRIDEPIN, INPUT);
  144. digitalWrite(OVERRIDEPIN, HIGH);
  145. pinMode(TAP1LED, OUTPUT);
  146. pinMode(TAP2LED, OUTPUT);
  147. }
  148.  
  149. void loop() {
  150. EthernetClient client = server.available();
  151. if (client) { //someone wants to change BIDs
  152. // an http request ends with a blank line
  153. boolean currentLineIsBlank = true;
  154. while (client.connected()) {
  155. if (client.available()) {
  156. char c = client.read();
  157. // if you've gotten to the end of the line (received a newline
  158. // character) and the line is blank, the http request has ended,
  159. // so you can send a reply
  160. if (c == '\n' && currentLineIsBlank) {
  161. // send a standard http response header
  162. client.println("HTTP/1.1 200 OK");
  163. client.println("Content-Type: text/html");
  164. client.println();
  165. // webpage title
  166. client.println("<center><p><h1>Untappd kegerator v1.1</h1></p><center><hr><br />");
  167. // form
  168. client.println("<form method=get name=form>");
  169. client.print("Tap #1 BID: <input type=text name=tap1 value=");
  170. client.print(eeprom_read_dword((uint32_t*)0));
  171. client.println(" maxlength=6 /><br />");
  172. client.print("Tap #2 BID: <input type=text name=tap2 value=");
  173. client.print(eeprom_read_dword((uint32_t*)4));
  174. client.println(" maxlength=6 /><br />");
  175. client.println("<input type=submit value=Submit />");
  176. client.println("</form><br />");
  177. // webpage footer
  178. client.println("<hr><center><a href=http://untappd.com>Untappd home</a><br />");
  179. break;
  180. }
  181. if (c == '\n') {
  182. // you're starting a new line
  183. currentLineIsBlank = true;
  184. // see if we got updated BID values & save to EEPROM
  185. for (int i = 0; i < command.length() ; i++) {
  186. if (command.substring(i,i+4) == "tap1") {
  187. eeprom_write_dword((uint32_t*)0,satoi(command.substring(i+5)));
  188. break;
  189. }
  190. }
  191. for (int i = 0; i < command.length() ; i++) {
  192. if (command.substring(i,i+4) == "tap2") {
  193. eeprom_write_dword((uint32_t*)4,satoi(command.substring(i+5)));
  194. break;
  195. }
  196. }
  197. command = "";
  198. }
  199. else if (c != '\r') {
  200. // you've gotten a character on the current line
  201. currentLineIsBlank = false;
  202. command += c;
  203. }
  204. }
  205. }
  206. // give the web browser time to receive the data
  207. delay(1);
  208. // close the connection:
  209. client.stop();
  210. }
  211. if (digitalRead(OVERRIDEPIN) == LOW) { //override button pressed - suppress checkins
  212. justpoured = 1;
  213. digitalWrite(TAP1LED, HIGH);
  214. digitalWrite(TAP2LED, HIGH);
  215. pouredTime = millis();
  216. }
  217. if (justpoured) { //pour recently happened (or override on)
  218. uint32_t timePassed = millis() - pouredTime;
  219. if (timePassed > 300000) { //5 min
  220. justpoured = 0;
  221. digitalWrite(TAP1LED, LOW);
  222. digitalWrite(TAP2LED, LOW);
  223. }
  224. } else {
  225. if (tap1flowrate > 60) { //tap 1 pouring - check it in!
  226. justpoured = 1;
  227. pouredTime = millis();
  228. digitalWrite(TAP1LED, HIGH);
  229. checkIn(eeprom_read_dword((uint32_t*)0));
  230. }
  231. if (tap2flowrate > 60) { //tap 2 pouring - check it in!
  232. justpoured = 1;
  233. pouredTime = millis();
  234. digitalWrite(TAP2LED, HIGH);
  235. checkIn(eeprom_read_dword((uint32_t*)4));
  236. }
  237. }
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement