Help Support Aussie Homebrewer by donating:

  1. We have implemented the ability to gift someone a Supporting Membership now! When you access the Upgrade page there is now a 'Gift' button. Once you click that you can enter a username to gift an account Upgrade to. Great way to help support this forum plus give some kudos to anyone who has helped you.
    Dismiss Notice

Arduino Development Thread

Discussion in 'Electronics, Hardware & Software' started by bonj, 16/7/08.

 

  1. vortex

    Well-Known Member

    Joined:
    25/10/11
    Messages:
    412
    Likes Received:
    19
    Gender:
    Male
    Home Page:
    Posted 4/4/13
    I'll see how they go. Not the end of the world if I need to move to SSR's but I really like the I2C interface to these.
     
  2. andytork

    Well-Known Member

    Joined:
    26/4/08
    Messages:
    443
    Likes Received:
    36
    Gender:
    Male
    Posted 6/4/13
    EMI Causes lots of issues with Arduinos (I know from recent 1st hand experience). Even the 12v solenoid through an opto isolated relay board caused EMI. First thing to go on Arudino is serial comms when EMI is around making it a bugger to debug.

    If you have any EMI issues go to Jaycar and buy a few "MS4001" for $5 each , place them near your load. Our you could spend weeks making RC snubbers and go mad
     
  3. matho

    The Braumiser

    Joined:
    30/4/08
    Messages:
    1,403
    Likes Received:
    141
    Gender:
    Male
    Posted 17/6/13
    made a brauduino shield into a simple fermentation controller [​IMG]


    [​IMG]

    /*
    brauduino semi automated single vessel RIMS
    created by s.mathison
    using part code orginal developed by Michael Pilcher 2/9/2010
    Copyright (C) 2012 Stephen Mathison

    compiled on Arduino V1.0

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program. If not, see <http://www.gnu.org/licenses/>.*/



    //libraries
    #include <EEPROM.h>
    #include <LiquidCrystal.h>
    #include <OneWire.h>
    #include <avr/pgmspace.h>
    OneWire ds(11);
    LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

    // push buttons
    const char Button_up = A3;
    const char Button_dn = A2;
    const char Button_prev = A1;
    const char Button_nxt = A0;


    // outputs
    const int Heat = 9;
    const int Cool = 8;
    const int Buzz = 10;

    //Global Variables

    unsigned long convStartTime,displayTime,start,buttonPress;

    float Temp_c,setTemp,hyst;

    byte data[2];
    byte firstNumber;
    byte secondNumber;
    byte remainder;
    byte second;
    byte minute;
    byte hour;
    byte day;
    byte compDelay;
    byte compTime;

    const byte gBigFontShapeTable[] PROGMEM = {
    //* LT[8] =
    B00111,
    B01111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    //* UB[8] =
    B11111,
    B11111,
    B11111,
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    //* RT[8] =
    B11100,
    B11110,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    //* LL[8] =
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B01111,
    B00111,
    //* LB[8] =
    B00000,
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111,
    //* LR[8] =
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11110,
    B11100,
    //* UMB[8] =
    B11111,
    B11111,
    B11111,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    //* LMB[8] =
    B11111,
    B00000,
    B00000,
    B00000,
    B00000,
    B11111,
    B11111,
    B11111


    };

    const byte gBigFontAsciiTable[] PROGMEM = {


    0, 1, 2, 3, 4, 5, // 0x30 0
    1, 2, 32, 32, 255, 32, // 0x31 1
    6, 6, 2, 3, 7, 7, // 0x32 2
    6, 6, 2, 7, 7, 5, // 0x33 3
    3, 4, 2, 32, 32, 5, // 0x34 4
    255, 6, 6, 7, 7, 5, // 0x35 5
    // 0, 6, 6, 7, 7, 5, // 0x35 5
    0, 6, 6, 3, 7, 5, // 0x36 6
    1, 1, 2, 32, 0, 32, // 0x37 7
    0, 6, 2, 3, 7, 5, // 0x38 8
    0, 6, 2, 32, 32, 255, // 0x39 9


    };


    boolean Conv_start = false;
    boolean run = false;
    boolean cool_on = false;
    boolean showlp = false;

    //***********Start of the Functions***************

    static void BigNumber_SendCustomChars(void)
    {
    uint8_t customCharDef[10];
    uint8_t ii;
    int jj;

    for (ii=0; ii<8; ii++)
    {
    for (jj=0; jj<8; jj++)
    {
    customCharDef[jj] = pgm_read_byte_near(gBigFontShapeTable + (ii * 8) + jj);
    }
    lcd.createChar(ii, customCharDef);
    }
    }

    // 1 second button press
    int Button_1sec_press (int Button_press){
    if (digitalRead(Button_press)==0){
    delay (1000);
    if (digitalRead(Button_press)==0){
    lcd.clear();
    while(digitalRead(Button_press)==0){
    }
    return 1;
    }
    }
    return 0;

    }




    // repeat button press
    int Button_repeat (int Button_press){
    if (digitalRead(Button_press)==0){
    delay(200);
    return 1;
    }
    return 0;
    }

    // holds whilst button pressed
    int Button_hold_press (int Button_press){
    if (digitalRead (Button_press)==0){
    delay(50);
    while (digitalRead (Button_press)==0){
    }
    return 1;
    }
    return 0;
    }

    void display_lcd (int pos , int line ,const char* lable){
    lcd.setCursor(pos,line);
    lcd.print(lable);
    }


    // reads the DS18B20 temerature probe
    void Temperature(void){
    // start conversion and return
    if (!(Conv_start)){
    ds.reset();
    ds.skip();
    ds.write(0x44,0);
    Conv_start = true;
    convStartTime = millis();
    return;
    }
    // check for conversion if it isn't complete return if it is then convert to decimal
    if (Conv_start){
    if ((millis()-convStartTime)<1000){
    return;
    }
    ds.reset();
    ds.skip();
    ds.write(0xBE);
    for ( int i = 0; i < 2; i++) { // we need 2 bytes
    data = ds.read();
    }
    unsigned int raw = (data[1] << 8) + data[0];
    unsigned int whole = (raw >>4);
    unsigned int remain = (raw & 0X000f);
    Temp_c = (raw) * 0.0625;
    firstNumber = whole/10;
    secondNumber = whole%10;
    remainder = (remain * 10)/16;
    Conv_start = false;
    return;
    }

    }
    //************************************************************************
    //* returns the width of the character
    static int DrawBigChar(byte theChar , int xLocation)
    {
    int offset;
    int ii;
    byte theByte;
    offset = theChar *6;
    lcd.setCursor(xLocation, 0);
    for (ii=0; ii<3; ii++)
    {
    theByte = pgm_read_byte_near(gBigFontAsciiTable + offset + ii);
    lcd.write(theByte);
    }

    lcd.setCursor(xLocation, 1);
    offset += 3;
    for (ii=0; ii<3; ii++)
    {
    theByte = pgm_read_byte_near(gBigFontAsciiTable + offset + ii);
    lcd.write(theByte);
    }

    }
    // displays large font numbers
    void PrintDegC(void){

    lcd.setCursor(13,0);
    lcd.print("o");
    lcd.setCursor(8,1);
    lcd.write(4);
    lcd.setCursor(14,1);
    lcd.write(8);
    lcd.write(6);
    }

    //Prints current Temperature in large font
    void displayBigTemp(){
    DrawBigChar(firstNumber,0);
    DrawBigChar(secondNumber,4);
    lcd.setCursor(8,1);
    lcd.write(4);
    DrawBigChar(remainder,10);
    PrintDegC();


    }

    //Timing of the fermentation
    void ferment_timing()
    {
    if ((millis()-start)>1000){ // timing routine
    start = millis();
    second++;
    if (second>59){
    second = 0;
    minute++;
    if(minute>59){
    minute = 0;
    hour++;
    if(hour>23){
    hour=0;
    day++;
    }
    }
    }
    }

    }

    float change_temp(float& temp_change,int upper_limit,int lower_limit)
    {
    // Increase set temp
    if (Button_repeat(Button_up)){
    temp_change+=0.1;
    if (temp_change > upper_limit)temp_change = upper_limit;
    }
    // decrease temp
    if (Button_repeat(Button_dn)){
    temp_change-=0.1;
    if ( temp_change < lower_limit) temp_change = lower_limit;
    }

    }
    void heatOff(){
    digitalWrite(Heat,LOW);
    }

    void heatOn(){
    digitalWrite(Heat,HIGH);
    }
    void coolOff(){
    digitalWrite(Cool,LOW);
    if (cool_on){
    compTime = minute;
    cool_on =false;
    }
    }
    void coolOn(){
    if ((minute - compTime)>= compDelay){
    digitalWrite(Cool,HIGH);
    cool_on= true;
    }
    }

    void save_settings (int addr,int data)
    {
    EEPROM.write(addr,highByte(data));
    EEPROM.write((addr+1),lowByte(data));

    }



    void save_settings (int addr,byte data){

    EEPROM.write(addr,data);

    }

    int change_set(byte& set_change,int upper_limit,int lower_limit,int step_size)
    {
    // Increase set temp
    if (Button_repeat(Button_up)){
    set_change+=step_size;
    display_lcd(0,1," ");
    }
    if (set_change > upper_limit)set_change = upper_limit;

    // decrease temp
    if (Button_repeat(Button_dn))
    {
    set_change-=step_size;
    display_lcd(0,1," ");
    }
    if ( set_change < lower_limit) set_change = lower_limit;
    }

    // settings for the unit
    void set(){
    for(int i=0;i<3;i++){
    boolean setLoop = true;
    byte setting;
    float settingFloat;
    int settingWord;
    if (i==0){
    setTemp= word(EEPROM.read(50),EEPROM.read(51));
    setTemp=setTemp/10.0;
    while (setLoop){
    display_lcd (0,0,"Set Temp = ");
    lcd.print(setTemp);
    change_temp(setTemp,35,2);
    if(Button_hold_press(Button_nxt)){
    setTemp=setTemp * 10;
    settingWord = word(setTemp);
    save_settings(50,settingWord);
    setLoop = false;
    }
    }
    }
    if (i==1){
    setting = (EEPROM.read(52));
    display_lcd(0,0," ");
    while (setLoop){
    settingFloat =setting/10.0;
    display_lcd (0,0,"Hyst = ");
    lcd.print(settingFloat);
    change_set(setting,20,1,1);
    if(Button_hold_press(Button_nxt)){
    save_settings(52,setting);
    setLoop = false;
    }
    }

    }
    if (i==2){
    setting = EEPROM.read(53);
    display_lcd(0,0," ");
    while (setLoop){
    display_lcd (0,0,"Comp Delay = ");
    lcd.print(setting);
    change_set(setting,9,2,1);
    if(Button_hold_press(Button_nxt)){
    save_settings(53,setting);
    setLoop = false;
    setTemp = word(EEPROM.read(50),EEPROM.read(51));
    setTemp = setTemp/10.0;
    lcd.clear();
    }
    }

    }
    }
    }
    void loadSettings(){
    setTemp = word(EEPROM.read(50),EEPROM.read(51))/10.0;
    hyst = EEPROM.read(52)/10.0;
    compDelay = EEPROM.read(53);
    }

    //control process
    void control(){

    loadSettings();

    while (run){
    Temperature();
    if (showlp){
    display_lcd(0,0,"Time=");
    lcd.print(day);
    lcd.print(":");
    lcd.print(hour);
    lcd.print(":");
    lcd.print(minute);
    lcd.print(":");
    if(second<10)lcd.print("0");
    lcd.print(second);
    display_lcd(0,1,"S/A=");
    lcd.print(setTemp);
    lcd.print("/");
    lcd.print(Temp_c);
    change_temp(setTemp,35,2);
    if (Button_hold_press(Button_nxt)){
    lcd.clear();
    showlp =false;
    }

    }
    else displayBigTemp();
    ferment_timing();
    if (Temp_c>=setTemp)heatOff();
    if (Temp_c<=setTemp)coolOff();
    if (Temp_c<=(setTemp-hyst))heatOn();
    if (Temp_c>=(setTemp-hyst))coolOn();
    if (Button_hold_press(Button_nxt)){
    showlp = true;
    lcd.clear();
    }
    if (Button_1sec_press(Button_prev))run= false;
    }
    }
    void setup(){
    lcd.begin(16,2);
    pinMode (Button_up,INPUT);
    pinMode (Button_dn,INPUT);
    pinMode (Button_prev,INPUT);
    pinMode (Button_nxt,INPUT);
    pinMode (Heat,OUTPUT);
    pinMode (Cool,OUTPUT);
    pinMode (Buzz,OUTPUT);
    // assignes each segment a write number

    BigNumber_SendCustomChars();
    setTemp = word(EEPROM.read(50),EEPROM.read(51));
    setTemp = setTemp/10.0;


    }

    void loop(){
    if (Button_1sec_press(Button_prev)){
    run = true;
    control();
    }
    if (Button_1sec_press(Button_nxt)){
    set();
    }

    digitalWrite(Heat,LOW);
    digitalWrite(Cool,LOW);
    second = 0;
    minute = 0;
    hour = 0 ;
    day = 0;
    display_lcd(1,0,"Ferment Control");
    display_lcd(1,1,"Set Temp = ");
    lcd.print(setTemp);

    }










    I'm thinking I might merge the two codes as they share a fair bit and make an all in one controller. I had the LCD scramble when switching the fridge so I put a 2200uF 16v electrolytic cap across the 12v supply to de-couple it a bit more, it has seemed to fix the problem.
     
    1 person likes this.
  4. Edak

    BrauShnizzleMyNizzle

    Joined:
    26/12/11
    Messages:
    1,488
    Likes Received:
    258
    Gender:
    Male
    Location:
    Burwood, Victoria
    Posted 17/6/13
    Good job there mate, i love the big font :)
     
  5. RodrigoRicco

    New Member

    Joined:
    8/7/13
    Messages:
    2
    Likes Received:
    0
    Posted 8/7/13
    Hey Guys, I´m new here and eletronics stuffs, I´m from Brazil! Let me ask something. I have to change anything in the board to connect 2 pumps, 2 thermo heater? Or, I have to connect directly those pumps in the same conector.
     
  6. vortex

    Well-Known Member

    Joined:
    25/10/11
    Messages:
    412
    Likes Received:
    19
    Gender:
    Male
    Home Page:
    Posted 22/9/13
    So I ended up getting some cheap SSRs and de-soldering some of the mechanical relays:

    [​IMG]
    Relay board by auvortex, on Flickr

    Fucked up one of the traces by getting it too hot when desoldering, and it came away from the board. Fortunately it was just the ground, so if my dodgy fix doesn't work I can just solder to another ground point pretty easily at least!

    Flickr image above doesn't work, just click the link. Have the new seppo overlords nuked external images?
     
  7. digger

    Active Member

    Joined:
    18/3/09
    Messages:
    25
    Likes Received:
    0
    Gender:
    Male
    Location:
    Bendigo, Vic
    Posted 23/9/13
    I'm interested in something like this (I think, not much of a programmer so very much muddling through it). What I'm after is a device to control a ferment temp with ranges for example start ferment at 18 degrees, let naturally warm to 21 then keep it steady there till finish.

    Was considering using an rpi but am more than happy to kit up an arduino for it for sure. Any tips greatly appreciated.
     
  8. vortex

    Well-Known Member

    Joined:
    25/10/11
    Messages:
    412
    Likes Received:
    19
    Gender:
    Male
    Home Page:
    Posted 23/9/13
    Arduino can do that pretty easily at a basic level. Otherwise you could just use an STC1000, which will be easier and about the same cost. Depends if you actually want to get your hands dirty in code or not I guess.

    If you're still interested in building, look for DS18B20 temp sensors, and for relays they can be controlled easily with the onboard pins.
     
  9. digger

    Active Member

    Joined:
    18/3/09
    Messages:
    25
    Likes Received:
    0
    Gender:
    Male
    Location:
    Bendigo, Vic
    Posted 23/9/13
    I'm looking to more automate the entire process from pitching basically, so have something sitting there watching the temp from initial until it hits the target on it's own then kick on, rather than me have to turn something on, constantly check an stc etc.

    I'm willing to learn code for it but at this stage don't really have a great deal of knowledge on it. More the hardware production side of things normally.
     
  10. Edak

    BrauShnizzleMyNizzle

    Joined:
    26/12/11
    Messages:
    1,488
    Likes Received:
    258
    Gender:
    Male
    Location:
    Burwood, Victoria
    Posted 16/10/13
    I want to build a raspberry pi for this AKA brewpi.

    Sent from my Nexus 4 using Tapatalk
     
  11. MastersBrewery

    Journeyman, the learning never stops

    Joined:
    7/6/11
    Messages:
    2,319
    Likes Received:
    681
    Gender:
    Male
    Posted 29/11/13
    or you could skip the raspberry and do it all in one with this : http://arduino.cc/en/Main/ArduinoBoardTre unfortunately not shipping till US spring
    (yes I caught it on the brewpi forum, but cool bit of kit)
     
  12. Edak

    BrauShnizzleMyNizzle

    Joined:
    26/12/11
    Messages:
    1,488
    Likes Received:
    258
    Gender:
    Male
    Location:
    Burwood, Victoria
    Posted 29/11/13
    ... and I bet it is going to be very expensive!
     
  13. MastersBrewery

    Journeyman, the learning never stops

    Joined:
    7/6/11
    Messages:
    2,319
    Likes Received:
    681
    Gender:
    Male
    Posted 29/11/13
    My guess around the $90: Raspberry is $50 odd, then an arduino say $10-15, so bling factor and the no f#*king around with multiple boards, cables, and power supplies, costs $30, oh and for the brewpi project I was looking at a usb hub to break out a second board for 2nd ferm chamber, this would skip that, as it has 4 host ports instead of 2 on the pi. I supose we'll see early next year.
     
  14. Edak

    BrauShnizzleMyNizzle

    Joined:
    26/12/11
    Messages:
    1,488
    Likes Received:
    258
    Gender:
    Male
    Location:
    Burwood, Victoria
    Posted 29/11/13
    Yeah and then the year after for it to be supported by brewpi project
     
    1 person likes this.
  15. lael

    Well-Known Member

    Joined:
    30/8/12
    Messages:
    1,888
    Likes Received:
    570
    Gender:
    Male
    Posted 29/11/13
    Be nice if they included wifi on it like the spark core!
     
    1 person likes this.
  16. Edak

    BrauShnizzleMyNizzle

    Joined:
    26/12/11
    Messages:
    1,488
    Likes Received:
    258
    Gender:
    Male
    Location:
    Burwood, Victoria
    Posted 29/11/13
    I really like the idea of spark core, I wish they had been around when building controllers for fermenting fridge and keezer. No more dismantling boxes to reprogram.
     
  17. vortex

    Well-Known Member

    Joined:
    25/10/11
    Messages:
    412
    Likes Received:
    19
    Gender:
    Male
    Home Page:
    Posted 29/11/13
    I don't like the Tre. Seems like a hack to try and win back some of the RasPi crowd back to an Arduino based device.

    My Arduinos basically went in the bin when I got my RasPi's and BeagleBone's (white and black) and I don't see them ever coming out again. Doesn't make sense to me to plug an Arduino into a RasPi like in BrewPi when the RasPi can do everything the Arduino can do..
     
  18. MastersBrewery

    Journeyman, the learning never stops

    Joined:
    7/6/11
    Messages:
    2,319
    Likes Received:
    681
    Gender:
    Male
    Posted 29/11/13
    Has a dedicated wireless port ... Xbee I think was mentioned though I don't know what protocols that uses

    Ed. I do agree wifi should have been included on board and was a glaring omission on the Raspberrypi for the very reasons Edak mentions, even if you just want a standalone device, the ease of reprogramming is obvious
     
  19. Edak

    BrauShnizzleMyNizzle

    Joined:
    26/12/11
    Messages:
    1,488
    Likes Received:
    258
    Gender:
    Male
    Location:
    Burwood, Victoria
    Posted 29/11/13
    The benefit of having Arduino connected to raspberry pi is that a more complex system is more likely to fail and thus in the event of failure or lock up of the processor, the low level operations will always run and control beer comfortably.
     

Share This Page