Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1from utime import sleep_us, time 

2from machine import Pin 

3from micropython import const 

4 

5 

6class HX711Exception(Exception): 

7 pass 

8 

9 

10class InvalidMode(HX711Exception): 

11 pass 

12 

13 

14class DeviceIsNotReady(HX711Exception): 

15 pass 

16 

17 

18class HX711(object): 

19 

20 """ 

21 Micropython driver for Avia Semiconductor's HX711 

22 24-Bit Analog-to-Digital Converter 

23 """ 

24 CHANNEL_A_128 = const(1) 

25 CHANNEL_A_64 = const(3) 

26 CHANNEL_B_32 = const(2) 

27 

28 DATA_BITS = const(24) 

29 MAX_VALUE = const(0x7fffff) 

30 MIN_VALUE = const(0x800000) 

31 READY_TIMEOUT_SEC = const(5) 

32 SLEEP_DELAY_USEC = const(80) 

33 

34 def __init__(self, d_out: int, pd_sck: int, channel: int = CHANNEL_A_128): 

35 self.d_out_pin = Pin(d_out, Pin.IN) 

36 self.pd_sck_pin = Pin(pd_sck, Pin.OUT, value=0) 

37 self.channel = channel 

38 

39 def __repr__(self): 

40 return "HX711 on channel %s, gain=%s" % self.channel 

41 

42 def _convert_from_twos_complement(self, value: int) -> int: 

43 """ 

44 Converts a given integer from the two's complement format. 

45 """ 

46 if value & (1 << (self.DATA_BITS - 1)): 

47 value -= 1 << self.DATA_BITS 

48 return value 

49 

50 def _set_channel(self): 

51 """ 

52 Input and gain selection is controlled by the 

53 number of the input PD_SCK pulses 

54 3 pulses for Channel A with gain 64 

55 2 pulses for Channel B with gain 32 

56 1 pulse for Channel A with gain 128 

57 """ 

58 for _ in range(self._channel): 

59 self.pd_sck_pin.value(1) 

60 self.pd_sck_pin.value(0) 

61 

62 def _wait(self): 

63 """ 

64 If the HX711 is not ready within READY_TIMEOUT_SEC 

65 the DeviceIsNotReady exception will be thrown. 

66 """ 

67 t0 = time() 

68 while not self.is_ready(): 

69 if time() - t0 > self.READY_TIMEOUT_SEC: 

70 raise DeviceIsNotReady() 

71 

72 @property 

73 def channel(self) -> tuple: 

74 """ 

75 Get current input channel in a form 

76 of a tuple (Channel, Gain) 

77 """ 

78 if self._channel == self.CHANNEL_A_128: 

79 return 'A', 128 

80 if self._channel == self.CHANNEL_A_64: 

81 return 'A', 64 

82 if self._channel == self.CHANNEL_B_32: 

83 return 'B', 32 

84 

85 @channel.setter 

86 def channel(self, value): 

87 """ 

88 Set input channel 

89 HX711.CHANNEL_A_128 - Channel A with gain 128 

90 HX711.CHANNEL_A_64 - Channel A with gain 64 

91 HX711.CHANNEL_B_32 - Channel B with gain 32 

92 """ 

93 if value not in (self.CHANNEL_A_128, self.CHANNEL_A_64, self.CHANNEL_B_32): 

94 raise InvalidMode('Gain should be one of HX711.CHANNEL_A_128, HX711.CHANNEL_A_64, HX711.CHANNEL_B_32') 

95 else: 

96 self._channel = value 

97 

98 if not self.is_ready(): 

99 self._wait() 

100 

101 for _ in range(self.DATA_BITS): 

102 self.pd_sck_pin.value(1) 

103 self.pd_sck_pin.value(0) 

104 

105 self._set_channel() 

106 

107 def is_ready(self) -> bool: 

108 """ 

109 When output data is not ready for retrieval, 

110 digital output pin DOUT is high. 

111 """ 

112 return self.d_out_pin.value() == 0 

113 

114 def power_off(self): 

115 """ 

116 When PD_SCK pin changes from low to high 

117 and stays at high for longer than 60 us , 

118 HX711 enters power down mode. 

119 """ 

120 self.pd_sck_pin.value(0) 

121 self.pd_sck_pin.value(1) 

122 sleep_us(self.SLEEP_DELAY_USEC) 

123 

124 def power_on(self): 

125 """ 

126 When PD_SCK returns to low, HX711 will reset 

127 and enter normal operation mode. 

128 """ 

129 self.pd_sck_pin.value(0) 

130 self.channel = self._channel 

131 

132 def read(self, raw=False): 

133 """ 

134 Read current value for current channel with current gain. 

135 if raw is True, the HX711 output will not be converted 

136 from two's complement format. 

137 """ 

138 if not self.is_ready(): 

139 self._wait() 

140 

141 raw_data = 0 

142 for _ in range(self.DATA_BITS): 

143 self.pd_sck_pin.value(1) 

144 self.pd_sck_pin.value(0) 

145 raw_data = raw_data << 1 | self.d_out_pin.value() 

146 self._set_channel() 

147 

148 if raw: 

149 return raw_data 

150 else: 

151 return self._convert_from_twos_complement(raw_data)