Other articles


  1. PyCom WiPy 2.0

    Getting acclimated to the WiPy 2.0 and Expansion Board.  My first "hello world" if you will is to get a TSL2591 Light Sensor running.  It is an i2c device.

    Initial Notes on WiPy 2.0 Setup:

    • Datasheet for Expansion Board are difficult to understand.  I assumed that the pinouts would closely resemble that of the WiPy 2.0 but they are not even close.  I am still working with the Expansion Board but dread pulling the WiPy 2.0 off of it and having to rework the circuit
    • ATOM w/Pymkr is flakey at best.  Sync Folder setting not working for me.  I find myself having to restart ATOM after a while as it stops responding often.
    • Firmware Upgrade Fails: I think?  Can't tell what the latest firmware should be so I am not sure what, if anything happened.
    • Connection with ATOM via IP address never worked.  USB connection is working great.

    TSL2991 Code:

    Stole this from https://github.com/maxlklaxl/python-tsl2591

    Out of the box this code did not work with the WiPy 2.0.  After debugging a bit it turns out the pin outs for SDA and SCL needed to be changed.

    Code Snippet (line 52ish of tsl2951.py that I changed to work with WiPy 2.0

    [sourcecode language="python" wraplines="false" collapse="false"]
    from machine import I2C, Pin
    class SMBusEmulator:
    __slots__ = ('i2c',)
    def __init__(self):
    self.i2c = I2C(pins=("P8", "P23")) #SDA SCL respectively
    [/sourcecode]

    Full Code:

    [sourcecode language="python" wraplines="false" collapse="false"]
    # tsl2591 lux sensor interface
    import time

    VISIBLE = 2
    INFRARED = 1
    FULLSPECTRUM = 0

    ADDR = 0x29
    READBIT = 0x01
    COMMAND_BIT = 0xA0
    CLEAR_BIT = 0x40
    WORD_BIT = 0x20
    BLOCK_BIT = 0x10
    ENABLE_POWERON = 0x01
    ENABLE_POWEROFF = 0x00
    ENABLE_AEN = 0x02
    ENABLE_AIEN = 0x10
    CONTROL_RESET = 0x80
    LUX_DF = 408.0
    LUX_COEFB = 1.64
    LUX_COEFC = 0.59
    LUX_COEFD = 0.86

    REGISTER_ENABLE = 0x00
    REGISTER_CONTROL = 0x01
    REGISTER_THRESHHOLDL_LOW = 0x02
    REGISTER_THRESHHOLDL_HIGH = 0x03
    REGISTER_THRESHHOLDH_LOW = 0x04
    REGISTER_THRESHHOLDH_HIGH = 0x05
    REGISTER_INTERRUPT = 0x06
    REGISTER_CRC = 0x08
    REGISTER_ID = 0x0A
    REGISTER_CHAN0_LOW = 0x14
    REGISTER_CHAN0_HIGH = 0x15
    REGISTER_CHAN1_LOW = 0x16
    REGISTER_CHAN1_HIGH = 0x17
    INTEGRATIONTIME_100MS = 0x00
    INTEGRATIONTIME_200MS = 0x01
    INTEGRATIONTIME_300MS = 0x02
    INTEGRATIONTIME_400MS = 0x03
    INTEGRATIONTIME_500MS = 0x04
    INTEGRATIONTIME_600MS = 0x05

    GAIN_LOW = 0x00
    GAIN_MED = 0x10
    GAIN_HIGH = 0x20
    GAIN_MAX = 0x30

    def _bytes_to_int(data):
    return data[0] + (data[1]\<\<8)

    from machine import I2C, Pin
    class SMBusEmulator:
    __slots__ = ('i2c',)
    def __init__(self):
    self.i2c = I2C(pins=("P8", "P23"))

    def write_byte_data(self, addr, cmd, val):
    buf = bytes([cmd, val])
    self.i2c.writeto(addr, buf)

    def read_word_data(self, addr, cmd):
    assert cmd \< 256
    buf = bytes([cmd])
    self.i2c.writeto(addr, buf)
    data = self.i2c.readfrom(addr, 4)
    return _bytes_to_int(data)

    SENSOR_ADDRESS=0x29

    class Tsl2591:
    def __init__(
    self,
    sensor_id,
    integration=INTEGRATIONTIME_100MS,
    gain=GAIN_LOW
    ):
    print(sensor_id)
    self.sensor_id = sensor_id
    self.bus = SMBusEmulator()
    self.integration_time = integration
    self.gain = gain
    self.set_timing(self.integration_time)
    self.set_gain(self.gain)
    self.disable()

    def set_timing(self, integration):
    self.enable()
    self.integration_time = integration
    self.bus.write_byte_data(
    SENSOR_ADDRESS,
    COMMAND_BIT | REGISTER_CONTROL,
    self.integration_time | self.gain
    )
    self.disable()

    def set_gain(self, gain):
    self.enable()
    self.gain = gain
    self.bus.write_byte_data(
    SENSOR_ADDRESS,
    COMMAND_BIT | REGISTER_CONTROL,
    self.integration_time | self.gain
    )
    self.disable()

    def calculate_lux(self, full, ir):
    if (full == 0xFFFF) | (ir == 0xFFFF):
    return 0

    case_integ = {
    INTEGRATIONTIME_100MS: 100.,
    INTEGRATIONTIME_200MS: 200.,
    INTEGRATIONTIME_300MS: 300.,
    INTEGRATIONTIME_400MS: 400.,
    INTEGRATIONTIME_500MS: 500.,
    INTEGRATIONTIME_600MS: 600.,
    }
    if self.integration_time in case_integ.keys():
    atime = case_integ[self.integration_time]
    else:
    atime = 100.

    case_gain = {
    GAIN_LOW: 1.,
    GAIN_MED: 25.,
    GAIN_HIGH: 428.,
    GAIN_MAX: 9876.,
    }

    if self.gain in case_gain.keys():
    again = case_gain[self.gain]
    else:
    again = 1.

    cpl = (atime * again) / LUX_DF
    lux1 = (full - (LUX_COEFB * ir)) / cpl

    lux2 = ((LUX_COEFC * full) - (LUX_COEFD * ir)) / cpl

    return max([lux1, lux2])

    def enable(self):
    self.bus.write_byte_data(
    SENSOR_ADDRESS,
    COMMAND_BIT | REGISTER_ENABLE,
    ENABLE_POWERON | ENABLE_AEN | ENABLE_AIEN
    )

    def disable(self):
    self.bus.write_byte_data(
    SENSOR_ADDRESS,
    COMMAND_BIT | REGISTER_ENABLE,
    ENABLE_POWEROFF
    )

    def get_full_luminosity(self):
    self.enable()
    time.sleep(0.120*self.integration_time+1)
    full = self.bus.read_word_data(
    SENSOR_ADDRESS, COMMAND_BIT | REGISTER_CHAN0_LOW
    )
    ir = self.bus.read_word_data(
    SENSOR_ADDRESS, COMMAND_BIT | REGISTER_CHAN1_LOW
    )
    self.disable()
    return full, ir

    def get_luminosity(self, channel):
    full, ir = self.get_full_luminosity()
    if channel == FULLSPECTRUM:
    return full
    elif channel == INFRARED:
    return ir
    elif channel == VISIBLE:
    return full - ir
    else:
    return 0

    def sample(self):
    full, ir = self.get_full_luminosity()
    return self.calculate_lux(full, ir)

    [/sourcecode]

    Simple main.py to print out 10 sensor readings. Hello World Complete!
    Will work on posting to the cloud/thingspeak or something of that nature next

    [sourcecode language="python" wraplines="false" collapse="false"]
    # main.py -- put your code here!
    import time
    from machine import Pin
    from machine import I2C
    import tsl2591

    tsl = tsl2591.Tsl2591(0) # initialize tls2591

    cnt = 0

    while cnt != 10:
    time.sleep(2)
    full, ir = tsl.get_full_luminosity() # read raw values (full spectrum and ir spectrum)
    lux = tsl.calculate_lux(full, ir) # convert raw values to lux
    print(lux, full, ir)
    cnt = cnt + 1
    [/sourcecode]

    read more

links

social