One wire DS18B20 reading +85°C, then -127°C and Arduino hanging up completely

Hello guys!

I hope, you can help also me! I have done my first Arduino project with a Arduino Nano also reading one-wire temperature sensors of type DS18B20 from the supplier "Adafruit".
Most of the time, always one out of 7 sensors is reading constantly +85°C, sometimes, all or some are reading "-127°C" especially when the ambient temperature where the complete electronics is gets colder now in autumn here (e.g. +3°C). Sometimes, after some days (e.g. 2, 3, 4), my complete program is hanging up, some other days it even works some weeks. Of course, I especially already searched for the "+85°C problem" here in the forum and elsewhere and I also could find several ideas and I somehow tried all of them, but in my case, nothing seems to work. So I guess, I have not tried the "correct combination" up to now. I tried a "delay(1000)" after the begin, and also right after the suggested "sensor_bus.requestTemperatures();". But it maybe just gets worse, definitely not better. And it's always only 1 specific sensor out from 7 where I read the temp with the +85°C. With the -127°C, sometimes this comes back from all sensors or just some.
Please be a bit patient with me, I am a beginner here, but I really tried a lot of things and nothing helped. I want to be this thing RELIABLY working all the time!

I would have liked of course to upload my code but it says: "New users are not allowed to upload something." BUT: Without my code provided to you, its absolutely senseless! Ridiculous setting for new users in my opinion. So what to do now? I search for your help but you cannot help me because I am not allowed to upload anything. How the guys who set this rule think now that another forum user can help me if I can't provide the most important thing: My code ??? Such a thing never ever happend to me in all the other forums I ever was and still am!

Regards,
bernd27000

2 Likes

You don't need to "upload" code. Just copy/paste it into your post, surrounded by code tags ("</>" editor button). Please add it to your original post.

A pullup resistor (typically 4.7K) from the data pin to Vcc is absolutely required, but people often forget about it.

IIRC, 85 is what you get from the sensor before you instruct it to read the temperature.

Ok, I thought copying my complete code just into here will not be nice readable, but ok.
I do have a pull-up resistor, but 1k (as I have read somewhere one person almost solved the issues with reducing it from 4k7 to 1k).
Ok, here my code:
I know, normally I only put parts of the code, but for me it does not make sense because its all connected together and I maybe, as a beginner, leave out an essential part of the code, where you say: "Ah, but if you also doing display stuff, that consumes too much time" or similar, so therefore all my code:

/****************** Include Files ******************************************************/
// "" => Looks in the same directory as the 'C' file I compile
// <> => Looks in the library paths

// Arduino
  #include <Arduino.h>
  
// OLED-Display
  #include <U8x8lib.h>

// 1-wire
  #include <OneWire.h>
  #include <DallasTemperature.h>

// MCP3221
  #include "MCP3221.h"


/****************** Constants **********************************************************/
// VCC voltage reference: Used for MCP3221 and internal Arduino ADC
  const float VCC_VREF_V = 5.02;    // Voltage reference ( = VCC) for in units [V]

// 1-wire
  #define ENABLE_SEARCH_ADDRESS           // Use the ENABLE_SEARCH_ADDRESS to gather all the unique addresses of the sensors. Comment it out if you don't want to use it.
  #define ENABLE_READ_BACK_RESOLUTION     // Use the ENABLE_READ_BACK_RESOLUTION to confirm that the right resolution has been set.
  #define ONE_WIRE_BUS 2                  // Data wire is plugged into port 2 on the Arduino;  Make sure a pull-up resistor (e.g. 1k) is connected (so from Data to VCC)
  #define TEMPERATURE_PRECISION 12        // 12 is maximum but slower.
  #define NUM_OW_SENSORS 8                // the number of DS18B20 sensors on the 1-Wire bus.

  // Array to hold device addresses. The address is a group of 8 bytes, and there are 'NUM_OW_SENSORS' of those groups of 8 bytes. The "DeviceAddress" type already defined as a group of 8 bytes.
  /*
  // Sensor data for small cooling box
    const DeviceAddress sensor_address[NUM_OW_SENSORS] =
    {
      { 0x28, 0x41, 0x6B, 0x07, 0xD6, 0x01, 0x3C, 0xAA },   // S01_ColdIntoPWT   = TempSensors_Temps[0]
      { 0x28, 0x4F, 0xEA, 0x07, 0xD6, 0x01, 0x3C, 0xBF },   // S02_ColdFromPWT   = TempSensors_Temps[1]
      { 0x28, 0xCF, 0xC2, 0x07, 0xD6, 0x01, 0x3C, 0x93 },   // S03_HotFromCompr  = TempSensors_Temps[2]
      { 0x28, 0xD4, 0x45, 0x07, 0xD6, 0x01, 0x3C, 0xAA },   // S04_HotFromPWT    = TempSensors_Temps[3]
      { 0x28, 0xC9, 0x05, 0x07, 0xD6, 0x01, 0x3C, 0x52 },   // S05_AmbientOfUnit = TempSensors_Temps[4]
      { 0x28, 0xAA, 0xD5, 0xAC, 0x1D, 0x13, 0x02, 0xE5 },   // S06_InsideFluid   = TempSensors_Temps[5]
      { 0x28, 0xAA, 0xC1, 0xDD, 0x1D, 0x13, 0x02, 0xA1 },   // S07_CoolBoxS01    = TempSensors_Temps[6]
      { 0x28, 0xAA, 0xFA, 0xE0, 0x1D, 0x13, 0x02, 0x80 },   // S08_CoolBoxS02    = TempSensors_Temps[7]
    };
  */

// Sensor data for big cooling box
    const DeviceAddress sensor_address[NUM_OW_SENSORS] =
    {
      { 0x28, 0x41, 0x6B, 0x07, 0xD6, 0x01, 0x3C, 0xAA },   // S01_ColdIntoPWT   = TempSensors_Temps[0]
      { 0x28, 0x4F, 0xEA, 0x07, 0xD6, 0x01, 0x3C, 0xBF },   // S02_ColdFromPWT   = TempSensors_Temps[1]
      { 0x28, 0xCF, 0xC2, 0x07, 0xD6, 0x01, 0x3C, 0x93 },   // S03_HotFromCompr  = TempSensors_Temps[2]
      { 0x28, 0xD4, 0x45, 0x07, 0xD6, 0x01, 0x3C, 0xAA },   // S04_HotFromPWT    = TempSensors_Temps[3]
      { 0x28, 0xC9, 0x05, 0x07, 0xD6, 0x01, 0x3C, 0x52 },   // S05_AmbientOfUnit = TempSensors_Temps[4]
      { 0x28, 0xAA, 0xD5, 0xAC, 0x1D, 0x13, 0x02, 0xE5 },   // S06_InsideFluid   = TempSensors_Temps[5]
      { 0x28, 0xD4, 0xD1, 0xEA, 0x32, 0x14, 0x01, 0xDF },   // S07_CoolBoxS01    = TempSensors_Temps[6]
      { 0x28, 0xAA, 0xC3, 0xDB, 0x1D, 0x13, 0x02, 0x2B },   // S08_CoolBoxS02    = TempSensors_Temps[7]
    };

  // Create labels in PROGMEM, see : https://www.arduino.cc/en/Reference/PROGMEM ; The order of the labels must match the order of the addresses in 'sensor_address[]'.
    const char string0[] PROGMEM = "S01_ColdIntoPWT";
    const char string1[] PROGMEM = "S02_ColdFromPWT";
    const char string2[] PROGMEM = "S03_HotFromCompr";
    const char string3[] PROGMEM = "S04_HotFromPWT";
    const char string4[] PROGMEM = "S05_AmbientOfUnit";
    const char string5[] PROGMEM = "S06_InsideFluid";
    const char string6[] PROGMEM = "S07_CoolBoxS01";
    const char string7[] PROGMEM = "S08_CoolBoxS02";
    
    const char * const string_table[] PROGMEM =
    {
      string0, string1, string2, string3, string4, string5, string6, string7,
    };

// MCP3221
    //  Each MCP3221 has 1 of 8 possible I2C addresses (factory hardwired & recognized by its specific part number & top marking on the package itself):
    //       PART                  DEVICE I2C ADDRESS          PART
    //      NUMBER             (BIN)      (HEX)     (DEC)     MARKING
    //  MCP3221A0T-E/OT       01001000      0x48       72       GE
    //  MCP3221A1T-E/OT       01001001      0x49       73       GH
    //  MCP3221A2T-E/OT       01001010      0x4A       74       GB
    //  MCP3221A3T-E/OT       01001011      0x4B       75       GC
    //  MCP3221A4T-E/OT       01001100      0x4C       76       GD
    //  MCP3221A5T-E/OT       01001101      0x4D       77       GA
    //  MCP3221A6T-E/OT       01001110      0x4E       78       GF
    //  MCP3221A7T-E/OT       01001111      0x4F       79       GG
    
  const byte SLAVE1 = 0x4E;                 // I2C address of the MCP3221 for measuring the compressor current
  const byte SLAVE2 = 0x4F;                 // I2C address of the MCP3221 for measuring the pump current
  const float MPC3221_VREF_V = VCC_VREF_V;  // Voltage reference ( = VCC) for the MCP3221 in units [V]

// ACS723 over MCP3221
  // Sensitivity
    const float SENS_ACS723_05__V_PER_A = 0.4;    // SENSitivity of the "ACS723LLCTR-05AB-T" in units [V/A]
    const float SENS_ACS723_10__V_PER_A = 0.2;    // SENSitivity of the "ACS723LLCTR-10AB-T" in units [V/A]    

// Internal ADC for 12V VBB (VBAT) voltage reading
  const int VBB_MEAS_ANALOG_IN_PIN = A6;          // Pin used for voltage VBB (VBAT) measurement reading through internal Arduino ADC
  const float VBB_MEAS_RES_DIV_GAIN = 4;          // Gain setting of the RESistor DIVider (potentiometer) between the VBB (VBAT) voltage (max. 20V foreseen) to VCC related (approx. 5V nom).

// Alive / Error LED
  const int AliveErrorLED = 4;                    // Pin "D4"

// Switches ( = Pushbuttons)
  #define ERROR_WINDOW_SW 50  // +/- this value
  #define DEBUG_ON
  int AnalogSwPin = 7;   // switch circuit input connected to analog pin 7

// Temperature control
  // Inside cooling box, set the initial value to which the system shall control the temperatures of the water e.g.
    float Temp_CoolBoxS02_Lo = -0.3;
    float Temp_CoolBoxS02_Hi = +0.5;
    bool Change_S01_Lo_or_Hi = false;     // If the switches / keys shall change the "Lo" or the "Hi" value of the "S01" temperature sensor.

// Compressor switch on / off
  #define ComprOnOffPin A3        // An analog hardware is connected to pin A3 which switches the relay off immediately as soon as this pin is going low. If this pin is going high, approx. 7 min has to be waited due to an RC time constant until the relay switches on. 
  bool ComprOnOff = false;        // If the compressor shall be turned on or off

// Miscellaneous
  // TBD.


// ??????????????????????? ****************** WAS IST DAS ?????  **********************************************************`?????????????????????????????/
// 1-wire
  // Orig. from: "https://forum.arduino.cc/index.php?topic=393653.0", and adapted to my sensor addresses etc. :
  //   "Changed the names of variable: sensor_bus is the bus (was called 'sensors').  // sensor_address[] is the array with the deviceaddresses of the sensors.
  //    Note that the index by the DallasTemperature is not our own index. I don't even print that index. The index used in the sketch is our own index, it matches the labels with the addresses.
  
  OneWire oneWire(ONE_WIRE_BUS);                          // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
  DallasTemperature sensor_bus( &oneWire);                // Pass our oneWire reference to Dallas Temperature.


/****************** Constructors ******************************************************/
// OLED-Display
  U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);       // Please update the pin numbers according to your setup. Use U8X8_PIN_NONE if the reset pin is not connected
   

/****************** Enumberations ******************************************************/


/****************** Structures *********************************************************/


/****************** Variables **********************************************************/
// 1-wire
  static int          CurNrOWdevsBus;                                             // Current number of 1-wire devices on the bus
  static float        TempSensors_Temps[NUM_OW_SENSORS];                          // Array which holds the current temperatures of all 1-wire temperature sensors

// Flow-sensor
  volatile  int   flow_frequency;   // Measures flow sensor pulses
            float l_minute = 0.0;   // Calculated litres/hour
  unsigned  char  flowsensor = 3;   // Sensor Input
  unsigned  long  currentTime;
  unsigned  long  cloopTime;

// MCP3221
  //static unsigned int Compr_Cur_DigCode;    // COMPRessor digital code read through MCP3221 ( 0 .. 4095 )
  static float Compr_Cur_DigCode;    // COMPRessor digital code read through MCP3221 ( 0 .. 4095 )
  static float Compr_Cur_A;          // COMPRessor CURrent read through MCP3221 stored in this variable in units "[A]"
  static float Pump_Cur_DigCode;     // PUMP       digital code read through MCP3221 ( 0 .. 4095 )
  static float Pump_Cur_A;           // PUMP       CURrent read through MCP3221 stored in this variable in units "[A]"

// Internal ADC for 12V VBB (VBAT) voltage reading
  static int   VBBmeas_ADC_val_DigCode = 0;
  static float VBBmeas_ADC_val_V = 0;    // ADC value for VBB (VBAT) measurement in units [V] but still from 0 .. 5V (not converted)
  static float VBBmeas_VBB_V  = 0;       // VBB (VBAT) measurement: VBB measured / converted in(to) units [V]

// Misc
  static unsigned short SysErr = 0;       // If there is an error in the system, e.g. overtemperature of the compressor etc.
  static unsigned short uCalive = 1;      // Change value every e.g. 1s and display some character on OLED display

// Debug
  unsigned  char  DEBUG_PIN = 4;
  
/****************** Subprograms / Functions ********************************************/


/***************************************************************************************/
/* Interrupt Subprogram / Function                                                     */
/***************************************************************************************/
void flow () // Interrupt function
{
   flow_frequency++;
}


///***************************************************************************************/
///* Subprogram / Function                                                               */
///***************************************************************************************/
//// Print the temperature for a device
//void func_OW_PrintTemperature(DeviceAddress deviceAddress)
//{
//  float tempC = sensors.getTempC(deviceAddress);
//  if(tempC == DEVICE_DISCONNECTED_C) 
//  {
//    Serial.println("Error: Could not read temperature data");
//    return;
//  }
//  Serial.print("Temp C: ");
//  Serial.print(tempC);
//}
//
///***************************************************************************************/
///* Subprogram                                                                          */
///***************************************************************************************/
//// Print a device address
//void func_OW_PrintAddress(DeviceAddress deviceAddress)
//{
//  for (uint8_t i = 0; i < 8; i++)
//  {
//    if (deviceAddress[i] < 16) Serial.print("0");
//    Serial.print(deviceAddress[i], HEX);
//  }
//}

/***************************************************************************************/
/* Subprogram                                                                          */
/***************************************************************************************/
void func_OW_GetDevicesOnBusAndAssignAddr()
{
  // locate devices on the bus
    Serial.print("Locating One-Wire devices...");
    sensor_bus.begin();                             // Start up the library

  #ifdef ENABLE_SEARCH_ADDRESS
    // Get the number of devices on the 1-Wire bus.
      CurNrOWdevsBus = sensor_bus.getDeviceCount();
      Serial.print(F( "Number of devices found: "));
      Serial.println( CurNrOWdevsBus );
  
    // Get the unique address: Use the actual number of found sensors, to make it possible to connect the sensors one by one (and press reset every time) and see the unique address. Once all the addresses are set in 'sensor_address[]', then the index of that is used, and not the index of the DallasTemperature.
      Serial.println(F( "Copy the 8 bytes of the sensor address into the sketch."));
      DeviceAddress sens;               // temporary sensor address.
      for( int i=0; i<CurNrOWdevsBus; i++)           // this is the index for the DallasTemperature library
      {
        sensor_bus.getAddress( sens, i);
       
        Serial.print(F( "Device found, address: "));
        for( int j=0; j<8; j++)
        {
          Serial.print(F( "0x"));
          if( sens[j] < 16)
            Serial.print(F( "0"));
          Serial.print( sens[j], HEX);
          if( j!=7)
            Serial.print(F( ", "));
        }
        Serial.println();
      }
  #endif
}


/***************************************************************************************/
/* Subprogram                                                                          */
/***************************************************************************************/
// Set the resolution of the 1-wire temperature sensors: Set to x bit (Each Dallas/Maxim device is capable of several different resolutions)
void func_OW_SetGetTempDevicesProperties()
{
  // Resolution: The next part is only valid if the sensor address had been written in the sketch.
    #ifdef ENABLE_READ_BACK_RESOLUTION
      Serial.println(F( "Resolution:"));
    #endif
  
    for( int i=0; i<NUM_OW_SENSORS; i++)
    {
      sensor_bus.setResolution( sensor_address[i], TEMPERATURE_PRECISION);
  
      #ifdef ENABLE_READ_BACK_RESOLUTION
        char buffer[40];
        strcpy_P( buffer, (char *) pgm_read_word( &(string_table[i])));
        Serial.print(F( "  "));
        Serial.print( buffer);
    
        Serial.print(F( " resolution: "));
        Serial.print( sensor_bus.getResolution( sensor_address[i]), DEC);
        Serial.println();
      #endif
    }

  // Parasite power: Report parasite power requirements
    Serial.print("Parasite power is: "); 
    if (sensor_bus.isParasitePowerMode()) Serial.println("ON");
    else Serial.println("OFF");
}

/***************************************************************************************/
/* Subprogram                                                                          */
/***************************************************************************************/
// Get current temperatures of all 1-wire temperature sensors and store them into an array
void func_OW_GetTempsensorTemps()
{
  sensor_bus.requestTemperatures();   // Global request to get the temperatures  // Gather all the temperatures  // The temperatures are requested by using the unique address of the sensor. The connected sensors with its address in this sketch will return a valid temperature, regardless of other sensors that might be missing or extra sensors that might have been added.
  for( int i=0; i<NUM_OW_SENSORS; i++)
  {
    TempSensors_Temps[i] = sensor_bus.getTempC( sensor_address[i]);   // Get temperature with its own unique address.  // This matches the labels to the specific sensor.
  }

  // Print all the temperatures
    for( int i=0; i<NUM_OW_SENSORS; i++)
    {
      char buffer[40];
      strcpy_P( buffer, (char *) pgm_read_word( &(string_table[i])));
      Serial.print( buffer);
      Serial.print(F( ": "));
      if( TempSensors_Temps[i] == -127.0)
      {
        Serial.print(F( "Error, not found  "));
      }
      else
      {
        Serial.print( TempSensors_Temps[i]);
        Serial.print(F( "  "));
      }
    }
    Serial.println();
}

/***************************************************************************************/
/* Subprogram                                                                          */
/***************************************************************************************/
// I2C Scanner from: "https://forum.arduino.cc/index.php?topic=632881.0" ; This sketch tests the standard 7-bit addresses, Devices with higher bit address might not be seen properly.
// If called stand-alone, it needs "#include <Wire.h>".
void func_I2C_Scanner()
{
  byte error, address;
  int nDevices;

  Serial.print(F("\n----------------------\n"));
  Serial.println("Scanning for I2C devices ...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }   
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
}

/***************************************************************************************/
/* Subprogram                                                                          */
/***************************************************************************************/
// Read 3 Switches = Pushbuttons over an analog input pin.
// (c) Bernd Cettl, 07/2021, based on script from "Doug LaRue" from "Nov. 2008".

/*
 *   analogPin                 VCC (+5 V)
 *      |                         |
 *      |                         |
 *      o --------------          | 
 *      |              |          |
 *      |              \          |
 *    -----      120R  /          |    
 *    -----  100nF     \          |
 *      |              /          |
 *      |              \          |
 *    _____            |____ \____|
 *     ___  ground     |   SW1    |
 *      _              \          \
 *                     /          /   
 *               1k5   \          \   1k5
 *                     /          /
 *                     \          \
 *                     |____ \____|
 *                     |   SW2    |
 *                     \          \
 *                     /          /   
 *               1k5   \          \   1k5
 *                     /          /
 *                     \          \
 *                     |____ \____|
 *                     |   SW3           
 *                     \
 *               1k5   /   
 *                     \   
 *                     /
 *                     \
 *                     |
 *                   _____   
 *                    ___     ground
 *                     _
 *
 */

int buttonPushed(int pinNum) {
  int val;         // variable to store the read value
    val = analogRead(pinNum);   // read the input pin
    
    #ifdef DEBUG_ON
      Serial.println(val);
    #endif

    if ( val >= (1023-ERROR_WINDOW_SW) and val <= (1023) ) { // 1022 .. 1023
      #ifdef DEBUG_ON
      Serial.println("switch 1 pressed/triggered");
      #endif
      return 1;
    }
    else if ( val >= (681-ERROR_WINDOW_SW) and val <= (681+ERROR_WINDOW_SW) ) { // 681
      #ifdef DEBUG_ON
      Serial.println("switch 2 pressed/triggered");
      #endif
      return 2;
    }
    else if ( val >= (340-ERROR_WINDOW_SW) and val <= (340+ERROR_WINDOW_SW) ) { // 340
      #ifdef DEBUG_ON
      Serial.println("switch 3 pressed/triggered");
      #endif
      return 3;
    }
    else
      return 0;  // no button found to have been pushed
}


/***************************************************************************************/
/* Main: Setup          // put your setup code here, to run once:                      */
/***************************************************************************************/
void setup()
{
// System LED  
  pinMode( LED_BUILTIN , OUTPUT );  

// AliveErrorLED
  pinMode( AliveErrorLED , OUTPUT );

// Compressor switch on / off
  pinMode( ComprOnOffPin , OUTPUT );

// Switches
  pinMode( AnalogSwPin , INPUT );
    
// start serial port
  Serial.begin(9600);
  while(!Serial);     // Acc. to Arduino Forum, basically: Wait for serial port to connect, necessary for some boards.  // In more detail: "On boards with an FT232 chip or other USB->Serial bridge chip (Uno, Mega, etc) it does absolutely nothing. On boards with a direct USB connection, such as the Leonardo or the Yùn it waits for an active serial connection to be established by the PC (i.e., for the serial port to be opened by a piece of software)."
  Serial.print(F("INITIATING SERIAL COMMUNICATION\n"));  
  Serial.print(F("Serial Port "));
  Serial.print(Serial ? "is open\n" : "Could not be opened\n"); 
  Serial.print(F("----------------------\n"));
    
// 1-wire
  // Get 1-wire device addresses and assign increasing integer number to them
    func_OW_GetDevicesOnBusAndAssignAddr();
    
  // Set the resolution of the 1-wire temperature sensors
    func_OW_SetGetTempDevicesProperties();

  // Get current temperatures of all 1-wire temperature sensors and store them into an array
    func_OW_GetTempsensorTemps();
    
// Flow-sensor
   pinMode(flowsensor, INPUT);
   digitalWrite(flowsensor, HIGH); // Optional Internal Pull-Up
   attachInterrupt(digitalPinToInterrupt(flowsensor), flow, RISING); // Setup Interrupt
   currentTime = millis();
   cloopTime = currentTime;

// Start communication with I2C: Needed for MCP3221
    Wire.begin();   

// I2C devices
  // I2C Scanner
    func_I2C_Scanner();
    
  // MCP3221: Hint from "https://forum.arduino.cc/index.php?topic=550117.0": Summary: It works, if we move the constructors ( = "MCP3221 mcp3221A(SLAVE1);" ; "MCP3221 mcp3221B(SLAVE2);") __INTO_ "loop()", thereby constructing 2 new slave devices at each cycle like so:
    MCP3221 mcp3221A(SLAVE1);
    // Ping
      Serial.print(F("Slave A reading:\t"));
      Serial.print(mcp3221A.ping() ? (F("Not Found\n")) : (F("Found!\n")));
    // Set different things
      mcp3221A.setSmoothing(NO_SMOOTHING);
    // Get raw data
      Compr_Cur_DigCode = mcp3221A.getData();
      Serial.print(F("Compressor current still in digital code (0..4095):  "));
      Serial.print(Compr_Cur_DigCode);
      Serial.print(F("[]\n"));

    MCP3221 mcp3221B(SLAVE2);
    // Ping
      Serial.print(F("Slave B reading:\t"));
      Serial.print(mcp3221B.ping() ? (F("Not Found\n")) : (F("Found!\n")));
    // Set different things
      mcp3221B.setSmoothing(NO_SMOOTHING);
    // Get raw data
      Pump_Cur_DigCode = mcp3221B.getData();
      Serial.print(F("Pump current still in digital code (0..4095):  "));
      Serial.print(Pump_Cur_DigCode);
      Serial.print(F("[]\n"));
      
  // OLED-Display
    u8x8.begin();
    u8x8.setPowerSave(0);
  
  // Write OW devices with addresses to OLED-Display
    u8x8.setFont(u8x8_font_chroma48medium8_r);
    u8x8.drawString(0,0,"Nr Devs OW bus:");
    u8x8.setCursor(0,1);
    u8x8.print(CurNrOWdevsBus);
    //u8x8.drawString(0,1,CurNrOWdevsBus_char);
    u8x8.refreshDisplay();    // only required for SSD1606/7  

// Show setup display 2 seconds long
  delay(2000);

// Clear display in order that some remaining characters are not displayed during the loop. E.g. If here in setup it says "Temperatures:" and later in the loop just say "Temps:" in the same line, that it doesn't write: "Temps:atures:"
  u8x8.clear();

// Debug
//  pinMode(LED_BUILTIN, OUTPUT);
}


/***************************************************************************************/
/* Main: Loop          // put your main code here, to run repeatedly:                  */
/***************************************************************************************/
void loop()
{

// Scheduler: Especially for flow-sensor
  currentTime = millis();
  
// Every second, calculate and print litres/hour
  if(currentTime >= (cloopTime + 2000))
  {

// ==============================================
// !! THERE ARE JUST 150ms LEFT FOR PROCESSING !!
// ==============================================
    
    // Debug
      // TBD.
  
    // Flow-sensor: Shall be the 1st entry in the loop (except Debug) because it shall be best exactly 1000ms and the difference how much it is more than 1000ms is calibrated away "(currentTime - cloopTime)", but if there are other time-consuming variable tasks in-between, this calibration is not good anymore. the 
      if(flow_frequency != 0){
        // Pulse frequency (Hz) = 7.5Q, Q is flow rate in L/min.
        //l_minute = (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour
        l_minute = 1000.0 / (currentTime - cloopTime) * (flow_frequency / 7.5); // (Pulse frequency x 60 min) / 7.5Q = flowrate in L/hour   // "1000.0 / (currentTime - cloopTime)" = Correction if loop takes longer than "1000" ms.
        flow_frequency = 0; // Reset Counter
        //Serial.print(l_minute, DEC); // Print litres/min
        //Serial.println(" l/min");
        l_minute = l_minute * 0.9;  // Correction: 3.0 l/min from Wasseruhr, YF-S201 displayed 3.33 l/min.  => After this correction measured approx. correct at least with flow rates checked with 1 (one) l/min, and 3 l/min (on 21.02.2021).
  // Durchfluss-Sensor brauch erneute Kalibration nachdem die LoopTime ohne Delay umgestellt worden ist!!
      }
      else {
        l_minute = 0;   // To not keep the last value forever if there is no more flow.
      }
  
    // Reset the time count right after (in order that not even more time passes than 1000ms) the Flow-Sensor but also not before it (otherwise calibration of flow sensor will fail, see there).
      cloopTime = currentTime; // Updates cloopTime
    
    // 1-wire
      // Get current temperatures of all 1-wire temperature sensors and store them into an array
        func_OW_GetTempsensorTemps();

      // Still just for fun:
        int countAbove70 = 0;
          for( int i=0; i<NUM_OW_SENSORS; i++)
          {
            if( TempSensors_Temps[i] > 86.0)
            {
              countAbove70++;
            }
          }
          Serial.print(F( "There are "));
          Serial.print( countAbove70);
          Serial.println(F( " sensors above 70.0"));
          if( countAbove70 > 0)           // at least one sensor above 70 degrees ?
          {
            SysErr = 1;
          }
          else
          {
            SysErr = 0;
          }

    // MCP3221: Hint from "https://forum.arduino.cc/index.php?topic=550117.0": Summary: It works, if we move the constructors ( = "MCP3221 mcp3221A(SLAVE1);" ; "MCP3221 mcp3221B(SLAVE2);") __INTO_ "loop()", thereby constructing 2 new slave devices at each cycle like so:
      // Set different things and get raw data    
        MCP3221 mcp3221A(SLAVE1);
        mcp3221A.setSmoothing(NO_SMOOTHING);      // Obviously has to be repeated here in the loop. Is not enough to once define it in the setup.
        Compr_Cur_DigCode = mcp3221A.getData();
        MCP3221 mcp3221B(SLAVE2);
        mcp3221B.setSmoothing(NO_SMOOTHING);      // Obviously has to be repeated here in the loop. Is not enough to once define it in the setup.
        Pump_Cur_DigCode = mcp3221B.getData();
      // Print raw data to serial
        Serial.print(F("Compressor current still in digital code (0..4095):  "));
        Serial.print(Compr_Cur_DigCode);
        Serial.print(F("[]\n"));
        Serial.print(F("Pump current still in digital code (0..4095):  "));
        Serial.print(Pump_Cur_DigCode);
        Serial.print(F("[]\n"));
      // Convert raw data to current
        Compr_Cur_A = MPC3221_VREF_V * ( 2 * Compr_Cur_DigCode - 4096 ) / ( 4096 * 2 * SENS_ACS723_10__V_PER_A );
        Pump_Cur_A  = MPC3221_VREF_V * ( 2 * Pump_Cur_DigCode  - 4096 ) / ( 4096 * 2 * SENS_ACS723_05__V_PER_A );
      // Print converted currents to Amperes to serial
        Serial.print(F("Compressor current in units [A]:  "));
        Serial.print(Compr_Cur_A);
        Serial.print(F("[]\n"));
        Serial.print(F("Pump current in units [A]:  "));
        Serial.print(Pump_Cur_A);
        Serial.print(F("[]\n"));
              
//# ToDo: In the setup: First set MCP3221 A and B voltage reference and smoothing "NO" and then check, if it has been set and only then proceed.  Also Values are not in mV but in "dig.code" !!!
//#       Schauen, wieviel Zeit float multiplikation braucht, ich habe lt. oben (siehe weiter oben!) nur mehr 150ms verfügbar und es kommen noch 2 Tempsenses und schalter und leds etc dazu!

    // 12V VBB (VBAT) voltage reading (internal ADC)
      VBBmeas_ADC_val_DigCode = analogRead( VBB_MEAS_ANALOG_IN_PIN );
      VBBmeas_ADC_val_V = VBBmeas_ADC_val_DigCode * ( VCC_VREF_V / 1024 );
      VBBmeas_VBB_V = VBBmeas_ADC_val_V * VBB_MEAS_RES_DIV_GAIN;

    // Switches
        int buttNum = buttonPushed(AnalogSwPin);
        
        #ifdef DEBUG_ON
          Serial.print("Button "); Serial.print(buttNum); Serial.println(" was pushed.");  
        #endif
        
        if ( Change_S01_Lo_or_Hi == false ) {           // If "Change_S01_Lo_or_Hi" = e.g. Lo ( = e.g. "false") ==> Allow to modify the "Lo" value with the switches / keys.
          if ( buttNum == 1 ) {
            Temp_CoolBoxS02_Lo = Temp_CoolBoxS02_Lo + 0.1;
          }
          else if ( buttNum == 2 ) {
            Temp_CoolBoxS02_Lo = Temp_CoolBoxS02_Lo - 0.1;
          }   
        }
        else {                                          // If "Change_S01_Lo_or_Hi" = e.g. Hi ( = e.g. "true") ==> Allow to modify the "Hi" value with the switches / keys.
          if ( buttNum == 1 ) {
            Temp_CoolBoxS02_Hi = Temp_CoolBoxS02_Hi + 0.1;
          }
          else if ( buttNum == 2 ) {
            Temp_CoolBoxS02_Hi = Temp_CoolBoxS02_Hi - 0.1;
          }
        }

        if ( buttNum == 3 ) {                           // Button nr. 3 changes the modification of either the "Lo" or "Hi" value of the "S01".
          Change_S01_Lo_or_Hi = !Change_S01_Lo_or_Hi;
        }

      // Higher limit must be higher than the lower limit, because it does only cooling
        if ( Temp_CoolBoxS02_Lo >= Temp_CoolBoxS02_Hi ) {
          Temp_CoolBoxS02_Hi = Temp_CoolBoxS02_Lo + 1;
        }
        
        #ifdef DEBUG_ON
          Serial.print("Temp_CoolBoxS02_Lo = "); Serial.println(Temp_CoolBoxS02_Lo);
          Serial.print("Temp_CoolBoxS02_Hi = "); Serial.println(Temp_CoolBoxS02_Hi);
        #endif

    // Compressor switch on / off control
      if ( SysErr == 1 ) {                                    // If a system error ( = e.g. critical temperature is reached anywhere) occurred ...
        ComprOnOff = false;                                   // ... turn off the compressor
      }
      else {
        if ( TempSensors_Temps[7] < Temp_CoolBoxS02_Lo ) {    // If the temperature of sensor "S02" is <= as the minimum set temperature ...
          ComprOnOff = false;                                 // ... turn off the compressor
        }
        if ( TempSensors_Temps[7] > Temp_CoolBoxS02_Hi ) {    // If the temperature of sensor "S02" is <= as the minimum set temperature ...
          ComprOnOff = true;                                  // ... turn on the compressor
        } 
      }

      if ( ComprOnOff == false ) {
        digitalWrite( ComprOnOffPin , LOW );
      }
      if ( ComprOnOff == true ) {
        digitalWrite( ComprOnOffPin , HIGH );
      }
      
    // OLED-Display
      // Write temperatures to OLED-Display
        //u8x8.drawString(0, 0, "Temps:");
        u8x8.drawString(0, 0, "CI");   // Cold Into the plate heat exchanger
        u8x8.drawString(0, 1, "CO");   // Cold Out of the plate heat exchanger
        u8x8.drawString(0, 2, "HC");   // Hot out of the Compressor
        u8x8.drawString(0, 3, "HO");   // Hot Out of the plate heat exchanger
        u8x8.drawString(0, 4, "AT");   // Ambient Temperature
        u8x8.drawString(0, 5, "IF");   // Inside Fluid
        u8x8.drawString(0, 6, "S1");   // CoolBox inside Sensor 01
        u8x8.drawString(0, 7, "S2");   // CoolBox inside Sensor 01
        for (uint8_t i = 0; i < CurNrOWdevsBus; i++) {      // If "NrOWdevs = 10", runs from 0 .. 9
          //u8x8.setCursor(0,i+1);  // Set cursor to column 0 of display
          // u8x8.print(i+1);        // Print the current number of device (e.g. "1" .."7")  // Obviously for an integer variable, the number of decimal places do not need to be defined explicitely with the command "print". So e.g. enough is "print(i)", "print(i,1)" is not needed.
       //   u8x8.setCursor(3,i+1);  // Set cursor to column 2 of display
          u8x8.setCursor(3,i);  // Set cursor to column 3 of display (starting with column "0")
          u8x8.print(TempSensors_Temps[i],2);
        }

      // Blank one character if displayed temp returns from below -10 degrees
          // At least do for inside S01 and S02; ToDo: Quick fix, gehört nochmal überarbeitet: => Was ist mit den anderen Temperatursensoren?
            u8x8.drawString(7, 6, " ");
            u8x8.drawString(7, 7, " ");
      
//u8x8.drawString(13, 6, "-");
          
      // Write flow rate to OLED-Display
        u8x8.drawString(9, 1, "     ");  // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
        u8x8.setCursor(9,1);
        u8x8.print(l_minute,2);
        u8x8.drawString(9, 0, "CAL!");  // Durchfluss-Sensor brauch erneute Kalibration nachdem die LoopTime ohne Delay umgestellt worden ist!!
        u8x8.drawString(14, 1, "FR");
    
      // Write compressor and pump current to OLED-Display
        u8x8.drawString(9, 2, "     ");  // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
        u8x8.setCursor(9,2);
        u8x8.print(Compr_Cur_A , 1);     // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
        u8x8.drawString(14, 2, "CC");   // CC = Compressor Current
        u8x8.drawString(9, 3, "     ");  // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
        u8x8.setCursor(9,3);
        u8x8.print(Pump_Cur_A , 1);      // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
        u8x8.drawString(14, 3, "PC");   // PC = Pump Current
        
      // Write VBB voltage to OLED-Display
        u8x8.drawString(9, 4, "     ");  // Obviously additionally needed to clear this part of the display, otherwise could happen, that if number falls below 4 digits (e.g. "1000"), then the last "0" remains, so e.g. if first was "1234mV" displayed, then only "980mV" that the display showed "9804mV".
        u8x8.setCursor(9,4);
        u8x8.print(VBBmeas_VBB_V , 1);     // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage
        u8x8.drawString(14, 4, "VB");   // VB = VBB (VBAT) = nom. 12V

      // Switches
        // u8x8.setCursor(15,5);
        // u8x8.print(buttNum , 1);     // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage

      // Compressor state
        if ( ComprOnOff == false ) {
          u8x8.drawString(13, 5, "OFF");
        }
        if ( ComprOnOff == true ) {
          u8x8.drawString(13, 5, " ON");
        }
      
      // Display the set temperatures
        // Lower value
          u8x8.drawString(8, 7, "    ");
          if ( Temp_CoolBoxS02_Lo < 0 ) {
            u8x8.drawString(8, 7, "-");
          }
          else {
            u8x8.drawString(8, 7, "+");
          }
          u8x8.setCursor(9,7);
          u8x8.print( abs(Temp_CoolBoxS02_Lo) , 1);     // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage


        // Higher value
          u8x8.drawString(12, 7, "   ");      // One blank " " less thank above ( = with "Temp_CoolBoxS02_Lo") because end column of display. 
          if ( Temp_CoolBoxS02_Hi < 0 ) {
            u8x8.drawString(12, 7, "-");
          }
          else {
            u8x8.drawString(12, 7, "+");
          }
          u8x8.setCursor(13,7);
          u8x8.print( abs(Temp_CoolBoxS02_Hi) , 1);     // Although "unsigned int", "1" decimal place necessary; with "0", it doesn't display the voltage

            
      // Show that uC and display is alive and switch "Alive/Error LED":   // If everything ok, then AliveErrorLED = "HI,LO,LO,LO", else "HI,LO,HI,HI" PWM.
        switch (uCalive) {
          case 1:
            u8x8.drawString(15, 0, "-");
            uCalive = 2;
            digitalWrite( LED_BUILTIN , HIGH ); 
            digitalWrite( AliveErrorLED , HIGH );
            break;
          case 2:
            u8x8.drawString(15, 0, "\\");
            uCalive = 3;
            digitalWrite( LED_BUILTIN , LOW ); 
            digitalWrite( AliveErrorLED , LOW );
            break;
          case 3:
            u8x8.drawString(15, 0, "|");
            uCalive = 4;
            if ( SysErr >= 1 )
              digitalWrite( AliveErrorLED , HIGH );
            break;
          case 4:
            u8x8.drawString(15, 0, "/");
            uCalive = 1;
            break;
          default:
            u8x8.drawString(15, 0, "E");    // Error !
            break; // Wird nicht benötigt, wenn Statement(s) vorhanden sind
        }

        // u8x8.drawString(15, 7, "T");   // Test

    
      // Other things
        // Debug
          //u8x8.setCursor(8,5);
          //u8x8.print((currentTime - cloopTime),1);
          //cloopTime = currentTime; // Updates cloopTime
        
        //u8x8.setCursor(8,4);
        //u8x8.userInterfaceMessage("Title1", "Title2", "Title3", " Ok \n Cancel ");
    
      // Update OLED-Display
        u8x8.refreshDisplay();    // only required for SSD1606/7
 
      // Debug
        // TBD.
  }
}
>
1 Like

The -127 is an error usually caused by not enough power or a bad connection.

Way too much code to start with!

Start with just one sensor, and the simple examples from here: DS18B20 Temperature Sensor Arduino Tutorial (4 Examples)

Expand when you understand what works, and what doesn't. It is not as straightforward as you seem to expect.

The Arduino Nano board gets the 5V from a L7805 which can handle 1A and this in turn gets the power from a Meanwell 12V/20A switched power supply.

Of course I started with 1 sensor, then 2, then 5, then 7, then other code, then more other code. As I said, it worked and I did not recognize the step or, better said, there was no step for me recognizable when I added this part of code, then it stopped working. No, it worked and still sometimes works, but gets more and more unreliable. That's the problem I have, therefore I cannot leave out any part of my complete code. Otherwise it would be easy: I have kept all versions and so I would just go back to the last working one and see the difference. But, as said, it some times works for even weeks, then after not using it for a while and re-powering the complete Arduino hangs up after one day of operation and one time so one time other, one time +85°C, one time all ok, one time some or all sensors -127° one time all ok, and so on ...

The DS18B20 can be very problematic, and you should never expect 100% reliable communications. Timing is critical and long leads very often give rise to temporary communication errors. So you have to introduce timeouts and error checks at critical steps (and plan for error recovery), NEVER use delay(), etc. You may even choose to reboot the Arduino to recover from some errors.

It looks like you have advanced quite far with this project, but did not describe important details (like the aforementioned cable lengths), which makes it difficult to impossible for forum members to pinpoint a particular problem.

Finally, you may be asking too much of the Nano to do all that, and still recover from errors.

How are you doing on memory ? Is it getting close to max ?
Edit:
To try to reduce possible sources of error. I will sometimes use random number generator
to simulate sensors.

How are the DS18B20s connected to each other and to Arduino? Post a drawing, include wire lengths.

1 Like

Hi, @bernd2700
Welcome to the forum.

Sorry but can you post your info in point form please to make it easier to read?

Can you please post a circuit diagram of your project?
Please include power supply, component names and pin labels.

Can you please post some images of your project so we can see your component layout?

Do you have a DMM?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Most of the Nano's use a AMS1117 regulator in SOT223 which has an internal limit of 1 amp with a thermal limit of 100c/w. so max power dissipation should be less than 1w. That means a practical limit of about 0.150 amps. It has about a 100C rise per watt, that is the limiting factor. You could get a bit more depending on how good the heat sinking is, the ambient and air flow. This is all given in the data sheet.

Post a schematic of what you have and links to technical information on all the hardware devices connected. What else is connected, it is acting like there is more that is being powered with the 5V then stated.

Dear jremington,

Thanks for your answer. My cable lengths are as follows: About 0.2m each in series (in a chain) from sensor 1 to sensor 5, from this last sensor 5 then approx. 2m cable and from this point ("X") 0.5m to sensor 6 and here in parallel also from point "X" ca. 1.5m to finally sensor 7.
Ok, somehow it seems too much for any processor, since to read the 7 temps takes a while and then there is not much time left for the rest of the tasks until the main loop called every 2 sec. starts again. But I do not like to go to 3 secs as reading the buttons then gets VERY slow when I am pressing one to modify e.g. the set temperature.

You still haven't given enough details for people to help.

Are you trying to use parasitic power (don't)? What value pullups, what resolution temperature, etc. Forum members are not going to go through your code to figure those things out.

Since conversion time can take up to 750 ms for one sensor, what is your approach to read seven sensors in 2 seconds?

Despite having only three pins, this sensor is in fact an extremely complicated device, and you will not succeed with the project until you thoroughly understand the data sheet, and principles of operation.

Dear “gilshultz”,

MANY THANKS for the hint with that the -127 is usually caused by bad connection, and INDEED, I have a 3 terminal connector to the 1-wire bus, which I unplugged and re-plugged and now, not only the -127°C error is GONE, but also now the 85°C at the moment!! I will keep you updated.

Dear “jremington”,

Thanks for your answer. My cable lengths are as follows: About 0.2m each in series (in a chain) from sensor 1 to sensor 5, from this last sensor 5 then approx. 2m cable and from this point ("X") 0.5m to sensor 6 and here in parallel also from point "X" ca. 1.5m to finally sensor 7.

Ok, somehow it seems too much for any processor, since to read the 7 temps takes a while and then there is not much time left for the rest of the tasks until the main loop called every 2 sec. starts again. But I do not like to go to 3 secs as reading the buttons then gets VERY slow when I am pressing one to modify e.g. the set temperature.

Dear “noweare”,

Also thank you for your hint with the memory. I did not look to this, good tip! But should be no problem: “Sketch uses 17900 bytes (58%) of program storage space. Maximum is 30720 bytes. Global variables use 1235 bytes (60%) of dynamic memory, leaving 813 bytes for local variables. Maximum is 2048 bytes.”

Dear “JCA34F”,

Unfortunately, I am not allowed to upload anything. So I describe my drawing with cable lengths. Please see above when I answered “jremington”.

Dear “TomGeorge”,

Same story: I am not allowed to upload anything. For cable lengths. Please see above when I answered “jremington”.

For the power, as I already described in my previous post: “The Arduino Nano board gets the 5V from a L7805 which can handle 1A and this in turn gets the power from a Meanwell 12V/20A switched power supply.” Nothing gets hot or even noticeably warm, as expected. From my posted code, you can read the port pins: “#define ONE_WIRE_BUS 2 // Data wire is plugged into port 2 on the Arduino; ”. From the hardware side, I am equipped with a good DMM (Fluke 289) and oscilloscope (Agilent DSO7014B).

Dear “gilshultz” (again)

As I said in my previous post, the Arduino is NOT powered from a “AMS1117” in SOT23, but from a L7805. Yes, there is more powered from this, the display, hall current sensors, a flow sensor, buttons, and 2 LEDS, but altogether consuming really not much. The input side of the L7805 I have fused with 500mAF (which has 0.9 Ohms). As answered now to “TomGeorge”, nothing gets hot or even noticeably warm, as expected.

Dear “jremington” (again),

No, it writes me that parasite power is off. A Pull-up resistor of 1k is connected, as already stated in my previous post. I read 12 bits accuracy, as you can gain from my already posted code. (Why should I write things redundantly again here?) So: “Forum members are not going to go through your code to figure those things out.” ==> Why the hell not? Therefore I exactly posted it! I really try to read with utmost care through ALL of your answers, since you also took the time for me to try to help. But posting my complete code: Exactly this would do me the big help, if someone COULD have a look into my code and tell me which parts are problematic and how I could re-write this or that section in order that the uC does not hang up, or gets more time. As I said, I come from the HW side, and all projects I have designed up to now, the HW is working reliably for many many years (except now in this project the new used shitty 3 pin connector seems to make troubles.)

By the way: In HW design, I am pretty experienced but I am not good in SW, it's exactly here I would need your help!

Anyway: MANY THANKS TO YOU ALL & best greetings,

bernd2700

Re your slow cycle time.
A trick I used was to run the devices in a two-phase method.

First pass,start the temperature conversion…l loop through your other devices and code.
Next pass colllect the data - hence, you’re not waiting for ‘complete’ on each device for the conversion.

MUCH faster if you handle ir well.

1 Like

Hi,

Have you got the bypass capacitors that the data sheet recommends?
Is the L7805 in the TO-220 case?
The L7805 can handle 1A, but may need a heatsink.

Where do you connect the 5V to on the Nano?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Post a schematic. A lot of people look at the max rating of the part and assume it will do that. It will but under predefined conditions as stated on the data sheet. Assuming you have a 12V power supply and 5V out at 500mA. that is 3.5 watts, multiply that by the 62 degrees per C that becomes a temperature of 217C + 25C Ambient that makes the case 242C, more then hot enough to leave skin on it if you touch it. Look at the data sheet for the thermal shutdown temperature, it will be about 175C so it will not supply 1/2 amp even if it is rated at 1A. An appropriate heat sink will get it to work. There are other parameters on the data sheet you must also meet for it to work properly.

What pull down resistor are you using on the sensor, i found by using a 3.9k instead of the 4.7k recommended works better