DIY Air Conditioner using unused fridge

Concept: Arduino Temperature Sensor with AC Relay to control unused fridge

And some ventilation to expel the heat of fridge to outside….

Arduino Group in San Francisco Bay Area?

Is anybody interested in Arduino hobby group meeting on weekends?

My projects in the past are here.

Let me know if anyone is interested.

Posted in Arduino. 1 Comment »

Arduino Kitchen Timer

Arduino Kitchen Timer is made of 4-digit 7-segment LED, and 12-key keypad, 8-bit shift register 74HC164, and some resistors, decoupling capacitor, and Piezo speaker for the sound output.

* Do not imagine I am using this timer in my kitchen because I don’t. :) It’s just the name of device…

Feature:
Kitchen Timer. Maximum duration is 99 minutes and 99 sec. Beep when it’s done.

Parts:
1 x Keypad 12 Button
1 x 7-Segment Yellow 4 Digit LED
1 x 74AC164
8 x 470 ohm Resistor (LED)
* 220 ohm may work but it’s a little bit brighter. I used 470 ohm resistor array.
3 x 4.7K ohm Resistor (Keypad pullup resistors)
1 x Piezo Speaker taken out from old PC.

Pin Assignment:
Digital 02-05 Common Cathode of LED
Digital 06-12 Keypad Scanning
Digital 13 Piezo Speaker Output
Analog 0 74AC164 Data
Analog 1 74AC164 Clock
Analog 3-5 Not Used.

Video and Semantic in eagle format will be added soon.
Porting to Arduino Kitchen Timer Shield is on the way, but I will replace the keypad with just three or four buttons.

 
#include   <GenKeypad.h> //My keypad library
#include   <MsTimer2.h> //download this library at http://www.arduino.cc/playground/Main/MsTimer2

#define SHIFT_DATA 15     // 74AC164 data pin
#define SHIFT_CLOCK  14   // clock pin
#define SPEAKER_PIN 13

int NumPins[4] = {2, 3, 4, 5};
int SS = 0;
int MM = 0;
int start = 0;
char input[4] = {0, 0, 0, 0};
int inputIndex = 0;
int length = 15; // the number of notes
char notes[] = "ccccccccccccccc";
int beats[] = { 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1, 3, 1, 1 };

int tempo = 300;
int beeping = 0;

/**
   Keypad 
 **/
GenKeypad keypad;

//Key Input Callback Functions 
  
void keyUP(char key)  
{  
  //Serial.print("keyUP: ");  
  //Serial.println(key);  
}  

int atoi(char c)
{
  if (c == 0)
    return 0;
  else
    return (c - '0');
}

void keyDOWN(char key)  
{           
  Serial.print("keyDOWN: ");  
  Serial.println(key);  
    
  if (key == '#' && start == 0)
  {
    //Convert input chars into MM:SS
    MM = atoi(input[0]) * 10 + atoi(input[1]);
    SS = atoi(input[2]) * 10 + atoi(input[3]);
    
    if (MM + SS > 0)
      start = 1;
    return;
  }
  else if (key == '#' && start == 1)
  {
    start = 0;
    return;
  }

  if (key == '*')    
  {
    if (beeping == 0)
    {
      for (int i = 0; i < 4; i++)
        input[i] = 0;
    }
          
    inputIndex = 0;
    start = 0;
    beeping = 0;
    digitalWrite(SPEAKER_PIN, LOW);
  }
  else
  {  
    shiftDigit(input);
    input[3] = key;      
    
    inputIndex++;
    inputIndex %= 4;  
  }
}  

void shiftDigit(char input[4])
{
  input[0] = input[1];
  input[1] = input[2];
  input[2] = input[3];
}

void keyPRESSING(char key)  
{  
  //Serial.print("keyPressed: ");  
  //Serial.println(key);  
}

void setup(void) 
{
  Serial.begin(9600);
  
  //Digital pins parameter order matters!!
  keypad.setRowPins(11, 6, 7, 9);  //These pins are used as OUTPUT pins.
  keypad.setColPins(10, 12, 8);    //These pins are used as INPUT pins.  
  keypad.setFunction(GenKeypad::EVENT_KEY_UP,       keyUP); 
  keypad.setFunction(GenKeypad::EVENT_KEY_DOWN,     keyDOWN); 
  keypad.setFunction(GenKeypad::EVENT_KEY_PRESSING, keyPRESSING);
  
  pinMode(SPEAKER_PIN, OUTPUT);
  
  pinMode(SHIFT_DATA, OUTPUT);
  pinMode(SHIFT_CLOCK, OUTPUT);
  
  pinMode(NumPins[0], OUTPUT);
  pinMode(NumPins[1], OUTPUT);
  pinMode(NumPins[2], OUTPUT);
  pinMode(NumPins[3], OUTPUT);
  
  digitalWrite(NumPins[0], HIGH);
  digitalWrite(NumPins[1], HIGH);
  digitalWrite(NumPins[2], HIGH);
  digitalWrite(NumPins[3], HIGH);
  
  // writing default values (from the datasheet)
  
  MsTimer2::set(1000, secPulse);
  MsTimer2::start();
}

int digitSS = 0;
int digitMM = 0;
int digit = 0;

  byte font[10] = {
	//abcdefg.
    0b11111100,
    0b01100000,
    0b11011010,
    0b11110010,
    0b01100110,
    0b10110110,
    0b10111110,
    0b11100100,
    0b11111110,
    0b11100110
  };
  
byte c2font(char c)
{
  const byte blank = 0b00000000;
  
  if (c == 0)
    return blank;
  else  
    return font[c-'0'];
}


void setChars(char input[4], int delaymsec)
{
  digitalWrite(NumPins[0], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[3])); 
  delay(delaymsec);
  digitalWrite(NumPins[0], HIGH);

  digitalWrite(NumPins[1], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[2])); 
  delay(delaymsec);
  digitalWrite(NumPins[1], HIGH);


  digitalWrite(NumPins[2], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[1])); 
  delay(delaymsec);
  digitalWrite(NumPins[2], HIGH);

  digitalWrite(NumPins[3], LOW);
  shiftOut(SHIFT_DATA, SHIFT_CLOCK, LSBFIRST, c2font(input[0])); 
  delay(delaymsec);
  digitalWrite(NumPins[3], HIGH);
  
  delay(delaymsec);
}

void beep()
{
  if (start)
  {
    digitalWrite(SPEAKER_PIN, HIGH);
    beeping = 1;  
    start = 0;
  }
  else
    digitalWrite(SPEAKER_PIN, LOW);
}

void secPulse()
{
  if (start)
  {
    SS--;  
    if (SS == 0 && MM == 0)
    {
      beep();
      start = 0;
      return;
    }
    
    if (SS == -1 && MM > 0)
    {
      MM--;
      SS = 59;
    }

  }
}
void playTone(int tone, int duration) {
  for (long i = 0; i < duration * 1000L; i += tone * 2) 
  {          
    digitalWrite(SPEAKER_PIN, HIGH);
    delayMicroseconds(tone);
    digitalWrite(SPEAKER_PIN, LOW);
    delayMicroseconds(tone);
  }
}

void playNote(char note, int duration) {
  char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C', 'F', 'G'};
  int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 473, 478};
  
  // play the tone corresponding to the note name
  for (int i = 0; i < 10; i++) {
    if (names[i] == note) 
    {
      playTone(tones[i], duration);
    }
  }
}

char * clearLeadingZero(char input[4])
{
  if (input[0] == '0')
  {
    input[0] = 0;    
    if (input[1] == '0')    
    {
      input[1] = 0;
      if (input[2] == '0')    
        input[2] = 0;
    }
  }
  
  return input;
}

void processLCD()
{
  static char chs[4] = {'0', '0', '0', '0'};
 
  if (start)
  {
    chs[3] = SS%10 + '0';
    chs[2] = SS/10 + '0';
    chs[1] = MM%10 + '0';
    chs[0] = MM/10 + '0';
    
    setChars(clearLeadingZero(chs), 2);
  }
  else
  {   
    setChars(input, 2);
  }  
}

void loop()
{  
  int someKeyDown = keypad.scanKeys(0);
  keypad.handlePostEvents(someKeyDown);      
 
  processLCD();
  
  if (beeping = 1)
  {
     beeping++;
     beeping %=3;
     
     for (int i = 0; i < length; i++) 
     {
       someKeyDown = keypad.scanKeys(0);
       keypad.handlePostEvents(someKeyDown);      

       processLCD();
       if (beeping != 0)
         playNote(notes[i], beats[i] * tempo/2);
    
       // pause between notes
       delay(tempo / 2); 
     } 
  } 
}

NTSC on Arduino

I switched to NTSC signal. I think it’s much simpler and easier, but it’s monochrome.
I’ve managed to get around 40 pixels width and working to increase vertical resolution.
It’s a very good idea to use constant length of interrupt to send NTSC signal apart from your pixel manipulation.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1188261175/0

I am trying to build VGA (analog RGB) signal output on Arduino.
I found out that H/V Sync can be done by the built-in timer interrupt.

1. Arduino Pin-out assignment.

02: Red
03: Green
04: Blue
(05: SyncFlag)
06: VSync
07: HSync
10-13: SPI for EEPROM

(On going memo)

* Memory?
Frame buffer: 640 x 480 pixels x 3 bytes per pixel = 900KB
External EEPROM 2MB AT45DB161D may be needed.

* Find out the maximum transmission rate.

* Double buffering with two Atmega chips and one 2MB AT45DB161D? possible?

* Any suggestions?

References:
http://avga.prometheus4.com/index.php?p=2-0 (AVR but not written for Arduino)
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1228264461/all (Implementation issues discussed here.)
H/V Sync code using ISR timer: http://olb7.free.fr/arduino/syncInterrupt.pde
EEPROM:
http://blog.blockos.org/?p=27
http://todotani.cocolog-nifty.com/blog/2009/07/arduino-4cf4.html

Posted in Arduino. 1 Comment »

Breadboard Arduino

You can build DIY arduino in your breadboard. The best site I found is: http://itp.nyu.edu/physcomp/Tutorials/ArduinoBreadboard

I have not managed the USB part yet, but I am sure you can add the Arduino Serial USB Board

So far, the LED blinking works good on my breadboard.
Eventually I am planning to do some VGA signal experiment on the breadboard.

Posted in Arduino. Tags: . 3 Comments »

Digit Counter with 7-segment LED + Arduino

It just counts 0 to 9 with 7-segment LED. Only digit 1 side has been used since the digit 2 is burned out…
Adjust output pins for your environment. For simplicity, you need 7 pins for output in this example.
I am sure I can reduce the number of pins with demux. That’s gonna be the next project.

Parts: Arduino Duemilanove, Breadboard, a register and LTD-5523AB (Datasheet)

The LED-facing-upright LTD-5523AB pin-order is:

18, 17, 16, 15, 14, 13, 12, 11, 10pin 
[------------LTD-5523AB------------] | - A - | | - A - | F B F B | - G - | | - G - | E C E C | - D - | | - D - | [------------LTD-5523AB------------] 01, 02, 03, 04, 05, 06, 07, 08, 09pin

[7-segment LED for digit 1]
A = 16pin, B = 15pin, C = 03pin, D = 02pin, E = 01pin, F = 18pin, DP = 04pin
14pin is common cathode for digit 1 (it means it should be GNDed all the time.)

For example, to make the digit 3, just turn on A, B, C, D and G.

[7segment.pde]
//Output Pins
//* Adjust this for your pin outputs.
int ledPin[8] = {4, 5, 6, 7, 9, 10, 11, 12};  

//Segment to Pin
//* Adjust this for your 7 segment LED spec.
//                 A,  B, C, D, E,  F,  G, DP
int Seg2Pin[8] = {11, 10, 5, 6, 7, 9, 12, 4};

//Digit to Segment
// * You don't need modify this unless you want to change digits.
int Dec2Seg[11] = 
{
//A(125), B(64), C(32), D(16), E(8), F(4), G(2), DP(1)
  0x07E, //Digit 0
  0x00C, //Digit 1
  0x0B6, //Digit 2
  0x09E, //Digit 3
  0x0CC, //Digit 4
  0x0DA, //Digit 5
  0x0FB, //Digit 6
  0x00E, //Digit 7
  0x0FF, //Digit 8  
  0x0DF, //Digit 9  
  0x100 //DP
};

void setup()                    // run once, when the sketch starts
{
  for (int i = 0; i < 8; i++)
    pinMode(ledPin[i], OUTPUT);      // sets the digital pin as output
}

void clearAllSegments()
{
  //Turn off all segments
  for (int i = 0; i  0)
  {
    seg /= 2;    
    if (seg & 0x1)
      digitalWrite(Seg2Pin[pin], HIGH);   // sets the LED on    
    pin++;
  }
}

void loop()                     // run over and over again
{
  //Count 0 to 9
  for( int digit = 0; digit <= 10; digit++)
  {    
    drawDigit(digit);    
    delay(1000);                  // waits for a second
    clearAllSegments();    
  }
}

Update 1: I change the 13pin to 9pin for output since 13pin has some builtin register.
Update 2: I implemented a bit mask to select segments.n