Multiple Fermenter Temperature-Controlled DIY Glycol System

Hello everyone, first time poster, long time creeper of the site. My name is Mike and I’d like to call myself a tinkerer/DIYer.

My goal is to create a solar-powered mobile nano-brewery and fermentation system. That way I don’t need to pay for land/rent, taxes, ventilation, utility costs, etc. Kind of ambitious, I know, but I’ve done a lot of research and I know it’s possible!! I just need to spend the money and take the time to put everything together. To establish initial street cred, I’ll have you know that I’ve already modified a stainless steel half barrel keg into an electric mash tun outfitted with a 240v 3500w heating element, custom false bottom, and welded faucet for emptying. Outside I’ve got the heating element controlled by a PID with a relay. I wired it all myself by blending a couple YouTube projects together. I’m really excited about my achievements so far and I really need your help going forward. My roommate is much more familiar with Arduino than myself so he’s willing to help, but he wanted me to get more info from this forum first. I can also provide pictures if people are interested. Anyway, I’ll just jump right in then!

So, in brewing there’s the “hot side”, which I just described above. Grain is essentially steeped in hot water and then boiled to sterilize. Then the wort is cooled down to yeast pitching temperature (below about 90 degrees F) and then a chilling controller brings the fermenter down to 70s and 80s for wine/champagne, 60s and 70s for ales, 40s and 50s for lagers. I wanna make lagers… This is where the “cold side” comes in, where the wort is cooled so that the specific yeast you want to take hold can survive/thrive. This is where I need your help: I have a 9 gallon all-stainless steel conical hopper with sanitary fittings–one of which has a ds18b20 temp sensor on the inside of the vessel–and a copper coil I had welded on the outside so as to act like a “jacketed” fermenter cooled with a glycol chilling system by pumping cold glycol-water inside and through the copper tubing surrounding the outside of the fermenter, thereby, thermodynamically pulling out the heat from the inside of the fermenter and recirculating it back into the DIY glycol chilling system. The idea is to get as cold as possible for as cheap as possible hahah. I’ve seen online DIY glycol chillers using a window a/c unit’s cold side in a cooler filled with water. The water get’s cold and a submersible pump pumps the cold water inside and through the copper tubing, returning to the cooler to be cooled again repeating the process over again. It’s not the most glamourous setup but it’s at least half as expensive as an actual Glycol chilling system you might get from a manufacture. Here’s a video of what I’m talking about, where a guy uses a Ranco controller: DIY Glycol Chiller - YouTube

If my concept is viable, (which based on some youtube videos, it is in theory!!), I want to be able to add more fermenters using the one DIY glycol chilling system, one Arduino. So, basically, a submergible pump (with constant flow) will be interrupted by a solenoid valve which controls the flow of glycol-water going to one of the 3+ fermenters. The Arduino will match temperature with solenoid valve “openness”. So I’m imagining if I want the temp inside the fermenter to be 45 degrees, this will correspond to a solenoid valve openness of “25%”, something like that.

I know I’ll need some form of the code below which I ripped from this website: Guide for DS18B20 Temperature Sensor with Arduino | Random Nerd Tutorials
How would I prompt the Arduino to tell solenoid valve #1 to open or close depending on temperature sensor #1? How similar or dissimilar will the code be in comparison to the “Garduino” projects I’ve seen?

void setup(void) {
 // start serial port
 Serial.begin(9600);
 
 // Start up the library
 sensors.begin();
 
 // Grab a count of devices on the wire
 numberOfDevices = sensors.getDeviceCount();
 
 // locate devices on the bus
 Serial.print("Locating devices...");
 Serial.print("Found ");
 Serial.print(numberOfDevices, DEC);
 Serial.println(" devices.");

 // Loop through each device, print out address
 for(int i=0;i<numberOfDevices; i++) {
   // Search the wire for address
   if(sensors.getAddress(tempDeviceAddress, i)) {  // Finds the sensors' addresses
     Serial.print("Found device ");
     Serial.print(i, DEC);
     Serial.print(" with address: ");
     printAddress(tempDeviceAddress);
     Serial.println();
   } else {
     Serial.print("Found ghost device at ");
     Serial.print(i, DEC);
     Serial.print(" but could not detect address. Check power and cabling");
   }
 }
}

void loop(void) { 
 sensors.requestTemperatures(); // Send the command to get temperatures
 
 // Loop through each device, print out temperature data
 for(int i=0;i<numberOfDevices; i++) {
   // Search the wire for address
   if(sensors.getAddress(tempDeviceAddress, i)){
   
   // Output the device ID
   Serial.print("Temperature for device: ");
   Serial.println(i,DEC);

   // Print the data
   float tempC = sensors.getTempC(tempDeviceAddress);  // Accepts as argument the device address from specific sensors
   Serial.print("Temp C: ");
   Serial.print(tempC);
   Serial.print(" Temp F: ");
   Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
   }   
 }
 delay(5000);
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress) {
 for (uint8_t i = 0; i < 8; i++) {
   if (deviceAddress[i] < 16) Serial.print("0");
     Serial.print(deviceAddress[i], HEX);
 }
}

Firstly I would put your code inside code tags before the forum police get to you.

Secondly, once you have completed the project I might steal it. :wink:

Thirdly, "My name is Mike and I'd like to call myself a tinkerer/DIYer." you should add moonshiner. :wink:

mvigno2:
How would I prompt the Arduino to tell solenoid valve #1 to open or close depending on temperature sensor #1? How similar or dissimilar will the code be in comparison to the "Garduino" projects I've seen?

Do you understand how the code you have posted is intended to work - do you even know if it does work?

You need to understand a program before you start thinking about modifying it. Often it is actually easier to build a program from scratch rather than modify an existing program.

The first step in programming for any non-trivial project is to write down (in English, not code) a very detailed description of all the actions and decisions that the program will have to do. Write each item on a separate line. It will be much easier to think about the problem this way as you don't have to worry about the syntax required for program code. When you have the completed description you will find that turning it into code is straightforward.

...R

you should add moonshiner

Well moonshine is liquor. I'd have to make beer first, ferment it, then distill it. Ergo, whiskey is essentially distilled grain beer. Likewise, brandy is distilled wine. I'd love to own my own pot still one day, but home-distilling is illegal in all US states besides Missouri (I'm in Illinois). I've researched that stuff too though. I need to achieve a good beer and wine fermentation set-up first. Haha, one day for sure! But I appreciate the sentiment, nonetheless.

Do you understand how the code you have posted is intended to work - do you even know if it does work?

You need to understand a program before you start thinking about modifying it. Often it is actually easier to build a program from scratch rather than modify an existing program. You need to understand a program before you start thinking about modifying it. Often it is actually easier to build a program from scratch rather than modify an existing program.

Thank you for responding. It means a lot to me you'd take the time to read this, ask technical questions, and give me positive/constructive criticism. No, I haven't seen if the code works. My intention was to show effort by including links and possible examples of code to work from, but honestly, no I don't know how to write a code from scratch. I was hoping I could get help from someone. I can pay for your time in beer hahah. While I've taken the time to review as many YouTube videos and project websites like: "beginner Arduino projects", but also specific videos on "Arduino controlled solenoid valves", "ds18b20 temp probe code", "Arduino solenoid valve code", or related stuff like "garduino code"; I still haven't found exactly what I'm looking for. Anyway, I'm not looking for a handout, I'm politely asking for help because I'm totally fresh to computer coding.

description of all the actions and decisions that the program will have to do... When you have the completed description you will find that turning it into code is straightforward

Ok before I try to draft a decision list far as the code is concerned, I might need to ask more about what other considerations need to be made about the code itself. I'm hoping to have the Arduino operated via a Wi-Fi connected laptop, and do monitoring of data and sensors from there, with no no built-in LCD screen or buttons. The submersible pump will be turned on at all times for consistent water pressure and have a return hose back for overdraft and return leads. The valve "openness" will dictate the amount of cool water being circulated around the fermentation vessel.

From what I understand, the Arduino needs to identify all connected devices. I've got a relay with pins IN1, IN2, IN3, and IN4 connected to pins 8, 9, 10, and 11, respectively. I've also got 4 ds18b20 water proof temp sensors plugged into the data 5 pin on the Arduino, daisy-chained together, each having their own unique identifier, ultimately only needing one data pin between the 4 of them. One piece of hardware, I've seen is the MAX31855 Thermocouple Reader, and I'm wondering; does anyone suggests I use this? Moreover, I'm planning to connect the solenoid valve in a "normally open" fashion to the relay so the solenoid doesn't waste energy or unnecessarily cause it to burnout over-time.

The valves "openness" will be mapped on a temperature range. So 0% valve openness will equate to -4C (24.8F), and 100% openness equates to 35C (95F); I'll only have glycol-chilled water temperatures within that range after all. So I would need variables called valveOpenness1, valveOpenness2, valveOpenness3, and valveOpenness4 for each of the 4 corresponding fermentation vessels. And if/then statements which give voltage to valve1, valve2, valve3, or valve 4 if any of them are above X desired temperature reading. It would basically be a series of if/then statements.

mvigno2:
From what I understand, the Arduino needs to identify all connected devices. I've got a relay with pins IN1, IN2, IN3, and IN4 connected to pins 8, 9, 10, and 11, respectively. I've also got 4 ds18b20 water proof temp sensors plugged into the data 5 pin on the Arduino, daisy-chained together, each having their own unique identifier, ultimately only needing one data pin between the 4 of them. One piece of hardware, I've seen is the MAX31855 Thermocouple Reader, and I'm wondering; does anyone suggests I use this? Moreover, I'm planning to connect the solenoid valve in a "normally open" fashion to the relay so the solenoid doesn't waste energy or unnecessarily cause it to burnout over-time.

Start by writing a short program to learn how to interface with one of those devices - perhaps the relay. When you are confident that you know how to do that make another short program for another device. Don't think about a combined program until you can do each thing separately - except to the extent that you should use different I/O pins for the different devices.

It will be much easier for you to learn with short programs and if you get stuck it will be much easier to get help with a short program.

...R

Why do you need variable "openness" for your solenoid valves? I would have expected that if the fermentation vessel is too hot, you cool it at the maximum rate. Is there some brewing advantage to more gentle cooling?

It will be much easier for you to learn with short programs and if you get stuck it will be much easier to get help with a short program.

OK, I'll try writing code for each device and come back when i have something more fleshed out. Thanks for the advice.

Why do you need variable "openness" for your solenoid valves? I would have expected that if the fermentation vessel is too hot, you cool it at the maximum rate. Is there some brewing advantage to more gentle cooling?

The fermentation set-up I need help with here actually has nothing to do with brewing. As I described in the original pilot comment, I've already assembled the brewing components and they are fully functional as of the time of writing this. Thus, for the sake of clarity, with regard to the creation of a single batch of beer-- turning grain water (wort) into beer (fermented wort)--the brewing process has been completed by the time the wort has been relocated from the mash kettle (brewing vessel) into the fermentation vessel. Put plainly, beer fermentation is a separate process and always follows the beer brewing process. Alternatively, however, and not to make things more confusing, there is absolutely no brewing process in wine/champagne, mead, or cider (all fermented with wine/champagne yeast). That's right: lager, ale, wine, and champagne yeast are all different species of yeast and create different end-products.

As such, brewing is unique to the creation of beer. The reason being is that wine ferments at a higher alcohol percentage (10%+) and kills off all other unwanted microbial nasties. For example, champagne yeast ferments at ~18%. Ale and lager yeast ferment at lower alcohol percentages so the wort needs to be boiled (sanitized) for an hour (the final stage of the brewing process), and then quickly (14 minutes max) reduced to yeast-pitching temperatures (below about 32C); only then do we introduce the ale or lager yeast we want to take hold, creating a clean slate of to-be-fermented wort and the ale/lager yeast you want, nothing else. Sorry to beat the horse to death here. I just want to be clear that I'm not asking for help in building a brewing set-up. That's already done. I'm asking for help to create a fermentation set-up, which theoretically could be used to ferment wine, mead, cider, OR beer (IF grain and hops are first brewed into WORT and then put into the fermentation vessel).

But to answer your question, fermentations in general turn out best if you have "gentle" temperature fluctuations (or lack thereof) for two reasons, 1), to prevent the instance of off-flavors in the final product, and 2), to increase the likelihood that you'd be able to repeat the exact same fermentation each and every time. Incidentally, reducing off flavors and repeatability are perhaps the two main goals of a professional/quality fermentation specialist. For example, anyone can make a an experimental fermentation, but can you make the exact same experimental fermentation more than twice or thrice? Maybe not, and this is where the computer technology comes in, to keep the temperature as consistent as possible. For example, though, some lagers, mid-fermentation, are reduced to almost freezing (lagering = storing in cold temps): this starves the yeast and forces them to cannibalize their yeasty dead ancestors. Fermentation is really messed up if you think about it because, in essence (as the joke goes), you isolate a single colony of yeast, give them hope to live in a paradise of perfect conditions, have them slave away by burping CO2 and peeing alcohol. Then you reduce the temperature and starve them so they cannibalize their dead ancestors (reducing cloudiness and off-flavors), only to collect their pee (alcohol) in the end. If you're lucky, after the fermentation, you can collect the yeast and reuse it for the next fermentation, creating a highly evolved, multi-multi-generational cannibalizing slave yeast colony :slight_smile:

Ok so what I found so far are 3 projects.

  1. “Multiple fermenter-Temperature control with Arduino”, but as you can see only controls a heating blanket and has an LCD screen wire in. What changes to the code are necessary to instead have the relay control a solenoid valve. And what changes to the code are necessary to have it controlled wirelessly from a laptop? It’s accompanied website is: Multiple Fermenter Temperature Control With Arduino : 5 Steps - Instructables
/* Multiple DS18B20 Temperature Sensors on 1 wire
   for controlling heating or cooling of muliple fermenters.
*/   
/*-----( Import needed libraries )-----*/
// Get 1-wire Library here: http://www.pjrc.com/teensy/td_libs_OneWire.html
#include <OneWire.h>

//Get DallasTemperature Library here:  http://milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library
#include <DallasTemperature.h>

/*-----( Declare Constants and Pin Numbers )-----*/
// Digital pin 2 for all the DS18B20 data lines.
#define ONE_WIRE_BUS_PIN 2

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

/*-----( Declare objects )-----*/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS_PIN);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

/*-----( Declare Variables )-----*/
// Pre-assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
// Uncomment the following lines for preassigning the addresses to the probes variable

//DeviceAddress Probe01 = { 0x28, 0xFF, 0x2F, 0x4F, 0x16, 0x15, 0x03, 0xCF }; 
//DeviceAddress Probe02 = { 0x28, 0xFF, 0x1C, 0x27, 0x16, 0x15, 0x03, 0x89 };
//DeviceAddress Probe03 = { 0x28, 0xFF, 0x85, 0x4F, 0x16, 0x15, 0x03, 0x41 };
//DeviceAddress Probe04 = { 0x28, 0x9A, 0x80, 0x40, 0x04, 0x00, 0x00, 0xD5 };
//DeviceAddress Probe05 = { 0x28, 0xE1, 0xC7, 0x40, 0x04, 0x00, 0x00, 0x0D };

//Comment out the following line if pre-assigning above.
DeviceAddress Probe01, Probe02, Probe03, Probe04, Probe05;

//Relay digital write pins on Arduino
int Relay1 = 5;
int Relay2 = 6;

float Probe01Temp = 0;
float Probe02Temp = 0;
float Probe03Temp = 0;

//Limit and floor are Celcius
//Adjust these temperature limits as needed
int Temp01SetPoint = 15;
int Temp01SetDiff = 1;
int Temp02SetPoint = 15;
int Temp02SetDiff = 1;


static bool Temp01CoolMaxed;
static bool Temp01WarmMaxed;
static bool Temp02CoolMaxed;
static bool Temp02WarmMaxed;
static bool Relay01Status;
static bool Relay02Status;

//Adjust the address of the I2C as needed
//See https://github.com/todbot/arduino-i2c-scanner
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);//, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);


void setup()   /****** SETUP: RUNS ONCE ******/
{
    
  // start lcd to show results
  lcd.begin(20,4);
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Starting Up");
  
  // Initialize the Temperature measurement library
  sensors.begin();

  // Comment out the following three lines if pre-assigned above
  sensors.getAddress(Probe01, 0);
  sensors.getAddress(Probe02, 1);
  sensors.getAddress(Probe03, 2);
  
  // set the resolution to 10 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 9);
  sensors.setResolution(Probe02, 9);
  sensors.setResolution(Probe03, 9);
  //sensors.setResolution(Probe04, 10);
  //sensors.setResolution(Probe05, 10);

  //set the relays
  pinMode(Relay1, OUTPUT);
  pinMode(Relay2, OUTPUT);
  //turn off the relays to start
  digitalWrite(Relay1, HIGH);
  digitalWrite(Relay2, HIGH);

  Temp01CoolMaxed = false;
  Temp01WarmMaxed = false;
  Temp02CoolMaxed = false;
  Temp02WarmMaxed = false;
  Relay01Status = false;
  Relay02Status = false;

  
  lcd.setCursor(0, 1);
  lcd.print("No. Sensors:");
  lcd.setCursor(12, 1);
  lcd.print(sensors.getDeviceCount());
  lcd.setCursor(0, 2);
  lcd.print("Getting temperatures");

  delay(5000);
  lcd.clear();

 //Set up labels on LCD
 lcd.setCursor(0, 0);
 lcd.print("C");
 lcd.setCursor(1,0);
 lcd.print("T1:");
 lcd.setCursor(6,0);
 lcd.print("-");
 lcd.setCursor(8,0);
 lcd.print("C");
 lcd.setCursor(10,0);
 lcd.print("H");
 lcd.setCursor(11,0);
 lcd.print("T2:");
 lcd.setCursor(16,0);
 lcd.print("+");
 lcd.setCursor(18,0);
 lcd.print("C");
 lcd.setCursor(0, 1);
 lcd.print("Carby1 Carby2 Outsde");
 lcd.setCursor(5, 2);
 lcd.print("C");
 lcd.setCursor(12, 2);
 lcd.print("C");
 lcd.setCursor(19,2);
 lcd.print("C");
 lcd.setCursor(0, 3);
 lcd.print("CL");
 lcd.setCursor(2,3);
 lcd.print("R1:");
 lcd.setCursor(10,3);
 lcd.print("HT");
 lcd.setCursor(12,3);
 lcd.print("R2:"); 

 lcd.setCursor(4,0);
 lcd.print(Temp01SetPoint);
 lcd.setCursor(7,0);
 lcd.print(Temp01SetDiff);
 lcd.setCursor(14,0);
 lcd.print(Temp02SetPoint);
 lcd.setCursor(17,0);
 lcd.print(Temp02SetDiff);

  
}//--(end setup )---

void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  delay(5000);
   
  // Command all devices on bus to read temperature  
  sensors.requestTemperatures();
  //First carboy
  Probe01Temp = sensors.getTempC(Probe01);
  //Second carboy
  Probe02Temp = sensors.getTempC(Probe02);
  //Outside temperature
  Probe03Temp = sensors.getTempC(Probe03);

  //Change calls to triggerCoolingRelay and triggerWarmingRelay
  //as needed such as both Relay01 and Relay02 both call triggerWarmingRelay()
  
  Relay01Status=triggerCoolingRelay(Probe01Temp, Relay1, Temp01SetPoint, Temp01SetDiff, Temp01CoolMaxed);
  Temp01CoolMaxed=Relay01Status;
  Relay02Status=triggerWarmingRelay(Probe02Temp, Relay2, Temp02SetPoint, Temp02SetDiff, Temp02WarmMaxed);
  Temp02WarmMaxed=Relay02Status;

  //Print to LCD
  lcd.setCursor(0,2);
  lcd.print(Probe01Temp);

  lcd.setCursor(7,2);
  lcd.print(Probe02Temp);

  lcd.setCursor(14,2);
  lcd.print(Probe03Temp);
  
  lcd.setCursor(5,3);
  if (Relay01Status)
    {
      lcd.print("On ");
    }
    else
    {
      lcd.print("Off");
    }
  lcd.setCursor(15,3);
  if (Relay02Status)
    {
      lcd.print("On ");
    }
    else
    {
      lcd.print("Off");
    }
  
    
}//--(end main loop )---


/*-----( Declare User-written Functions )-----*/
bool triggerCoolingRelay(float tempC, int Relay, int TempSetLimit, int TempSetDiff, bool TempCoolMaxed)
{
  bool result;
  
    if (TempCoolMaxed)
      {
      if (tempC < (TempSetLimit-TempSetDiff))
        {
        //TempCoolMaxed=false;
        result=false;
        }
      }
    else
      {
      if (tempC > TempSetLimit)
         {
           //TempCoolMaxed=true;
           digitalWrite(Relay, LOW);
           result=true;
         } 
       else 
         {
          digitalWrite(Relay, HIGH);
          result=false;
         }
      }
    return result;
 }// End triggerCoolingRelay

bool triggerWarmingRelay(float tempC, int Relay, int TempSetLimit, int TempSetDiff, bool TempWarmMaxed)
{
  bool result;
  
    if (TempWarmMaxed)
      {
      if (tempC > (TempSetLimit+TempSetDiff))
        {
        //TempWarmMaxed=false;
        result=false;
        }
      }
    else
      {
      if (tempC < TempSetLimit)
         {
         //TempWarmMaxed=true;
         digitalWrite(Relay, LOW);
         result=true;
         } 
        else 
          {
          digitalWrite(Relay, HIGH);
          result=false;
          }
       }
   return result;
   
 }// End triggerWarmingRelay

//*********( THE END )***********
  1. A second project I found has a 4-channel relay but it doesn’t seem to have a designated load, it only actuates the relay I guess. How would I get relayPin1 to respond to temp sensor 1, relayPin2, to respond to temp sensor 2, etc? Here is the website I found this project from: Getting Started With The 4 Channel Relay Breakout - BC Robotics
int relayPin1 = 2;  //This is the Arduino Pin that will control Relay #1
int relayPin2 = 3;  //This is the Arduino Pin that will control Relay #2
int relayPin3 = 4;  //This is the Arduino Pin that will control Relay #3
int relayPin4 = 5;  //This is the Arduino Pin that will control Relay #4
 
void setup() {
  // put your setup code here, to run once:
  pinMode(relayPin1, OUTPUT);
  pinMode(relayPin2, OUTPUT);
  pinMode(relayPin3, OUTPUT);
  pinMode(relayPin4, OUTPUT);
}
 
void loop() {
  // put your main code here, to run repeatedly: 
  digitalWrite(relayPin1, HIGH);
  delay(1000);
  digitalWrite(relayPin1, LOW);
  digitalWrite(relayPin2, HIGH);
  delay(1000);
  digitalWrite(relayPin2, LOW);
  digitalWrite(relayPin3, HIGH);
  delay(1000);
  digitalWrite(relayPin3, LOW);
  digitalWrite(relayPin4, HIGH);
  delay(1000);
  digitalWrite(relayPin4, LOW);
}
  1. A third project i found is more focused on the solenoid valve control but only has the valve open for an arbitrary 5 seconds. Also, it only uses a 1 channel relay. What changes to the code below are necessary when operating a 4 channel relay and how do I get the Arduino to actuate, via the 4-channel relay, valve1 based on a temperature input1, valve2 based on a temperature input2, etc? Here's the website I found it from: Solenoid valve control using arduino
// Code to Open and close an NC valve in 5 seconds gap.
int valvepin = 2;

void setup() {
  pinMode(valvepin, OUTPUT);
}

void loop() {
  //Opens the valve for 5 seconds
  digitalWrite(valvepin, HIGH);
  delay(5000);
  //Close the valve for 5 seconds
  digitalWrite(valvepin, LOW);
  delay(5000);
}

mvigno2:
Ok so what I found so far are 3 projects.

When I suggested in Reply #4 that you should write short programs to control each device I was not thinking of you searching for ready-made examples. I was thinking of you writing your own programs from scratch.

By all means use examples for learning, but IMHO you will spend more time trying to adapt a collection of other people’s programs than if you write your own code which, eventually, will be tailored to to your project.

Also keep in mind that the simple techniques to control relays etc will be used in many different projects, not just those related to beer production.

…R

couple of things.

First, I think the correct wording might be : Tinkerer/DIYer/Brewer

Second, it would help to eliminate all the discussion outside of control. we do not care what the vessel is or the ‘product’

your first post might be, what do I need to do to control glycol flow, or a vessel cooled by glycol ?
we assume you have a totally separate control for the chiller system.

In the world of measurement and control, it is simply a sensor, a comparitor [controller/Arduino or whatever] a controlled device.
controlled device often means :

  • a motor driver (remember your controller is the Arduino, and not the power driver for the motor,
  • a motor
  • a device being driven, in this case it could be a pump, or a valve

You must cold glycol with a second control loop.

There are a few options.
#1) run a pump // off and on, or variable speed.
#2) turn a solenoid off and on // horrible choice for off or on rates of more than a few an hour
#3) modulate flow with a water flow valve

Putting a temperature sensor into the cold side of the pumped glycol and the warm side of the return glycol, will give you more information.

You mentioned a window of about 10 degrees. If you want to narrow that to a few degrees, then you need more elaborate control.

As you have it, open the solenoid or turn the pump on
Monitor both your tank temperature and the return glycol temperature
Shut off the solenoid when you get near the lower limit.
Allow the tank to warm to the upper limit,
Repeat

As a note, temperature control is horribly sloppy. when you add 1,000 BTU, it might take 5 minutes for the wort (?) to change temperature.
Over shoot and under shoot are about all you can expect.
If you add PID, just toss out the D and use PI control. life will be much simpler.

If you want to try to control temperature to a more fine degree, then measure fluid flow.
One gallon of 40 degree glycol per minute with have X BTU’s. The 5 gallons of (what is it called ? mash ? wort ? ) will exchange BTU’s with the glycol at some efficiency rate.

You control BTU’s not temperature.
Yeast will make BTU’s at some near constant hourly rate and rise and fall over the length of the brewing process
a MUCH finer temperature control can be had if you control by BTUs

This might mean a variable speed pump
Or a pump with a 3-way valve where the 3rd leg just recirculates the glycol back into the storage tank and allows some to go into the cooling chamber.
Or the cold tank elevated so convection causes flow.

=========

if you have a sufficient storage tank, then additional brewing chambers can be added with either one pump creating pressure and using valves, or individual variable speed pumps. Or some creative way of moving the fluid.

The great part about this sort of project is the reward at the end.

I'll be honest, I have no idea how to actually start a code. I know the Arduino needs to be told what devices to detect, i can understand/follow basic logic scenarios as they're presented to me, and I realize that Arduino can perform loops with virtually any kind of sensory input imaginable. But I have no knowledge of which device goes first in the line, the precise nomenclature, "grammar", or "punctuation" of computer language so the Arduino knows exactly when or how each device functions, the foresight needed to be able to plan the entire code from start to finish, etc. The code I've provided thus far is essentially the extent of my knowledge. I'm still in the "copy-paste, barely understand each line" phase of my Arduino career. I've basically spent the last couple years researching concepts, collecting and assembling materials, and wiring hardware. Besides that, I'm asking for a heavy amount of help with the code, as I have severely limited experience with computer languages. Will people frown upon helping me create this from scratch? I guess I thought that's what the forum was for.

If you want to try to control temperature to a more fine degree, then measure fluid flow.

I happened to find an Arduino thread from this forum on something similar. Robin and Dave-in-NJ both happen to make comments in there:

Ok, so really what I'm looking for is basically a temperature controlled thermostatic mixing valve or something like that? Are there any that are Arduino-controlled? As it happens, I haven't had much luck finding anything like that. I've seen thermostatic mixing valves before but do they require a pump before or after the valve? Additionally, does Arduino not have PID capabilities? I guess I thought it did.

I have a 1/3 horse power submersible pump. The volume of each conical fermentation vessel is just shy of 8 gallons. How many a/c BTUs do i need to cool 8 gallons to, say a temp of 7C (~45F)? Mind you the fermentation creates heat so the glycol chiller would have to be able to chill to close to freezing temps (hence the glycol). I'm hoping to cool multiple 8-gallon vessels at different temps (to be able to do wines, meads, ales, lagers, whatever). Based on these specs what do you all recommend? What kind of efficiency can I expect? I can also send pictures of the fermentation vessel if you want

mvigno2:
the foresight needed to be able to plan the entire code from start to finish, etc.

While it's not a bad idea to have an overall plan, it is a very common beginner mistake to try to build the whole thing. Then you end up with a huge mess of code that doesn't work and have no clue how to fix it.

Better to do the smallest part of it you can find, get that working and then add the next smallest etc. etc.

mvigno2:
But I have no knowledge of which device goes first in the line, the precise nomenclature, "grammar", or "punctuation" of computer language so the Arduino knows exactly when or how each device functions, the foresight needed to be able to plan the entire code from start to finish, etc.

That's why I suggested in Reply #2 that the first step is to describe the process in great detail in English

The code I've provided thus far is essentially the extent of my knowledge. I'm still in the "copy-paste, barely understand each line" phase of my Arduino career.

Other people here may have different views but I reckon this is a moderately complex project and you need to become reasonably proficient at coding and debugging in order to complete it successfully. That may mean taking a timeout to do the necessary learning. I could fully understand that taking the trouble to learn programming would not be attractive if this is the only project on which you plan to use those programming skills - but I don't see an alternative, other than paying a programmer to do the job.

...R

Get a relay board,
a $3 pump. and some tubing for it.

the volume of water needed for a 5 gallon batch would not be much. you are trying to maintain a temperature, not cool something hot.

I missed the volume of the chilled water tank and the volume of the cooling tank.

one of those $3 pumps moves about 1 gallon every 2 minutes when there is no head pressure.
you can get them in 5v or 12v so, that should be simple as well.

the first steps should be simple

read the water temperature with a sensor like the DS18B20
lots of tutorials on that. ditto relays.

the control is super simple.

if temperature is greater than 50, turn on the pump
if the temperature is less than 45 turn off the pump

a beginner can do that in a weekend.

get a few other DS18B20 sensors and you can see lots of other things.

Since you are still in the raw beginner stages, here is a link.

you can get a fountain pump. again, get small ones.

for relays, I prefer the ones with screw terminals on both sides

as for mixing valves, too soon for that.
Consider a circulating pump, a tiny pond pump. just have the water in the tank moving.

if you are in the 50 gallon range for the cooling tank, then you need a lot more volume.
so it would seem some more data is needed for actual parts selection.

Robin2:
Other people here may have different views but I reckon this is a moderately complex project and you need to become reasonably proficient at coding and debugging in order to complete it successfully. That may mean taking a timeout to do the necessary learning. I could fully understand that taking the trouble to learn programming would not be attractive if this is the only project on which you plan to use those programming skills - but I don’t see an alternative, other than paying a programmer to do the job.
…R

I am going to both agree and disagree with this statement.
first, the rudiments of control are (input) sense, figure-figure, output
assuming the chilled water part is 100% done and you have a container of chilled water.
one pump running all the time to circulate (spin) the glycol in the mash tank jacket.
you need to sense temperature. the DS18B20 is a simple to use, has lots of tutorials and the parts are cheap.
a simple NANO/UNO and you can read a dozen of them easily by copy paste of others code. and it makes sense so you will be able to understand it.
control at the beginner level is also simple.
assuming you have a high glycol overflow point that returns water to the cooling resovour tank, then all you need to do is to pump glycol into the cooling jacket.
you measure that jacket temperature and use some simple if() statements.
if (jacket_temperature <= 45 ) {
digitalWrite(pump, ON );
}
if (jacket_temperature >= 50 ) {
digitalWrite(pump, OFF );
}
that would give you simple control. and it will be sloppy, but it should stay within that 10 degree window.
as you get things to work, you get more comfortable with things like reading the sensors, and turning on pumps and your confidence grows with your knowledge.
in a year, you will look back and say Robin2 was right, after all the additional features added, this is a program that is not something a beginner could do easily.

as a note, I would offer that if you google ‘batch control’ and look at the images, you will get an idea of how to draw up a representative diagram of your parts and have a better idea of things.
I assume you will buy stuff now that will not work well and will replace it as you learn of the short comings.
in control the final control element and the primary sensing element are magnitudes more important that software and programs.
imagine using a yardstick (meter stick) to measure the thickness of a piece of paper.
or a yardstick to measure a mile. the primary device has to be sensitive “IN THE RANGE” of the desired control.
This is magnitudes more important on the output side. imagine trying to add 2 drops of water using a fire hose, or filling a swimming pool with a garden hose.
you should be able to get pumps and hoses and fittings and make this work without the needs of sensors.
your rate of heating is based on the yeast and the outside temperatures, we are talking BTU per hour. one PERFECTLY sized pump should be able run continuous and achieve the perfect temperature. (not expecting that on any level)
a closely selected pump will run for a few minutes, create the needed change, then shut off. an oversized pump will need a lot of supporting valves, and controls and timing to get the same result.
Remember, this used to be done with guys sitting around dropping in some ice now and again.
the project is not rocket surgery.
one unknown value is the RATE OF CHANGE based on the mash and yeast. does it rise at 1 degree per minute ? or 1 degree per hour ? that will help you select what is needed. that faster the rate of change is both your blessing and your curse. it will give you stability in the variable, but also cause you fluctuations in control.

sorry for getting so windy and repeating myself.

the $3 pump can pump about 1 gallon every 2 minutes.
2 can pump about 1 gallon a minute.
that is ‘equivalent’ to a full tank change in 4 minutes.
I do not think your heat is anywhere near that much. (I have also been wrong)

I assume your glycol reservoir is lower than your chilling tank and there is an overflow valve to allow level control. if not, then there is another control loop needed. ( this is screaming for a schematic of the process )

The DS18B20 uses a library called the one-wire. any tutorial you find will walk you through that.

There are tutorials on using relays with Arduino so any of those tutorials will handle that bit.

if you get a button and do a mash run…
…and watch the temperatures and you just press the button to turn on the pump,
…then watch how long before the temperature changes AND time it.
then turn off the pump, time how long for the temperature to change…
you will get the very first clue to what is needed.

you can then put in a software simple timer to turn on the pump for 10 seconds, wait for it to mix, see the result.
choose to run another 10 seconds or if it was enough, then let it warm up a bit.

the crude temperature control program is :

if the temperatue is over 50 add cooling
if the temperature is under 45 stop adding.

a crude but slightly better would be

if the temperature is over 46 run the pump for 20 seconds
wait for 20 seconds to allow to mix

this second one does not care about lower temperatures as your mash never adds cooling, it is always a heat source.

the control would be simple to implement IF THE PUMP WERE SIZED WELL

say you turn on the pump for 20 seconds and then over the next minute, you watch the temperature fall to 44 and then over the next 5 minutes, rise back up to 46.

or, say you run for 20 sec, wait 20 sec and the temp dropped 0.3 degree.
you might run for 60 seconds.

the great thing is that you can watch the graph on the monitor to see the saw tooth results.

These first steps are beginner and are easy to do and are within your ability.

===============

As a note, I think Robin2’s right about how long it will take and that you have a LOT of learning ahead.
but, I also think YOU will be the driving force on that front.

if you can get the pump and relay to work ‘well enough’ and are satisifed, you will not push for more.
if you say, I can get in a 3 degree window, but want to make that 2 degrees or 1 degrees or half a degree…
you will be pushing yourself to learn what is needed to make it better.

I envisioned having a 100-gallon cooler and inside of it an a/c unit evaporator coil along with a 1/3 horsepower submersible pump. This creates constant subzero temperature glycol-water and constant flow rate. Let’s say I have fermenter 1 with a lager, fermenter 2 with a champagne, and fermenter 3 with an ale; each having their own target temperature. Since the valves are wired in a normally open fashion with the relay, the valves remain off until prompted to open or close depending on the given if statements below

  1. Subzero temp glycol flows from 100-gallon cooler to solenoid valve1

  2. If LagerTempSensor > 7C, send voltage from relay in order to open solenoid valve 1 by 1%

  3. Wait 60 seconds

  4. Repeat until LagerTempSensor = 7C

  5. If LagerTempSensor < 7C, send voltage from relay in order to close solenoid valve 1 by 1%

  6. Wait 60 seconds

  7. Repeat until LagerTempSensor = 7C

  8. If LagerTempSensor = 7C, do not send voltage to solenoid valve 1 (it remains not actuated until given voltage)

  9. Subzero-temp glycol-water flows from 100-gallon cooler to solenoid valve2

  10. If ChampagneTempSensor > 15.5C, send voltage from relay in order to open solenoid valve 2 by 1%

  11. Wait 60 seconds

  12. Repeat until ChampagneTempSensor = 15.5C

  13. If ChampagneTempSensor < 15.5C, send voltage from relay in order to close solenoid valve 2 by 1%

  14. Wait 60 seconds

  15. Repeat until ChampagneTempSensor = 15.5C

  16. If ChampagneTempSensor = 15.5C, do not send voltage to solenoid valve 2 (it remains not actuated)

  17. Subzero-temp glycol-water flows from 100-gallon cooler to solenoid valve3

  18. If AleTempSensor > 17C, send voltage from relay in order to open solenoid valve 3 by 1%

  19. Wait 60 seconds

  20. Repeat until AleTempSensor = 17C

  21. If AleTempSensor < 17C, send voltage from relay in order to close solenoid valve 3 by 1%

  22. Wait 60 seconds

  23. Repeat until AleTempSensor = 17C

  24. If AleTempSensor = 17C, do not send voltage to solenoid valve 3 (it remains not actuated)

Controlling a pump on or off seems like it will create wild temperature fluctuations. It seems to me that controlling slight movement changes in valve openness will create more gentle fluctuations (there’s inevitably going to be some fluctuation). Am I wrong in assuming this? As a beginner is it not easy to code for solenoid valve openness? Or is that an advanced task?

Do you have a solenoid that can cater to your needs for partial opening?