Advertisement
masa-

Temperature logging: sensor error detection and handling

Dec 21st, 2013
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.68 KB | None | 0 0
  1. void read_temperatures(system_vars_t *vars)
  2. {
  3.     uint8_t i, j, error;
  4.  
  5.     // Sensors are having problems and are shutdown for the moment
  6.     if(vars->sensor_reset_counter > 0)
  7.     {
  8.         // Decrement the cooldown counter
  9.         vars->sensor_reset_counter--;
  10.         return;
  11.     }
  12.  
  13.     for(i = 0; i < NUM_TEMP_SENSORS; i++)
  14.     {
  15.         if(vars->sensor_lines[i] > 0)   // sensor enabled
  16.         {
  17.             // sensor_lines: 0 = disabled => subtract one to get the index, multiply by 8
  18.             // to get the correct position (8 bytes long address)
  19.             error = read_sensor(&vars->temperature[i], &vars->onewire_addr[(vars->sensor_lines[i] - 1) * 8]);
  20.  
  21.             if(error == ERROR_CODE_ONEWIRE_CRC) // XXX debug: error counters
  22.             {
  23.                 vars->onewire_crc_errors++;
  24.                 continue;   // Don't do temperature error handling if the sensor can't be read
  25.             }
  26.             else if(error != 0) /*if(error == ERROR_CODE_ONEWIRE_NO_DEVICE)*/
  27.             {
  28.                 vars->onewire_other_errors++;
  29.                 continue;
  30.             }
  31.  
  32.             // Stuck at 0.75 degrees, which is the most common erroneous reading
  33.             if(vars->temperature[i] == 75)
  34.             {
  35.                 // Try to check if the 0.75 degrees reading is actually valid.
  36.                 // We do this by comparing it to a previous valid (non 0.75 degrees) reading.
  37.                 // If the difference is small enough, we accept the reading for a longer grace period.
  38.  
  39.                 // If the difference from the last non 0.75 degrees reading is less than 0.5 degrees
  40.                 // (ie. the reading is hovering near 0.75 degrees naturally),
  41.                 // the reading is probably valid, so we increase the grace period.
  42.                 if(
  43.                     (vars->temperature[i] >= vars->temperature_valid[i] && (vars->temperature[i] - vars->temperature_valid[i]) < 50) ||
  44.                     (vars->temperature[i] < vars->temperature_valid[i] && (vars->temperature_valid[i] - vars->temperature[i]) < 50)
  45.                 )
  46.                 {
  47.                     // Set the grace period to 60 seconds.
  48.                     // If the reading does not fluctuate once in 60 seconds, we assume
  49.                     // that the sensor bugged out again.
  50.                     vars->sensor_error_limit[i] = 60;
  51.                 }
  52.             }
  53.             else if(vars->temperature[i] == 8500)
  54.             {
  55.                 // Reset the error limit if we get the 85 degrees reading
  56.                 vars->sensor_error_limit[i] = 5;
  57.             }
  58.  
  59.             // If the sensor is messed up (showing 0.75 or 85.00 degrees constantly),
  60.             // we want to "disconnect" it, by pulling the data line low for X amount
  61.             // of time, so that the sensor can hopefully recover.
  62.             if(vars->temperature[i] == 75 || vars->temperature[i] == 8500)
  63.             {
  64.                 // X second grace period
  65.                 if(++vars->sensor_error_count[i] >= vars->sensor_error_limit[i])
  66.                 {
  67.                     // Halt all 1-wire activity for X seconds
  68.                     vars->sensor_reset_counter = 1800;
  69.  
  70.                     // Reset the error counters and limits
  71.                     for(j = 0; j < NUM_TEMP_SENSORS; j++)
  72.                     {
  73.                         vars->sensor_error_count[j] = 0;
  74.                         vars->sensor_error_limit[j] = 5;
  75.                     }
  76.  
  77.                     // Put the sensor(s) into "cooldown mode", ie. pull the data line
  78.                     // low so the sensor is unpowered for a while.
  79.                     onewire_mosfet_release();
  80.                     onewire_low();
  81.                     onewire_out();
  82.  
  83.                     return;
  84.                 }
  85.             }
  86.             else
  87.             {
  88.                 // When the temperature reading is something other than 0.75 or 85, reset the error counter
  89.                 vars->sensor_error_count[i] = 0;
  90.                 // reset the successive erroneous readings limit: normally we trigger the cooldown
  91.                 // after 5 seconds of being stuck, if the hop from the previous value to the erroneous 0.75
  92.                 // reading is "big enough", see above
  93.                 vars->sensor_error_limit[i] = 5;
  94.                 // Store a valid temperature, so that we can calculate the change if we get an erroneous reading the next time
  95.                 vars->temperature_valid[i] = vars->temperature[i];
  96.             }
  97.         }
  98.     }
  99.  
  100.     vars->flags |= FLAG_NEW_TEMPERATURE_DATA;
  101.     onewire_global_conv_temp(); // start next conversion
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement