• Benvenuti su RaspberryItaly!
Benvenuto ospite! Login Login con Facebook Registrati Login with Facebook


Valutazione discussione:
  • 0 voto(i) - 0 media
  • 1
  • 2
  • 3
  • 4
  • 5

[-]
Tags
tsl2561 il luminosità di sensore usare

[Risolto] usare il sensore di luminosità TSL2561
#1
salve,

Sto cercando di utilizzare il sensore in oggetto. Su web si trovano vari listati in Python per usarlo su Raspberry

https://github.com/seanbechhofer/raspber...TSL2561.py



ma tutti quelli che ho trovato implicano l'importazione di una libreria che non si trova più su web


https://github.com/adafruit/Adafruit-Ras...uit_I2C.py

Pertanto non so come risolvere.

Qualche idea?

Grazie per l'attenzione.

Saluti

LaPa
With a little/big help from my friends Rolleyes
Risposta
#2
Ciao
googlando ho trovato questo, spero possa esserti d'aiuto.

Codice:
#!/usr/bin/python

import smbus

# ===========================================================================
# Adafruit_I2C Class
# Adafruit_I2C.py is essentially a fork of the Adafruit Raspberry Pi I2C module.
# Any pull requests for this module should be directed to the following, and I
# can pull them. I'd rather not deviate from the original:
# https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/tree/master/Adafruit_I2C
# ===========================================================================

class Adafruit_I2C :

 def __init__(self, address, busnum=-1, debug=False):
   self.address = address
   self.bus = smbus.SMBus(busnum if busnum >= 0 else 1)
   self.debug = debug

 def reverseByteOrder(self, data):
   "Reverses the byte order of an int (16-bit) or long (32-bit) value"
   # Courtesy Vishal Sapre
   byteCount = len(hex(data)[2:].replace('L','')[::2])
   val       = 0
   for i in range(byteCount):
     val    = (val << 8) | (data & 0xff)
     data >>= 8
   return val

 def errMsg(self):
   print("Error accessing 0x%02X: Check your I2C address" % self.address)
   return -1

 def write8(self, reg, value):
   "Writes an 8-bit value to the specified register/address"
   try:
     self.bus.write_byte_data(self.address, reg, value)
     if self.debug:
       print("I2C: Wrote 0x%02X to register 0x%02X" % (value, reg))
   except IOError as err:
     return self.errMsg()

 def write16(self, reg, value):
   "Writes a 16-bit value to the specified register/address pair"
   try:
     self.bus.write_word_data(self.address, reg, value)
     if self.debug:
       print("I2C: Wrote 0x%02X to register pair 0x%02X,0x%02X" %
        (value, reg, reg+1))
   except IOError as err:
     return self.errMsg()

 def writeList(self, reg, list):
   "Writes an array of bytes using I2C format"
   try:
     if self.debug:
       print("I2C: Writing list to register 0x%02X:" % reg)
       print(list)
     self.bus.write_i2c_block_data(self.address, reg, list)
   except IOError as err:
     return self.errMsg()

 def readList(self, reg, length):
   "Read a list of bytes from the I2C device"
   try:
     results = self.bus.read_i2c_block_data(self.address, reg, length)
     if self.debug:
       print("I2C: Device 0x%02X returned the following from reg 0x%02X" %
        (self.address, reg))
       print(results)
     return results
   except IOError as err:
     return self.errMsg()

 def readU8(self, reg):
   "Read an unsigned byte from the I2C device"
   try:
     result = self.bus.read_byte_data(self.address, reg)
     if self.debug:
       print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
        (self.address, result & 0xFF, reg))
     return result
   except IOError as err:
     return self.errMsg()

 def readS8(self, reg):
   "Reads a signed byte from the I2C device"
   try:
     result = self.bus.read_byte_data(self.address, reg)
     if result > 127: result -= 256
     if self.debug:
       print("I2C: Device 0x%02X returned 0x%02X from reg 0x%02X" %
        (self.address, result & 0xFF, reg))
     return result
   except IOError as err:
     return self.errMsg()

 def readU16(self, reg):
   "Reads an unsigned 16-bit value from the I2C device"
   try:
     result = self.bus.read_word_data(self.address,reg)
     if (self.debug):
       print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg))
     return result
   except IOError as err:
     return self.errMsg()

 def readS16(self, reg):
   "Reads a signed 16-bit value from the I2C device"
   try:
     result = self.bus.read_word_data(self.address,reg)
     if (self.debug):
       print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, result & 0xFFFF, reg))
     return result
   except IOError as err:
     return self.errMsg()

if __name__ == '__main__':
 try:
   bus = Adafruit_I2C(address=0)
   print("Default I2C bus is accessible")
 except:
   print("Error accessing default I2C bus")
Saluti
GP

Smile
Risposta
#3
Grazie, lo provo quanto prima e riferisco.

Mi potresti indicare la pagina dove hai recuperato lo script?

Saluti

LaPa
With a little/big help from my friends Rolleyes
Risposta
#4
ciao
il link della pagina da cui ti ho copiato il codice è
https://github.com/adafruit/adafruit-bea...uit_I2C.py
Saluti
GP

Smile
Risposta
#5
grazie, il listato che mi hai postato funziona correttamente.
Tuttavia più che rilevare la luminosità il sensore sembra un emettitore di numeri casuali Wink .

Al momento non ci siamo, spero di trovare uno script che funzioni meglio.

saluti

LaPa
With a little/big help from my friends Rolleyes
Risposta
#6
Salve,

continuo ad avere problemi con questo sensore:

Fornisce letture molto casuali.

Ho provato sia con impostazione auto gain, che con impostazione LUX High gain, che con Lux low gain. Il risultato è sempre numeri molto discutibili non correlati ai cambiamenti luminosi.


io ho utilizzato il seguente codice per leggere il sensore.




Codice:
import sys
# Not needed here. Thanks to https://github.com/mackstann for highlighting this.
#import smbus
import time
#Adafruit_I2C from https://github.com/adafruit/Adafruit-Raspberry-Pi-Python-Code/blob/master/Adafruit_I2C/Adafruit_I2C.py
from Adafruit_I2C import Adafruit_I2C


### Written for Python 2 <-!!!
### Big thanks to bryand, who wrote the code that I borrowed heavily from/was inspired by
### More thanks pandring who kind of kickstarted my work on the TSL2561 sensor
### A great big huge thanks to driverblock and the Adafruit team (Congrats on your many succeses
### Ladyada).  Without you folks I would just be a guy sitting somewhere thinking about cool stuff
### Now I'm a guy building cool stuff.
### If any of this code proves useful, drop me a line at medicforlife.blogspot.com

# TODO: Strip out values into constants.

class TSL2561:
   i2c = None

   def __init__(self, address=0x39, debug=0, pause=0.8):
       self.i2c = Adafruit_I2C(address)
       self.address = address
       self.pause = pause
       self.debug = debug
       self.gain = 0 # no gain preselected
       self.i2c.write8(0x80, 0x03)     # enable the device


   def setGain(self,gain=1):
       """ Set the gain """
       if (gain != self.gain):
           if (gain==1):
               self.i2c.write8(0x81, 0x02)     # set gain = 1X and timing = 402 mSec
               if (self.debug):
                   print "Setting low gain"
           else:
               self.i2c.write8(0x81, 0x12)     # set gain = 16X and timing = 402 mSec
               if (self.debug):
                   print "Setting high gain"
           self.gain=gain;                     # safe gain for calculation
           time.sleep(self.pause)              # pause for integration (self.pause must be bigger than integration time)


   def readWord(self, reg):
       """Reads a word from the I2C device"""
       try:
           wordval = self.i2c.readU16(reg)
           newval = self.i2c.reverseByteOrder(wordval)
           if (self.debug):
               print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, wordval & 0xFFFF, reg))
           return newval
       except IOError:
           print("Error accessing 0x%02X: Check your I2C address" % self.address)
           return -1


   def readFull(self, reg=0x8C):
       """Reads visible+IR diode from the I2C device"""
       return self.readWord(reg);

   def readIR(self, reg=0x8E):
       """Reads IR only diode from the I2C device"""
       return self.readWord(reg);

   def readLux(self, gain = 0):
       """Grabs a lux reading either with autoranging (gain=0) or with a specified gain (1, 16)"""
       if (gain == 1 or gain == 16):
           self.setGain(gain) # low/highGain
           ambient = self.readFull()
           IR = self.readIR()
       elif (gain==0): # auto gain
           self.setGain(16) # first try highGain
           ambient = self.readFull()
           if (ambient < 65535):
               IR = self.readIR()
           if (ambient >= 65535 or IR >= 65535): # value(s) exeed(s) datarange
               self.setGain(1) # set lowGain
               ambient = self.readFull()
               IR = self.readIR()

       if (self.gain==1):
          ambient *= 16    # scale 1x to 16x
          IR *= 16         # scale 1x to 16x
                       
       ratio = (IR / float(ambient)) # changed to make it run under python 2

       if (self.debug):
           print "IR Result", IR
           print "Ambient Result", ambient

       if ((ratio >= 0) & (ratio <= 0.52)):
           lux = (0.0315 * ambient) - (0.0593 * ambient * (ratio**1.4))
       elif (ratio <= 0.65):
           lux = (0.0229 * ambient) - (0.0291 * IR)
       elif (ratio <= 0.80):
           lux = (0.0157 * ambient) - (0.018 * IR)
       elif (ratio <= 1.3):
           lux = (0.00338 * ambient) - (0.0026 * IR)
       elif (ratio > 1.3):
           lux = 0

       return lux

if __name__ == "__main__":
   tsl=TSL2561()

print tsl.readLux(16)

#print "LUX HIGH GAIN ", tsl.readLux(16)
#print "LUX LOW GAIN ", tsl.readLux(1)
#print "LUX AUTO GAIN ", tsl.readLux()



Allora ho pensato di usare un il seguente driver, ma mi dice che non posso importare "from Adafruit_GPIO import I2C"

Sapreste dirmi come fare?

Codice:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
'''Driver for the TSL2561 digital luminosity (light) sensors.

Pick one up at http://www.adafruit.com/products/439

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Code ported from Adafruit Arduino library,
commit ced9f731da5095988cd66158562c2fde659e0510:
https://github.com/adafruit/Adafruit_TSL2561
'''

import time
from Adafruit_GPIO import I2C
from tsl2561.constants import *  # pylint: disable=unused-wildcard-import

__author__ = 'Georges Toth <georges@trypill.org>'
__credits__ = ['K.Townsend (Adafruit Industries)', 'Yongwen Zhuang (zYeoman)', 'miko (mikostn)', 'Simon Gansen (theFork)']
__license__ = 'BSD'
__version__ = 'v3.0'

'''HISTORY
v3.1 - Fix import
v3.0 - Port to Python 3.x
v2.2 - Merge PR #4 regarding wrong use of integration time
v2.1 - Minor adaptations required by latest Adafruit pyton libraries
v2.0 - Rewrote driver for Adafruit_Sensor and Auto-Gain support, and
      added lux clipping check (returns 0 lux on sensor saturation)
v1.0 - First release (previously TSL2561)
'''


class TSL2561(object):
   '''Driver for the TSL2561 digital luminosity (light) sensors.'''
   def __init__(self, address=None, busnum=None,
                integration_time=TSL2561_INTEGRATIONTIME_402MS,
                gain=TSL2561_GAIN_1X, autogain=False, debug=False):

       # Set default address and bus number if not given
       if address is not None:
           self.address = address
       else:
           self.address = TSL2561_ADDR_FLOAT
       if busnum is None:
           self.busnum = 1

       self.i2c = I2C.get_i2c_device(self.address, busnum=busnum)

       self.debug = debug
       self.integration_time = integration_time
       self.gain = gain
       self.autogain = autogain

       if self.integration_time == TSL2561_INTEGRATIONTIME_402MS:
           self.delay_time = TSL2561_DELAY_INTTIME_402MS
       elif self.integration_time == TSL2561_INTEGRATIONTIME_101MS:
           self.delay_time = TSL2561_DELAY_INTTIME_101MS
       elif self.integration_time == TSL2561_INTEGRATIONTIME_13MS:
           self.delay_time = TSL2561_DELAY_INTTIME_13MS
       self._begin()

   def _begin(self):
       '''Initializes I2C and configures the sensor (call this function before
       doing anything else)
       '''
       # Make sure we're actually connected
       x = self.i2c.readU8(TSL2561_REGISTER_ID)

       if not x & 0x0A:
           raise Exception('TSL2561 not found!')
       ##########

       # Set default integration time and gain
       self.set_integration_time(self.integration_time)
       self.set_gain(self.gain)

       # Note: by default, the device is in power down mode on bootup
       self.disable()

   def enable(self):
       '''Enable the device by setting the control bit to 0x03'''
       self.i2c.write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
                       TSL2561_CONTROL_POWERON)

   def disable(self):
       '''Disables the device (putting it in lower power sleep mode)'''
       self.i2c.write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_CONTROL,
                       TSL2561_CONTROL_POWEROFF)

   @staticmethod
   def delay(value):
       '''Delay times must be specified in milliseconds but as the python
       sleep function only takes (float) seconds we need to convert the sleep
       time first
       '''
       time.sleep(value / 1000.0)

   def _get_data(self):
       '''Private function to read luminosity on both channels'''

       # Enable the device by setting the control bit to 0x03
       self.enable()

       # Wait x ms for ADC to complete
       TSL2561.delay(self.delay_time)

       # Reads a two byte value from channel 0 (visible + infrared)
       broadband = self.i2c.readU16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT |
                                    TSL2561_REGISTER_CHAN0_LOW)

       # Reads a two byte value from channel 1 (infrared)
       ir = self.i2c.readU16(TSL2561_COMMAND_BIT | TSL2561_WORD_BIT |
                             TSL2561_REGISTER_CHAN1_LOW)

       # Turn the device off to save power
       self.disable()

       return (broadband, ir)

   def set_integration_time(self, integration_time):
       '''Sets the integration time for the TSL2561'''

       # Enable the device by setting the control bit to 0x03
       self.enable()

       self.integration_time = integration_time

       # Update the timing register
       self.i2c.write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
                       self.integration_time | self.gain)

       # Turn the device off to save power
       self.disable()

   def set_gain(self, gain):
       '''Adjusts the gain on the TSL2561 (adjusts the sensitivity to light)
       '''

       # Enable the device by setting the control bit to 0x03
       self.enable()

       self.gain = gain

       # Update the timing register
       self.i2c.write8(TSL2561_COMMAND_BIT | TSL2561_REGISTER_TIMING,
                       self.integration_time | self.gain)

       # Turn the device off to save power
       self.disable()

   def set_auto_range(self, value):
       '''Enables or disables the auto-gain settings when reading
       data from the sensor
       '''
       self.autogain = value

   def _get_luminosity(self):
       '''Gets the broadband (mixed lighting) and IR only values from
       the TSL2561, adjusting gain if auto-gain is enabled
       '''
       valid = False

       # If Auto gain disabled get a single reading and continue
       if not self.autogain:
           return self._get_data()

       # Read data until we find a valid range
       _agcCheck = False
       broadband = 0
       ir = 0

       while not valid:
           if self.integration_time == TSL2561_INTEGRATIONTIME_13MS:
               _hi = TSL2561_AGC_THI_13MS
               _lo = TSL2561_AGC_TLO_13MS
           elif self.integration_time == TSL2561_INTEGRATIONTIME_101MS:
               _hi = TSL2561_AGC_THI_101MS
               _lo = TSL2561_AGC_TLO_101MS
           else:
               _hi = TSL2561_AGC_THI_402MS
               _lo = TSL2561_AGC_TLO_402MS

           _b, _ir = self._get_data()

           # Run an auto-gain check if we haven't already done so ...
           if not _agcCheck:
               if _b < _lo and self.gain == TSL2561_GAIN_1X:
                   # Increase the gain and try again
                   self.set_gain(TSL2561_GAIN_16X)
                   # Drop the previous conversion results
                   _b, _ir = self._get_data()
                   # Set a flag to indicate we've adjusted the gain
                   _agcCheck = True
               elif _b > _hi and self.gain == TSL2561_GAIN_16X:
                   # Drop gain to 1x and try again
                   self.set_gain(TSL2561_GAIN_1X)
                   # Drop the previous conversion results
                   _b, _ir = self._get_data()
                   # Set a flag to indicate we've adjusted the gain
                   _agcCheck = True
               else:
                   # Nothing to look at here, keep moving ....
                   # Reading is either valid, or we're already at the chips
                   # limits
                   broadband = _b
                   ir = _ir
                   valid = True
           else:
               # If we've already adjusted the gain once, just return the new
               # results.
               # This avoids endless loops where a value is at one extreme
               # pre-gain, and the the other extreme post-gain
               broadband = _b
               ir = _ir
               valid = True

       return (broadband, ir)

   def _calculate_lux(self, broadband, ir):
       '''Converts the raw sensor values to the standard SI lux equivalent.
       Returns 0 if the sensor is saturated and the values are unreliable.
       '''
       # Make sure the sensor isn't saturated!
       if self.integration_time == TSL2561_INTEGRATIONTIME_13MS:
           clipThreshold = TSL2561_CLIPPING_13MS
       elif self.integration_time == TSL2561_INTEGRATIONTIME_101MS:
           clipThreshold = TSL2561_CLIPPING_101MS
       else:
           clipThreshold = TSL2561_CLIPPING_402MS

       # Return 0 lux if the sensor is saturated
       if broadband > clipThreshold or ir > clipThreshold:
           raise Exception('Sensor is saturated')

       # Get the correct scale depending on the integration time
       if self.integration_time == TSL2561_INTEGRATIONTIME_13MS:
           chScale = TSL2561_LUX_CHSCALE_TINT0
       elif self.integration_time == TSL2561_INTEGRATIONTIME_101MS:
           chScale = TSL2561_LUX_CHSCALE_TINT1
       else:
           chScale = 1 << TSL2561_LUX_CHSCALE

       # Scale for gain (1x or 16x)
       if not self.gain:
           chScale = chScale << 4

       # Scale the channel values
       channel0 = (broadband * chScale) >> TSL2561_LUX_CHSCALE
       channel1 = (ir * chScale) >> TSL2561_LUX_CHSCALE

       # Find the ratio of the channel values (Channel1/Channel0)
       ratio1 = 0
       if channel0 != 0:
           ratio1 = (channel1 << (TSL2561_LUX_RATIOSCALE + 1)) / channel0

       # round the ratio value
       ratio = (int(ratio1) + 1) >> 1

       b = 0
       m = 0

       if ratio >= 0 and ratio <= TSL2561_LUX_K1T:
           b = TSL2561_LUX_B1T
           m = TSL2561_LUX_M1T
       elif ratio <= TSL2561_LUX_K2T:
           b = TSL2561_LUX_B2T
           m = TSL2561_LUX_M2T
       elif ratio <= TSL2561_LUX_K3T:
           b = TSL2561_LUX_B3T
           m = TSL2561_LUX_M3T
       elif ratio <= TSL2561_LUX_K4T:
           b = TSL2561_LUX_B4T
           m = TSL2561_LUX_M4T
       elif ratio <= TSL2561_LUX_K5T:
           b = TSL2561_LUX_B5T
           m = TSL2561_LUX_M5T
       elif ratio <= TSL2561_LUX_K6T:
           b = TSL2561_LUX_B6T
           m = TSL2561_LUX_M6T
       elif ratio <= TSL2561_LUX_K7T:
           b = TSL2561_LUX_B7T
           m = TSL2561_LUX_M7T
       elif ratio > TSL2561_LUX_K8T:
           b = TSL2561_LUX_B8T
           m = TSL2561_LUX_M8T

       temp = (channel0 * b) - (channel1 * m)

       # Do not allow negative lux value
       if temp < 0:
           temp = 0

       # Round lsb (2^(LUX_SCALE-1))
       temp += 1 << (TSL2561_LUX_LUXSCALE - 1)

       # Strip off fractional portion
       lux = temp >> TSL2561_LUX_LUXSCALE

       # Signal I2C had no errors
       return lux

   def lux(self):
       '''Read sensor data, convert it to LUX and return it'''
       broadband, ir = self._get_luminosity()
       return self._calculate_lux(broadband, ir)


if __name__ == "__main__":
   tsl = TSL2561(debug=True)

   print(tsl.lux())




Grazie per tutto

Saluti

LaPa
With a little/big help from my friends Rolleyes
Risposta
#7
Help!!!!

magari qualcuno di voi sa semplicemente dove posso trovare Adafruit_GPIO . Io ho girellato in lungo e in largo su web senza cavarne un ragno dal buco.


Grazie comunque


Saluti

LaPa
With a little/big help from my friends Rolleyes
Risposta
#8
Hai provato a scrivere ad Adafruit?
Risposta
#9
(07/03/2017, 21:07)Zzed Ha scritto: Hai provato a scrivere ad Adafruit?

No, buon suggerimento, magari è il prossimo passo.
With a little/big help from my friends Rolleyes
Risposta
#10
... ed infatti era un ottimo suggerimento: è bastato andare sul forum ed inserire il nel campo cerca TSL2561 per trovare lo script di Python funzionante: https://github.com/ductsoup/Ductsoup_Python_TSL2561

Nella sezione README è descritto come installare il tutto.

E' necessario fare un file.py con il contenuto della sezione usage.


Senza di voi come farei Wink

Grazie

Saluti

LaPa
With a little/big help from my friends Rolleyes
Risposta
  


Vai al forum:


Navigazione: 1 Ospite(i)
Forum con nuovi Post
Forum senza nuovi post
Forum bloccato
Forum Redirect