{"id":691,"date":"2020-11-06T07:55:05","date_gmt":"2020-11-05T23:55:05","guid":{"rendered":"http:\/\/wp.vicds.com\/?p=691"},"modified":"2021-05-08T12:37:10","modified_gmt":"2021-05-08T04:37:10","slug":"i2c-raspberry","status":"publish","type":"post","link":"https:\/\/wp.vicds.com\/?p=691","title":{"rendered":"i2c @raspberry"},"content":{"rendered":"\n<p>\u5e6braspberry\u88dd\u4e86ups_hat<\/p>\n\n\n\n<p><a href=\"https:\/\/www.waveshare.com\/wiki\/UPS_HAT\">https:\/\/www.waveshare.com\/wiki\/UPS_HAT<\/a><\/p>\n\n\n\n<p>\u64da\u5b98\u7db2\u7684\u8aaa\u6cd5\u662f\u6709\u4e00\u652fpython\u53ef\u4ee5\u770b\u5269\u9918\u96fb\u91cf, \u88dd\u4e86\u4ee5\u5f8c\u6c92\u53cd\u61c9.<\/p>\n\n\n\n<p><a href=\"http:\/\/www.waveshare.com\/w\/upload\/d\/d9\/UPS_HAT.7z\">http:\/\/www.waveshare.com\/w\/upload\/d\/d9\/UPS_HAT.7z<\/a><\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"language-\">import smbus\nimport time\n\n# Config Register (R\/W)\n_REG_CONFIG                 = 0x00\n# SHUNT VOLTAGE REGISTER (R)\n_REG_SHUNTVOLTAGE           = 0x01\n\n# BUS VOLTAGE REGISTER (R)\n_REG_BUSVOLTAGE             = 0x02\n\n# POWER REGISTER (R)\n_REG_POWER                  = 0x03\n\n# CURRENT REGISTER (R)\n_REG_CURRENT                = 0x04\n\n# CALIBRATION REGISTER (R\/W)\n_REG_CALIBRATION            = 0x05\n\nclass BusVoltageRange:\n    &quot;&quot;&quot;Constants for ``bus_voltage_range``&quot;&quot;&quot;\n    RANGE_16V               = 0x00      # set bus voltage range to 16V\n    RANGE_32V               = 0x01      # set bus voltage range to 32V (default)\n\nclass Gain:\n    &quot;&quot;&quot;Constants for ``gain``&quot;&quot;&quot;\n    DIV_1_40MV              = 0x00      # shunt prog. gain set to  1, 40 mV range\n    DIV_2_80MV              = 0x01      # shunt prog. gain set to \/2, 80 mV range\n    DIV_4_160MV             = 0x02      # shunt prog. gain set to \/4, 160 mV range\n    DIV_8_320MV             = 0x03      # shunt prog. gain set to \/8, 320 mV range\n\nclass ADCResolution:\n    &quot;&quot;&quot;Constants for ``bus_adc_resolution`` or ``shunt_adc_resolution``&quot;&quot;&quot;\n    ADCRES_9BIT_1S          = 0x00      #  9bit,   1 sample,     84us\n    ADCRES_10BIT_1S         = 0x01      # 10bit,   1 sample,    148us\n    ADCRES_11BIT_1S         = 0x02      # 11 bit,  1 sample,    276us\n    ADCRES_12BIT_1S         = 0x03      # 12 bit,  1 sample,    532us\n    ADCRES_12BIT_2S         = 0x09      # 12 bit,  2 samples,  1.06ms\n    ADCRES_12BIT_4S         = 0x0A      # 12 bit,  4 samples,  2.13ms\n    ADCRES_12BIT_8S         = 0x0B      # 12bit,   8 samples,  4.26ms\n    ADCRES_12BIT_16S        = 0x0C      # 12bit,  16 samples,  8.51ms\n    ADCRES_12BIT_32S        = 0x0D      # 12bit,  32 samples, 17.02ms\n    ADCRES_12BIT_64S        = 0x0E      # 12bit,  64 samples, 34.05ms\n    ADCRES_12BIT_128S       = 0x0F      # 12bit, 128 samples, 68.10ms\n\nclass Mode:\n    &quot;&quot;&quot;Constants for ``mode``&quot;&quot;&quot;\n    POWERDOW                = 0x00      # power down\n    SVOLT_TRIGGERED         = 0x01      # shunt voltage triggered\n    BVOLT_TRIGGERED         = 0x02      # bus voltage triggered\n    SANDBVOLT_TRIGGERED     = 0x03      # shunt and bus voltage triggered\n    ADCOFF                  = 0x04      # ADC off\n    SVOLT_CONTINUOUS        = 0x05      # shunt voltage continuous\n    BVOLT_CONTINUOUS        = 0x06      # bus voltage continuous\n    SANDBVOLT_CONTINUOUS    = 0x07      # shunt and bus voltage continuous\n\n\nclass INA219:\n    def __init__(self, i2c_bus=1, addr=0x40):\n        self.bus = smbus.SMBus(i2c_bus);\n        self.addr = addr\n\n        # Set chip to known config values to start\n        self._cal_value = 0\n        self._current_lsb = 0\n        self._power_lsb = 0\n        self.set_calibration_32V_2A()\n\n    def read(self,address):\n        data = self.bus.read_i2c_block_data(self.addr, address, 2)\n        return ((data[0] * 256 ) + data[1])\n\n    def write(self,address,data):\n        temp = [0,0]\n        temp[1] = data &amp; 0xFF\n        temp[0] =(data &amp; 0xFF00) &gt;&gt; 8\n        self.bus.write_i2c_block_data(self.addr,address,temp)\n\n    def set_calibration_32V_2A(self):\n        &quot;&quot;&quot;Configures to INA219 to be able to measure up to 32V and 2A of current. Counter\n           overflow occurs at 3.2A.\n           ..note :: These calculations assume a 0.1 shunt ohm resistor is present\n        &quot;&quot;&quot;\n        # By default we use a pretty huge range for the input voltage,\n        # which probably isn&#039;t the most appropriate choice for system\n        # that don&#039;t use a lot of power.  But all of the calculations\n        # are shown below if you want to change the settings.  You will\n        # also need to change any relevant register settings, such as\n        # setting the VBUS_MAX to 16V instead of 32V, etc.\n\n        # VBUS_MAX = 32V             (Assumes 32V, can also be set to 16V)\n        # VSHUNT_MAX = 0.32          (Assumes Gain 8, 320mV, can also be 0.16, 0.08, 0.04)\n        # RSHUNT = 0.1               (Resistor value in ohms)\n\n        # 1. Determine max possible current\n        # MaxPossible_I = VSHUNT_MAX \/ RSHUNT\n        # MaxPossible_I = 3.2A\n\n        # 2. Determine max expected current\n        # MaxExpected_I = 2.0A\n\n        # 3. Calculate possible range of LSBs (Min = 15-bit, Max = 12-bit)\n        # MinimumLSB = MaxExpected_I\/32767\n        # MinimumLSB = 0.000061              (61uA per bit)\n        # MaximumLSB = MaxExpected_I\/4096\n        # MaximumLSB = 0,000488              (488uA per bit)\n\n        # 4. Choose an LSB between the min and max values\n        #    (Preferrably a roundish number close to MinLSB)\n        # CurrentLSB = 0.0001 (100uA per bit)\n        self._current_lsb = .1  # Current LSB = 100uA per bit\n\n        # 5. Compute the calibration register\n        # Cal = trunc (0.04096 \/ (Current_LSB * RSHUNT))\n        # Cal = 4096 (0x1000)\n\n        self._cal_value = 4096\n\n        # 6. Calculate the power LSB\n        # PowerLSB = 20 * CurrentLSB\n        # PowerLSB = 0.002 (2mW per bit)\n        self._power_lsb = .002  # Power LSB = 2mW per bit\n\n        # 7. Compute the maximum current and shunt voltage values before overflow\n        #\n        # Max_Current = Current_LSB * 32767\n        # Max_Current = 3.2767A before overflow\n        #\n        # If Max_Current &gt; Max_Possible_I then\n        #    Max_Current_Before_Overflow = MaxPossible_I\n        # Else\n        #    Max_Current_Before_Overflow = Max_Current\n        # End If\n        #\n        # Max_ShuntVoltage = Max_Current_Before_Overflow * RSHUNT\n        # Max_ShuntVoltage = 0.32V\n        #\n        # If Max_ShuntVoltage &gt;= VSHUNT_MAX\n        #    Max_ShuntVoltage_Before_Overflow = VSHUNT_MAX\n        # Else\n        #    Max_ShuntVoltage_Before_Overflow = Max_ShuntVoltage\n        # End If\n\n        # 8. Compute the Maximum Power\n        # MaximumPower = Max_Current_Before_Overflow * VBUS_MAX\n        # MaximumPower = 3.2 * 32V\n        # MaximumPower = 102.4W\n\n        # Set Calibration register to &#039;Cal&#039; calculated above\n        self.write(_REG_CALIBRATION,self._cal_value)\n\n        # Set Config register to take into account the settings above\n        self.bus_voltage_range = BusVoltageRange.RANGE_32V\n        self.gain = Gain.DIV_8_320MV\n        self.bus_adc_resolution = ADCResolution.ADCRES_12BIT_32S\n        self.shunt_adc_resolution = ADCResolution.ADCRES_12BIT_32S\n        self.mode = Mode.SANDBVOLT_CONTINUOUS\n        self.config = self.bus_voltage_range &lt;&lt; 13 | \\\n                      self.gain &lt;&lt; 11 | \\\n                      self.bus_adc_resolution &lt;&lt; 7 | \\\n                      self.shunt_adc_resolution &lt;&lt; 3 | \\\n                      self.mode\n        self.write(_REG_CONFIG,self.config)\n\n    def getShuntVoltage_mV(self):\n        self.write(_REG_CALIBRATION,self._cal_value)\n        value = self.read(_REG_SHUNTVOLTAGE)\n        if value &gt; 32767:\n            value -= 65535\n        return value * 0.01\n\n    def getBusVoltage_V(self):\n        self.write(_REG_CALIBRATION,self._cal_value)\n        self.read(_REG_BUSVOLTAGE)\n        return (self.read(_REG_BUSVOLTAGE) &gt;&gt; 3) * 0.004\n\n    def getCurrent_mA(self):\n        value = self.read(_REG_CURRENT)\n        if value &gt; 32767:\n            value -= 65535\n        return value * self._current_lsb\n\n    def getPower_W(self):\n        self.write(_REG_CALIBRATION,self._cal_value)\n        value = self.read(_REG_POWER)\n        if value &gt; 32767:\n            value -= 65535\n        return value * self._power_lsb\n        \nif __name__==&#039;__main__&#039;:\n\n    # Create an INA219 instance.\n    ina219 = INA219(addr=0x42)\n    while True:\n        bus_voltage = ina219.getBusVoltage_V()             # voltage on V- (load side)\n        shunt_voltage = ina219.getShuntVoltage_mV() \/ 1000 # voltage between V+ and V- across the shunt\n        current = ina219.getCurrent_mA()                   # current in mA\n        power = ina219.getPower_W()                        # power in W\n        p = (bus_voltage - 6)\/2.4*100\n        if(p &gt; 100):p = 100\n        if(p &lt; 0):p = 0\n\n        # INA219 measure bus voltage on the load side. So PSU voltage = bus_voltage + shunt_voltage\n        #print(&quot;PSU Voltage:   {:6.3f} V&quot;.format(bus_voltage + shunt_voltage))\n        #print(&quot;Shunt Voltage: {:9.6f} V&quot;.format(shunt_voltage))\n        print(&quot;Load Voltage:  {:6.3f} V&quot;.format(bus_voltage))\n        print(&quot;Current:       {:9.6f} A&quot;.format(current\/1000))\n        print(&quot;Power:         {:6.3f} W&quot;.format(power))\n        print(&quot;Percent:       {:3.1f}%&quot;.format(p))\n        print(&quot;&quot;)\n\n        time.sleep(2)\n<\/code><\/pre>\n\n\n\n<p>\u62dc\u4e86\u4e00\u4e0bGOOGLE, \u53c8\u662fraspi-config\u88e1\u7684\u8a2d\u5b9a, \u8981\u628ai2c enable\u5373\u53ef.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u5e6braspberry\u88dd\u4e86ups_hat ht [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28],"tags":[],"class_list":["post-691","post","type-post","status-publish","format-standard","hentry","category-raspberry"],"_links":{"self":[{"href":"https:\/\/wp.vicds.com\/index.php?rest_route=\/wp\/v2\/posts\/691","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wp.vicds.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wp.vicds.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wp.vicds.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wp.vicds.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=691"}],"version-history":[{"count":1,"href":"https:\/\/wp.vicds.com\/index.php?rest_route=\/wp\/v2\/posts\/691\/revisions"}],"predecessor-version":[{"id":692,"href":"https:\/\/wp.vicds.com\/index.php?rest_route=\/wp\/v2\/posts\/691\/revisions\/692"}],"wp:attachment":[{"href":"https:\/\/wp.vicds.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=691"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wp.vicds.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=691"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wp.vicds.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=691"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}