instability with Adafruit Data-logger with 4 / ds18B20

Hi I have an Adafriut data logger shield on top an UNO and firstly had 2 sensors one for air on for pond temp. It logs every 5 minutes. After a month the Vcc started to go wild swinging from 1 up to 13 so I changed the Wallwart 9v power to a uniden 9v from my telephone, it settled. Now I have added 2 more ds18B20 sensors all on the same digi pin 5 it loggs but misses some fields so I added delays between the PrintTemperature ( AirThermometer) , PrintTemperature ( MichaelThermometer)etc. It still leaves random fields blank. Also returns 85 as a value every now and then. Any Ideas would be great. The project is to monitor Koura(freshwater crayfish) ponds I have 5 and are identified J1,J2 Michael ,Tito, Marlon, so I know which is which. Eventually I would like to monitor Disolved Oxygen but Optic sensors are US$ 2000.00 each sensor, so temp will have to do for now.millis stamp datetime Air temp Michael temp Tito temp Marlon temp vcc 1199998 1342022332 "2012/7/11 15:58" 11 4.75 4.25 1500000 1342022632 "2012/7/11 16:3" 10.75 4.75 4 4.17 1799999 1342022931 "2012/7/11 16:8" 85 4.75 4.14 2099998 1342023231 "2012/7/11 16:13" 11 5 4.75 4 4.14 [/table]

Sorry the table didn't copy very well but you can see the gaps and 85's

Here is the code

// libraries
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
#include <OneWire.h>
#include <DallasTemperature.h>

// DS18B20 sensors on I/O pin 5

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

// Assign the addresses of your 1-Wire temp sensors.
DeviceAddress AirThermometer = { 0x28, 0x2C, 0x41, 0x3A, 0x03, 0x00, 0x00, 0x46 };
DeviceAddress MichaelThermometer = { 0x28, 0xAD, 0x7F, 0x3A, 0x03, 0x00, 0x00, 0xBD };
DeviceAddress TitoThermometer = {0x28, 0x29, 0x7C, 0x3A, 0x03, 0x00, 0x00, 0xC5  };
DeviceAddress MarlonThermometer = { 0x28, 0x1C, 0x32, 0x3A, 0x03, 0x00, 0x00, 0x88 };


// definitions
#define LOG_INTERVAL 300000 // mills between entries (reduce to take more/faster data) 5 minutes
#define SYNC_INTERVAL 300000 // mills between calls to flush() - to write data to the card
#define ECHO_TO_SERIAL 1 // echo data to serial port-- 1 to see 0 when in service
#define redLEDpin 2
#define greenLEDpin 3
//#define tempPin A1 // analog 1
#define BANDGAPREF 14 // special indicator that we want to measure the bandgap
#define bandgap_voltage 1.1 // this is not super guaranteed but its not -too- off

// other stuff??
RTC_DS1307 RTC; // define the Real Time Clock object
uint32_t syncTime = 0; // time of last sync()
const int chipSelect = 10;// for the data logging shield, we use digital pin 10 for the SD cs line
File logfile; // the logging file

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  digitalWrite(redLEDpin, HIGH); // red LED indicates error
  while(1);// lock up if error
}

void setup(void)
{
  Serial.begin(9600);
// Start up the library
  sensors.begin();
  // set the resolution to 10 bit (good enough?)
  sensors.setResolution(AirThermometer, 10);
  sensors.setResolution(MichaelThermometer, 10);
  sensors.setResolution(TitoThermometer, 10);
  sensors.setResolution(MarlonThermometer, 10);

  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
  digitalWrite(greenLEDpin, HIGH);

  // initialize the SD card
  Serial.print("Initializing SD card...");
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    error("Card failed, or not present");
  }
  Serial.println("card initialized.");

  // create a new file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {  
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE);
      break; // leave the loop!
    }
  }

  if (! logfile) {
    error("couldnt create file");
  }

  Serial.print("Logging to: ");
  Serial.println(filename);

  // connect to RTC
  Wire.begin();
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif //ECHO_TO_SERIAL
  }
  logfile.println("millis,stamp,datetime,Pond temp,Air temp,vcc");
#if ECHO_TO_SERIAL
  Serial.println("millis,stamp,datetime,Pond temp,Air temp,vcc");
#endif //ECHO_TO_SERIAL

 float voltage = 0; // setup some variables float for 2 decimal places
 float sensor = 0;
 float TempC = 0;
}
    void printTemperature(DeviceAddress deviceAddress)
 {
        float tempC = sensors.getTempC(deviceAddress);
        if (tempC == -127.00) {
        Serial.print("Error getting temperature");
        } else {
                 logfile.print(tempC,2);
                 logfile.print(',');
                #if ECHO_TO_SERIAL
                 Serial.print(tempC,2);
                 Serial.print(',');}
              #endif
               

 }

void loop(void)
{
  DateTime now;

    // delay for the amount of time we want between readings
    delay((LOG_INTERVAL -1) - (millis() % LOG_INTERVAL));
    digitalWrite(greenLEDpin, HIGH); // have green light on just to see its working ok to here.

    uint32_t m = millis(); // log milliseconds since starting
    logfile.print(m); // milliseconds since start
    logfile.print(", ");
   #if ECHO_TO_SERIAL
    Serial.print(m); // milliseconds since start
    Serial.print(", ");
   #endif

   // fetch the time
    now = RTC.now();
   // log time
    logfile.print(now.unixtime()); // seconds since 1/1/1970
    logfile.print(", ");
    logfile.print('"');
    logfile.print(now.year(), DEC);
    logfile.print("/");
    logfile.print(now.month(), DEC);
    logfile.print("/");
    logfile.print(now.day(), DEC);
    logfile.print(" ");
    logfile.print(now.hour(), DEC);
    logfile.print(":");
    logfile.print(now.minute(), DEC);
    logfile.print('"');
    logfile.print(',');
  #if ECHO_TO_SERIAL
    Serial.print(now.unixtime()); // seconds since 1/1/1970
    Serial.print(", ");
    Serial.print('"');
    Serial.print(now.year(), DEC);
    Serial.print("/");
    Serial.print(now.month(), DEC);
    Serial.print("/");
    Serial.print(now.day(), DEC);
    Serial.print(" ");
    Serial.print(now.hour(), DEC);
    Serial.print(":");
    Serial.print(now.minute(), DEC);
    Serial.print('"');
    Serial.print(',');
  #endif //ECHO_TO_SERIAL
 
      { 
      delay(2000);
      sensors.requestTemperatures();
       printTemperature(AirThermometer); 
      delay(200); 
       printTemperature(MichaelThermometer);
      delay(200);
       printTemperature(TitoThermometer);
      delay(200);
       printTemperature(MarlonThermometer);
    
        }

  // Log the estimated 'VCC' voltage by measuring the internal 1.1v ref
  analogRead(BANDGAPREF);
  delay(10);
  int refReading = analogRead(BANDGAPREF);
  float supplyvoltage = (bandgap_voltage * 1024) / refReading;

  logfile.print(supplyvoltage);
#if ECHO_TO_SERIAL
  Serial.print(supplyvoltage);
#endif 

  logfile.println();
#if ECHO_TO_SERIAL
  Serial.println();
#endif // ECHO_TO_SERIAL

  digitalWrite(greenLEDpin, LOW);

  // Now we write data to disk! Don't sync too often - requires 2048 bytes of I/O to SD card
  // which uses a bunch of power and takes time
  if ((millis() - syncTime) < SYNC_INTERVAL) return;
  syncTime = millis();

  // blink LED to show we are syncing data to the card & updating FAT!
  digitalWrite(redLEDpin, HIGH);
  logfile.flush();
  digitalWrite(redLEDpin, LOW);

}

I think that protocol is prone to occasional failure. I would probably test for improbable temperatures and just discard them. Presumably the water is not colder than 0, nor hotter than about 25.

And after that, take an average of the last 10 readings.

Thanks Nick, So the test for probable would be adding to the conditions in this section

  float tempC = sensors.getTempC(deviceAddress);
        if (tempC == -127.00) {
        Serial.print("Error getting temperature");

And you are saying that the loss of returned temperature is just part of using this particular protocol, which is fine I can live with losing 10 or 15mins of data the ponds are 1000 sq m they take a little time to heat and cool.

I should ask while I'm here has anyone any thoughts on sensing disolved oxygen.

Thank you Nick.

Yes, something like:

float tempC = sensors.getTempC(deviceAddress);
        if (tempC < 0.0 || tempC > 30.0) {
        Serial.print("Error getting temperature");

I had some of those sensors here, in the roof and in the room, and they periodically returned nonsense. I just filtered those readings out.

I think there is a CRC check on the data it gets back from the sensor, not sure if the code checks it or not.