Bubble-counter for beer brewing

I’ve to make a sensor for counting bubbles in the beer fermentor I have downstairs in the basement. I had to work quickly to get some results, since the fermentation probably will slow down within a couple of days.

The idea is from this post and this post, essentially using an infrared diode + an infrared transistor to sense when a bubble passes through the air-lock. The demo-data is quite erratic (as seen below) 🙂 but the bubble-counter mechanism seems to work ok-ish (I don’t think I’m really counting actual bubbles, but the count is related at least). I should probably count over a longer period of time.

BubbleCounter

 

And the temperature is measures (with a separate MSP430 board and separate wifi-module) using DS18B20 1-wire sensor, bought on Aliexpress for 1.2 USD. It is encased in stainless steel, but I haven’t actually put it into the beer… it’s taped onto the outside of the bucket.

 

And since the above live feed will fade away in history as my brewing ends, here’s a screenshot:

ubidots

The original code comes from a 43oh.com post, but has been changed by me a bit.

The code now is pretty ugly, but for those who can take it, here it is:

#define SSID “piano”
#define PASS “xxx”
#define DST_IP “things.ubidots.com”
#define idvariableTemp “xxx” // replace with your Ubidots Variable ID
#define idvariableCount “xxx” // replace with your Ubidots Variable ID
#define token “xxx” // replace with your Ubidots token
int len;
volatile int dropCounter = 0;
volatile int state = LOW;

#define POS_TRANS P1_5
#define NEG_TRANS P1_4
#define BLUE P2_5
#define RED P2_4
#define GREEN P2_3

void setup()
{
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(RED, OUTPUT);
pinMode(POS_TRANS, INPUT_PULLUP);
pinMode(NEG_TRANS, OUTPUT);
digitalWrite(NEG_TRANS, LOW);
attachInterrupt(POS_TRANS, drop, FALLING);
digitalWrite(GREEN, LOW);
digitalWrite(RED, LOW);
digitalWrite(BLUE, LOW);
analogReference(INTERNAL1V5);
analogRead(TEMPSENSOR);

// Open serial communications and wait for port to open:
char cmd[254];
Serial.begin(9600);
Serial.setTimeout(5000);
//test if the module is ready
Serial.println(“AT+RST”);
delay(1000);
if (Serial.find(“ready”))
{
//dbgSerial.println(“Module is ready”);
}
else
{
//dbgSerial.println(“Module have no response.”);
while (1);
}
delay (1000);
//connect to the wifi
boolean connected = false;
for (int i = 0; i < 5; i++)
{
if (connectWiFi())
{
connected = true;
break;
}
}
if (!connected) {
while (1);
}
delay(5000);
Serial.println(“AT+CIPMUX=0”);
}

void loop()
{

int dropCountSinceLast = dropCounter;
dropCounter = 0;
String var = “{\”value\”:”+ String(dropCountSinceLast)+”.0}”;
reportWeb(idvariableCount, var);

//reportWeb(idvariableTemp, varCount);

}

void reportWeb(const char* idvariable, String var)
{

int num = var.length();
String cmd = “AT+CIPSTART=\”TCP\”,\”things.ubidots.com\”,80″;
//cmd += DST_IP;
//cmd += “\”,80″;
Serial.println(cmd);
if (Serial.find(“Error”)) return;

len=strlen (“POST /api/v1.6/datasources/”);
len=len+strlen (idvariable);
len=len+strlen (“/values HTTP/1.1\nContent-Type: application/json\nContent-Length: “);
char numlenght[4]; // this will hold the length of num which is the length of the JSON element
sprintf(numlenght, “%d”, num); // saw this clever code off the net; works yay
len=len+strlen (numlenght);
len=len + num; //fixed length of the string that will print as Content-Length: in the POST
len=len+strlen (“\nX-Auth-Token: “);
len=len+strlen (token);
len=len+strlen (“\nHost: things.ubidots.com\n\n”);
len=len+strlen (“\n\n”);
Serial.print(“AT+CIPSEND=”);
Serial.println (len); //lenght of the entire data POST for the CIPSEND command of ESP2866
//Serial.println(cmd.length());
if (Serial.find(“>”))
{
//Serial.print(“>”);
} else
{
Serial.println(“AT+CIPCLOSE”);
delay(1000);
return;
}
Serial.print (“POST /api/v1.6/variables/”);
Serial.print (idvariable);
Serial.print (“/values HTTP/1.1\nContent-Type: application/json\nContent-Length: “);
Serial.print (num);
Serial.print (“\nX-Auth-Token: “);
Serial.print (token);
Serial.print (“\nHost: things.ubidots.com\n\n”);
Serial.print (var);
Serial.println (“\n\n”);
delay(9000);
//Serial.find(“+IPD”); clear the input buffer after the web site responds to the POST
while (Serial.available())
{
char c = Serial.read();
}
delay(1000);
}

boolean connectWiFi()
{
Serial.println(“AT+CWMODE=1”);
String cmd = “AT+CWJAP=\””;
cmd += SSID;
cmd += “\”,\””;
cmd += PASS;
cmd += “\””;
Serial.println(cmd);
delay(2000);
if (Serial.find(“OK”))
{
return true;
} else
{
return false;
}
}

void drop()
{
dropCounter++;
state = !state;
digitalWrite(BLUE, state);
//digitalWrite(BLUE, HIGH);
//delay(100);
//digitalWrite(BLUE, LOW);
}

Leave a Reply

Your email address will not be published. Required fields are marked *