My PIR detector sketch

PIR and DS1307 RTC module control a light

This time I have written a sketch to control a light with a PIR detector, well in this case the light is just a led. When the PIR detector detects movement it turns on the light, and after 30 seconds the light goes out. This is a common circuit in home automation, some of these PIR modules also have a clock so you can set the time for when it should work. There is no need to turn it on during the day when there is natural light. Since I have a DS1307 RTC module I thought why not try to make this myself. I did not use the RTC library to get the time from the DS1307 but instead used code that I found here. With this code you can get the date and time from the DS1307, in the form of bytes over the I2C bus. The bytes are then converted to decimals so we can use them in our sketch. In this case we request the first 3 bytes, which are seconds, minutes and hours. In total you can request 7 bytes from the DS1307: second, minute, hour, day of the week, day of the month, month, year. I have made the sketch so that the PIR detector will turn on the the light after 18:00, and the light will turn off after 30 seconds.
The sketch:

/*

http://www.bajdi.com

  PIR detector turns on light, light switches automatically off after 30 seconds.
  Light will only turn on in the evening (after 18:00)
 */

#include <Wire.h>
const int DS1307_I2C_ADDRESS = 0x68;
const int pir = 2;     // the number of the PIR pin
const int light =  13;      // the number of the light pin

unsigned long on;      //start time for pir light on

int pirState = 0;         // variable for reading the pushbutton status

byte second, minute, hour;

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

  second     = bcdToDec(Wire.receive() & 0x7f);
  minute     = bcdToDec(Wire.receive());
  hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
}

void setup() {
  Wire.begin();
  pinMode(light, OUTPUT);
  pinMode(pir, INPUT);
}

void loop(){

  getDateDs1307();

  pirState = digitalRead(pir);

  if (pirState == HIGH && hour >= 18) {
    digitalWrite(light, HIGH);
    on = millis();
  } 

  unsigned long currentMillis = millis();

  if ((currentMillis - on) > 30000) {
    digitalWrite(light, LOW);
  }

}

Arduino digital clock

Arduino digital clock with DS1307
I found a DS1307 module in my mailbox today. The DS1307 is a serial real time clock, or RTC. You can easily find this chip at your favourite electronics dealer and make your own circuit with it. Several companies that make Arduino stuff sell modules with this chip. They all come with a small battery and an oscillator that is required to let the DS1307 do it’s thing. I found mine on Ebay from a Hungarian seller, arrived here pretty quickly so I immediately wanted to try it out. Adafruit sells a board with the DS1307 chip and has made a nice library for it. It comes with an example that shows the time and date to the serial monitor. I changed the sketch to show the date and time on my I2C LCD display. The DS1307 is also an I2C device so I had to use my new little breadboard to connect both devices to the I2C pins of my Arduino Uno.
Here is the sketch:

// http://www.bajdi.com
// Arduino digital clock
// Date and time shown on I2C LCD display
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);

RTC_DS1307 RTC;

void setup () {
    Wire.begin();
    RTC.begin();
    lcd.init(); // initialize the lcd
    lcd.backlight();
  }

void loop () {
    DateTime now = RTC.now();
    lcd.clear();
    lcd.print(now.year(), DEC);
    lcd.print('/');
    lcd.print(now.month(), DEC);
    lcd.print('/');
    lcd.print(now.day(), DEC);
    lcd.setCursor(0, 1);
    lcd.print(now.hour(), DEC);
    lcd.print(':');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
    lcd.print(now.second(), DEC);
    delay(1000);
}

An RTC module is a very handy device if you want to some sort of data logging or other time based things. For example in a home automation program where you want to turn on devices at a certain time.

Arduino Mega 2560 and sd card module

Arduino Mega 2560 and sd card module

Arduino Mega 2560 and sd card module

I bought a sd card module some time ago, from a Chinese seller on Ebay. These modules are really cheap, I paid 2,03€ for it and that includes shipping to Belgium. You really wonder how they can do it. To try it out I connected the sd card module to my Arduino Uno and uploaded the data logger example sketch. This sketch reads the value of 3 analogue inputs and logs it to a file on the sd card. This worked out of the box. Then I tried doing the same with my Arduino Mega 2560 and it caused me some head scratching. I plugged my sensor shield on the mega, this shield has a break out connector for a sd card module. Unfortunately the pinout of this connector is not written on the board itself. After some googling I finally found a small drawing with the pinout of the connector.

Arduino Mega shield

Arduino Mega shield

The sd card talks to the Arduino over the SPI bus. The Mega 2560 uses different pins for the SPI then the Uno. This caused me some trouble in getting the sketch to work. In the example data logger sketch the chipselect pin is set to 4, and the pinmode for pin 10 is to output. This is necessary for the sd library to work. After some fiddling I found that for the Mega 2560 you have to set both to pin 53 for the sd library to work :)
Here is the sketch:

/*

http://www.bajdi.com

  SD card datalogger for Arduino Mega (this sketch will ONLY work with Arduino Mega) 

 This example shows how to log data from three analog sensors
 to an SD card using the SD library.

 The circuit:
 * analog sensors on analog ins 0, 1, and 2
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 51
 ** MISO - pin 50
 ** CLK - pin 52
 ** CS - pin 53

 created  24 Nov 2010
 updated 2 Dec 2010
 by Tom Igoe
 updated 22 Jan 2012 for Arduino Mega
 by Bajdi.com 

 This example code is in the public domain.

 */

#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 53;

void setup()
{
  Serial.begin(9600);
  Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(53, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.");
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = "";

  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) {
      dataString += ",";
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
  }
}

ADXL345 simple sketch

Arduino + ADXL345 from Bajdi on Vimeo.

After running the example sketch sketches that come with the ADXL345 accelerometer library it was time to try something on my own. And the simplest thing is fading a couple of leds. By mapping the value of the Y-axis to 2 big 10mm leds connected to 2 PWM outputs on an Arduino Mega 2560 you can fade the leds by tilting the ADXL345 from left to right.
Here is the sketch:

// http://www.bajdi.com
// ADXL345 over I2C
// 2 leds connected to 2 PWM outputs
// The leds fade by tilting the sensor over the Y-axis.

#include "Wire.h"
#include "ADXL345.h"

ADXL345 adxl;

void setup(){
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  Wire.begin();
  adxl.powerOn();
  delay(1);
  adxl.set_bw(ADXL345_BW_12);
  delay(500);
}

void loop(){

  int x,y,z;
  adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables  x,y,z

    if (y >= 20) {
    y = map(y, 20, 250, 0, 255);
    analogWrite(2, y);
  }

  else {
    analogWrite(2, 0);
  }

  if (y <= -20) {
    y = map(y, -250, -20, 255, 0);
    analogWrite(3, y);
  }

  else  {
    analogWrite(3, 0);
  }
}

Arduino Uno test

I wanted to do a quick check if all the digital pins on my Arduino Uno were still working.  The Arduino Uno has 14 digital pins, these can all be set as input or output. So I needed a sketch with 14 times the same statement to declare the pins as output and to write them high. That’s a lot of typing :) But I found out that there is an easier way. Store all the pin numbers in an array…

So I came up with the following simple sketch :)

/*

http://www.bajdi.com

  Set all digital pins as outputs and write them high.
 */
int outputPins[] = {
  0,1,2,3,4,5,6,7,8,9,10,11,12,13};

void setup() {
  for(int index = 0; index < 14; index++)
  {
    pinMode(outputPins[index], OUTPUT);
  }
}

void loop() {
  for(int index = 0; index < 14; index++)
  {
    digitalWrite(outputPins[index], HIGH);
  }
}