Other articles


  1. Drill Chuck Clean Up

    Started off with 3 seized up drill chucks.  PB Blaster and some persuasion freed them up.  Spinning them in the lathe with some Scotch Brite pads made the look great.

    Img 20170514 111607

    Img 20170514 105707

    read more
  2. WiPy 2.0 and Atom

    Yesterday I posted how the WiPy 2.0 and Atom had trouble connecting over IP address and that USB worked great. Well no more. Today for no apparent reason the connection is wonky. Code runs, shows in console, exits and goes to REPL prompt. >> Can't type in console at that point, reconnect does note reconnect, reset device, code reruns as console show output. Can't sync, won't connect......blah 1 hour wasted.

    PyCom says they have PyMakr plugin for other editors, cool. Loaded up Sublime, no PyMakr to be found in package list (assuming that's where it would be but just guessing because PyCom docs are less than accurate.

    Next up PyCharm ...wait not ready yet according to recent forum post...

    I have a brick!

    OK, looks like for whatever reason repl>> command line is busted.  Does not work in Atom and or in screen /dev/cu.ser.... mode.

    I will have a look some more tomorrow but as far as I can tell - PyCom is not ready for prime time.

    read more
  3. 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