Electronics

Fermenter heating pad

posted Aug 12, 2011, 2:16 PM by Eric McKinley   [ updated Aug 12, 2011, 2:41 PM ]

The idea is very similar to the chicken coop dimmer.  However, I want to add a readout and temperature adjustments. 

The first step was disabling the heating pad's auto-off feature, which interrupts power to the heating elements if the pad has been on for more than 60 minutes.  The Kaz HP215 SoftHeat heating pad, found at Wal-Mart, is the victim.  After I got the case open, I examined the circuit within.  I noticed a transistor near the output to the pad, and looked up the part number.  It is a z0103 Triac, used to switch high-voltage power.  Following the trace, I noticed it was connected to the mystery microcontroller's (try to find a datasheet for a 13-000022) pin 2.  I hit it with the iron and pried the pin up.  The device now thinks it is going to sleep (LED flashes) but it can't trip the triac, so my pad stays nice and toasty. 

Step two is to get a display working with count up/down on the arduino.  I used this great blog post to get me started.  Only thing is I found out: my display's upper left led on the first digit is out, and I needed to reverse the binary in numbers[] to get it to work (ie 0b1000000 became 0b0111111, etc.).

Step three is to get a real reading on my thermistor finally.  I made a spreadsheet to help me with the math.  On the way to that spreadsheet, I made a csv for everyone.  Yay!  See the attachments section down there VVVV. 

Analog Thermostat

posted Jun 3, 2010, 11:05 AM by Eric McKinley   [ updated Jun 4, 2010, 11:15 AM ]

Young poultry needs a tightly regulated temperature to stay alive.  During the first week, they need a heat source in the 95-100 degree range.  My pullets are arriving tomorrow, so I was a little crunched on time when I came up with the idea of an arduino controlling a light dimmer via a continuous-rotation servo

The simple control looks like this:

Temperature-dependent resistor > Arduino > Servo > Dimmer > Lamp


  • The Arduino reads the voltage in the middle of the voltage-divider circuit and calculates the resistance of the temperature-dependent resistor. 
  • It then calculates (using an oversimplified equation, I know) the temperature in degrees Fahrenheit. 
    • It gets three temperature readings and averages them for stability. 
  • If the averaged temperature is outside the threshold range, it executes either the "cooler" or "warmer" functions. 
    • The functions simply turn the servo one direction for a given time, and sleep the program to allow the temperature-dependent resistor to catch up. 
      • Note the two different servo turn times.  This is sort of a self-calibrating method.  If one second up is too much, and one second down is too little, it will just go back and forth continuously.  The smaller "down" time allows a sort of ratcheting in temperature adjustments, by putting the high and low adjustments out of phase. 

Code

#include <Servo.h>
 
//------Declarations and variables--------------
Servo dimmer;   // create servo object to control our dimmer
int ledPin =  13; // to indicate state for diagnostics
int fwd = 100;  // moves servo forward
int stp = 90;   // stops servo.  My continuous-rotation servo has been set to 90 being the stop point.  
                    // Yours may be different.  Set the stop value here, and set 'fwd' and 'rev' higher and lower than this number, by at least 10.
int rev = 80;   //moves servo backward
int tempSensor = 0; // defines temperature sensor pin
int i = 0; // initializer/counter
float temp1;    // Holds our first temp for averaging
float temp2;    // Holds our second temp for averaging
float temp3;    // Holds our third temp for averaging
float tempAvg;  // Holds our averaged temperature
float resistance; // Define resistance here because we use it outside the for loop

float threshHigh = 98; // defines the high threshold for temp, in degrees farenheit
float threshLow = 96;   // defines the low threshold for temp, in degrees farenheit


//------Functions---------------------------------------
int hotter ()  // Function to turn temp up
{
  Serial.println("warming...");
  digitalWrite(ledPin, HIGH);   // set the LED on
  dimmer.attach(3);  // attaches the servo on pin 3 to the servo object
  dimmer.write(fwd); //turn the dimmer up
  delay(1000);  //for 1 second
  dimmer.write(stp); //then stop
  dimmer.detach();
  digitalWrite(ledPin, LOW);    // set the LED off
  delay(30000); //wait 30 seconds to allow thermometer to warm
}

int cooler ()  // Function to turn temp down
{
  Serial.println("cooling...");
  digitalWrite(ledPin, HIGH);   // set the LED on
  dimmer.attach(3);  // attaches the servo on pin 9 to the servo object
  dimmer.write(rev); //turn the dimmer down
  delay(750);  //for .75 seconds
  dimmer.write(stp); //then stop
  dimmer.detach();
  digitalWrite(ledPin, LOW);    // set the LED off
  delay(30000); //wait 30 seconds to allow thermometer to cool
}


 
void setup()
{
   
  Serial.begin(9600);
  Serial.println("Ready");
  pinMode(ledPin, OUTPUT);     
 
}
 
 
void loop()
{  
  i = 1;
  for (i=1; i <= 3; i++){  // Get temperature three times
   

  float tempRaw = analogRead(tempSensor); // get the value of the temperature sensor
 
  //--------calculate temperature---------------
 
   float voltage = tempRaw / 1024 * 5.0;
   resistance = (5600 * voltage) / (5.0 - voltage);
   float tempC = (-0.0040617 * resistance) + 63.6279;

  // Convert to Fahrenheit
   float tempF = tempC * 9.0/5.0 + 32.0;
   
   switch (i) {
    case 1:
      temp1 = tempF;
      break;
    case 2:
      temp2 = tempF;
      break;
    case 3:
      temp3 = tempF;
      break;
   }  
    delay(1000);
  }
 
  tempAvg = (temp1 + temp2 + temp3) / 3;  // Average the three temperatures
 

 
  Serial.print (resistance);
  Serial.print (", ");
  Serial.println (tempAvg);
  delay(1500);
 
  if (tempAvg > threshHigh)
  {
    cooler();
  }
  else if (tempAvg < threshLow)
  {
    hotter();
  }
 
}


I'll update some of the hardware build when I get some time to snap pictures.
Here's the few I've taken so far, with probably cryptic captions:

Sourcing the gearpost: (yup, that's a binder clip arm)

Middle gear post hot-glued to switchplate, with washers for standoff:

Final gear glued to dimmer knob:

RFID Door Locks

posted May 25, 2010, 1:29 PM by Eric McKinley   [ updated May 28, 2010, 10:49 AM ]

I use RFID a lot in my life:
  • Accessing most doors and elevators at work
  • Accessing my church's doors
  • Accessing my marina's gate
  • Entering and exiting fare gates for BART
So why not at home?  We recently moved to a house that has three outside doors and three keys.  They're all the same type, and it's such a hassle to figure out by trial and error which is the right key.  Sure, there are easy solutions like color-coded keys, but that's boring and not minimalistic. 

Enter the RFID Door Strike.  With minimal expense (~$70/door) I can have all the benefits of keycard-access entryways:
  • Deactivate lost keys, instead of re-keying the locks
  • Track and announce who is entering
  • Open the door hands-free (like when carrying a box)
  • Coolness factor

Hardware

Here's what I've purchased so far, from sparkfun.com and seeedstudio.com:

Wiegand RFID reader

Electronic Brick Relay Module


Arduino Pro Mini



RFID Glass Capsule
Connections

The general flow works like this:
A more detailed schematic is in the works.

Code
This is a mashup of the code on the seeedstudio site and some code found on the arduino.cc forums:

Simple RFID Arduino Code


#ifndef RFID  // if we haven't said it somewhere before, assign these variables and pins
#define RFID
//==============================
#define DATA0 0x01 //Data pin 0 from RFID module
#define DATA1 0x02 //Data pin 1 from RFID module
#define D_DIR  DDRB
#define D_IN   PINB
//==============================
#endif

// =========Place allowed tags here in this format=============

char eric_glass[4] = {122,133,14,5};

char ashley_disc[4] = {234,567,14,5};

//========================================================

//===========Other definitions and pin assignments go here=============
char card_total[4] = {0,0,0,0};  // Used to typecast the serial data
int door_lock = 10;  // Assigns the relay to pin 10
//=========================================================


//================Start Program================================

void setup()
{
  Serial.begin(9600);
  D_DIR&=~(DATA0+DATA1);
  pinMode(door_lock, OUTPUT); //Set our relay pin to output
}
void loop()
{
  unsigned char recieve_count=0;  //Define a counter
  unsigned char card_num[4]={ 
    0,0,0,0  };
  for(;;)
  {
    unsigned char data0=0,data1=0;
    if(D_IN&DATA0)  //DATA0 incoming signal
    {
      data0=1;
    }
    if(D_IN&DATA1)  //DATA1 incoming signal
    {
      data1=1;
    }
    //--------------------------------------------   
    if(data0!=data1)  // card detected
    {
      recieve_count++;
      if(recieve_count==1) //drop even bit
      {
      }
      else if(recieve_count<10)// card data group 1
      {
        if(!data1)
        {
          card_num[0]|=(1<<(9-recieve_count));
        }
      }
      else if(recieve_count<18)// card data group 2
      {
        if(!data1)
        {
          card_num[1]|=(1<<(17-recieve_count));
        }
      }
      if(!data1) // card data group 3
      {       
        card_num[2]|=(1<<(25-recieve_count));
      }
      delayMicroseconds(80);  //Data impulse width delay 80us
    }
    else    // no card incoming or finish reading card
    {
      unsigned char i=0;
//-------------This is the if conditional that starts whenever any card is detected------------------
      if(recieve_count>= 25)  //output card number
      {

        recieve_count = 0; //reset flag
        for(i=0;i<4;i++)
        {
          card_total[i] = (char) card_num[i];        // Typecast our data so we can compare   
          Serial.print(card_num[i],DEC);      // Send the card number to the serial port so we can add new cards if needed
          card_num[i]=0;            //reset card_number array
         
        }
        Serial.println();
        //------------This is the if conditional that compares the read card to our database of cards-----------
        if (strcmp(eric_glass, card_total)  == 0)  // test to see the read card matches eric_glass
        {
          Serial.println("Welcome home, Eric!");
          digitalWrite(door_lock, HIGH);  // Turn the relay on
          delay(3000);
          digitalWrite(door_lock, LOW);  // Turn the relay off
        }
        elseif (strcmp(ashley_disc, card_total)  == 0)  // test to see the read card matches ashley_disc
        {
          Serial.println("Welcome home, Ashley!");
          digitalWrite(door_lock, HIGH);  // Turn the relay on
          delay(3000);
          digitalWrite(door_lock, LOW);  // Turn the relay off
        }
        else  // if the card is not in the database, do the following:
        {
           Serial.println("Nope.");
        }
    }
      //----------------------------------------------------     
    }
  }
}

Prototype
Here's a video of everything connected and working reading my glass capsule


Arduino Mini Temporary FTDI Header

posted May 13, 2010, 10:00 AM by Eric McKinley   [ updated Jul 7, 2010, 2:25 PM ]

Using the Arduino Mini in an installation is great for its size and price.  The only problem is uploading code. 
I didn't want to solder headers on each of the three boards, as they will be a permanent installation.

I found these cool header pins in a broken VCR.  They were used to attach the power supply board at a set height to the main board.  I'm sure you can find something else that would work just as well.

With a coated paperclip (or a breadboard jumper, though these aren't as stiff), we can apply the header temporarily and securely. 



  1. Straighten the paperclip, except for the small bend.
  2. Set header into Arduino Mini, and lean it towards the reset button.

  3. Hook the paperclip near the top of the header.

  4. Bend the paperclip around the board's edge by the reset button
    .
  5. Trim the excess paperclip.

Now removal is as easy as popping the paperclip off of the Arduino's edge, and uploading is as easy as plugging in the FTDI cable!





Help me get a camera with macro mode by clicking on the ads!

1-4 of 4