Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 20:24 16 Sep 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : uM2(+): SI1145 port of Adafruit code

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10397
Posted: 09:53am 12 May 2016
Copy link to clipboard 
Print this post

At lew247's request here is a simple 1:1 port of Adafruit's code for the SI1145 Digital UV Index / IR / Visible Light sensor





option explicit
option default NONE
'/* COMMANDS */
const SI1145_PARAM_QUERY = &H80
const SI1145_PARAM_SET = &HA0
const SI1145_NOP = &H0
const SI1145_RESET = &H01
const SI1145_BUSADDR = &H02
const SI1145_PS_FORCE = &H05
const SI1145_ALS_FORCE = &H06
const SI1145_PSALS_FORCE = &H07
const SI1145_PS_PAUSE = &H09
const SI1145_ALS_PAUSE = &H0A
const SI1145_PSALS_PAUSE = &HB
const SI1145_PS_AUTO = &H0D
const SI1145_ALS_AUTO = &H0E
const SI1145_PSALS_AUTO = &H0F
const SI1145_GET_CAL = &H12

'/* Parameters */
const SI1145_PARAM_I2CADDR = &H00
const SI1145_PARAM_CHLIST = &H01
const SI1145_PARAM_CHLIST_ENUV = &H80
const SI1145_PARAM_CHLIST_ENAUX = &H40
const SI1145_PARAM_CHLIST_ENALSIR = &H20
const SI1145_PARAM_CHLIST_ENALSVIS = &H10
const SI1145_PARAM_CHLIST_ENPS1 = &H01
const SI1145_PARAM_CHLIST_ENPS2 = &H02
const SI1145_PARAM_CHLIST_ENPS3 = &H04

const SI1145_PARAM_PSLED12SEL = &H02
const SI1145_PARAM_PSLED12SEL_PS2NONE = &H00
const SI1145_PARAM_PSLED12SEL_PS2LED1 = &H10
const SI1145_PARAM_PSLED12SEL_PS2LED2 = &H20
const SI1145_PARAM_PSLED12SEL_PS2LED3 = &H40
const SI1145_PARAM_PSLED12SEL_PS1NONE = &H00
const SI1145_PARAM_PSLED12SEL_PS1LED1 = &H01
const SI1145_PARAM_PSLED12SEL_PS1LED2 = &H02
const SI1145_PARAM_PSLED12SEL_PS1LED3 = &H04

const SI1145_PARAM_PSLED3SEL = &H03
const SI1145_PARAM_PSENCODE = &H05
const SI1145_PARAM_ALSENCODE = &H06

const SI1145_PARAM_PS1ADCMUX = &H07
const SI1145_PARAM_PS2ADCMUX = &H08
const SI1145_PARAM_PS3ADCMUX = &H09
const SI1145_PARAM_PSADCOUNTER = &H0A
const SI1145_PARAM_PSADCGAIN = &H0B
const SI1145_PARAM_PSADCMISC = &H0C
const SI1145_PARAM_PSADCMISC_RANGE = &H20
const SI1145_PARAM_PSADCMISC_PSMODE = &H04

const SI1145_PARAM_ALSIRADCMUX = &H0E
const SI1145_PARAM_AUXADCMUX = &H0F

const SI1145_PARAM_ALSVISADCOUNTER = &H10
const SI1145_PARAM_ALSVISADCGAIN = &H11
const SI1145_PARAM_ALSVISADCMISC = &H12
const SI1145_PARAM_ALSVISADCMISC_VRNG = &H20

const SI1145_PARAM_ALSIRADCOUNTER = &H1D
const SI1145_PARAM_ALSIRADCGAIN = &H1E
const SI1145_PARAM_ALSIRADCMISC = &H1F
const SI1145_PARAM_ALSIRADCMISC_RANGE = &H20

const SI1145_PARAM_ADCCOUNTER_511CLK = &H70

const SI1145_PARAM_ADCMUX_SMALLIR = &H00
const SI1145_PARAM_ADCMUX_LARGEIR = &H03



'/* REGISTERS */
const SI1145_REG_PARTID = &H00
const SI1145_REG_REVID = &H01
const SI1145_REG_SEQID = &H02

const SI1145_REG_INTCFG = &H03
const SI1145_REG_INTCFG_INTOE = &H01
const SI1145_REG_INTCFG_INTMODE = &H02

const SI1145_REG_IRQEN = &H04
const SI1145_REG_IRQEN_ALSEVERYSAMPLE = &H01
const SI1145_REG_IRQEN_PS1EVERYSAMPLE = &H04
const SI1145_REG_IRQEN_PS2EVERYSAMPLE = &H08
const SI1145_REG_IRQEN_PS3EVERYSAMPLE = &H10


const SI1145_REG_IRQMODE1 = &H05
const SI1145_REG_IRQMODE2 = &H06

const SI1145_REG_HWKEY = &H07
const SI1145_REG_MEASRATE0 = &H08
const SI1145_REG_MEASRATE1 = &H09
const SI1145_REG_PSRATE = &H0A
const SI1145_REG_PSLED21 = &H0F
const SI1145_REG_PSLED3 = &H10
const SI1145_REG_UCOEFF0 = &H13
const SI1145_REG_UCOEFF1 = &H14
const SI1145_REG_UCOEFF2 = &H15
const SI1145_REG_UCOEFF3 = &H16
const SI1145_REG_PARAMWR = &H17
const SI1145_REG_COMMAND = &H18
const SI1145_REG_RESPONSE = &H20
const SI1145_REG_IRQSTAT = &H21
const SI1145_REG_IRQSTAT_ALS = &H01

const SI1145_REG_ALSVISDATA0 = &H22
const SI1145_REG_ALSVISDATA1 = &H23
const SI1145_REG_ALSIRDATA0 = &H24
const SI1145_REG_ALSIRDATA1 = &H25
const SI1145_REG_PS1DATA0 = &H26
const SI1145_REG_PS1DATA1 = &H27
const SI1145_REG_PS2DATA0 = &H28
const SI1145_REG_PS2DATA1 = &H29
const SI1145_REG_PS3DATA0 = &H2A
const SI1145_REG_PS3DATA1 = &H2B
const SI1145_REG_UVINDEX0 = &H2C
const SI1145_REG_UVINDEX1 = &H2D
const SI1145_REG_PARAMRD = &H2E
const SI1145_REG_CHIPSTAT = &H30

const SI1145_ADDR = &H60
'
' Main Program
'
dim float UVindex
i2c open 400,1000 'device will run at full speed
if(read8(SI1145_REG_PARTID)<>&H45) then
print "SI1145 not found"
else
reset_SI1145()
start_SI1145()
do
print "Vis: ",readVisible()
Print "IR: ",readIR()
UVindex = readUV()
UVindex = UVindex /100.0
print "UV: ",UVindex
print ""
pause 1000
loop
endif
end
'
'*******************************************************************************************************
'
' Subroutines
'

sub start_SI1145() 'set up the sensor and start it reading
local integer i
' ***********************************
' enable UVindex measurement coefficients!
write8(SI1145_REG_UCOEFF0, &H29)
write8(SI1145_REG_UCOEFF1, &H89)
write8(SI1145_REG_UCOEFF2, &H02)
write8(SI1145_REG_UCOEFF3, &H00)

' enable UV sensor
i=writeParam(SI1145_PARAM_CHLIST, SI1145_PARAM_CHLIST_ENUV OR SI1145_PARAM_CHLIST_ENALSIR OR SI1145_PARAM_CHLIST_ENALSVIS OR SI1145_PARAM_CHLIST_ENPS1)
' enable interrupt on every sample
write8(SI1145_REG_INTCFG, SI1145_REG_INTCFG_INTOE)
write8(SI1145_REG_IRQEN, SI1145_REG_IRQEN_ALSEVERYSAMPLE)

'****************************** Prox Sense 1

' program LED current
write8(SI1145_REG_PSLED21, &H03)' 20mA for LED 1 only
i=writeParam(SI1145_PARAM_PS1ADCMUX, SI1145_PARAM_ADCMUX_LARGEIR)
' prox sensor #1 uses LED #1
i=writeParam(SI1145_PARAM_PSLED12SEL, SI1145_PARAM_PSLED12SEL_PS1LED1)
' fastest clocks, clock div 1
i=writeParam(SI1145_PARAM_PSADCGAIN, 0)
' take 511 clocks to measure
i=writeParam(SI1145_PARAM_PSADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
' in prox mode, high range
i=writeParam(SI1145_PARAM_PSADCMISC, SI1145_PARAM_PSADCMISC_RANGE OR SI1145_PARAM_PSADCMISC_PSMODE)

i=writeParam(SI1145_PARAM_ALSIRADCMUX, SI1145_PARAM_ADCMUX_SMALLIR)
' fastest clocks, clock div 1
i=writeParam(SI1145_PARAM_ALSIRADCGAIN, 0)
' take 511 clocks to measure
i=writeParam(SI1145_PARAM_ALSIRADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
' in high range mode
i=writeParam(SI1145_PARAM_ALSIRADCMISC, SI1145_PARAM_ALSIRADCMISC_RANGE)



' fastest clocks, clock div 1
i=writeParam(SI1145_PARAM_ALSVISADCGAIN, 0)
' take 511 clocks to measure
i=writeParam(SI1145_PARAM_ALSVISADCOUNTER, SI1145_PARAM_ADCCOUNTER_511CLK)
' in high range mode (not normal signal)
i=writeParam(SI1145_PARAM_ALSVISADCMISC, SI1145_PARAM_ALSVISADCMISC_VRNG)


'************************

' measurement rate for auto
write8(SI1145_REG_MEASRATE0, &HFF)' 255 * 31.25uS = 8ms

' auto run
write8(SI1145_REG_COMMAND, SI1145_PSALS_AUTO)

end sub

sub reset_SI1145() 'Reset the sensor
write8(SI1145_REG_MEASRATE0, 0)
write8(SI1145_REG_MEASRATE1, 0)
write8(SI1145_REG_IRQEN, 0)
write8(SI1145_REG_IRQMODE1, 0)
write8(SI1145_REG_IRQMODE2, 0)
write8(SI1145_REG_INTCFG, 0)
write8(SI1145_REG_IRQSTAT, &HFF)

write8(SI1145_REG_COMMAND, SI1145_RESET)
pause 10
write8(SI1145_REG_HWKEY, &H17)
pause 10
end sub

' returns the UV index * 100 (divide by 100 to get the index)
FUNCTION readUV() as integer
readUV= read16(&H2C)
end function

' returns visible+IR light levels
FUNCTION readVisible() as integer
readVisible = read16(&H22)
end function

' returns IR light levels
FUNCTION readIR() as integer
readIR = read16(&H24)
end function

' returns "Proximity" - assumes an IR LED is attached to LED
FUNCTION readProx() as integer
readProx = read16(&H26)
end function

function writeParam(p as integer, v as integer) as integer
write8(SI1145_REG_PARAMWR, v)
write8(SI1145_REG_COMMAND, p OR SI1145_PARAM_SET)
writeParam = read8(SI1145_REG_PARAMRD)
end function

FUNCTION readParam(uint8_t p) as integer
write8(SI1145_REG_COMMAND, p OR SI1145_PARAM_QUERY)
readParam = read8(SI1145_REG_PARAMRD)
end function

sub write8(reg as integer, myval as integer)
i2c write SI1145_ADDR,0,2,reg,myval
end sub

function read8(reg as integer) as integer
local integer i
i2c write SI1145_ADDR,1,1,reg
i2c read SI1145_ADDR,0,1,i
read8=i
end function

function read16(reg as integer) as integer
local integer i(1)
i2c write SI1145_ADDR,1,1,reg
i2c read SI1145_ADDR,0,2,i()
read16=i(0) OR (i(1)<<8)
end function
Edited by matherp 2016-05-14
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 11:47pm 12 May 2016
Copy link to clipboard 
Print this post

Thanks :)
Hopefully I'll be able to sort it out myself from now on
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025