Re: Arduino Entry system using 12VAC doorbell trafo
Posted: Sat Oct 16, 2010 3:45 pm
Weekend update:
All electronics are done, everything hooked up with utp network-cable and working nicely (pics to follow).
Started the big coding job. Got buttons, LCD and RFID working. Next is to log data to the domotiga server (have to set up some arbitrary devices there) and storing some important data (RFID tags, resistorladder offset) in eeprom.
All electronics are done, everything hooked up with utp network-cable and working nicely (pics to follow).
Started the big coding job. Got buttons, LCD and RFID working. Next is to log data to the domotiga server (have to set up some arbitrary devices there) and storing some important data (RFID tags, resistorladder offset) in eeprom.
Code: Select all
#include <LCD3Wire.h>
#include <Tone.h>
#include <NewSoftSerial.h>
#include <EEPROM.h>
#define OCTAVE_OFFSET 0
#define LCD_LINES 2 // VFD
#define LCD2_LINES 2 // LCD
#define DOUT_PIN 9 // Dout pin vfd+lcd
#define CLK_PIN 8 // Clock pin vfd+lcd
#define STR_PIN 7 // Strobe pin vfd
#define STR2_PIN 6 // Strobe pin lcd
#define MAX_NO_CARDS 102 //Amount of RFID tags eeprom can hold
#define BELL A0 // ding-dong pin
#define BIGBELL A1 //Add a ding pin
//RFID global vars
int c = 0;
char code[11]; //RFID tag is 10 chars and then terminate
int offset = 0;
byte tag[5]; // tag serial numbers are 5 bytes long
// Resistor ladder inputs
byte channelAInput = 4; //Resladder on pin 4
byte channelBInput = 5; //Resladder on pin 5
int correctIn = 15; //Correct the indoor resladder readings for temp etc.
int correctOut = 0; //Correct the outdoor resladder readings for temp etc.
// Got milk?
boolean doorOuter = false;
boolean doorInner = false;
boolean doorBasement = false;
boolean buttonKids = false;
boolean buttonAdult = false;
boolean buttonMenu1= false;
boolean buttonMenu2 = false;
// Lets create the RFID class
NewSoftSerial mySerial(2, 53);
// ...and create some classes for the LCDs
LCD3Wire lcd1 = LCD3Wire(LCD_LINES, DOUT_PIN, STR_PIN, CLK_PIN);
LCD3Wire lcd2 = LCD3Wire(LCD2_LINES, DOUT_PIN, STR2_PIN, CLK_PIN);
//Play some music or at least be prepared
Tone tone1;
int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
char *song = "smb:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6";
void setup()
{
//Init LCDs
lcd1.init();
lcd2.init();
lcd1.clear();
lcd2.clear();
lcd1.printIn("Starting...");
lcd2.printIn("Starting...");
// set the data rate for serial debugging port and the NewSoftSerial port
Serial.begin(9600);
mySerial.begin(9600);
//Set up music & bell pins
tone1.begin(5);//Playback on Pin 5
pinMode(BELL, OUTPUT);
pinMode(BIGBELL, OUTPUT);
}
void loop()
{
//Read resistor ladder inputs
byte frontStatus = checkSensor(channelAInput, correctOut);
byte insideStatus = checkSensor(channelBInput, correctIn);
//Lets check front door
if ((frontStatus & (1<<0)) && (doorOuter == false) ) {
doorOuter=true;
lcd1.clear();
lcd1.printIn("Door closed");
} else if ( (!(frontStatus & (1<<0))) && (doorOuter == true)) {
doorOuter=false;
lcd1.clear();
lcd1.printIn("Door open");
};
//Lets check if someone is at the door
if ( frontStatus & (1<<1)) {
buttonAdult=true;
lcd2.printIn("Adults bell");
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH);
digitalWrite(A1, HIGH);
delay (20);
digitalWrite(A0, LOW);
digitalWrite(A1, LOW);
delay (4500);
} else {
buttonAdult=false;
lcd2.clear();
};
//Any kids at the door?
if ( frontStatus & (1<<3)) {
buttonKids=true;
lcd2.printIn("Kids bell");
play_rtttl(song); // Play Mariotune
} else {
lcd2.clear();
buttonKids=false;
};
// For debugging on serial
Serial.println("");
//Check for rfid tags
rfid();
//No stress, lets take a break
delay (300);
}
void rfid()
{
if (mySerial.available() > 0)
{
c = mySerial.read();
if ( c == 2 || c == 4 )
{
code[offset] = 0;
if ( c == 4 )
{
lcd1.printIn("LCD 1 - Tag code is ");
lcd1.printIn(code);
// lcd2.cursorTo(1,0);
lcd2.printIn("LCD -2 Tag code is ");
// lcd2.cursorTo(2,0);
lcd2.printIn(code);
delay (1000);
lcd1.clear();
lcd2.clear();
}
offset = 0;
}
else
{
code[offset++] = c;
}
}
}
boolean checkSensor( byte sensorInput, int correction )
{
byte state;
int sensorReading = analogRead(sensorInput) + correction ;
if( sensorReading > 1010 ) {
state = B01111 ;
} else if ( sensorReading > 509 ) {
state = B01110 ;
} else if ( sensorReading >= 320 ) {
state = B01101;
} else if ( sensorReading >= 246 ) {
state = B01100;
} else if ( sensorReading >= 212 ) {
state = B01011;
} else if ( sensorReading >= 176 ) {
state = B01010;
} else if ( sensorReading >= 148 ) {
state = B01001;
} else if ( sensorReading >= 131 ) {
state = B01000;
} else if ( sensorReading >= 115 ) {
state = B00111;
} else if ( sensorReading >= 105 ) {
state = B00110;
} else if ( sensorReading >= 95 ) {
state = B00101;
} else if ( sensorReading >= 87 ) {
state = B00100;
} else if ( sensorReading >= 83 ) {
state = B00011;
} else if ( sensorReading >= 78 ) {
state = B00010;
} else if ( sensorReading >= 73 ) {
state = B00001;
} else {
state = B00000;
}
Serial.print(sensorInput, DEC);
Serial.print(": ");
Serial.print(sensorReading, DEC);
Serial.print(" (");
Serial.print(state, BIN);
Serial.print(") ");
// Pass the current state back to the calling function
return state;
}
#define isdigit(n) (n >= '0' && n <= '9')
void play_rtttl(char *p)
{
// Absolutely no error checking in here
byte default_dur = 4;
byte default_oct = 6;
int bpm = 63;
int num;
long wholenote;
long duration;
byte note;
byte scale;
// format: d=N,o=N,b=NNN:
// find the start (skip name, etc)
while(*p != ':') p++; // ignore name
p++; // skip ':'
// get default duration
if(*p == 'd')
{
p++; p++; // skip "d="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num > 0) default_dur = num;
p++; // skip comma
}
// get default octave
if(*p == 'o')
{
p++; p++; // skip "o="
num = *p++ - '0';
if(num >= 3 && num <=7) default_oct = num;
p++; // skip comma
}
// get BPM
if(*p == 'b')
{
p++; p++; // skip "b="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
bpm = num;
p++; // skip colon
}
// BPM usually expresses the number of quarter notes per minute
wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds)
// now begin note loop
while(*p)
{
// first, get note duration, if available
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num) duration = wholenote / num;
else duration = wholenote / default_dur; // we will need to check if we are a dotted note after
// now get the note
note = 0;
switch(*p)
{
case 'c':
note = 1;
break;
case 'd':
note = 3;
break;
case 'e':
note = 5;
break;
case 'f':
note = 6;
break;
case 'g':
note = 8;
break;
case 'a':
note = 10;
break;
case 'b':
note = 12;
break;
case 'p':
default:
note = 0;
}
p++;
// now, get optional '#' sharp
if(*p == '#')
{
note++;
p++;
}
// now, get optional '.' dotted note
if(*p == '.')
{
duration += duration/2;
p++;
}
// now, get scale
if(isdigit(*p))
{
scale = *p - '0';
p++;
}
else
{
scale = default_oct;
}
scale += OCTAVE_OFFSET;
if(*p == ',')
p++; // skip comma for next note (or we may be at the end)
// now play the note
if(note)
{
tone1.play(notes[(scale - 4) * 12 + note]);
delay(duration);
tone1.stop();
}
else
{
delay(duration);
}
}
}