In this example we connect a Si1145 sensor to an ESP32 running Micropython
The Si1145/46/47 is a low-power, reflectance-based, infrared proximity, ultraviolet (UV) index, and ambient light sensor with I2C digital interface and programmableevent interrupt output. This touchless sensor IC includes an analog-to-digital converter, integrated high-sensitivity visible and infrared photodiodes, digital signal processor, and one, two, or three integrated infrared LED drivers with fifteen selectable drive levels.
The Si1145/46/47 offers excellent performance under a wide dynamic range and a variety of light sources including direct sunlight. The Si1145/46/47 can also work under dark glass covers.
The photodiode response and associated digital conversion circuitry provide excellent immunity to artificial light flicker noise and natural light flutter noise. With two or more LEDs, the Si1146/47 is capable of supporting multiple-axis proximity motion detection
Parts List
Connection
An easy module to connect to an ESP32, SCL is 22 and SDA is 21 on the Wemos board I used, you can see this is the schematic below
Code
You can use any method to upload files to the ESP32, I used uPyCraft
The following is based on a github library – https://github.com/neliogodoi/MicroPython-SI1145. The first part of this is the library which I upload to my ESP32
I used the si1145_lowmem.py library
[codesyntax lang=”python”]
""" MicroPython driver for SI1145 light I2C sensor, low memory version : https://github.com/neliogodoi/MicroPython-SI1145 Version: 0.3.0 @ 2018/04/02 """ import time from ustruct import unpack class SI1145(object): def __init__(self, i2c=None, addr=0x60): if i2c is None: raise ValueError('An I2C object is required.') self._i2c = i2c self._addr = addr self._reset() self._load_calibration() def _read8(self, register): result = unpack( 'B', self._i2c.readfrom_mem( self._addr, register, 1) )[0] & 0xFF return result def _read16(self, register, little_endian=True): result = unpack('BB', self._i2c.readfrom_mem(self._addr, register, 2)) result = ((result[1] << 8) | (result[0] & 0xFF)) if not little_endian: result = ((result << 8) & 0xFF00) + (result >> 8) return result def _write8(self, register, value): value = value & 0xFF self._i2c.writeto_mem(self._addr, register, bytes([value])) def _reset(self): self._write8(0x08, 0x00) self._write8(0x09, 0x00) self._write8(0x04, 0x00) self._write8(0x05, 0x00) self._write8(0x06, 0x00) self._write8(0x03, 0x00) self._write8(0x21, 0xFF) self._write8(0x18, 0x01) time.sleep(.01) self._write8(0x07, 0x17) time.sleep(.01) def _write_param(self, parameter, value): self._write8(0x17, value) self._write8(0x18, parameter | 0xA0) return self._read8(0x2E) def _load_calibration(self): self._write8(0x13, 0x7B) self._write8(0x14, 0x6B) self._write8(0x15, 0x01) self._write8(0x16, 0x00) self._write_param( 0x01, 0x80 | 0x40 | 0x20 | 0x10 | 0x01) self._write8(0x03, 0x01) self._write8(0x04, 0x01) self._i2c.writeto_mem(0x60, 0x0F, b'0x03') self._write_param(0x07, 0x03) self._write_param(0x02, 0x01) self._write_param(0x0B, 0) self._write_param(0x0A, 0x70) self._write_param(0x0C, 0x20 | 0x04) self._write_param(0x0E, 0x00) self._write_param(0x1E, 0) self._write_param(0x1D, 0x70) self._write_param(0x1F, 0x20) self._write_param(0x11, 0) self._write_param(0x10, 0x70) self._write_param(0x12, 0x20) self._write8(0x08, 0xFF) self._write8(0x18, 0x0F) @property def read_uv(self): return self._read16(0x2C, little_endian=True) / 100 @property def read_visible(self): return self._read16(0x22, little_endian=True) @property def read_ir(self): return self._read16(0x24, little_endian=True) @property def read_prox(self): return self._read16(0x26, little_endian=True)
[/codesyntax]
I then create a file called main.py and uploaded them to my ESP32
[codesyntax lang=”python”]
import machine import si1145 import time i2c = machine.I2C(sda=machine.Pin(21),scl=machine.Pin(22)) sensor = si1145.SI1145(i2c=i2c) for i in range(10): uv = sensor.read_uv ir = sensor.read_ir view = sensor.read_visible print(" UV: %f\n IR: %f\n Visible: %f" % (uv, ir, view)) time.sleep(1)
[/codesyntax]
Testing
Open up the REPL window. Here is what I saw in uPyCraft
Ready to download this file,please wait!
…
download ok
exec(open(‘./main.py’).read(),globals())
UV: 0.000000
IR: 407.999992
Visible: 265.999984
UV: 0.040000
IR: 407.999992
Visible: 265.999984
UV: 0.040000
IR: 417.999982
Visible: 265.999984
UV: 0.040000
IR: 411.999988
Visible: 266.999983
UV: 0.040000
IR: 409.999990
Visible: 266.999983
Links
https://www.silabs.com/documents/public/data-sheets/Si1145-46-47.pdf