행복한 하루

라즈베리파이 제로 프로젝트(6) – 온도,습도 구하기-번외 편(HTU21D python2 소스를 python3 버전으로 수정) 본문

RaspberryPi/Raspberry Pi Zero

라즈베리파이 제로 프로젝트(6) – 온도,습도 구하기-번외 편(HTU21D python2 소스를 python3 버전으로 수정)

변화의 물결 2020. 10. 8. 00:46

 

 

안녕하세요.

 

  HTU21D 모듈은 2편으로 끝이 났습니다. 그런데, python 소스로 공개된 것이 대부분 python2 버전이다 보니, 현재 소스를 컴파일하면 작동이 되지 않았습니다.    

a bytes-like object is required, not 'str'

 이런 에러를 발생하거나 io 함수가 지원하지 않는다 거나 여러 에러가 발생했습니다.

 그래서 이전 소스를 사용할 수 있도록 수정하여 번외로 공유드립니다. 

 

1. 수정사항

 

a bytes-like object is required, not 'str'

  - 위의 에러가 발생했을 때, encode(), decode()를 사용해보라고 했는데 잘 되지 않았습니다. 기존의 헥사 0x는 그냥 사용해도 되지만,

 "\xE3"

 같은 문자열은 변환이 되지 않아 에러가 발생했습니다. 그래서 간단하게 앞에 b라고 붙여주면 바이트 타입으로 인식하게 합니다.

   

HTU21D_ADDR = 0x40
CMD_READ_TEMP_HOLD = b"\xE3"

 

 - fread, fwread 에러 

  소스에 self.fw.write로 표시된 경우,  self.fwrite.write처럼  fw -> fwrite, fr -> fread 줄이지 말고 다 적어줍니다.    

 

 - print 경우, 이전 버전에서는 ( ) 괄호 없이도 되었지만, python3 버전에서는 사용하라고 하고 있습니다. 그래서 괄호를 넣어주고 , (콤마) 대신 %를 넣고 변수를 적어주면 C 언어의 printf처럼 사용 가능합니다.

 

2. 최종 소스

import struct, array, time, io, fcntl


I2C_SLAVE=0x0703
HTU21D_ADDR = 0x40
CMD_READ_TEMP_HOLD = b"\xE3"
CMD_READ_HUM_HOLD = b"\xE5"
CMD_READ_TEMP_NOHOLD = b"\xF3"
CMD_READ_HUM_NOHOLD = b"\xF5"
CMD_WRITE_USER_REG = b"\xE6"
CMD_READ_USER_REG = b"\xE7"
CMD_SOFT_RESET= b"\xFE"

class i2c(object):
 
   def __init__(self, device, bus):

      #self.fr = io.open("/dev/i2c-"+str(bus), "rb", buffering=0)
      #self.fw = io.open("/dev/i2c-"+str(bus), "wb", buffering=0)

      self.fread = io.open("/dev/i2c-%d" % bus, "rb", buffering=0)
      self.fwrite = io.open("/dev/i2c-%d" % bus, "wb", buffering=0)

      # set device address

      fcntl.ioctl(self.fread, I2C_SLAVE, HTU21D_ADDR)
      fcntl.ioctl(self.fwrite, I2C_SLAVE, HTU21D_ADDR)

   def write(self, bytes):
      self.fwrite.write(bytes)

   def read(self, bytes):
      return self.fread.read(bytes)

   def close(self):
      self.fw.close()
      self.fr.close()

class HTU21D(object):
   def __init__(self):
      self.dev = i2c(HTU21D_ADDR, 1) #HTU21D 0x40, bus 1
      self.dev.write(CMD_SOFT_RESET) #soft reset
      time.sleep(.1)

   def ctemp(self, sensorTemp):
      tSensorTemp = sensorTemp / 65536.0
      return -46.85 + (175.72 * tSensorTemp)

   def chumid(self, sensorHumid):
      tSensorHumid = sensorHumid / 65536.0
      return -6.0 + (125.0 * tSensorHumid)

   def crc8check(self, value):
      # Ported from Sparkfun Arduino HTU21D Library: https://github.com/sparkfun/HTU21D_Breakout
      remainder = ( ( value[0] << 8 ) + value[1] ) << 8
      remainder |= value[2]
      
      # POLYNOMIAL = 0x0131 = x^8 + x^5 + x^4 + 1
      # divsor = 0x988000 is the 0x0131 polynomial shifted to farthest left of three bytes
      divsor = 0x988000
      
      for i in range(0, 16):
         if( remainder & 1 << (23 - i) ):
             remainder ^= divsor
         divsor = divsor >> 1
      
      if remainder == 0:
         return True
      else:
         return False
   
   def read_tmperature(self):
      self.dev.write(CMD_READ_TEMP_NOHOLD) #measure temp
      time.sleep(.1)

      data = self.dev.read(3)
      buf = array.array('B', data)

      if self.crc8check(buf):
         temp = (buf[0] << 8 | buf [1]) & 0xFFFC
         return self.ctemp(temp)
      else:
         return -255
         
   def read_humidity(self):
      self.dev.write(CMD_READ_HUM_NOHOLD) #measure humidity
      time.sleep(.1)

      data = self.dev.read(3)
      buf = array.array('B', data)
      
      if self.crc8check(buf):
         humid = (buf[0] << 8 | buf [1]) & 0xFFFC
         return self.chumid(humid)
      else:
         return -255
         
if __name__ == "__main__":
   obj = HTU21D()
   print ("Temp: %.2f C" % obj.read_tmperature())
   print ("Humid: %.1f %%" % obj.read_humidity())

 

  위와 같이 실행하면 온도와 습도 값을 2편에서 본 라이브러리 다운로드 없이 사용할 수 있게 됩니다.

 

감사합니다.

 

 

Comments