' *****************************************************************************
' VEML7700 - 16-bit ambient light sensor (ALS), I2C interface
'
' I2C address:
'   7-bit address : 0x10
'   Write address : 0x20 = (0x10 << 1) + 0
'   Read address  : 0x21 = (0x10 << 1) + 1
'
' The VEML7700 uses 16-bit registers. Register data is transferred
' low byte first, followed by the high byte.
'
' Basic configuration used here:
'   ALS_CONF = 0x0000
'   - ALS enabled (shutdown disabled)
'   - Gain = x1
'   - Integration time = 100 ms
'   - Interrupt disabled
'
' With gain x1 and an integration time of 100 ms, the nominal
' resolution is 0.0576 lux/count.
'
'   Lux = ALS_Counts * 0.0576
'
' Integer arithmetic is used to avoid floating-point calculations:
'
'   Lux = ALS_Counts * 576 / 10000
'
' Note:
'   This simple conversion is suitable for basic measurements.
'   More accurate measurements can include the VEML7700 high-lux
'   compensation recommended by the manufacturer.
' *****************************************************************************

' *****************************************************************************
' By COS (dogflu66@yahoo.es)
' With AI assistance: ChatGPT
' Pic18 Basic Oshonsoft v9.11
' Version: 2026/04/03
' *****************************************************************************
' The _I2C.bas library is required.
' *****************************************************************************

Const VEML7700_W = 0x20
Const VEML7700_R = 0x21


' -----------------------------------------------------------------------------
' Initialize the VEML7700.
'
' ALS_CONF register (0x00) = 0x0000
' Data is written low byte first, followed by the high byte.
' -----------------------------------------------------------------------------
Proc VEML7700_Init()

	START_I2C()

	WRITE_I2C(VEML7700_W)	' VEML7700 write address.
	WRITE_I2C(0x00)			' Select ALS_CONF register.
	WRITE_I2C(0x00)			' ALS_CONF low byte.
	WRITE_I2C(0x00)			' ALS_CONF high byte.

	STOP_I2C()

End Proc


' -----------------------------------------------------------------------------
' Read the ambient light level.
'
' ALS register (0x04) contains the 16-bit ambient light measurement.
' The VEML7700 returns the low byte first and the high byte second.
'
' For the configuration used above:
'
'   Resolution = 0.0576 lux/count
'
' The result is returned as an integer value in lux.
' -----------------------------------------------------------------------------
Function VEML7700_Read_Lux() As Word

	Dim low_byte As Byte
	Dim high_byte As Byte
	Dim als_count As Word
	Dim lux As Word

	' Select the ALS data register (0x04).
	START_I2C()
	WRITE_I2C(VEML7700_W)
	WRITE_I2C(0x04)

	' Repeated START switches the bus from write to read mode.
	ReStart_I2C()
	WRITE_I2C(VEML7700_R)

	' Read the 16-bit ALS value, low byte first.
	low_byte = READ_I2C(ACK)	' ACK: another byte will be read.
	high_byte = READ_I2C(NACK)	' NACK: this is the last byte.

	STOP_I2C()

	' Combine both bytes into a 16-bit value.
	als_count = high_byte * 256 + low_byte

	' Convert ALS counts to lux using integer arithmetic.
	' Equivalent to: lux = als_count * 0.0576
	lux = CLong als_count * 576 / 10000

	ReturnValue lux

End Function
