# function Package adcRead_Pkg.py import cmd, time, logging, smbus, RPi.GPIO as GPIO #Source: https://smartypies.com/projects/ads1115-with-raspberrypi-and-python/ads1115runner/ #DC #ADS1115 Datasheet: https://www.ti.com/lit/ds/symlink/ads1115.pdf?ts=1647366695082&ref_url=https%253A%252F%252Fwww.digchip.com%252F # Usage once: # define adcRead constants # see the main program test_adcRead.py # BUS = adcReadInit(I2C_BUS,icNumber) # create BUS class object # BUS.open(I2C_BUS) # . . . then repeatedly # value = adcRead(nChannel) # read nChannel of the ADS1115 once # # no other functions need to be called # # the only externally callable functions are # adcReadInit() # adcRead() # # stop this program using ctrl+c # how to stop the test def MUX(n): if n==0: m="00" if n==1: m="01" if n==2: m="10" if n==3: m="11" return m #def end def swap2Bytes(c): '''Revert Byte order for Words (2 Bytes, 16 Bit).''' return (c>>8 |c<<8)&0xFFFF #def end def prepareLEconf(BEconf): '''Prepare LittleEndian Byte pattern from BigEndian configuration string, with separators.''' c = int(BEconf.replace('-',''), base=2) return swap2Bytes(c) #def end def LEtoBE(c): '''Little Endian to BigEndian conversion for signed 2Byte integers (2 complement).''' c = swap2Bytes(c) if(c >= 2**15): c= c-2**16 return c #def end def BEtoLE(c): '''BigEndian to LittleEndian conversion for signed 2 Byte integers (2 complement).''' if(c < 0): c= 2**16 + c return swap2Bytes(c) #def end def resetChip(RESET_ADDRESS, RESET_COMMAND): #BUS.write_byte(RESET_ADDRESS, RESET_COMMAND) return #def end class ADS1115Runner(cmd.Cmd): # this is the entry-point for Runner.cmdloop() # NB cmd.Cmd has been deprecated # cmd.Cmd will cause the self.cmdLoop() to return to the object's main method. # the ''' permits the definition of a string variable containing LFs #intro = '''usage: type following commands # 1 - one-shot measurement mode, timed # 2 - one-shot measurement mode, alerted through GPIO # 3 - continuous measurment mode, alerted through GPIO # 4 low high - continuous mode, alerted when value out of range [low, high] # q (quit) # just hitting enter quits any mode 1-4. Enter 'y' to continue in modes 1 and 2.''' #prompt = 'Enter 1,2,3,4 or q >>' # if you enter 1 it will run do_1(), 2 . . . do_2() etc file = None __logfile = None def alerted(self, arg): # deprecated data_raw = BUS.read_word_data(DEVICE_ADDRESS, POINTER_CONVERSION) print('alerted:' + str(LEtoBE(data_raw))) return #def end alerted() def do_q(self, arg): exit #def end do_q() def mydo_1(self,BUS,AINn): RESET_ADDRESS = 0b0000000 RESET_COMMAND = 0b00000110 POINTER_CONVERSION = 0x0 POINTER_CONFIGURATION = 0x1 POINTER_LOW_THRESHOLD = 0x2 POINTER_HIGH_THRESHOLD = 0x3 DEVICE_ADDRESS = 0x48 # device address selected on the IC chip # replaces do_1 routine #print("into do_1 arg:",arg) #print("into do_1") '''One-shot, Read value from channel AINn with wait time''' #resetChip(RESET_ADDRESS, RESET_COMMAND) #deprecated BUS.write_byte(RESET_ADDRESS, RESET_COMMAND) #replace # compare with configuration settings from ADS1115 datasheet #DC # start single conversion - AIN2/GND - 4.096V - single shot - 8SPS - X # - X - X - disable comparator # conf = prepareLEconf('1-110-001-1-000-0-0-0-11') #DC # AINn = 2 arg1 is AINn the nChannel to read ADSn = MUX(AINn) #e.g. AINn=2 read AIN2 ( AIN2 to GND*) #DC conf = prepareLEconf('1-1'+ADSn+'-001-1-000-0-0-0-11') #DC go = 'y' #while True and go in ['y','Y']: if True : #only do this once BUS.write_word_data(DEVICE_ADDRESS, POINTER_CONFIGURATION, conf) # long enough to be safe that data acquisition (conversion) has completed # may be calculated from data rate + some extra time for safety. # check accuracy in any case. time.sleep(0.2) value_raw = BUS.read_word_data(DEVICE_ADDRESS, POINTER_CONVERSION) value = LEtoBE(value_raw) #print("mid do_1") global g_adcValue g_adcValue = value # so adcRead() can see it #print(value) # test_adcRead() will print it #enter to break, repeat with 'y' if False : # deprecated go= input('continue: n/y') if (len(go)==0): go='n' #time.sleep(sleepTime) #if end return value #def end mydo_1() def shutdown(self): #GPIO.cleanup() #BUS.close() pass #def end shutdown() #class end ADS1115Runner() def adcRead(BUS,nChannel=0) : # nChannel is the number of the analog input to read i.e. 0 = AIN0 # adcRead returns value 0 to ~11000 as the actual reading #by D@CC on 202CMar16 DC #must be preceded by # BUS.adcReadInit(I2C_BUS,icNumber) # BUS.open(I2C_BUS) #Source: https://smartypies.com/projects/ads1115-with-raspberrypi-and-python/ads1115runner/ #DC #ADS1115 Datasheet: https://www.ti.com/lit/ds/symlink/ads1115.pdf?ts=1647366695082&ref_url=https%253A%252F%252Fwww.digchip.com%252F #Jumper S of KY-18 photo-cell to AIN2 # invert the KY-18 3v3 and GND to measure the opposite [ light (not dark) ] # terminal strip is L-R on the ADS1115 for RPi from SeeedStudios # 3V3,AIN3,AIN2,AIN1,AIN0,GND # Uses 3 objects:BUS.write_byte(RESET_ADDRESS, RESET_COMMAND) #replace # Runner. for ADS1115 ADC # BUS. for ADS11#Jumper S of KY-18 photo-cell to AIN2 #DC # GPIO. for ALERTPIN class is not used #DC try: # I (D@CC) do not know anything about the logging logging.basicConfig( level=logging.DEBUG, #format='%(name)-12s: %(levelname)-8s %(message)s') format='%(message)s') logger = logging.getLogger('ADS1115Runner') #print("logger:",logger) #AINn=2 # AINn=2 to read AIN2 Runner = ADS1115Runner() # create object Runner #print("before .cmdloop") Runner.mydo_1(BUS,nChannel) # nChannel is 2 to read AIN2 #Runner.cmdloop() # will run the main Runner.method (cmd.Cmd) # which prompts for a response & invokes do_r(arg) # for a response of "r arg" #print("after .cmdloop") global g_adcValue returnValue = g_adcValue # from mydo_1 return returnValue finally: Runner.shutdown() #release this object #BUS.close() #release this object #if end adcRead() def adcReadInit(I2C_BUS=1,icNumber="ADS1115") : # arg1 is the BUS number used by the IC chip # arg2 is the number of the IC chip used on the Seeed ADS1115 4 channel RPi board # usage of global variables # global g_adcValue if icNumber=="ADS1115" : BUS=smbus.SMBus(I2C_BUS) #returns the BUS object , (usually BUS=smbus.SMBus(I2C_BUS) ) # Open I2C device # I2C_BUS = 1 # DEVICE_ADDRESS = 0x48 return BUS else: print('ERROR025: ic supported is "ADS1115"') exit #def end adcReadInit() # 9 constants included in adcRead_Pkg.py RESET_ADDRESS = 0b0000000 RESET_COMMAND = 0b00000110 POINTER_CONVERSION = 0x0 POINTER_CONFIGURATION = 0x1 POINTER_LOW_THRESHOLD = 0x2 POINTER_HIGH_THRESHOLD = 0x3 DEVICE_ADDRESS = 0x48 # device address selected on the IC chip icNumber = "ADS1115" # IC chip used I2C_BUS = 1 # BUS number used by the IC chip # end of adcRead_pkg.py