ok here you go (error being only time lcd not display on line 1 is when sdcard not inserted)
sdcard from here SD/MMC Mini Board datasheet attached
arduino brd atmega 238 ett card pins sd desc
10 16 ss 1 cd/dat3
11 17 mosi 2 cmd
12 18 miso 7 dat0
13 19 sck 5 clk
3.3vdc vcc 3.3v 4 vcc 3.3v
gnd 22 & 8 gnd 3 & 6 gnd
lcd(4, 5, 6, 7, 8, 9); // changed these pin to suit SD card
//
// water_meter_v1.3
// 17-12-2011
//
// changed LCD pin to allow for SD card use and changed toggle sw pins
// added RTC to serial monitor
// added sd logging date/time/house/block/tank
// added **** CHANGEOVER ****
//
int calpulse = 240; // pulses calibration is 240 .....24 for testing
int pulsePin = 2; // water meter pulse pin 2
unsigned long highCounter = 0;
unsigned long duration = 0;
int pulse = 0;
int lastPulse = LOW;
unsigned long timeNow = 0;
unsigned long lastTime = 0;
int pulscount = 0;
unsigned long litre = 0;
unsigned long klitre = 25000; // 25 for testing normal 25k-30k
int pulcunt = 0;
const int meterhouse = 14;// the number of toggle pin14 is analogue 0
const int meterblock = 3;// the number of toggle pin
// ************************
unsigned long housecount = 536464;
unsigned long blockcount = 675797;
unsigned long tankcount = 0;
// variables will change:
int houseState = 0; // variable for reading the toggle status
int blockState = 0;
int tankState = 0;
// ***********************************
// Global Variables
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
// ***********************
#include <SD.h>
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address
File myFile;
#include <LiquidCrystal.h>
LiquidCrystal lcd(4, 5, 6, 7, 8, 9); // changed these pin to suit SD card
void setup() {
pinMode(pulsePin, INPUT);
// enable the 20K pull-up resistor to
// steer the input pin to a HIGH reading.
digitalWrite(pulsePin, HIGH);
// *******************
// initialize the toggle pin as an input:
pinMode(meterhouse, INPUT);
// initialize the toggle pin as an input:
pinMode(meterblock, INPUT);
// ********************
Wire.begin();
Serial.begin(9600);
Serial.println("Water Meter - Version 1.3");
Serial.println("Initializing SD card...");
pinMode(10, OUTPUT);
if (!SD.begin(10)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// *****************************************************************
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.print("Water Meter ");
lcd.setCursor(0, 1);
lcd.print("ver 1.3");
}
void loop() {
// get data and print it to serial monitor
getDateDs1307();
pulse = digitalRead(pulsePin);
if (pulse != lastPulse) { // pulse has changed
timeNow = millis();
duration = timeNow - lastTime;
pulscount = pulse + pulscount;
pulcunt = pulscount;
if ( pulcunt>=calpulse ) {//litre = litre++; //every 240 pulses is 1 litre increment count
pulscount = 0; // reset counter
}
//*****************************************
//Serial.print(pulscount); //uncomment for calibration of calpulse
//Serial.print(", "); // ditto
//Serial.println(litre); // ditto
//*****************************************
// read the state of the toggle switch value:
houseState = digitalRead(meterhouse);
blockState = digitalRead(meterblock);
// check if the toggle switch is changed
// if it is, the buttonState is HIGH:
if (houseState == HIGH) {
Serial.println("House ON, ");
if (pulcunt>=calpulse) { housecount = housecount++;
Serial.print(housecount); // did have ln
printdatetime(); // ##################################
logtosdcard();
lcd.clear();
lcd.print("House Use(L)");
lcd.setCursor(0, 1);
lcd.print(housecount);
changeover();
}
}
// ******************************************
if (blockState == HIGH) {
Serial.println("Block ON, ");
if (pulcunt>=calpulse) { blockcount = blockcount++;
Serial.print(blockcount);
printdatetime();
logtosdcard();
lcd.clear();
lcd.print("Block Use(L)");
lcd.setCursor(0, 1);
lcd.print(blockcount);
changeover();
}
}
//********************************************
if (houseState == LOW && blockState == LOW) {
Serial.println("Tank ON, ");
if (pulcunt>=calpulse) {tankcount = tankcount++;
Serial.print(tankcount);
printdatetime();
logtosdcard();
lcd.clear();
lcd.print("Tank Use(L)");
lcd.setCursor(0, 1);
lcd.print(tankcount);
//changeover(); // not needed here
}
}
lastPulse = pulse;
lastTime = timeNow;
if (pulse == HIGH) highCounter++;
}
}
// ds1307 stuff
// Gets the date and time from the ds1307 and prints result
void getDateDs1307()
{
// Reset the register pointer
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.send(0x00);
Wire.endTransmission();
Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
// A few of these need masks because certain bits are control bits
second = bcdToDec(Wire.receive() & 0x7f);
minute = bcdToDec(Wire.receive());
hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm
dayOfWeek = bcdToDec(Wire.receive());
dayOfMonth = bcdToDec(Wire.receive());
month = bcdToDec(Wire.receive());
year = bcdToDec(Wire.receive());
}
void printdatetime()
{
// display time date to serial monitor
Serial.print(" ");
Serial.print(hour, DEC);
Serial.print(":");
{
if (minute<10) {
Serial.print("0"); // add a leading zero if minute <10
}
}
Serial.print(minute, DEC);
Serial.print(":");
{
if (second<10) {
Serial.print("0"); // add a leading zero if second <10
}
}
Serial.print(second, DEC);
Serial.print(" ");
Serial.print(dayOfMonth, DEC);
Serial.print("/");
Serial.print(month, DEC);
Serial.print("/20");
Serial.println(year, DEC);
}
void logtosdcard()
{
myFile = SD.open("h2olog.csv", FILE_WRITE);
if (myFile) {
myFile.print(dayOfMonth, DEC);
myFile.print("/");
myFile.print(month, DEC);
myFile.print("/20");
myFile.print(year, DEC);
myFile.print(",");
if (hour<10) {
myFile.print("0"); // add a leading zero if hour <10
}
myFile.print(hour, DEC);
myFile.print(":");
if (minute<10) {
myFile.print("0"); // add a leading zero if minute <10
}
myFile.print(minute, DEC);
myFile.print(":");
if (second<10) {
myFile.print("0"); // add a leading zero if second <10
}
myFile.print(second,DEC);
myFile.print(",");
myFile.print(housecount);
myFile.print(",");
myFile.print(blockcount);
myFile.print(",");
myFile.println(tankcount);
// close the file:
myFile.close();
} else {
// if the file didn't open, print an error:
Serial.println("error opening h2olog.csv");
}
}
void changeover()
{
litre = litre++;
if (litre >= klitre) {
Serial.println("*** CHANGEOVER ***");
lcd.setCursor(9, 1);
lcd.print("CHANGE ");
litre = 0;
}
}
MINISC.pdf (126 KB)
water_meter_v1_3.pde (7.1 KB)