[PYTHON] Verwenden Sie "TSL2561 Beleuchtungssensormodul Hersteller Teilenummer: TSL2561", hergestellt von Strawberry Linux mit Raspberry pi 3 (Versuch und Irrtum)

Es ist ein Kampfrekord für die Verwendung des "Beleuchtungsstärkemoduls TSL2561 (Hersteller-Teilenummer: TSL2561)", hergestellt von Strawberry Linux mit Rasberry pi 3. Es gibt einige Artikel über Sensoren, die den TSL2561-Chip verwenden, aber sie haben nicht funktioniert oder waren Python3. Also habe ich es mit python2 versucht.

Übrigens ... Ich bin seit einem halben Monat neu in Python und ich bin neu in der elektronischen Arbeit, daher habe ich wenig Wissen ... Ich hoffe, es wird hilfreich sein, wenn Sie dies berücksichtigen.

Derzeit ist die Zusammenfassung der zu verwendenden Teile hier.

Physikalische Verkabelung

Es ist notwendig, den Stiftkopf zu löten, um den gelieferten Sensor auf dem Steckbrett zu platzieren. Danach verdrahten Sie, während Sie das mitgelieferte Papier betrachten. Die GPIO-Pin-Konfiguration von Raspi ist nicht schwierig, da sie angezeigt wird, sobald Sie suchen.

Sensor 1 Pin (GND) -> Raspi 6. Pin Sensor 2pin (SDA) -> Raspi Pin 3 Sensor 3-polig (SCL) -> Raspi-5-polig Sensor 4-polig (VDD) -> Raspi-Stift 1

Es ist so. TSL2561.png

Aktivieren Sie I2C mit Raspberry pi

Ich bin mir nicht sicher, was I2C ist. Laut Wiki scheint es jedoch ein Standard zu sein, um verschiedene Geräte mit einer Kette wie scsi zu verbinden. Aktivieren Sie es auf jeden Fall für die Verwendung mit Raspbian.

Öffnen Sie das OS-Konfigurationsmenü über die SSH-Konsole und legen Sie fest.

$ sudo raspi-config

Wählen Sie das Menü in der Reihenfolge "9 erweiterte Optionen" -> "A7 I2C". Sie werden gefragt, ob die ARM I2C-Schnittstelle aktiviert werden soll. Wählen Sie also Ja. Sie werden gefragt, ob das I2C-Kernelmodul standardmäßig geladen werden soll. Wählen Sie also Ja.

Bearbeiten Sie dann /boot/config.txt wie folgt:

$ sudo vi /boot/config.txt
...Folgende Inhalte wurden hinzugefügt
dtparam=i2c_arm=on

Bearbeiten Sie außerdem / etc / modules wie folgt.

$ sudo vi /etc/modules
...Folgende Inhalte wurden hinzugefügt
snd-bcm2835
i2c-dev

Starten Sie Raspy nach Abschluss der Einstellungen neu. Stellen Sie sicher, dass das Kernelmodul nach dem Neustart mit dem Befehl lsmod geladen ist.

$ lsmod
...
i2c_dev                 6709  0 
snd_bcm2835            21342  0 
...

Installieren Sie Werkzeuge

Installieren Sie die Befehle, um I2C und die Python-Bibliothek (möglicherweise) zu verwenden.

$ sudo apt-get install i2c-tools python-smbus

Adressbestätigung

Wenn die Verkabelung abgeschlossen und die Werkzeuge installiert sind, überprüfen Sie mit dem Befehl, ob das Sensormodul erkannt wird.

$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Es scheint an der Adresse 0x39 erkannt zu werden.

... bisher war es in Ordnung.

Versuchen Sie es trotzdem

Als ich es mit Bezug auf diesen Artikel versuchte, schien es zunächst nicht mit hell und dunkel verbunden zu sein, obwohl der Wert herauskam. http://qiita.com/masato/items/1dd5bed82b19477b45d8

Als ich weiter nachforschte, kam ich zu diesem Artikel, aber es ist Python3. http://shimobayashi.hatenablog.com/entry/2015/07/27/001708

Hmmm, kann ich nicht mit dem Standard-Python2 darauf zugreifen?

Greifen Sie über Python auf I2C zu

Wenn Sie den obigen Artikel und die Quelle von git lesen, sollten Sie anscheinend die smbus-Bibliothek verwenden, um von Python aus auf I2C-Geräte zuzugreifen. Ich bin mir jedoch nicht sicher, wie ich es verwenden soll, daher werde ich es durch Ausprobieren versuchen.

Laut dem Anhang von Strawberry Linux

Schreiben Sie 0x03 in das interne Register 0xA0, um den Sensorbetrieb zu starten. Wenn 2 Bytes von der internen Adresse 0xAC gelesen werden, werden dies die Rohdaten der Helligkeit des Sensors für sichtbares Licht (16 Bit, das untere Byte steht an erster Stelle). Wenn 2 Bytes von der internen Adresse 0xAE gelesen werden, werden dies die Rohdaten des Infrarotsensors (16 Bit, das untere Byte steht an erster Stelle).

Es gibt. ... Hmm Nanno Kotcha.

Wie auch immer, Raspi scheint TSL2561 bei 0x39 zu erkennen, also habe ich mich gefragt, ob ich 0xA0, 0xAC, 0xAE von dort lesen oder schreiben soll, aber das Problem ist, wie es geht.

Als ich mit smbus verschieden gesucht habe, bin ich auf folgende Seite gestoßen. http://raspberrypi.stackexchange.com/questions/8469/meaning-of-cmd-param-in-write-i2c-block-data http://www.raspberry-projects.com/pi/programming-in-python/i2c-programming-in-python/using-the-i2c-interface-2

Ich kann nicht gut Englisch, also lese ich diagonal um die Beispielquelle herum und versuche, durch Intuition Fehler zu machen. Als Ergebnis verschiedener Versuche scheint es, dass Sie die angegebene interne Adresse lesen oder schreiben können, indem Sie die folgenden Schritte ausführen.

bus		= smbus.SMBus(1)
bus.write_i2c_block_data(0x39, 0xA0, [0x03])
bus.read_i2c_block_data(0x39, 0xAC ,2)

Der erste smbus.SMBus (1) erstellt möglicherweise ein Objekt für den Zugriff auf den Bus. '1' scheint mit der am Ende von "sudo i2cdetect -y 1" angegebenen 1 identisch zu sein und scheint das X der "i2c-X" -Datei unter / dev / anzugeben.

Verwenden Sie die Methode bus.read_i2c_block_data, um die Daten zu lesen.

bus.read_i2c_block_data (I2C-Adresse, interne Adresse, Anzahl der zu lesenden Datenbytes)

Verwenden Sie die Methode write_i2c_block_data, um Daten zu schreiben.

write_i2c_block_data (I2C-Adresse, interne Adresse, zu schreibendes Datenarray)

Als ich die Beispielquelle schrieb, kamen einige dieser Werte heraus. Wenn Sie Ihre Hand darüber halten, ändert sich der Wert als Antwort. Ich fühle mich wie ich gehen kann!

#!/usr/bin/python -u
# -*- coding: utf-8 -*-
import smbus
import time
bus	= smbus.SMBus(1)
bus.write_i2c_block_data(0x39, 0x80, [0x03])

while True:
	data 	= self.bus.read_i2c_block_data(self.address, 0xAC ,2)
	raw 	= data[1] << 8 | data[0]
	print "Umgebungslicht: " + str(raw)

	data 	= self.bus.read_i2c_block_data(self.address, 0xAE ,2)
	raw 	= data[1] << 8 | data[0]
	print "Infrarot: " + str(raw)

	time.sleep(1.0)

Lesen Sie das Datenblatt des Herstellers

Es scheint, dass Rohdaten erhalten werden können, also werde ich versuchen, die Beleuchtungsstärke (Lux) zu berechnen. Wieder laut Anhang von Strawberry Linux

Im Datenblatt des Herstellers finden Sie einen Algorithmus, der Rohdaten von sichtbaren Sensoren und Infrarotsensoren in Beleuchtungsstärke (Lux) umwandelt.

Es gibt. Wo ist der Hersteller! Aufgrund verschiedener Googles beim Nachdenken scheint die folgende URL das Datenblatt auf dem TAOS-Chip zu sein.

https://cdn-shop.adafruit.com/datasheets/TSL2561.pdf

Cool! !! (Erbrechen) Ist es ein englisches Dokument, kämpfen, kämpfen, ängstliches Herz ~ .... Ich schaffe es diagonal zu lesen, während ich mich frage, was ich mit GW mache. Dann gab es auf Seite 23 "Lux berechnen" und ich fand die Berechnungsformel, die ich in der Git-Quelle sah.

Versuchen Sie, 1 zu klassifizieren

Ich verstehe, ich verstehe den Fluss, also klassifizieren wir ihn.

#!/usr/bin/python -u
# -*- coding: utf-8 -*-

import smbus
import time

#Aus "TSL2561 Illumination Sensor Module" von Strawberry Linux
#Klasse zum Erfassen von Daten mit I2C (1)
# https://strawberry-linux.com/catalog/items?code=12561
# 2016-05-03 Boyaki Machine
class SL_TSL2561:
	def __init__(self, address, channel):
		self.address	= address
		self.channel	= channel
		self.bus		= smbus.SMBus(self.channel)
		self.bus.write_i2c_block_data(self.address, 0x80, [0x03])
		time.sleep(0.5)

	def getVisibleLightRawData(self):
		data 	= self.bus.read_i2c_block_data(self.address, 0xAC ,2)
		raw 	= data[1] << 8 | data[0]	#16bit mit niedrigerem Byte zuerst
		return raw

	def getInfraredRawData(self):
		data 	= self.bus.read_i2c_block_data(self.address, 0xAE ,2)
		raw 	= data[1] << 8 | data[0]	#16bit mit niedrigerem Byte zuerst
		return raw

	def getLux(self):
		#Erfassung von Sensorrohdaten
		VLRD = getVisibleLightRawData()
		IRRD = getInfraredRawData()

		#Teilen Sie nicht durch 0
		if (float(VLRD) == 0):
			ratio = 9999
		else:
			ratio = (IRRD / float(VLRD))

		#Lux Berechnung
		if ((ratio >= 0) & (ratio <= 0.52)):
			lux = (0.0315 * VLRD) - (0.0593 * VLRD * (ratio**1.4))
		elif (ratio <= 0.65):
			lux = (0.0229 * VLRD) - (0.0291 * IRRD)
		elif (ratio <= 0.80):
			lux = (0.0157 * VLRD) - (0.018 * IRRD)
		elif (ratio <= 1.3):
			lux = (0.00338 * VLRD) - (0.0026 * IRRD)
		elif (ratio > 1.3):
			lux = 0

		return lux 

if __name__ == "__main__":
	sensor 	= SL_TSL2561(0x39,1) 
	while True:
		print "Lux : " + str(sensor.getLux())
		time.sleep(1.0)

Es war sowieso ziemlich einfach, aber das Lesen der Git-Quelle macht es komplizierter und langwieriger. Was ist der Unterschied?

Versuchen Sie es durch Ausprobieren

Beim Lesen der Git-Quelle werden Gain und Scale vor der Berechnung der Beleuchtungsstärke angezeigt. Nachdem ich untersucht hatte, was zum Teufel war, fand ich die Beschreibung von "High Gain (16 ×)" in "Timing Register" auf Seite 15 des Datenblattes und las diesen Bereich sorgfältig durch.

Anscheinend hat dieser Sensor eine Spezifikation, die den Erfassungsbereich durch die Kombination von "Verstärkung" und "Integrationszeit" erweitert. Bedeutet dies, dass die Empfindlichkeit bei Einstellung auf Höhenverstärkung 16-mal höher ist? Wenn die Integrationszeit von 402 ms auf 101 ms und 13,7 ms geändert wird, wird die Integrationszeit des Erfassungswerts verkürzt und die Empfindlichkeit verringert (= der Ausgabewert nimmt ab). Fühlt es sich an, als würde die Belichtungszeit verkürzt?

Ändern Sie basierend auf diesen Informationen die Verstärkungs- und Integrationszeit auf verschiedene Arten, um die Ausgabe von Rohdaten anzuzeigen. Zunächst wurde festgestellt, dass bei Einstellung auf High Gain ein Wert von etwa dem 16-fachen erhalten wurde. Es wurde auch gefunden, dass, wenn die Integrationszeit auf 101 ms und 13,7 ms eingestellt wurde, die Werte von 101/402 und 13,7 / 402 erhalten wurden.

Beispielsweise wird in Hinata im Mai im Standardzustand (Verstärkung 1, Integrationszeit 402 ms) die Ausgabe von sichtbarem Licht 65535 (Maximalwert 16 Bit) und der korrekte Wert kann nicht erhalten werden. In einem solchen Fall scheint es die Spezifikation zu sein, die Integrationszeit kurz zu setzen und einen gültigen Wert zu erhalten.

Zum Zeitpunkt von High Gain gab es jedoch bei einer bestimmten Lichtmenge (in der Nähe des Fensters während des Tages) das Problem, dass die Rohdaten sowohl für sichtbares Licht als auch für Infrarotlicht auf 5047 festgelegt wurden, was nicht gelöst werden konnte. Es funktioniert gut bei schlechten Lichtverhältnissen.

Wie auch immer, es scheint, dass Sie die Rohdaten skalieren müssen, bevor Sie die Beleuchtungsstärkeberechnung durchführen, da sich die Ausgabe je nach Einstellung ändert. Was ich hier nicht wirklich verstanden habe, war, auf welcher Einstellung die Berechnungsformel des Datenblattes basiert. Betrachtet man die Git-Quelle, so werden die Rohdaten bei Low Gain mit 16 multipliziert. Schreiben Sie einen Beispielcode, um die tatsächlichen Messdaten abzurufen und mit der folgenden Site zu vergleichen.

http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12117474762

Infolgedessen kam ich zu dem Schluss, dass High Gain die Basis sein könnte. Ich frage mich, ob es irgendwo im Datenblatt steht. .. ..

Versuchen Sie, 2 zu klassifizieren

Erstellen Sie die Klasse basierend auf Versuch und Irrtum neu. Wir haben eine Methode vorbereitet, mit der Sie die Verstärkungs- und Integrationszeit ändern können.

#!/usr/bin/python -u
# -*- coding: utf-8 -*-

import smbus
import time

#Aus "TSL2561 Illumination Sensor Module" von Strawberry Linux
#Klasse zum Abrufen von Daten in I2C
# https://strawberry-linux.com/catalog/items?code=12561
# 2016-05-03 Boyaki Machine
class SL_TSL2561:
	def __init__(self, address, channel):
		self.address	= address
		self.channel	= channel
		self.bus		= smbus.SMBus(self.channel)
		self.gain 		= 0x00			# 0x00=normal, 0x10=×16
		self.integrationTime 	= 0x02	# 0x02=402ms, 0x01=101ms, 0x00=13.7ms
		self.scale 		= 1.0

		#Initialisierung der Sensoreinstellungen
		self.setLowGain()
		self.setIntegrationTime('default')

	def powerOn(self):
		self.bus.write_i2c_block_data(self.address, 0x80, [0x03])
		time.sleep(0.5)

	def powerOff(self):
		self.bus.write_i2c_block_data(self.address, 0x80, [0x00])

	#Auf High Gain einstellen(16 mal empfindlicher?)
	def setHighGain(self):
		#Bei Einstellung auf High Gain werden Rohdaten möglicherweise nicht richtig abgerufen.
		#Untersuchung der Ursache erforderlich(5047 Festwert)	
		self.gain 	= 0x10
		data 		= self.integrationTime | self.gain
		self.bus.write_i2c_block_data(self.address, 0x81, [data])
		self.calcScale()

	# Low Gain(default)Einstellen
	def setLowGain(self):
		self.gain 	= 0x00
		data 		= self.integrationTime | self.gain
		self.bus.write_i2c_block_data(self.address, 0x81, [data])
		self.calcScale()

	#Einstellen der Integrationszeit (Zeit für eine Erfassung?)
	# val = shor, middle, logn(default)
	def setIntegrationTime(self, val):
		if val=='short':
			self.integrationTime 	= 0x00	# 13.7ms scale=0.034
		elif val=='middle':
			self.integrationTime 	= 0x01 	# 101ms	 scale=0.252
		else:
			self.integrationTime 	= 0x02  # defaultVal 402ms  scale=1.0
		data = self.integrationTime | self.gain
		self.bus.write_i2c_block_data(self.address, 0x81, [data])
		self.calcScale()

	def getVisibleLightRawData(self):
		data 	= self.bus.read_i2c_block_data(self.address, 0xAC ,2)
		raw 	= data[1] << 8 | data[0]	#16bit mit niedrigerem Byte zuerst
		return raw

	def getInfraredRawData(self):
		data 	= self.bus.read_i2c_block_data(self.address, 0xAE ,2)
		raw 	= data[1] << 8 | data[0]	#16bit mit niedrigerem Byte zuerst
		return raw

	def getRawData(self):
		data 	= self.bus.read_i2c_block_data(self.address, 0xAC ,4)
		VL 		= data[1] << 8 | data[0]	#Sichtbares Licht 16 Bit, unteres Byte zuerst
		IR 		= data[3] << 8 | data[2]	#Infrarot 16bit, unteres Byte zuerst
		return (VL,IR)

	def calcScale(self):
		_scale = 1.0
		#Skalieren Sie nach IntegrationTime
		if self.integrationTime == 0x01:	# middle
			_scale = _scale / 0.252
		elif self.integrationTime == 0x00:	# short
			_scale = _scale / 0.034
		
		#Skalieren Sie nach Gewinn
		if self.gain == 0x00 :				# gain 1
			_scale = _scale * 16.0

		self.scale = _scale

	def getLux(self):
		#Erfassung von Sensorrohdaten
		raw  = self.getRawData()

		#Implementierung zur Ausgabe eines Fehlers bei 65535
		if raw[0] == 65535 or raw[1] == 65535:
			return "Range Over"

		#Skalieren Sie Rohdaten mit Sensoreinstellungen
		VLRD = raw[0] * self.scale
		IRRD = raw[1] * self.scale

		#Teilen Sie nicht durch 0
		if (float(VLRD) == 0):
			ratio = 9999
		else:
			ratio = (IRRD / float(VLRD))

		#Lux Berechnung
		if ((ratio >= 0) & (ratio <= 0.52)):
			lux = (0.0315 * VLRD) - (0.0593 * VLRD * (ratio**1.4))
		elif (ratio <= 0.65):
			lux = (0.0229 * VLRD) - (0.0291 * IRRD)
		elif (ratio <= 0.80):
			lux = (0.0157 * VLRD) - (0.018 * IRRD)
		elif (ratio <= 1.3):
			lux = (0.00338 * VLRD) - (0.0026 * IRRD)
		elif (ratio > 1.3):
			lux = 0

		return lux 


if __name__ == "__main__":
	sensor 	= SL_TSL2561(0x39,1) 
	sensor.powerOn()
	# sensor.setHighGain()
	sensor.setIntegrationTime('default')
	while True:
		print "Lux : " + str(sensor.getLux())
		time.sleep(1.0)

Am Ende

Mit der obigen Klasse können Sie einen solchen Wert erhalten. Das Problem des High Gain wurde jedoch nicht gelöst. Ich kann nicht bestätigen, ob die Implementierung überhaupt korrekt ist ...

Betrachtet man die Beispielquelle des Datenblattes, so ist es beim Zugriff auf die interne Adresse (Ist es ein Register?) 0xAX oder 0x8X. In Bezug auf die Spezifikationen von "Register Set" werden nur 0h bis Fh geschrieben. Wenn Sie anhand der Quelle erraten, ob es sich um 0xA oder 0x8 handelt, geben Sie meiner Meinung nach den Typ des zu erfassenden Werts an, aber ich kenne die Wahrheit nicht. Unabhängig davon, welche Adresse Sie angeben, wird derselbe Wert erhalten, daher vermute ich, dass Python ihn in eine gute konvertiert. Bitte lassen Sie mich wissen, wenn jemand weiß.

Ich denke, dass Sie einen weiten Bereich nahtlos messen können, indem Sie den Wert der Rohdaten entsprechend überprüfen und die Einstellungen für Verstärkung und Integrationszeit ändern, wenn der Grenzwert erreicht wird.

Wenn es hilfreich ist, bin ich glücklich.

Recommended Posts

Verwenden Sie "TSL2561 Beleuchtungssensormodul Hersteller Teilenummer: TSL2561", hergestellt von Strawberry Linux mit Raspberry pi 3 (Versuch und Irrtum)
Verwenden Sie "TSL2561 Beleuchtungssensormodul (Hersteller-Teilenummer: TSL2561)", hergestellt von Strawberry Linux mit Rasberry pi 3 (Zusammenfassung)
Verwenden Sie das 9-Achsen-Sensormodul "MPU-9250 (Hersteller-Teilenummer: MPU-9250)" von Strawberry Linux mit Rasberry pi 3.
Ein Memo zur einfachen Verwendung des Beleuchtungsstärkesensors TSL2561 mit Raspberry Pi 2
Verwenden Sie den Grove-Sensor mit Raspberry Pi
Grove - Temperatur- und Feuchtigkeitssensor (DHT11) mit Raspberry Pi
Verwendung des digitalen Beleuchtungsstärkesensors TSL2561 mit Raspberry Pi
Ubuntu 20.04 auf Himbeer-Pi 4 mit OpenCV und mit Python verwenden
Verwenden Sie NeoPixel mit Himbeerkuchen