1
\$\begingroup\$

I have uploaded the DS18x20 Temperature example sketch (unaltered, except I tried multiple pins for the I2C communication) to my proven Duemilanove and my mighty 1284p.

On the Duemilanove my two DS18B20 temperature sensors are found and read correctly:

ROM = 28 36 6D 51 4 0 0 75
  Chip = DS18B20
  Data = 1 D6 1 4B 46 7F FF A 10 43  CRC=43
  Temperature = 29.37 Celsius, 84.87 Fahrenheit
ROM = 28 19 6 51 4 0 0 86
  Chip = DS18B20
  Data = 1 A7 1 4B 46 7F FF 9 10 E0  CRC=E0
  Temperature = 26.44 Celsius, 79.59 Fahrenheit
No more addresses.
(...)

Whereas the 1284p only says

No more addresses.

No more addresses.

(...)

I have not changed the wiring of the sensors; they are connected +5/GND, Data is pulled to +5V with a 2k7 and also to the reading pin, respectively. I have tested multiple pins for I2C communication - they all work on the Duemilanove, none work on the 1284p.

I am assuming some issues with I2C with mighty 1284p, but maybe someone else has another idea.

Here's the code (the unchanged example sketch, I have been taught to "include the used code, always!", so here it is):

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library

OneWire  ds(0);  // on pin 10

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

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;

  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }

  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();

  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1);         // start conversion, with parasite power on at the end

  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present,HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // convert the data to actual temperature

  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // count remain gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    if (cfg == 0x00) raw = raw << 3;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
    // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

Thank you.

\$\endgroup\$
3
  • \$\begingroup\$ Can you test for activity on the pin that you are using, eg. using a oscilloscope? You should see activity on the pin when it tries to find devices. Don't use pins d0 and d1, they are slightly different wired on the Arduino, which may cause problems in some circumstances. On a side note: OneWire is not I²C. \$\endgroup\$
    – jippie
    May 20, 2013 at 8:40
  • \$\begingroup\$ Sadly I don't have an oscilloscope. I'll try to hook up my buspirate and see if I can snoop any OneWire data - thanks for the tip! \$\endgroup\$
    – Christian
    May 20, 2013 at 10:31
  • \$\begingroup\$ OLS (using the BusPirate) seems to be unable to either show the logic levels changing with the (OneWire working) Arduino nor with my 1284p (OneWire still not working). The BusPirate itself can read and access the OneWire devices just fine. \$\endgroup\$
    – Christian
    May 20, 2013 at 20:40

1 Answer 1

2
\$\begingroup\$

Turns out I had the ATMega1284p running at "just" 1 MHz. Fusing it to run at 8 MHz made everything work just fine. Stable connection, reliable recognition of sensors, no data dropouts as far as I can see.

I'll try to get in contact with the mighty1284p and Arduino OneWire Library folks to discuss this, I guess their code either hardcodedly assumes the device to be running at 8 MHz or having it run at 1 MHz makes the communication unreliable.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.