1+ # FILE: LTR507.py
2+ # AUTHOR: Josip Šimun Kuči @ Soldered
3+ # BRIEF: A Micropython module for the LTR-507 Light and proximity sensor
4+ # LAST UPDATED: 2025-06-10
5+
6+ from machine import I2C , Pin
7+ from os import uname
8+ from time import sleep_ms
9+ from ltr507_config import *
10+
11+ class LTR507 :
12+ def __init__ (self , i2c = None , address = 0x3A ):
13+ """
14+ Initialize the LTR507 sensor.
15+
16+ :param i2c: Initialized I2C object
17+ :param address: I2C address of the sensor (default 0x3A)
18+ """
19+ if i2c != None :
20+ self .i2c = i2c
21+ else :
22+ if uname ().sysname == "esp32" or uname ().sysname == "esp8266" :
23+ self .i2c = I2C (0 , scl = Pin (22 ), sda = Pin (21 ))
24+ else :
25+ raise Exception ("Board not recognized, enter I2C pins manually" )
26+ self .address = address
27+ self .raw = bytearray (2 ) # Buffer for reading multi-byte registers
28+
29+ def _read_register (self , reg , length = 1 ):
30+ """
31+ Read bytes from a sensor register.
32+
33+ :param reg: Register address to read from
34+ :param length: Number of bytes to read (default 1)
35+ :return: Bytes read from the register
36+ """
37+ return self .i2c .readfrom_mem (self .address , reg , length )
38+
39+ def _write_register (self , reg , data ):
40+ """
41+ Write a single byte to a sensor register.
42+
43+ :param reg: Register address to write to
44+ :param data: Byte value to write
45+ """
46+ self .i2c .writeto_mem (self .address , reg , bytes ([data ]))
47+
48+ def _write_registers (self , reg , values ):
49+ """
50+ Write multiple bytes to consecutive sensor registers.
51+
52+ :param reg: Starting register address
53+ :param values: Iterable of byte values to write
54+ """
55+ self .i2c .writeto_mem (self .address , reg , bytes (values ))
56+
57+ def begin (self ):
58+ """
59+ Initialize the sensor with default configuration settings.
60+ Enables ALS and PS modes and sets recommended measurement parameters.
61+ """
62+ self .set_als_mode (True )
63+ self .set_ps_mode (True )
64+ self .set_als_gain (LTR507_ALS_GAIN_RANGE1 )
65+ self .set_als_bitwidth (LTR507_ALS_ADC_BIT_WIDTH_16BIT )
66+ self .set_als_meas_rate (LTR507_ALS_MEASUREMENT_RATE_100MS )
67+ self .set_led_pulse_freq (LTR507_LED_PULSE_FREQ_60KHZ )
68+ self .set_led_duty_cycle (LTR507_LED_CURRENT_DUTY_DEFAULT )
69+ self .set_ps_meas_rate (LTR507_PS_MEASUREMENT_RATE_100MS )
70+ self .set_led_peak_current (LTR507_LED_PEAK_CURRENT_50MA )
71+ self .set_ps_num_pulses (1 )
72+
73+ def set_ps_mode (self , mode ):
74+ """
75+ Enable or disable proximity sensing mode.
76+
77+ :param mode: Boolean indicating whether to enable (True) or disable (False) PS mode
78+ """
79+ val = self ._read_register (LTR507_PS_CONTR_REG )[0 ]
80+ val &= ~ LTR507_PS_MODE_MASK
81+ val |= (mode << LTR507_PS_MODE_SHIFT ) & LTR507_PS_MODE_MASK
82+ self ._write_register (LTR507_PS_CONTR_REG , val )
83+
84+ def set_als_mode (self , mode ):
85+ """
86+ Enable or disable ambient light sensing mode.
87+
88+ :param mode: Boolean indicating whether to enable (True) or disable (False) ALS mode
89+ """
90+ val = self ._read_register (LTR507_ALS_CONTR_REG )[0 ]
91+ if mode :
92+ val |= 0x02 # Set bit 1
93+ else :
94+ val &= 0xFD # Clear bit 1
95+ self ._write_register (LTR507_ALS_CONTR_REG , val )
96+
97+ def set_led_pulse_freq (self , freq ):
98+ """
99+ Set the LED pulse frequency for proximity sensing.
100+
101+ :param freq: Frequency constant (e.g., LTR507_LED_PULSE_FREQ_60KHZ)
102+ """
103+ val = self ._read_register (LTR507_PS_LED_REG )[0 ]
104+ val &= ~ LTR507_LED_PULSE_FREQ_MASK
105+ val |= (freq << LTR507_LED_PULSE_FREQ_SHIFT ) & LTR507_LED_PULSE_FREQ_MASK
106+ self ._write_register (LTR507_PS_LED_REG , val )
107+
108+ def set_led_duty_cycle (self , duty ):
109+ """
110+ Set the duty cycle of the proximity LED.
111+
112+ :param duty: Duty cycle constant (e.g., LTR507_LED_CURRENT_DUTY_DEFAULT)
113+ """
114+ val = self ._read_register (LTR507_PS_LED_REG )[0 ]
115+ val &= ~ LTR507_LED_DUTY_CYCLE_MASK
116+ val |= (duty << LTR507_LED_DUTY_CYCLE_SHIFT ) & LTR507_LED_DUTY_CYCLE_MASK
117+ self ._write_register (LTR507_PS_LED_REG , val )
118+
119+ def set_ps_meas_rate (self , rate ):
120+ """
121+ Set the measurement rate for proximity sensing.
122+
123+ :param rate: Measurement rate constant (e.g., LTR507_PS_MEASUREMENT_RATE_100MS)
124+ """
125+ val = rate & LTR507_PS_MEAS_RATE_MASK
126+ self ._write_register (LTR507_PS_MEAS_RATE_REG , val )
127+
128+ def set_led_peak_current (self , current ):
129+ """
130+ Set the peak drive current of the proximity LED.
131+
132+ :param current: Current constant (e.g., LTR507_LED_PEAK_CURRENT_50MA)
133+ """
134+ val = self ._read_register (LTR507_PS_LED_REG )[0 ]
135+ val &= ~ LTR507_LED_PEAK_CURRENT_MASK
136+ val |= current & LTR507_LED_PEAK_CURRENT_MASK
137+ self ._write_register (LTR507_PS_LED_REG , val )
138+
139+ def set_ps_num_pulses (self , num_pulses ):
140+ """
141+ Set the number of LED pulses for each proximity measurement.
142+
143+ :param num_pulses: Integer value between 1 and 15
144+ """
145+ num_pulses = max (1 , min (15 , num_pulses ))
146+ val = num_pulses & LTR507_PS_PULSES_MASK
147+ self ._write_register (LTR507_PS_N_PULSES_REG , val )
148+
149+ def set_als_gain (self , gain ):
150+ """
151+ Set the analog gain for ambient light sensing.
152+
153+ :param gain: Gain constant (e.g., LTR507_ALS_GAIN_RANGE1)
154+ """
155+ val = self ._read_register (LTR507_ALS_CONTR_REG )[0 ]
156+ val &= ~ LTR507_ALS_GAIN_MASK
157+ val |= (gain << LTR507_ALS_GAIN_SHIFT ) & LTR507_ALS_GAIN_MASK
158+ self ._write_register (LTR507_ALS_CONTR_REG , val )
159+
160+ def set_als_bitwidth (self , bitwidth ):
161+ """
162+ Set the ADC resolution (bit width) for ambient light measurements.
163+
164+ :param bitwidth: Bit width constant (e.g., LTR507_ALS_ADC_BIT_WIDTH_16BIT)
165+ """
166+ val = self ._read_register (LTR507_ALS_MEAS_PATE_REG )[0 ]
167+ val &= ~ LTR507_ALS_ADC_BIT_WIDTH_MASK
168+ val |= (bitwidth << LTR507_ALS_ADC_BIT_WIDTH_SHIFT ) & LTR507_ALS_ADC_BIT_WIDTH_MASK
169+ self ._write_register (LTR507_ALS_MEAS_PATE_REG , val )
170+
171+ def set_als_meas_rate (self , rate ):
172+ """
173+ Set the ambient light sensor measurement rate.
174+
175+ :param rate: Measurement rate constant (e.g., LTR507_ALS_MEASUREMENT_RATE_100MS)
176+ """
177+ val = self ._read_register (LTR507_ALS_MEAS_PATE_REG )[0 ]
178+ val &= ~ LTR507_ALS_MEASURE_RATE_MASK
179+ val |= (rate << LTR507_ALS_MEASURE_RATE_SHIFT ) & LTR507_ALS_MEASURE_RATE_MASK
180+ self ._write_register (LTR507_ALS_MEAS_PATE_REG , val )
181+
182+ def getLightIntensity (self ):
183+ """
184+ Read and return the current ambient light level.
185+
186+ :return: 16-bit integer light value (0 if data not ready)
187+ """
188+ status = self ._read_register (LTR507_ALS_PS_STATUS_REG )[0 ]
189+ if not (status & 0x04 ): # Check if ALS data is valid
190+ return 0
191+ data = self ._read_register (LTR507_ALS_DATA_0_REG , 2 )
192+ return data [0 ] | (data [1 ] << 8 ) # Combine low and high bytes
193+
194+ def getProximity (self ):
195+ """
196+ Read and return the current proximity sensor value.
197+
198+ :return: 16-bit integer proximity value
199+ """
200+ data = self ._read_register (LTR507_PS_DATA_LOW_REG , 2 )
201+ low = data [0 ] & LTR507_PS_DATA_LOW_MASK
202+ high = data [1 ] & LTR507_PS_DATA_HIGH_MASK
203+ return low | (high << 8 ) # Combine low and high bytes
0 commit comments