Thursday, November 8, 2012

Arduino PID Temperature Controller and Sous Vide

Project Objective: To design a PID temperature controller using the Arduino and apply it to Sous Vide.

Introduction: This all started as a project to control beer brewing which is still in the works. In order to get there, there are a series of projects which can be used to break the problem down into workable pieces. Basically, brewing beer requires heating liquids contained in kettles and then moving the liquid from kettle to kettle. So what is needed is a way to heat the liquid to a controlled temperature and then turning pumps on and off. So what do we need:
  • Kettles with heaters, fittings and pumps.
  • An electronic controller with PID capabilities.
A single kettle version of this is what is need for a Sous Vide system including a small pump to keep the temperature of the water, uniform.

Interesting Links: Before we get started here are some useful links on this subject.

  • Lower East Kitchen:  On this site you will find a kit for a PID controller design for Sous Vide. Though the controller can be used for any water bath they suggest using a stainless coffee  urn available from Amazon for $25. 


PID Controller: A Arduino based PID temperature controller has been developed by Brett Beauregard and Rocket Scream Electronics called the osPID.  This design was predated by the Reflow Oven Controller Shield available from Rocket Scream





Sous Vide Hardware:



To Be Continued: 11/8/12

Thursday, September 20, 2012

Arduino as Serial LCD Display


Project Objective: In this project we will use the Arduino to emulate the PH Anderson #117 serial text display minus big numbers. The layout of a piggyback pcb will complete the  project.

Introduction: See the discussion in the "Controlling a Serial Display" project which covers several of the serial LCD displays on the market. Most of these products have a similar command set and the sketch presented here could be modified to emulate many of these.

Serial LCD displays are available in both text and graphic versions. This project covers text displays with one to four lines and up to 40 columns. Initially, the displays will be limited to 80 total characters, a limitation of the Arduino standard LCD library.

Since the serial LCD is a one wire device, all control of the LCD terminal must use command sequences. Here are the commands used in this project:


Arduino Serial LCD Rev. A: Command Set (as of 9/16/12)
Command 
?a home cursor
?b destructive backspace
?c# set cursor style,   0= none 2= blinking 3=underline
?f clear screen
?g Beep 
?h Backup Cursor (Non-destructive backspace)
?i Forward cursor
?j Up cursor
?k Down cursor
?l Clear cursor line
?m Carriage Return
?n CRLF, cursor at start of next line, line cleared
?p### Position cursor x = ##, y = #
?x##  Position cursor on x column, (two characters are required), first column is column 0, 
?y# Position cursor at y row, first row is row 0 (one character only)
?? display a "?"
?! Send direct command to LCD
?B Backlight Intensity – sets PWM value, two hex digits req. (00 to FF)
?D#      Define custom character. See text.
?# Print a custom character
?H High output on auxiliary digital pins: valid numbers are 1,2,3,4
?L Low output on auxiliary digital pins: valid numbers are 1,2,3,4
?G Configure for LCD geometry. Supported formats: 2X16, 2X20, 2X24, 2X40, 4X16 and 4X20.


Except for the ?p### command they are identical to the PH Anderson, #117 chip. The start character for a command sequence is a '?', but this can be easily changed in the sketch, say to a '!'. The sketch below compiles, but some commands are missing.

One of the nice features of the #117 command set is that control can be accomplished using a PC termial program. In fact, using the Arduino IDE to update the code the built in terminal can be opened to test changes.The piggyback pcb can be modified and updated the same way.

Note: As of 10/08/12 the code was updated, as well as the schematic.The schematic changes were made to simplify the piggyback pcb layout. Because of this there were also changes to code. Several additional commands have been added and we will continue to add more.


Schematic Used with Solderless Breadboard:



The schematic above shows the parts which need to be added to the solderless breadboard for this project. The headers in the schematic are the the headers on the Arduino board. The piggyback board will require a different schematic and include the atmega328, as well as, serial interface circuits and jumpers.

The image below shows the Arduino Serial LCD connected to an Arduino sending serial data at 9600 baude. The text being sent is "Temperature" and "76.8" or "77.6", where the word Temperature is sent once and the numbers sent alternately in the loop section of the sketch. Before the numbers are sent the cursor is positioned at character column 14. The small round object is a piezo speaker.


Arduino on left is sending serial data to Arduino on right.
















Sketch:Version  0.6


/*
Arduino_PHAnderson #117 Serial LCD emulator
Date: 10/08/12
Author: R. LaSalle

*/

#include <LiquidCrystal.h>
#include <EEPROM.h>

/* LCD pin assignments
RS 8
RW 9
E  10
D4 4
D5 5
D6 6
D7 7
*/

#define BP 3
#define BL 11
#define Bd0 14
#define Bd1 15

#define maxrowloc 0
#define maxcolloc 1
#define bootscrloc 2
#define curtypeloc 3
#define ledblloc 4
#define tabloc 5
#define user0 10
#define user1 30
#define user2 50
#define user3 70

#define commchr '?'
//#define VER .5

uint16_t bauderate = 9600;
uint8_t maxrow = 4;
uint8_t maxcol = 20;
uint8_t bootscr = 1;
uint8_t ledbl = 0x7f;
uint8_t nrow =0;
uint8_t ncol =0;
int8_t temp =0;
int8_t temp1 =0;
int8_t temp2 =0;
int8_t temp3 =0;

LiquidCrystal lcd(8,9,10,4,5,6,7);

void setup() {
//  EEPROM.write(maxrowloc,0);
//  EEPROM.write(maxcolloc,0);
  temp=EEPROM.read(maxrowloc);
  temp1=EEPROM.read(maxcolloc);
  if(temp==0 && temp1==0){  //Is EEPROM empty? If yes load defaults.
    maxrow=4;
    maxcol=20;
    EEPROM.write(maxrowloc,maxrow);
    EEPROM.write(maxcolloc,maxcol);
  }
  maxrow=EEPROM.read(maxrowloc);
  maxcol=EEPROM.read(maxcolloc);
  lcd.begin(maxcol,maxrow); // Change this for other screen sizes.
  pinMode(Bd0,INPUT);  //bauderate set bit 0
  pinMode(Bd1,INPUT);  //bauderate set bit 1
  digitalWrite(Bd0,HIGH);  //pullup
  digitalWrite(Bd1,HIGH);  //pullup
  if(digitalRead(Bd0)==LOW && digitalRead(Bd1)==LOW){bauderate=2400;}
  if(digitalRead(Bd0)==HIGH && digitalRead(Bd1)==LOW){bauderate=9600;}
  if(digitalRead(Bd0)==LOW && digitalRead(Bd1)==HIGH){bauderate=19200;}
  if(digitalRead(Bd0)==HIGH && digitalRead(Bd1)==HIGH){bauderate=38400;}
  Serial.begin(bauderate); // Default baudrate.
  pinMode(BL,OUTPUT);
  pinMode(BP,OUTPUT);

  analogWrite(BL, ledbl); // Set maximum brightness.

// Boot Screens
  if(bootscr==1){    //Config screen
    ncol=0;
    nrow=0;
    lcd.setCursor(ncol,nrow);  //home cursor
    lcd.print("Arduino_PHA117");
    lcd.setCursor(0, 1);
    lcd.print("G:");lcd.print(maxrow);lcd.print("x");
    lcd.print(maxcol/10);lcd.print(maxcol%10);
    lcd.print(" B:");lcd.print(bauderate);
    lcd.setCursor(0,0);  //home cursor
  }
}

void loop() {
  byte rxbyte = getc(); // Command
//byte temp; // Parameter

  if (rxbyte == commchr) {
    switch (getc()) {
    case 'p': // Set cursor position (2 parameters, column, row)
 temp=getn();
 temp1=getn();
          temp2=getn();
          if(temp=='e'||temp1=='e'){
            error();
            break;
          }
          temp=temp*10+temp1;
          if(temp>maxcol-1){
            error();
   break;
 }
          ncol=temp;
            if(temp2=='e'){
             error();
            break;
           }
           if(temp2>maxrow-1){
             error();
            break;
           }
            nrow=temp2;                
      lcd.setCursor(ncol, nrow);
      break;
    case 'a': // Cursor home (doesn't clear the screen!)
      lcd.home();
      ncol=0;
      nrow=0;
      break;
case 'b': //Destructive backspace
 lcd.command(16);  //cursor back
 lcd.write(' ');    // write space
 lcd.command(16);  //cursor back
 ncol=ncol-1;
 break;
    case 'c': // Set Cursor type
      switch (getc()){
        case '0':
          lcd.noCursor();
          lcd.noBlink();
          break;
        case '2':
           lcd.cursor();
           lcd.noBlink();
           break;
        case '3':
            lcd.cursor();
            lcd.blink();
            break;
           default:
           break;
        }
        break;
    case 'f': // Clear screen
      lcd.clear();
      ncol=0;
      nrow=0;
      break;
    case 'g': //beep
      tone(BP,4000,250);
      break;
    case 'h': // Move cursor back
      if(ncol>0){
lcd.command(16);
ncol=ncol-1;
      }
      break;
    case 'i': // Move cursor forward
if(ncol<maxcol){
lcd.command(20);
 ncol=ncol+1;
}
      break;
    case 'j': //Cursor up
if(nrow>0){
 nrow=nrow-1;
 lcd.setCursor(ncol,nrow);
}
     break;
     case 'k': //Cursor down
if(nrow<maxrow){
 nrow=nrow+1;
 lcd.setCursor(ncol,nrow);
}
      break;
      case 'l':  //clear cursor line
        ncol=0;
 //       maxcol=20;
        lcd.setCursor(ncol,nrow);
        for(byte i=0;i<=maxcol-1;i++){lcd.write(' ');}
        ncol=0;
        lcd.setCursor(ncol,nrow);
      break;
      case 'm':  //CR
        ncol=0;
        lcd.setCursor(ncol,nrow);
      break;
      case 'n':  //CRLF
        ncol=0;
        if(nrow<maxrow-1){nrow=nrow+1;}
        lcd.setCursor(ncol,nrow);
      break;
      case 'x':
          temp=getn();
          temp1=getn();
          if(temp=='e'||temp1=='e'){
            error();
            break;
          }
          temp=temp*10+temp1;
          if(temp>maxcol-1){
            error();
   break;
 }
          ncol=temp;
          lcd.setCursor(ncol,nrow);
break;

case 'y':
          temp=getn();
           if(temp=='e'){
             error();
            break;
           }
           if(temp>maxrow-1){
             error();
            break;
           }
            nrow=temp;
            lcd.setCursor(ncol,nrow);
        break;
       case 'B':
         temp=geth();
         temp1=geth();
         if(temp==0xff || temp1==0xff){break;}
         temp=temp<<4;
         ledbl=temp+temp1;
         EEPROM.write(ledblloc,ledbl);
         analogWrite(BL,ledbl);
       break;
       case 'G':  //enter R,C
         temp=getn();
         temp1=getn();
         temp2=getn();
         if(temp=='e' || temp1=='e' || temp2=='e'){error();break;}
         maxcol=temp1*10+temp2;
         maxrow=temp;
         EEPROM.write(maxcolloc,maxcol);
         EEPROM.write(maxrowloc,maxrow);
       break;
    }
  }
  else{
  // Otherwise its a plain char so we print it to the LCD.
  lcd.write(rxbyte);
  ncol=ncol+1;
  }
}

/*
 * Waits for a byte to be available, reads and returns it.
 */
byte getc() {  //get character
  while (Serial.available() == 0);
  return Serial.read();
}

byte getn() {  //get decimal digit
  byte temp;
  while (Serial.available() ==0);
  temp=Serial.read()-48;
  if(0>temp>9){
    return 'e';
  }
  else{
  return temp;
  }
}

byte geth(){  //get hex digit
  byte temp=getc();
  if(temp>=0x30 && temp<=0x39){
    temp=temp-0x30;
    return temp;
  }
  if(temp>=0x61 && temp<=0x66){
    temp=temp-0x57;
    return temp;
  }
  return 0xff;
}

void error(){
  tone(6,4000,250);
  return;
}



.

To Be Continued

Tuesday, July 3, 2012

uLab40AVR, the ATmega1284P for Solderless Breadboard

Project Objective: The uLab40AVR is designed to be functional similar to the uLab28AVR.

Introduction: This PCB is designed to be a mate to the Daiduino except that it uses the Sanguino pin designations. This will not cause a problem because of the Arduino IDE pin maping. For example, if you connect a LED/resistor to D13 on the uLab40AVR and the Daiduino, then select the appropriate board in the Arduino IDE, the blink sketch will work.

Specifications:

  1. Use of thru hole parts except for regulators
  2. Dual regulators for 5V and 3.3V
  3. Use a breakout boards for serial communication, USB or RS232
  4. Power switch
  5. Use jumpers for selecting power source.
  6. 36 pin header for signals and two separate pin sets for powering the SLBB.




Note: The design is not complete. 7/3/12

uLab28AVR, Arduino for Solderless Breadboard

Project Objective: To transpose the Arduino to a solderless breadboard plugin.

Introduction: This board has all the features of the GMduino, Arduino clone, shown on another post. The digital and analog pin designations are identical to the GMduino and, therefore, the Duemilanove. In addition, the ATmega328P pin designations are also shown.

Specifications:
  1. Use of thru hole parts except for regulators
  2. Dual regulators for 5V and 3.3V
  3. Use a breakout boards for serial communication, USB or RS232
  4. Power switch
  5. Use jumpers for selecting power source.
  6. 25 pin header for signals and two separate pin sets for powering the SLBB.




GMduino, a Buildable Clone

Project Objective: Design a Arduino clone that is easy to assemble for clubs and beginners

Introduction: With the criteria of ease of assembly, the first problem is the FTDI USB chip which even for the experienced assembler is not an easy mounting task, but the availability of small FTDI breakout boards solves the problem. I am using the BUB II by Modern Devices since they leave the connector for you to assemble which I add underneath the board.. Adafruit has the Friend, but it is pre-assembled with the connector on the top.

The standard 7805 type regulator is real-estate hungry and two will be needed, so surface mount LDO regulators are used. These are three pin devices and mounting is not difficult. Low drop out, LDO, devices are used to limit heat dissipation. In fact, we use a 6V wall power supply which at low current has a 8.5VDC output where a 9V wart is at 12VDC.

The commercial Arduino uses a circuit for switching between external power, wart, and USB which can take up surface space unless smd parts are used. Further, it would be nice if RS232 serial communiction could also be used which means the clone would need to supply power to that breakout. So we opted for jumpers for both power selection and board voltage. In addition a power switch was added for convenience during development and if not wanted can be jumpered out.

Finally, a vertical reset switch is placed at the front of the board as well as the LED's. This means that with a shield mounted on the Arduino the reset button is still accessible and the LED's can be seen.

Specifications:
  1. Use of thru hole parts except for regulators
  2. Dual regulators for 5V and 3.3V
  3. Use a breakout board for serial communiction
  4. Place LED's and reset switch at front of board
  5. Add power switch
  6. Use jumpers for selecting power source.

GMduino with BUB II. Note the mounting position of BUB II connector.






Friday, June 22, 2012

GMduino II, Arduino Clone with RTC and EEPROM

Project Objective: To design an Arduino clone with through hole parts for easy assembly. The clone also includes an on board real time calendar clock with battery backup and an EEPROM. The board should operate at 5V and 3.3V including the RTC.

Specifications:
  1. Arduino clone with stacking connectors
  2. MCU: ATmega328P with Optiboot
  3. Through hole parts, except for regulators
  4. Serial communication using breakout boards
  5. Dual ldo regulators for 5V and 3.3V
  6. Power :input:  6V to 9V wart or USB jumper selectable
  7. Power switch
  8. Auto reset defeat switch
  9. On board I2C, EEPROM and RTC with battery backup.
  10. Vertical reset and ISP at front
Introduction: The project is an outgrowth of the Rainwater Monitoring System , RMS. The original development was done with the uLab28 PIC, then resulting in the Picduino. The RMS is basically a water tank level data logger with LCD display and keyboard.






Note: Layout complete ready for BatchPCB, GMduino.03C

Under construction

Thursday, June 14, 2012

Daiduino, an Arduino form with the ATmega1284P

Project Objective:
Wouldn't you like to have an Arduino that had 4 times the code capacity, more IO pins and used standard shields, but was only slightly larger? So would I. Further, I would like it to use through hole parts, so that it could be assembled as a kit. By the way, dai is a japanese word that means great or big. So Daiduino is a big Arduino but not a mega Arduino.

Discussion:
I started my Google search, looking at the Sanguino which uses the ATmega644P and has 64k bytes of code space, but soon found the ATmega1284P which has the same pinouts and 128k code space. As a matter of fact the Atmega1284P can be used on the Sanguino pcb. Another interesting item is that there is only 6 cent difference in price. Update: Downloading the Sanguino ZIP file indicated that the ATmega1284P is also included in their design.

Maniacbug site has the most useful data for this project and, in particular, have integrated the ATmega1284P into the Arduino IDE 1.0 environment. So the next step is to determine board size and pin assignments. Since I have already designed a through hole Arduino clone, transfering the power section to the Daiduino will be the first step. That process created a board 3.4" by 2.1".

For pin assignments, there are two designs on the Web to look at, Calunium and Bobuino.. Of the two the Calunium can use a standard shield, but is only USB powered. There is limited information on the Bobuino, but Maniacbug includes it in his zip file.

Specifications:
  1. Same width as the Arduino but longer, 2.1" by 3.5"
  2. Basic set of stacking connectors, UNO
  3. Dual regulators for 3.3V and 5V
  4. Power source: USB or wart
  5. USB interface on a plug in, such as a BUB II
  6. Through hole parts with the exception of the regulators.
  7. LED's, reset switch and ISP at front of the board
  8. Jumpers A4, A5 to I2C for UNO compatibility
  9. Jumper Auto Reset
Note: First version PCB ready for Batchpcb, 06/18/12. Ordered 06/19/12

Working