DS18B20 Neden 12Bit dönüşüm yapmıyor?

Mucit23

Üye
Katılım
7 Ekim 2022
Mesajlar
75
Selamlar

DS18B20 sıcaklık sensörü STM32 ile basit ortam sıcaklığı ölçümü yapmak istedim. Bu sensörle bir türlü 12 bit sıcaklık ölçümü yapamadım. 0.1 Derece çözünürlük için uğraşıyorum.

Şöyle bir init kodum var.


Kod:
/**
  * @brief  Initialize DS18B20 temperature sensor with configuration
  * @param  None
  * @return DS18B20_StatusTypeDef: DS18B20_OK if successful
  */
DS18B20_StatusTypeDef Ds18B20_Init(void)
{
  HAL_StatusTypeDef hal_status;
 
  /* Initialize OneWire interface */
  hal_status = OneWire_Init();
  if(hal_status != HAL_OK)
  {
    return DS18B20_ERROR;
  }
 
  /* Reset OneWire bus and check for slave presence */
  hal_status = OneWire_Reset();
  if(hal_status != HAL_OK)
  {
    return DS18B20_ERROR;  /* No sensor detected */
  }
 
  /* Write configuration: Skip ROM + Write scratchpad command */
  OneWire_WriteByte(DS18B20_CMD_SKIP_ROM);    
  OneWire_WriteByte(DS18B20_CMD_WRITE_CONFIG);
  OneWire_WriteByte(0xFF);  /* TH (upper alarm threshold) */
  OneWire_WriteByte(0xFF);  /* TL (lower alarm threshold) */
  OneWire_WriteByte(0x1F);  /* Config: 12-bit resolution, 750ms conversion time */
 
//  /* Copy Scratchpad to EEPROM to save configuration permanently */
//  OneWire_Reset();
//  OneWire_WriteByte(DS18B20_CMD_SKIP_ROM);
//  OneWire_WriteByte(DS18B20_CMD_COPY_SCRATCHPAD);
//  //HAL_Delay(100);  /* Wait for EEPROM write completion */
 
  /* Reset to finish write operation */
  OneWire_Reset();
 
  return DS18B20_OK;
}

Sıcaklık okuma fonksiyonumda bu şekilde


Kod:
/**
  * @brief  Read temperature from DS18B20 sensor
  * @param  pTemp: Pointer to temperature value (in Celsius)
  * @return DS18B20_StatusTypeDef: DS18B20_OK if successful, DS18B20_ERROR on failure
  */
DS18B20_StatusTypeDef Ds18B20_Read(float *pTemp)
{
  GPIO_PinState busy = GPIO_PIN_RESET;
  int8_t data1, data2;
  int16_t raw_temp;
  float temperature;
  uint32_t conversion_timeout = DS18B20_CONVERSION_TIMEOUT;
  HAL_StatusTypeDef hal_status;
 
  /* Validate input pointer */
  if(pTemp == NULL)
  {
    return DS18B20_ERROR;
  }
 
  /* Reset OneWire bus */
  hal_status = OneWire_Reset();
  if(hal_status != HAL_OK)
  {
    return DS18B20_ERROR;
  }
 
  /* Initiate temperature conversion */
  OneWire_WriteByte(DS18B20_CMD_SKIP_ROM);
  OneWire_WriteByte(DS18B20_CMD_CONVERT_TEMP);
 
  /* Wait for conversion to complete with timeout protection */
  while((conversion_timeout > 0) && (busy == GPIO_PIN_RESET))
  {
    busy = OneWire_ReadBit();
    if(busy == GPIO_PIN_RESET)
    {
      HAL_Delay(1);  /* 1ms delay between checks */
      conversion_timeout--;
    }
  }
 
  if(conversion_timeout == 0)
  {
    return DS18B20_TIMEOUT;  /* Conversion timeout */
  }
 
  /* Reset and read temperature */
  hal_status = OneWire_Reset();
  if(hal_status != HAL_OK)
  {
    return DS18B20_ERROR;
  }
 
  OneWire_WriteByte(DS18B20_CMD_SKIP_ROM);
  OneWire_WriteByte(DS18B20_CMD_READ_SCRATCHPAD);
 
  /* Read first two bytes (temperature LSB and MSB) */
  data1 = (int8_t)OneWire_ReadByte();
  data2 = (int8_t)OneWire_ReadByte();
 
  /* Combine bytes into 16-bit signed value */
  raw_temp = (((int16_t)data2 << 8) | ((uint16_t)data1 & 0xFF));
 
  /* Convert to Celsius: each LSB = 0.0625°C */
  temperature = (float)raw_temp * 0.0625f;
 
  /* Store result */
  *pTemp = temperature;
 
  return DS18B20_OK;
}

Sıcaklık doğru ve düzgün bir şekilde okunuyor. Hiç bir problem yok gibi fakat 12 bit çözünürlüğe ulaşamıyorum. Çözünürlük hep 0.5 derece. Bir yerde hata yapıyor olabilirmiyim? Hata varsa bile ben göremedim. Acaba bu sensörler sahte mi? Böyle birşey olabilir mi?


Ek olarak OneWire Hattını lojik analizör ile inceledim. İnit aşamasında göndermiş olduğum komutların hepsi gidiyor. Ona rağmen çözünürlüğüm 9 bit de kalıyor.
 
Son düzenleme:
Kod:
OneWire_WriteByte(0x1F);  /* Config: 12-bit resolution,

1769584080741.png


Sanki bundan dolayı oluyor
 
Evet bununla alakalı kesinlikle. Fakat anlamadığım nokta şu daha önce bir çok kullanmış olduğum sensör var. Ben bu kütüphane ile daha önce 12 bit okuma yapıyordum. Anlamadım. Bazen çok basit şeyleri göremiyorsun gerçekten.
 
Sensör olarak BME280 de kullanabilirsiniz. Ortam sıcaklığı ölçmek için iyidir.
 
default hali 12 bit imiş. Daha önce yazdıktan sonra bir şekilde resetlenip default haline dönmüş olabilir bugüne kadar.
 
0x1F verdikten sonra iki okuma arasında da en az 750us olmalı.
 

Forum istatistikleri

Konular
8,850
Mesajlar
144,037
Üyeler
3,554
Son üye
burak balcı

Son kaynaklar

Back
Top