EcoBx Source Code
*
ECO-BX Version 1.0.1
First Deployment-May 25, 2011 @ BSTN
Coded by William McKessy
Developed by William Justice
*/
#include <SdFat.h>
#include <Wire.h>
#include “RTClib.h”
//The I2C address of the pressure sensor
#define I2C_ADDRESS 0x77
// A simple data logger for theArduino analog pins
#define LOG_INTERVAL 2000 // mills between entries
#define WAIT_TO_START 0 // Wait for serial input in setup()
// the digital pins that connect to the LEDs
//#define redLEDpin 2
#define number_of_sound_readings 10
// The analog pins that connect to the sensors
#define photocellPin 0 // analog 0
#define humiPin 1 // analog 1
#define soundPin 2 // analog 2
#define tempPin 3 // analog 3
#define BANDGAPREF 14 // special indicator that we want to measure the bandgap
#define aref_voltage 3.3 // we tie 3.3V to ARef and measure it with a multimeter!
#define bandgap_voltage 1.1 // this is not super guaranteed but its not -too- off
// constants won’t change. They’re used here to
// set pin numbers:
//#define buttonPin 4 // the number of the pushbutton pin
#define piezpin 5 // The pin the buzzer is tied too
// Buzzer Properties
#define chrpFqz 20
#define chrpDly 500
#define chrpQnt 4
#define chrpDlyb 200
const unsigned char oversampling_setting = 3; //oversamplig for measurement
const unsigned char pressure_waittime[4] = { 5, 8, 14, 26 };
//just taken from the BMP085 datasheet
int ac1;
int ac2;
int ac3;
unsigned int ac4;
unsigned int ac5;
unsigned int ac6;
int b1;
int b2;
int mb;
int mc;
int md;
// Controls
int tick=0;
// sound array
float sound_buffer[number_of_sound_readings];
RTC_DS1307 RTC; // define the Real Time Clock object
DateTime now;
// The objects to talk to the SD card
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
void error(char *str)
{
Serial.print(“error: “);
Serial.println(str);
while(1) {
tick=0;
while(tick<chrpQnt) {
digitalWrite(piezpin, LOW);
delay(chrpFqz);
digitalWrite(piezpin, HIGH);
delay(chrpDlyb);
tick++;
}
delay(chrpDly);
}
}
void sd_card_file_init()
{
// initialize the SD card
if (!card.init()) error(“card.init”);
// initialize a FAT volume
if (!volume.init(card)) error(“volume.init”);
// open root directory
if (!root.openRoot(volume)) error(“openRoot”);
// create a new file “v”+version number+screenstyle+ “m” +”U” unit number+ xx + .CSV
char name[] = “LOGC3000.CSV”;
for (uint16_t i = 0; i < 1000; i++) {
name[5] = i/1000 + ‘0’;
name[6] = i/100 + ‘0’;
name[7] = i%10 + ‘0’;
if (file.open(root, name, O_CREAT | O_EXCL | O_WRITE)) break;
}
if (!file.isOpen()) error (“file.create”);
// write header
// write header
file.writeError = 0;
now = RTC.now();
// set creation date time
if (!file.timestamp(T_CREATE,now.year(),now.month(),now.day(),now.hour(),
now.minute(),now.second() )) {
error(“create time”);
}
// set write/modification date time
if (!file.timestamp(T_WRITE,now.year(),now.month(),now.day(),now.hour(),
now.minute(),now.second() )) {
error(“write time”);
}
// set access date
if (!file.timestamp(T_ACCESS,now.year(),now.month(),now.day(),now.hour(),
now.minute(),now.second() )) {
error(“access time”);
}
file.println(“milliseconds,unix.time,year,month,day,h,m,s,"yyyy.mm.dd",hh.mm.ss,hhmmss,hhmm,mmss,light,sound,humidity,pres,temp.analog,temp.digital,vcc”);
// attempt to write out the header to the file
if (file.writeError || !file.sync()) {
error(“write header”);
}
}
void start_rtc()
{
if (!RTC.begin()) {
file.println(“RTC failed”);
Serial.print(“RTC failed”);
#if ECHO_TO_SERIAL
Serial.println(“RTC failed”);
#endif //ECHO_TO_SERIAL
}
}
void setup()
{
// serial init
Serial.begin(9600);
Wire.begin();
// Initialize Screen
backlightOn();
selectLineOne();
// initialize the error buzzer’s pin as an OUTPUT on pin 5;
pinMode(piezpin, OUTPUT);
sd_card_file_init();
delay(10);
start_rtc();
// arduino stuff
// pinMode(redLEDpin, OUTPUT);
// If you want to set the aref to something other than 5v
analogReference(EXTERNAL);
bmp085_get_cal_data();
goTo(0);
}
void bmp085_read_temperature_and_pressure(int& temperature, long& pressure);
void loop(void)
{
// delay for the amount of time we want between readings
// digitalWrite(redLEDpin, LOW);
// clear print error
file.writeError = 0;
// initial delay
delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
// time stamp MS
uint32_t m = millis();
int snd_delay = 5;
for (int i = 0; i< number_of_sound_readings; i++){
sound_buffer[i] = analogRead(soundPin);
delay(snd_delay);
}
float photocellReading = analogRead(photocellPin);
delay(10);
float humiReading = analogRead(humiPin);
delay(10);
float tempReading = analogRead(tempPin);
delay(10);
float refReading = analogRead(BANDGAPREF);
delay(10);
// BAROMETRIC PRESSURE STUFF
int temperature_baro = 0;
long pressure = 0;
bmp085_read_temperature_and_pressure(&temperature_baro,&pressure);
// AVERAGE PORTION
temperature_baro = ((temperature_baro/10) * 9 / 5) + 32;
// Log the estimated ‘VCC’ voltage by measuring the internal 1.1v ref
float supplyvoltage = (bandgap_voltage * 1024) / refReading;
// converting that reading to voltage, for 3.3v arduino use 3.3, for 5.0, use 5.0
photocellReading = ((photocellReading * aref_voltage) / 1024.0)*1000;
// sound average
float sound_total = 0;
for (int i = 0; i<number_of_sound_readings; i++){
sound_total += sound_buffer[i];
}
sound_total = sound_total / number_of_sound_readings;
// float hmp = 20 * log (sound_total);
sound_total = ((sound_total* aref_voltage)/1024.0);
float hmp = 200 * log (sound_total);
humiReading = humiReading * aref_voltage / 1024.0;
// converting that reading to voltage, for 3.3v arduino use 3.3, for 5.0, use 5.0
float voltage = tempReading * aref_voltage / 1024.0;
float temperatureC = (voltage - 0.5) * 100 ;
float temperatureF = (temperatureC * 9 / 5) + 32;
humiReading = (humiReading - 0.958)/0.0307;
//
// FILE I/O
//
// fetch the time
now = RTC.now();
//millis
file.print(m); // milliseconds since start
file.print(“, “);
//unix.time
file.print(now.unixtime()); // seconds since 1/1/1970
file.print(“, “);
//y
file.print(now.year(), DEC);
file.print(“, “);
//m
if (now.month() <= 9) file.print(‘0’);
file.print(now.month(), DEC);
file.print(“, “);
//d
if (now.day() <= 9) file.print(‘0’);
file.print(now.day(), DEC);
file.print(“, “);
//h
if (now.hour() <= 9) file.print(‘0’);
file.print(now.hour(), DEC);
file.print(“, “);
//m
if (now.minute() <= 9) file.print(‘0’);
file.print(now.minute(), DEC);
file.print(“, “);
//s
if (now.second() <= 9) file.print(‘0’);
file.print(now.second(), DEC);
file.print(“, “);
//”yyyy/mm/dd”
file.print(‘”’);
file.print(now.year(), DEC);
file.print(“/”);
if (now.month() <= 9) file.print(‘0’);
file.print(now.month(), DEC);
file.print(“/”);
if (now.day() <= 9) file.print(‘0’);
file.print(now.day(), DEC);
file.print(‘”’);
file.print(“, “);
//”hh:mm:ss”
file.print(‘”’);
if (now.hour() <= 9) file.print(‘0’);
file.print(now.hour(), DEC);
file.print(“:”);
if (now.minute() <= 9) file.print(‘0’);
file.print(now.minute(), DEC);
file.print(“:”);
if (now.second() <= 9) file.print(‘0’);
file.print(now.second(), DEC);
file.print(‘”’);
file.print(“, “);
//hhmmss
if (now.hour() <= 9) file.print(‘0’);
file.print(now.hour(), DEC);
if (now.minute() <= 9) file.print(‘0’);
file.print(now.minute(), DEC);
if (now.second() <= 9) file.print(‘0’);
file.print(now.second(), DEC);
file.print(“, “);
//hhmm
if (now.hour() <= 9) file.print(‘0’);
file.print(now.hour(), DEC);
if (now.minute() <= 9) file.print(‘0’);
file.print(now.minute(), DEC);
file.print(“, “);
//mmss
if (now.minute() <= 9) file.print(‘0’);
file.print(now.minute(), DEC);
if (now.second() <= 9) file.print(‘0’);
file.print(now.second(), DEC);
file.print(“, “);
/*
char ascii[32];
int valueToStuff = 2;
sprintf( ascii, “%0.2d”, valueToStuff)
*/
/// VARIABLES
//light
file.print(photocellReading);
file.print(“, “);
//sound
file.print(hmp);
file.print(“, “);
//humidity
file.print(humiReading);
file.print(“, “);
//bar
file.print(pressure);
file.print(“, “);
//analog.tempF
file.print(temperatureF);
file.print(“, “);
//digital.temp
file.print(temperature_baro);
file.print(“, “);
//vcc
file.print(supplyvoltage);
file.println();
if (file.writeError) error(“write data”);
if (!file.sync()) error(“sync”);
// LCD OUT STUFF
//clearLCD();
//selectLineOne();
// Serial.print(” ”);
Serial.print(now.hour(), DEC);
Serial.print(“:”);
Serial.print(now.minute(), DEC);
Serial.print(“:”);
Serial.print(now.second(), DEC);
//selectLineTwo();
// Serial.print(“BP=”);
// Serial.print(pressure);
// Serial.print(“Pa”);
// digitalWrite(redLEDpin, LOW);
} // X MARKS THE SPOT, END OF LOOP()
/////////// BARO METRIC PRESSURE FUNCTIONS
void bmp085_read_temperature_and_pressure(int* temperature, long* pressure) {
long ut= bmp085_read_ut();
long up = bmp085_read_up();
long x1, x2, x3, b3, b5, b6, p;
unsigned long b4, b7;
//calculate the temperature
x1 = ((long)ut - ac6) * ac5 » 15;
x2 = ((long) mc « 11) / (x1 + md);
b5 = x1 + x2;
*temperature = (b5 + 8) » 4;
//calculate the pressure
b6 = b5 - 4000;
x1 = (b2 * (b6 * b6 » 12)) » 11;
x2 = ac2 * b6 » 11;
x3 = x1 + x2;
//b3 = (((int32_t) ac1 * 4 + x3)<> 2;
if (oversampling_setting == 3) b3 = ((int32_t) ac1 * 4 + x3 + 2) « 1;
if (oversampling_setting == 2) b3 = ((int32_t) ac1 * 4 + x3 + 2);
if (oversampling_setting == 1) b3 = ((int32_t) ac1 * 4 + x3 + 2) » 1;
if (oversampling_setting == 0) b3 = ((int32_t) ac1 * 4 + x3 + 2) » 2;
x1 = ac3 * b6 » 13;
x2 = (b1 * (b6 * b6 » 12)) » 16;
x3 = ((x1 + x2) + 2) » 2;
b4 = (ac4 * (uint32_t) (x3 + 32768)) » 15;
b7 = ((uint32_t) up - b3) * (50000 » oversampling_setting);
p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
x1 = (p » 8) * (p » 8);
x1 = (x1 * 3038) » 16;
x2 = (-7357 * p) » 16;
*pressure = p + ((x1 + x2 + 3791) » 4);
}
unsigned int bmp085_read_ut() {
write_register(0xf4,0x2e);
delay(5); //longer than 4.5 ms
return read_int_register(0xf6);
}
void bmp085_get_cal_data() {
Serial.println(“Reading Calibration Data”);
ac1 = read_int_register(0xAA);
Serial.print(“AC1: “);
Serial.println(ac1,DEC);
ac2 = read_int_register(0xAC);
Serial.print(“AC2: “);
Serial.println(ac2,DEC);
ac3 = read_int_register(0xAE);
Serial.print(“AC3: “);
Serial.println(ac3,DEC);
ac4 = read_int_register(0xB0);
Serial.print(“AC4: “);
Serial.println(ac4,DEC);
ac5 = read_int_register(0xB2);
Serial.print(“AC5: “);
Serial.println(ac5,DEC);
ac6 = read_int_register(0xB4);
Serial.print(“AC6: “);
Serial.println(ac6,DEC);
b1 = read_int_register(0xB6);
Serial.print(“B1: “);
Serial.println(b1,DEC);
b2 = read_int_register(0xB8);
Serial.print(“B2: “);
Serial.println(b1,DEC);
mb = read_int_register(0xBA);
Serial.print(“MB: “);
Serial.println(mb,DEC);
mc = read_int_register(0xBC);
Serial.print(“MC: “);
Serial.println(mc,DEC);
md = read_int_register(0xBE);
Serial.print(“MD: “);
Serial.println(md,DEC);
}
long bmp085_read_up() {
write_register(0xf4,0x34+(oversampling_setting«6));
delay(pressure_waittime[oversampling_setting]);
unsigned char msb, lsb, xlsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(0xf6); // register to read
Wire.endTransmission();
Wire.requestFrom(I2C_ADDRESS, 3); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.receive();
while(!Wire.available()) {
// waiting
}
lsb |= Wire.receive();
while(!Wire.available()) {
// waiting
}
xlsb |= Wire.receive();
return (((long)msb«16) | ((long)lsb«8) | ((long)xlsb)) »(8-oversampling_setting);
}
void write_register(unsigned char r, unsigned char v)
{
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(r);
Wire.send(v);
Wire.endTransmission();
}
char read_register(unsigned char r)
{
unsigned char v;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(r); // register to read
Wire.endTransmission();
Wire.requestFrom(I2C_ADDRESS, 1); // read a byte
while(!Wire.available()) {
// waiting
}
v = Wire.receive();
return v;
}
int read_int_register(unsigned char r)
{
unsigned char msb, lsb;
Wire.beginTransmission(I2C_ADDRESS);
Wire.send(r); // register to read
Wire.endTransmission();
Wire.requestFrom(I2C_ADDRESS, 2); // read a byte
while(!Wire.available()) {
// waiting
}
msb = Wire.receive();
while(!Wire.available()) {
// waiting
}
lsb = Wire.receive();
return (((int)msb«8) | ((int)lsb));
}
// screen stuff
void selectLineOne(){ //puts the cursor at line 0 char 0.
Serial.print(0xFE, BYTE); //command flag
Serial.print(128, BYTE); //position
}
void selectLineTwo(){ //puts the cursor at line 0 char 0.
Serial.print(0xFE, BYTE); //command flag
Serial.print(192, BYTE); //position
}
void goTo(int position) { //position = line 1: 0-15, line 2: 16-31, 31+ defaults back to 0
if (position<16){ Serial.print(0xFE, BYTE); //command flag
Serial.print((position+128), BYTE); //position
}else if (position<32){Serial.print(0xFE, BYTE); //command flag
Serial.print((position+48+128), BYTE); //position
} else { goTo(0); }
}
void clearLCD(){
Serial.print(0xFE, BYTE); //command flag
Serial.print(0x01, BYTE); //clear command.
}
void backlightOn(){ //turns on the backlight
Serial.print(0x7C, BYTE); //command flag for backlight stuff
Serial.print(157, BYTE); //light level.
}
void backlightOff(){ //turns off the backlight
Serial.print(0x7C, BYTE); //command flag for backlight stuff
Serial.print(128, BYTE); //light level for off.
}
void serCommand(){ //a general function to call the command flag for issuing all other commands
Serial.print(0xFE, BYTE);
}

