Sunday 9 May 2010

Acquisition of temperature data to SD Card

I have managed to hack together from various sites a temperature data logger thats writes to a 2GB SD Card, firstly I had a blown up laptop motherboard and so I desoldered the SD card socket this was not very easy as they are surface mounted and is not designed to be removed. I then soldered 9 header pins to it and used a glue gun and melted glue all around the soldered part to strenghten it, afterwards I found a better way it was to use a MicroSD convertor to a standard SD card adaptor and soldered header pins to it.



or MicroSD adaptor



Library Used:

AF_SDLog library. from http://www.ladyada.net/make/gpsshield/download.html

I also have used the Sparkfun FAT16 library and examples <HERE> for use with there shield <HERE> and changed the '#define CS    8' on line 33 to '#define CS    10' in the examples to work with my build.

Code




/************************************/

/*            SD card temperature Logger         */

/*                             Version 1.e                          */

/*                           Chris Hawkins                      */

/************************************/


#include "AF_SDLog.h"

#include "util.h"

#include <avr/pgmspace.h>



AF_SDLog card;

File f;


#define ledBusyPin 8

#define powerPin 9

#define temperaturePin 0

#define BUFFSIZE 99

#define buttonStartStop 7


int buttonState = 0;         // current state of the button

int runState = false;     // previous state of the button

float lastPressed =0;


char buffer[BUFFSIZE];

uint8_t bufferidx = 0;

uint8_t i;


unsigned int logCount;



// blink out an error code

void error(uint8_t errno) {

while(1) {

for (i=0; i<errno; i++) {

digitalWrite(ledBusyPin, HIGH);

digitalWrite(powerPin, HIGH);

delay(200);

digitalWrite(ledBusyPin, LOW);

digitalWrite(powerPin, LOW);

delay(200);

}

for (; i<10; i++) {

delay(300);

}

}

}


void setup()

{


Serial.begin(9600);

putstring_nl("\r\nData logger");


// configure PINS

pinMode(ledBusyPin, OUTPUT);

pinMode(powerPin, OUTPUT);

pinMode(buttonStartStop, INPUT);

digitalWrite(powerPin, HIGH);


// check SD card - FAT 2GB

if (!card.init_card()) {

putstring_nl("Card init. failed!");

error(1);

}

if (!card.open_partition()) {

putstring_nl("No partition!");

error(2);

}

if (!card.open_filesys()) {

putstring_nl("Can't open filesys");

error(3);

}

if (!card.open_dir("/")) {

putstring_nl("Can't open /");

error(4);

}


// Check for next file in sequence 00 to 99

strcpy(buffer, "TMPLOG00.TXT");

for (buffer[6] = '0'; buffer[6] <= '9'; buffer[6]++) {

for (buffer[7] = '0'; buffer[7] <= '9'; buffer[7]++) {

putstring("\ntrying to open ");

Serial.println(buffer);

f = card.open_file(buffer);

if (!f)

break;

card.close_file(f);

}

if (!f)

break;

}


if(!card.create_file(buffer)) {

putstring("couldnt create ");

Serial.println(buffer);

error(5);

}

f = card.open_file(buffer);

if (!f) {

putstring("error opening ");

Serial.println(buffer);

card.close_file(f);

error(6);

}

putstring("writing to ");

Serial.println(buffer);

putstring_nl("ready!");


delay(250);


// clear buffer

strcpy(buffer,"");

}



void loop(){


// get button state

buttonState = digitalRead(buttonStartStop);


//  if button pressed and 2 seconds passed

if (buttonState ==HIGH && (millis() - lastPressed)>2000) {

lastPressed = millis();

runState = !runState;


}

// if the state has true then log temperature data

if (runState == true) {


// build string to write to card

sprintf(buffer, "%s,%d,%u,%d\n",getDate(),getTime (),logCount++,getTemperature());


//log data to SD Card

logData();


}

}



int getTemperature(){


//getting the voltage reading from the temperature sensor

float temperature = getVoltage(temperaturePin);


//converting from 10 mv per degree wit 500 mV offset

temperature =  (temperature - .5) * 100;


return temperature;

}


unsigned int getTime(){

//replace with RTC code once added

return  (millis() /1000);

}


char* getDate (){

//replace with RTC code once added

return "24/04/2010";

}

float getVoltage(int pin){

return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range

// to 0 to 5 volts (each 1 reading equals ~ 5 millivolts

// using TMP36 temperature sensor

}


void logData( )

{


digitalWrite(ledBusyPin, HIGH);// LED on for witting to card


// get string length

bufferidx = strlen(buffer);


// write data to sd card

if(card.write_file(f, (uint8_t *) buffer, bufferidx) != bufferidx) {

putstring_nl("can't write!");

error(5);


}


digitalWrite(ledBusyPin, LOW);// LED off to show finished writting to card


}

/* End code */





Sample of output to SD card



Schematic

Monday 22 March 2010

Linux folder backup script

Here is my script I use to backup a linux folder, firstly it mounts the backup drive and checks to see if it has mounted by reading a file named NOT_MOUNTED created by using
touch NOT_MOUNTED

Then using rsync it copies only new and modified files to the backup drive and excludes all .* files, this is to stop the backing up folders like the .Trash folder. It also creates and appends a log file stored in $LOGDIR.

Add as a cron job by:
crontab -e
add @daily /root/{filename} <-- name of script

Remember to change the file to make it executable
chmod +x {filename}

Usage:

$LOGDIR = log file
$SOURCE DIR =Source directory
$DESTDIR = Destination directory
# Backup SH file by Chris Hawkins
# Get date and time
DATETIME=$(date)
LOGDIR=/usr/log
SOURCEDIR=/home
DESTDIR=/backup
mount $DESTDIR

if [ -f $DESTDIR/NOT_MOUNTED ];
then

LOGMESSAGE='Backup NOT Mounted (ERROR) - Backup NOT completed'

echo $DATETIME $LOGMESSAGE >>$LOGDIR/backuplog

else

LOGMESSAGE='Backup Started'

echo $DATETIME $LOGMESSAGE >>$LOGDIR/backuplog

rsync -auqlP --delete --exclude='.*' $SOURCEDIR $DESTDIR
# Get date and time
DATETIME=$(date)
LOGMESSAGE='Backup Completed'
echo $DATETIME $LOGMESSAGE >>$LOGDIR/backuplog

fi

cd $LOGDIR
umount $DESTDIR

Friday 5 March 2010

Arduino and TMP36 (temperature sensor) Part 2

I have now added conversion from Celsius and Fahrenheit via a push button, so you just need to press and hold the button until the display shows either a C or an F then you can release the button and the conversion is done.

Latest code v1.4 can be found here http://code.google.com/p/arduino-fun/downloads/list
// Arduino - TMP36 and 7 segment LED v1.3
// By Chris Hawkins
// February 2010
// Temperature code from http://oomlout.com/TMP36/TMP36-Guide.pdf
//
// using bitRead help from http://arduinofun.com/blog/2009/12/06/connecting-a-7-segment-led-to-the-arduino-build-it/
//
// Changes from 1.2
// Push button added to pin 12
// Added conversion scales from Celsius and Fahrenheit
// streamlined splitting the two digits

// Code Start
// pins that 7 segment is connect to
int ledSegment[] = {
  2,3,4,5,6,7,8,9};

// Analog pin that TMP36 is connect to
int tempMonitor =0;

//pin for Switching from C to F
int pinSwitch =12;

// Button state for temperature scales
boolean displayType = false;
// encode the on/off state of the LED segments for the characters
// '0' to '9' and 'DP' into the bits of the bytes
const byte numDef[11] = {
  63, 6, 91, 79, 102, 109, 124, 7, 127, 103,128 };

void setup()
{
  // Serial.begin (9600);

  // set pinmode for switch
  pinMode (pinSwitch,INPUT);

  // Sets the pinMode for all LEDs
  for (int x = 0; x<=7; x++)
  {
    pinMode (ledSegment[x],OUTPUT);
  }

  // enable on by one each LED to test them.
  for (int x =0;x<=7;x++){
    digitalWrite (ledSegment[x],HIGH);
    delay (50);

  }
  // disable one by one to finish test of each LED
  for (int x =0;x<=7;x++){

    digitalWrite (ledSegment[x],LOW);
    delay (50);
  }
}

void loop(){

  // Check if button is pressed
  if (digitalRead(pinSwitch)) {
    displayType = !displayType;
    if (displayType) {
      setSegments(113); // send byte for C to display
      delay(1500);
    }
    else{
      setSegments(57); // send byte to F to display
      delay(1500);
    }
  }

  float temperature = getVoltage(tempMonitor);  //getting the voltage reading from the temperature sensor
  temperature = (temperature - .5) * 100;          //converting from 10 mv per degree wit 500 mV offset

  if (displayType){
    temperature = ((temperature *1.8) +32);
  }

  // Print temperature to serial for use in processing
  //Serial.println (temperature);

  // Split two digit number to send to display
  int digit1 = temperature / 10;
  int digit2 = int(temperature) % 10;
  // send ten's number to display
  setSegments( numDef[digit1] );

  // Delay to display the 10's digit of the temperature
  delay (1000);

  // send unit number to display and DP
  setSegments( numDef[digit2] +  numDef[10] );

  // Delay to display the unit digit of the temperature
  delay (2000);
}

void setSegments(byte segments)
{
  // for each of the segments of the LED
  for (int s = 0; s < 8; s++)
  {
    int bitVal = bitRead( segments, s ); // grab the bit
    digitalWrite(s+2, bitVal); // set the segment
  }
}

float getVoltage(int pin){
  return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range
  // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}

Breadboard view of how I configured the Arduino:

[caption id="attachment_82" align="alignnone" width="300" caption="Designed using the Fritzing program"]Breadboard view[/caption]

Sunday 28 February 2010

Arduino and TMP36 (temperature sensor)

Here is my first build of a temperature sensor and 7 segment LED connected to an Arduino Duemilanove, the display displays the first digit (10's) and pauses and then displays the second digit (units) pauses and then the decimal point to show end/start of temperature display.     

     

And here is the video:     





     
  

The full source code below

// Arduino - TMP36 and 7 segment LED
// By Chris Hawkins
// February 2010
// Temperature code from http://oomlout.com/TMP36/TMP36-Guide.pdf
//
// using bitRead help from connecting-a-7-segment-led-to-the-arduino-build-it/

// pins that 7 segment is connect to
int ledSegment[] = {
2,3,4,5,6,7,8,9};     

// Analog pin that TMP36 is connect to
int tempMonitor =0;     

// encode the on/off state of the LED segments for the characters
// '0' to '9' and 'DP' into the bits of the bytes
const byte numDef[11] = {
63, 6, 91, 79, 102, 109, 124, 7, 127, 103,128 };     

void setup()
{
Serial.begin (9600);     

// Sets the pinMode for all LEDs
for (int x = 0; x<=7; x++)
{
pinMode (ledSegment[x],OUTPUT);
}     

// enable on by one each LED to test them.
for (int x =0;x<=7;x++){
digitalWrite (ledSegment[x],HIGH);
delay (50);     

}
// disable one by one to finish test of each LED
for (int x =0;x30 ){
setSegments( numDef[3] );
}
// check Temperature is over 20 and below 30
else if (temperature >=20 && temperature =10 && temperature =10){
temperature=temperature -10;
}     

// Print temperature to serial for use in processing
Serial.println(temperature);     

// Delay to display the 10's digit of the temperature
delay (1000);     

// now display unit of the temperature
for (int x = 0;x<=9;x++){
if (int(temperature) == x){
setSegments( numDef[x] );
}
}
// Delay to display the unit digit of the temperature
delay (1000);     

// Now display the decimal point (DP)
setSegments( numDef[10] );     

// delay to show DP
delay (2000);     

}     

void setSegments(byte segments)
{
// for each of the segments of the LED
for (int s = 0; s < 8; s++)
{
int bitVal = bitRead( segments, s ); // grab the bit
digitalWrite(s+2, bitVal); // set the segment
}
}     

float getVoltage(int pin){
return (analogRead(pin) * .004882814); //converting from a 0 to 1024 digital range
// to 0 to 5 volts (each 1 reading equals ~ 5 millivolts
}     


todos's : make code work easily with temperature greater than 30
Next project add two 7 segment LEDs and add shift registers

Thursday 11 February 2010

Arduino in a box



Arduino in a box

Originally uploaded by Christhawkins


Well I mean on a breadboard at the moment but it will be in a box running the Scalextric Lap Counter code.

For prototyping/testing I have used 5v LED's but will us 2.5v LED's in the working model. I have also used a 24mhz Crystal because I haven't got to Maplins yet, so timing is out but works fine for this test.

Next I need to add reset switch..

Sunday 7 February 2010

Scalextric Lap Counter Schematic for Arduino



Scalextric Lap Counter Schematic for Arduino

Originally uploaded by Christhawkins


Here is my Schematic for a Scalextric Lap counter that uses and Arduino and Processing, the Arduino controls the sensors, LED's and buttons and it then relays the information via Serial to the Processing program. I have illustrated on the diagram a optocoulper but I had actual used a slotted Optical Switch (HA221).

Flickr

This is a test post from flickr, a fancy photo sharing thing.

Saturday 30 January 2010

Atmega328 c/w Arduino bootloader on breadboard

Here is my start of making an atmega328 with arduino bootloader to work standalone either on a breadboard or in a IC socket on a veroboard, I have stuck a pinout label so it should help.