Questo forum utilizza i cookies
Questo forum fa uso di cookie per migliorare l'esperienza utente. I cookie sono piccoli file di testo memorizzati sul tuo browser. I cookie impostati dal forum possono essere utilizzati solo su questo sito e non costituiscono rischio per la sicurezza, vengono utilizzati unicamente per memorizzare le tue preferenze. Navigando sul sito accetti che RaspberryItaly installi i cookie sul tuo browser.
Per maggiori informazioni consulta l'informativa sui Cookie di RasberryItaly

Un cookie verra memorizzato nel browser indipendentemente dalla scelta per evitare che questa domanda ti venga posta di nuovo. Sarai in grado di modificare le impostazioni dei cookie in qualsiasi momento utilizzando il link nel footer.
  • 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:
Forum con nuovi Post
Forum senza nuovi post
Forum bloccato
Forum Redirect