Hatte zwischen den Jahren etwas Zeit und habe mich mit diesem Sensor befasst. Diesen gibt es auch schon fertig als Breakoutboard, so dass die fummelige SMD-Lötarbeit entfällt. Für das Arduino-System ist schon alles einsatzbereit programmiert, für BASCOM habe ich jedoch nichts gefunden. Die Funktionen des Sensors sind sehr gut mit Programmbeispielen dokumentiert, so dass die Umsetzung für BASCOM nicht allzu schwierig erschien. Als neue Funktion habe ich eine automatische Anpassung der Empfindlichkeit eingebaut. Vielleicht findet es ja der ein oder andere nützlich:
Code:
'##TSL2561 Luminosity Sensor##
' >3.3V VCC
' >GND
' >SCL > PC0
' >SDA > PC1
$regfile = "m328pdef.dat"
$crystal = 16000000
$baud = 115200
$lib "i2c_twi.lbx" '
Config Sda = Portc.1
Config Scl = Portc.0
Config Twi = 400000
Dim C0low As Byte
Dim C0high As Byte
Dim C0 As Word
Dim C1low As Byte
Dim C1high As Byte
Dim C1 As Word
Dim Integrationtime As Byte
Dim Gain As Byte
Dim Gainintegrationtime As Byte
Dim Chscale As Dword
Dim Ratio1 As Dword
Dim Ratio As Dword
Dim Temp As Dword
Dim Temp1 As Dword
Dim Temp2 As Dword
Dim B As Word
Dim M As Word
Dim I As Byte
Dim Channel0 As Dword
Dim Channel1 As Dword
Dim Lux As Word
Const Tsl2561_integrationtime_13ms = &H00 'Integrationszeit 13.7ms
Const Tsl2561_integrationtime_101ms = &H01 'Integrationszeit 101ms
Const Tsl2561_integrationtime_402ms = &H02 'Integrationszeit 402ms
Const Tsl2561_gain_0x = &H00 'No Gain
Const Tsl2561_gain_16x = &H10 '16x Gain (16fache Empfindlichkeit)
Const Lux_scale = 14 'Scale By 2 ^ 14
Const Ratio_scale = 9 'Scale Ratio By 2 ^ 9
Const Ch_scale = 10 'Scale Channel Values By 2 ^ 10
Const Chscale_tint0 = &H7517 '322 / 11 * 2 ^ Ch_scale
Const Chscale_tint1 = &H0FE7 '322 / 81 * 2 ^ Ch_scale
'Werte fuer T-package
Const K1t = &H0040 ' 0.125 * 2^RATIO_SCALE
Const B1t = &H01F2 ' 0.0304 * 2^LUX_SCALE
Const M1t = &H01BE ' 0.0272 * 2^LUX_SCALE
Const K2t = &H0080 ' 0.250 * 2^RATIO_SCALE
Const B2t = &H0214 ' 0.0325 * 2^LUX_SCALE
Const M2t = &H02D1 ' 0.0440 * 2^LUX_SCALE
Const K3t = &H00C0 ' 0.375 * 2^RATIO_SCALE
Const B3t = &H023F ' 0.0351 * 2^LUX_SCALE
Const M3t = &H037B ' 0.0544 * 2^LUX_SCALE
Const K4t = &H0100 ' 0.50 * 2^RATIO_SCALE
Const B4t = &H0270 ' 0.0381 * 2^LUX_SCALE
Const M4t = &H03FE ' 0.0624 * 2^LUX_SCALE
Const K5t = &H0138 ' 0.61 * 2^RATIO_SCALE
Const B5t = &H016F ' 0.0224 * 2^LUX_SCALE
Const M5t = &H01FC ' 0.0310 * 2^LUX_SCALE
Const K6t = &H019A ' 0.80 * 2^RATIO_SCALE
Const B6t = &H00D2 ' 0.0128 * 2^LUX_SCALE
Const M6t = &H00FB ' 0.0153 * 2^LUX_SCALE
Const K7t = &H029A ' 1.3 * 2^RATIO_SCALE
Const B7t = &H0018 ' 0.00146 * 2^LUX_SCALE
Const M7t = &H0012 ' 0.00112 * 2^LUX_SCALE
Const K8t = &H029A ' 1.3 * 2^RATIO_SCALE
Const B8t = &H0000 ' 0.000 * 2^LUX_SCALE
Const M8t = &H0000 ' 0.000 * 2^LUX_SCALE
Declare Sub Enable_tsl2561 'TSL2561 AN
Declare Sub Disable_tsl2561 'TSL2561 AUS
Declare Sub Setgainintegration_tsl2561(byval Gain As Byte , Byval Integrationtime As Byte) 'Integrationszeit und Empfindlichkeit (Gain) setzen
Declare Sub Getchanelvalues 'ADC Werte auslesen
Declare Function Calclux(integrationtime As Byte , Gain As Byte , C0 As Word , C1 As Word) As Word 'Lux berechnen
Declare Sub Autogain(byval Integrationtime As Byte , Byval C0 As Word , Byval C1 As Word) 'Automatische Anpassung der Empfindlichkeit (Gain)
Integrationtime = Tsl2561_integrationtime_402ms 'Startwert Integrationszeit
Gain = Tsl2561_gain_16x 'Startwert Empfindlichkeit (Gain)
'##################################### Programmschleife
Do
Call Enable_tsl2561 'Enable
Call Setgainintegration_tsl2561(integrationtime , Gain) 'Integrationszeit und Empfindlichkeit (Gain) setzen
Call Getchanelvalues 'ADC Werte auslesen
Call Autogain(integrationtime , C0 , C1) 'Automatische Anpassung der Empfindlichkeit (Gain); falls zu hoch, wird Gain=0 gestetzt
Call Enable_tsl2561 'Nochmal alles, um LUX mit ggf. geaendertem Gain zu berechnen
Call Setgainintegration_tsl2561(integrationtime , Gain)
Call Getchanelvalues
Lux = Calclux(integrationtime , Gain , C0 , C1)
Print "Lux: " ; Lux ; " " ; "Gain: " ; Gain ; " " ; "C0 " ; C0 ; " C1 " ; C1 ; " " 'Ausgabe der Werte
Wait 1
Loop
End
'#####################################
Sub Enable_tsl2561
I2cstart
I2cwbyte &H72
I2cwbyte &H80
I2cwbyte &H03 'Enable
I2cstop
End Sub
'#####################################
Sub Disable_tsl2561
I2cstart
I2cwbyte &H72
I2cwbyte &H80
I2cwbyte &H00 'Disable
I2cstop
End Sub
'#####################################
Sub Setgainintegration_tsl2561(integrationtime As Byte , Gain As Byte)
Gainintegrationtime = Gain + Integrationtime
I2cstart
I2cwbyte &H72
I2cwbyte &H81
I2cwbyte Gainintegrationtime
I2cstop
End Sub
'#####################################
Sub Getchanelvalues
Select Case Integrationtime
Case Tsl2561_integrationtime_13ms:
Waitms 14
Case Tsl2561_integrationtime_101ms:
Waitms 102
Case Tsl2561_integrationtime_402ms:
Waitms 403
End Select
I2cstart
I2cwbyte &H72
I2cwbyte &HAC
I2cstop
I2cstart
I2cwbyte &H73
I2crbyte C0low , Ack
I2crbyte C0high , Nack
I2cstop
I2cstart
I2cwbyte &H72
I2cwbyte &HAE
I2cstop
I2cstart
I2cwbyte &H73
I2crbyte C1low , Ack
I2crbyte C1high , Nack
I2cstop
C0 = Makeint(c0low , C0high)
C1 = Makeint(c1low , C1high)
'Waitus 350
'C0 = C0high * 256
'C0 = C0 + C0low
'C1 = C1high * 256
'C1 = C1 + C1low
End Sub
'#####################################
Function Calclux(integrationtime As Byte , Gain As Byte , C0 As Word , C1 As Word) As Word 'Berechnung gem. Datenblatt
Select Case Integrationtime
Case Tsl2561_integrationtime_13ms:
Chscale = Chscale_tint0
Case Tsl2561_integrationtime_101ms:
Chscale = Chscale_tint1
Case Tsl2561_integrationtime_402ms:
Chscale = &H400
End Select
If Gain = Tsl2561_gain_0x Then Shift Chscale , Left , 4
Channel0 = C0 * Chscale
Shift Channel0 , Right , Ch_scale
Channel1 = C1 * Chscale
Shift Channel1 , Right , Ch_scale
If Channel0 > 0 Then
Shift Channel1 , Left , 10
Ratio1 = Channel1 / Channel0
End If
Ratio = Ratio1 + 1
Shift Ratio , Right , 1
If Ratio >= 0 And Ratio <= K1t Then
B = B1t : M = M1t
Elseif Ratio <= K2t Then
B = B2t : M = M2t
Elseif Ratio <= K3t Then
B = B3t : M = M3t
Elseif Ratio <= K4t Then
B = B4t : M = M4t
Elseif Ratio <= K5t Then
B = B5t : M = M5t
Elseif Ratio <= K6t Then
B = B6t : M = M6t
Elseif Ratio <= K7t Then
B = B7t : M = M7t
Elseif Ratio > K8t Then
B = B8t : M = M8t
End If
'Print "B " ; Hex(b) ; " M " ; Hex(m) ; " ";
Shift Channel1 , Right , 10
Temp = Channel0 * B
Temp1 = Channel1 * M
Temp2 = Temp - Temp1
If Temp2 < 0 Then Temp2 = 0
Temp2 = Temp2 + &H2000
Shift Temp2 , Right , Lux_scale
Calclux = Temp2
End Function
'#####################################
Sub Autogain(integrationtime As Byte , Gain As Byte , C0 As Word , C1 As Word)
Select Case Integrationtime
Case Tsl2561_integrationtime_13ms:
If C0 = 5047 Then 'siehe Datenblatt (Full scale ADC count value)
Gain = Tsl2561_gain_0x
Elseif C0 < 500 Then
Gain = Tsl2561_gain_16x
End If
Case Tsl2561_integrationtime_101ms:
If C0 = 37177 Then 'siehe Datenblatt (Full scale ADC count value)
Gain = Tsl2561_gain_0x
Elseif C0 < 500 Then
Gain = Tsl2561_gain_16x
End If
Case Tsl2561_integrationtime_402ms:
If C0 = 65535 Then 'siehe Datenblatt (Full scale ADC count value)
Gain = Tsl2561_gain_0x
Elseif C0 < 500 Then
Gain = Tsl2561_gain_16x
End If
End Select
End Sub
'#####################################