# mPy - Esp32s2 driver for 16 bit adc ads1115 over i2c
# Copyright by Anthony Vogelaar, Perth Scotland
# rev 0.10  2024-12-11  initial release

# Used board: RW2050 with ads1115 connected to portD and 3V3

from	micropython		import	const
from	collections		import	deque

# ================================= ads1115 ========================================

class Ads1115:

    SEL_DTA		= const(0x00)						# select data register
    SEL_CFG		= const(0x01)						# select config registert
    MUX_A0_A1 	= const(0x00)						# differential A0=Pos A1=Neg
    MUX_A2_A3 	= const(0x30)						# differential A0=Pos A1=Neg
    MUX_A0_GND 	= const(0x40)						# differential A0=Pos A1=Neg
    GAIN_2V   	= const(0x04)						# +/- 2.048V
    GAIN_1V   	= const(0x06)						# +/- 1.024V
    DR_8     	= const(0x00)						#   8 samples per second
    DR_32     	= const(0x40)						#  32 samples per second
    DR_128     	= const(0x80)						# 128 samples per second


    # ads1115 setup 0..2Volt between A0 and GND at 32 samples per second
    def __init__(self, i2c, addr=0x48, avg=8, mux=MUX_A0_GND, gain=GAIN_2V):
        self.i2c  = i2c
        self.addr = addr
        self.avg  = avg
        self.que  = None
        data      = bytes([self.SEL_CFG, mux | gain, DR_32])
        i2c.writeto(addr, data)
        if avg >= 3:
            self.que  = deque([self.get()]*avg, avg)
        
    
    # read ADC value 0..32767 and update the deque, t = 1 mSec
    def get(self):
        data   = bytes([self.SEL_DTA])
        self.i2c.writeto(self.addr, data)
        data   = self.i2c.readfrom(self.addr, 2)
        res    = data[0] * 256 + data[1]
        if self.que:
            self.que.append(res)
        return res        


    # return the average value of the que without largest and smallest values
    def getAvg(self):
        if self.que:
            data = list(self.que )
            data.sort()
            data = data[1:-1]
            return sum(data) // (self.avg-2)

# ================================ generator =============================

if __name__ == '__main__':
    
    from 	machine			import 	Pin, I2C, freq;			freq(240000000)
    import	time
    
    portD   = (14, 13)										# Rx, Tx | SCL, SDA
    i2c		= I2C(1, scl=Pin(portD[0]), sda=Pin(portD[1]), freq=400000)

    # dump average ads1115 value @ 10 Hz
    def generator():
        adc = Ads1115(i2c)
        while True:
            for _ in range(3):
                time.sleep_ms(33)			# sample at 30Hz, adc internal is 32 Hz
                adc.get()
            print(adc.getAvg())				# print Avg @ 10 Hz
            
            
    generator()
    
# ================================== End =================================
