Brewery Programming

The forum for discussing all kinds of brewing paraphernalia.
Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Sun Apr 15, 2012 2:50 am

your code has been uploaded to my brand new arduino Jabba :)
i couldnt find a source for the avr/pgmspace lib on the playground page for it, I just included it?? it compiled ok??
i only asked for 2 sensors in my sample request and have them wired with 4.6k resistors not 4.7, but i get readings for both in my test harness, took me a while to transpose the pinouts from the start up examples for the lcd to match your 2,3,4,5,6,7, and 8 for the onewire. ive got no outputs wired up as yet.

but am quite chuffed to have gotten this far considering it was mid day i finally plucked up the courage to attempt soldering the pins to the lcd screen..
thanks for the inspiration..
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

Matho

Re: Brewery Programming

Post by Matho » Sun Apr 15, 2012 2:14 pm

here is the code for the brauduino

https://github.com/mathoaus/braumiser-c ... duino2.pde

its working fairly well just need to tweak a few things

cheers steve

edit: its about 14.5k compiled

JabbA

Re: Brewery Programming

Post by JabbA » Tue Apr 17, 2012 10:27 am

Nice one Fil :D

Yep, no library needed for the avr/pgmspace.

After doing a couple of brews now I've tweaked the code a little and need have a couple of minor changes to do but it works pretty well. I've also used the sous vide mode twice, it needed quite a bit of re-working but works well now too. I think I've settled on the P, I & D values- I've not got round to implementing the autotune library or the Processing graphical output yet but with a bit of trial and error 500, 20 & 1 seem to work well for me with little initial overshoot and a +/- 0.1°C deviation during use.

I also had a go at using the pump potentiometer to control the vigorous-ness of the boil, I need to have a play with diffident pot values as the control was not a 'smooth' as I'd have liked.

Happy hacking!

Cheers,
Jamie

PS, I J-B welded an end of the SS tube at the weekend, just need to file / rub it smooth and get it used in this weekends brew. Cheers again!

Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Thu Apr 19, 2012 1:17 am

Cheers Jamie, hope the SS pipe works,,

now your system is not only loaded but runs too, :) a few lil typos and the wrong resistors in the button circuits staled me slightly..

been making sensors this evening ...
Image

and the 3 ive made so far all read with consistant values :)

cheers again..
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

JabbA

Re: Brewery Programming

Post by JabbA » Thu Apr 19, 2012 9:09 am

Looking good there Fil :D =D> :lol:

I've been getting a case for my set-up sorted out this week- I should have some stripboard and DC sockets delivered today to make a better job of it!

Cheers,
Jamie

User avatar
barneey
Telling imaginary friend stories
Posts: 5423
Joined: Mon Jul 25, 2011 10:42 pm
Location: East Kent

Re: Brewery Programming

Post by barneey » Thu Apr 19, 2012 9:37 am

All looking very good indeed, my basic kit arrived, the Mrs saw it, took it from me and said thats a Birthday present then. Another month I `ll get my hands on it again.
Hair of the dog, bacon, butty.
Hops, cider pips & hello.

Name the Movie + song :)

JabbA

Re: Brewery Programming

Post by JabbA » Thu Apr 19, 2012 9:40 am

Oh no!

Cheers,
Jamie

Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Fri Apr 20, 2012 10:45 am

not so good barneey, roll on next month, if like me your planning on stealing Jamie's work you will need a few odds n sods which can take a few weeks to arrive if sourced via ebay/china ssrs and reatsinks for example.. my arduino kit didnt have any 4k7 resistors needed for the sensors in the bundle, or if it did i lost em.. pm me if u need some i got 200 for quid cover my postage n i will send u a couple of dozen.. ebay seller 'electronic pound shop' seems to have most things for this and is a uk seller so things will arrive quickly..

Jamie cheers again you said you have tried the cook function? How was the steak?
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

JabbA

Re: Brewery Programming

Post by JabbA » Fri Apr 20, 2012 12:00 pm

Hi Fil, the steak was really good, would have been better if i hadn't seasoned it with a good pinch of salt before sealing and leaving in the fridge for 3 days- quite a lot of juice cam out! I need to get a piece of shin or similar and see how that cooks for 4 hrs or so.

I did need to change the code somewhat to what I posted tho. Once I've got a few other minor mods done I'll post it up again.

Cheers,
Jamie

Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Fri Apr 20, 2012 4:27 pm

I missed that post Jamie, looks very good..

Ive spotted a few obvious typos in the code or should in say the compiler spotted em ,, but im not pickin and am grateful for your generosity in sharring what must have taken hours..

i hit my own frustration level last night with wiring up jack plugs of all things.. so have decided to put it all away for the weekend, and i doubt i will be allowed another saturday off the shopping hehe

I had never even heard of this sous vide cooking before, but do like my 5hour gasmark 2-3 pot roasts so am looking forward to giving that a go too..
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Sat Apr 21, 2012 11:48 pm

If anyones interested ive cut n pasted a working pid using the front end to control it. single sensor and no error checking just the basic skeleton. all the result of cut n paste :) thanks to alexe for the lcd handling routines..

the front end uses 'processing' for the pc software all thats needed to use the out of the box sample front end is to edit one line to match the index of your ardurino comm port, and the sample code points you to this and just running the code will list the comm ports and indices for you in its "Text Window" the bottom space of the processing ide.

i also changed the
float InScaleMax = 1024
to 100 (its the input scale, and 100c is the limit of the temp range of interest to us ..

also dont try having the serial monitor running to monitor the arduino when trying to connect with the processing front end..
:)




For testing ive set the setpoint low so warming i fingers is enough to trigger the pid
but once connected to the front end you can change that :) and any other parameter..

Code: Select all

/* basic pid operation using front end demo as control interface.
Hardware: Uno board
          12v power supply
          20 x 4 lcd display
          1 x 1 wire temperature sensors + 1 x 4.7k resistor)
          breadboard and jump leads
          
          LCD pin assignment using minimum pins on board
          lcd1(VSS)             to GND
          lcd2VDD)              to +5v
          lcd3(Contrast)        to GND
          lcd4(RS)              to Pin2
          lcd5(R/W)             to GND
          lcd6 Enable)         'to Pin 3
          lcd7 not connected
          lcd8 not connected
          lcd9 not connected
          lcd10 not connected
          lcd11 (data 4)       to pin4
          lcd12 (data 5)       to pin5
          lcd13 (data 6)       to pin6
          lcd14 (data7 )       to pin7
          lcd15 backlight Pwr   +5v
          lcd16 backlight gnd   GND
          set up using the function call: LiquidCrystal lcd (2,3,4,5,6,7); //setup LCD display pins

          Temp sensors wiered with flat face faceing you..
          L - GND
          R - +5v
          Centre bridged with 4.7k r and +5v connected to Uno pin 8
          Its a one wire protocol more than one sensor on the same wire is ok.
          setup on board with:
              #define ONE_WIRE_BUS 8
              
              OneWire oneWire(ONE_WIRE_BUS);
              DallasTemperature sensors(&oneWire);
*/

#include <LiquidCrystal.h>
#include <PID_v1.h>
#include <OneWire.h> // one wire protocols lib
#include <DallasTemperature.h> // dallas temp lib for sensor reading




#define RelayPin 13   // set the pin for the ssr onboard led for testing
#define SensorPin 8   //  set the pin for the one wire temp sensors
#define TEMPERATURE_PRECISION 9 // set the accuracy of the reading

OneWire oneWire(SensorPin);   // setup onewire comms on sensor pin
DallasTemperature sensors(&oneWire);
// arrays to hold device addresses
DeviceAddress tempSensor1; // only one senosor being used here..

LiquidCrystal lcd (2,3,4,5,6,7); //setup lcd on 6pins minimum interface.

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

int WindowSize = 5000; // pid window time size
unsigned long windowStartTime; //container for current window start time

unsigned long serialTime; //this will help us know when to talk with processing

void setup()
{
  windowStartTime = millis();  // assign start time of the window
  serialTime = millis();
  Serial.begin(9600);  // set up serial comms
  lcd.clear();
  sensors.begin();     // set up the sensors
  //initialize the variables we're linked to
   //initialize the variables we're linked to
   
  sensors.requestTemperatures(); // Send the command to get temperatures
   
  Input = sensors.getTempCByIndex(0); //  using the first sensor as input for the pid.

  Setpoint = 20;

  //tell the PID to range between 0 and the full window size
  myPID.SetOutputLimits(0, WindowSize);

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  
  lcd_print("Sensor :", 0,0);
  lcd_print_float(Input, 10,0);
  lcd_print("C", 14,0);
}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  Input = sensors.getTempCByIndex(0); //  using the first sensor as input for the pid.
  myPID.Compute();

  /************************************************
   * turn the output pin on/off based on pid output
   ************************************************/
  if(millis() - windowStartTime>WindowSize)
  { //time to shift the Relay Window
    windowStartTime += WindowSize;
  }
  if(Output < millis() - windowStartTime) digitalWrite(RelayPin,HIGH);
  else digitalWrite(RelayPin,LOW);
  
  //----------- front end comms --------------------------------

  //send-receive with processing if it's time
  if(millis()>serialTime)
  {
    SerialReceive();
    SerialSend();
    serialTime+=500;
  }
  
  lcd_print_float(Input, 10,0); //update lcd
}


/********************************************
 * Serial Communication functions / helpers
 ********************************************/


union {                // This Data structure lets
  byte asBytes[24];    // us take the byte array
  float asFloat[6];    // sent from processing and
}                      // easily convert it to a
foo;                   // float array



// getting float values from processing into the arduino
// was no small task.  the way this program does it is
// as follows:
//  * a float takes up 4 bytes.  in processing, convert
//    the array of floats we want to send, into an array
//    of bytes.
//  * send the bytes to the arduino
//  * use a data structure known as a union to convert
//    the array of bytes back into an array of floats

//  the bytes coming from the arduino follow the following
//  format:
//  0: 0=Manual, 1=Auto, else = ? error ?
//  1: 0=Direct, 1=Reverse, else = ? error ?
//  2-5: float setpoint
//  6-9: float input
//  10-13: float output  
//  14-17: float P_Param
//  18-21: float I_Param
//  22-245: float D_Param
void SerialReceive()
{

  // read the bytes sent from Processing
  int index=0;
  byte Auto_Man = -1;
  byte Direct_Reverse = -1;
  while(Serial.available()&&index<26)
  {
    if(index==0) Auto_Man = Serial.read();
    else if(index==1) Direct_Reverse = Serial.read();
    else foo.asBytes[index-2] = Serial.read();
    index++;
  } 
  
  // if the information we got was in the correct format, 
  // read it into the system
  if(index==26  && (Auto_Man==0 || Auto_Man==1)&& (Direct_Reverse==0 || Direct_Reverse==1))
  {
    Setpoint=double(foo.asFloat[0]);
    //Input=double(foo.asFloat[1]);       // * the user has the ability to send the 
                                          //   value of "Input"  in most cases (as 
                                          //   in this one) this is not needed.
    if(Auto_Man==0)                       // * only change the output if we are in 
    {                                     //   manual mode.  otherwise we'll get an
      Output=double(foo.asFloat[2]);      //   output blip, then the controller will 
    }                                     //   overwrite.
    
    double p, i, d;                       // * read in and set the controller tunings
    p = double(foo.asFloat[3]);           //
    i = double(foo.asFloat[4]);           //
    d = double(foo.asFloat[5]);           //
    myPID.SetTunings(p, i, d);            //
    
    if(Auto_Man==0) myPID.SetMode(MANUAL);// * set the controller mode
    else myPID.SetMode(AUTOMATIC);             //
    
    if(Direct_Reverse==0) myPID.SetControllerDirection(DIRECT);// * set the controller Direction
    else myPID.SetControllerDirection(REVERSE);          //
  }
  Serial.flush();                         // * clear any random data from the serial buffer
}

// unlike our tiny microprocessor, the processing ap
// has no problem converting strings into floats, so
// we can just send strings.  much easier than getting
// floats from processing to here no?
void SerialSend()
{
  Serial.print("PID ");
  Serial.print(Setpoint);   
  Serial.print(" ");
  Serial.print(Input);   
  Serial.print(" ");
  Serial.print(Output);   
  Serial.print(" ");
  Serial.print(myPID.GetKp());   
  Serial.print(" ");
  Serial.print(myPID.GetKi());   
  Serial.print(" ");
  Serial.print(myPID.GetKd());   
  Serial.print(" ");
  if(myPID.GetMode()==AUTOMATIC) Serial.print("Automatic");
  else Serial.print("Manual");  
  Serial.print(" ");
  if(myPID.GetDirection()==DIRECT) Serial.println("Direct");
  else Serial.println("Reverse");
}
//*************************************************************************************
// LCD print functions
//*************************************************************************************

void lcd_print(char *string, int x, int y)
{
  lcd.setCursor(x,y);
  lcd.print(string);
}

void lcd_print_int(int i, int x, int y)
{  
  lcd.setCursor(x,y);
  lcd.print(i);
}

void lcd_print_float(float f, int x, int y)
{  
  int temp;
  
  lcd.setCursor(x,y);
  
  if(f < 0.1) {
    lcd.print ("--.-");
    return;
  }
  
  if (f < 10) lcd.print (" ");
  
  lcd.print((int)f);
  lcd.print(".");
  
  temp = (f - (int)f) * 10;
  
  lcd.print(abs(temp));
}

void lcd_clear(int c)
{
  if (c!=4) {
    lcd_print("                    ", 0, c);
      } else{
        lcd_print("                    ", 0, 0);
        lcd_print("                    ", 0, 1);
        lcd_print("                    ", 0, 2);
        lcd_print("                    ", 0, 3);
      }
}
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

Matho

Re: Brewery Programming

Post by Matho » Mon Apr 23, 2012 10:39 am

I have been working on a shield to go with my program https://github.com/mathoaus/braumiser-c ... duino2.pde and yesterday I decided to modify it so it could be made at home using the transfer method

http://www.mediafire.com/view/?j43whn9tt446p73

here is a PDF of the top and bottom tracks, a parts list and some quick instructions

http://www.mediafire.com/view/?ncqd46jcgqa6mnq

a quick note:

I couldn't find any 10k resistors on the little bird web so I left them out of the parts list by accident, you guys in the UK will probably have to find other suppliers anyway. I have also left the push buttons out but as always with push buttons get ones that have a nice positive click to them cause they are less likely to cause bouncing issues.

cheers steve

Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Mon Apr 23, 2012 8:12 pm

fantastic stuff matho.. VERY elegant code too, nice concise functions, and taught me about persistent memory access with eeprom lib, cheers:)

Your a bad influence, i got an arduino with the intention of ripping off Jamie's excellent design, then alexe turns up with a pc based gui monitoring progress and now your telling us how to print our own custom boards too .. i have to admit thats way beyond my comfort level tho.. il be happy with my finished product on the breadboard with hot glue holding it all in place :)
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

Matho

Re: Brewery Programming

Post by Matho » Tue Apr 24, 2012 11:45 am

thanks FIL, I'm still learning this stuff I had advice on the code from a very experienced brew bot builder and programmer.
I'm getting some boards made up professionally, for kits I'm making up here in OZ, I might have a few left over, they will fit in a normal envelope so it would cost too much to post, if I do Ill let you guys know

cheers steve

Fil
Telling imaginary friend stories
Posts: 5229
Joined: Sun Oct 16, 2011 1:49 pm
Location: Cowley, Oxford

Re: Brewery Programming

Post by Fil » Sat Apr 28, 2012 7:12 pm

I could use a bit of basic arduino support???

I have a UNO Rev3 made in italy board, and am running V1.0 of the windows software.

After going a bit 'kid in the sweetshop' with ebay and enhancements, ive opted to replace the simple 4-5 contact switch interface with a full keypad, little buttons, dark patio, me after a few beers, uping downing numbers might be a bit of a struggle..(Based on the hours it seems to set the central heating after a pint or 2..) anyway that decision led to a shortage of pins.. SO i then got a I2C interface board which arrived this morning.. chores done i soldered it up, and have hit a snag with the library code..

I have installed the right lib, according to the online documentation, ive opened the .h and .ccp files to confirm the error kicked up by the sketch compiler.

the I2C lib BV4618_i.h for the product http://www.byvac.com/bv3/index.php?rout ... uct_id=100

the compiler is kicking out an error:

"Wire.Recieve() has been renamed Wire.Read()"



the Text window details a lot of:

C:\arduino-1.0-windows\arduino-1.0\libraries\bv4618_I\bv4618_I.cpp: In member function 'char BV4618_I::key()':
bv4618_I.pde:-1: error: 'class TwoWire' has no member named 'receive'

As of Arduino 1.0, the Wire.receive() function was renamed to Wire.read() for consistency with other libraries.



Which points at the bv4168_i lib having compatibility issues? it also has the following #include Wprogram.h which has been replaced with Arduino.h??

a little digging tells me arduino 1.0 was released december 2011 and the bv5618 lib predates that june 2011.

so i need to edit the .ccp file and .h file to replace the , Recieve() calls with .Read() and recompile the library??

to start with???

if so what compiler should i look at im working on an 8gb netbook with msxp. so space is at a premium. any gotchas i should look out for?

Im a little worried i could be Very wrong tho, My google searches have not uncovered anyone else having this or a similar issue, and i cant be the first person since june last year to buy n try one of these beasties.

I did find a refference to a few timing issues which pre-date the new lib which is probably a response and fix to those issues??

I have emailed the supplier/maker BV but its a saturday and i have itchy brew controller fingers.. :)


cheers any advice would be appreciated
ist update for months n months..
Fermnting: not a lot..
Conditioning: nowt
Maturing: Challenger smash, and a kit lager
Drinking: dry one minikeg left in the store
Coming Soon Lots planned for the near future nowt for the immediate :(

Post Reply