### Electronics

#### Post Index

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

#### 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);
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:

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 ]