class ANGLE():  # 1
    def __init__(self, port=PORTB):
        global class_map
        from machine import ADC
        if class_map['adc'] != None:
            class_map['adc'].deinit()
        self.adc = ADC(PORTB[1])
        self.adc.atten(ADC.ATTN_11DB)
        class_map['adc'] = self.adc

    def deinit(self):
        self.adc.deinit()

    def readraw(self):
        return 4095 - self.adc.readraw()

    def read(self):
        data = 0
        max = 0
        min = 4096
        for i in range(0, 10):
            newdata = 4095 - self.adc.readraw()
            data += newdata
            if newdata > max:
                max = newdata
            if newdata < min:
                min = newdata
        data -= (max + min)
        data >>= 3
        return round(1024 * data / 4095, 2)
Beispiel #2
0
class Battery:
    """
    TODO: Have to calibrate the results voltage using Vref on efuse.
    But the necessary functions seem not to be implemented to MicroPython yet.

      * esp_adc_cal_characterize()
      * esp_adc_cal_raw_to_voltage()

    This module calculate current battery voltage roughly for now.
    """
    def __init__(self, battery_pin, battery_resistance_num, width, atten):
        self._battery_adc = ADC(Pin(battery_pin))
        self._battery_adc.width(width)
        self._battery_adc.atten(atten)

        self._battery_resistance_num = battery_resistance_num

    def get_voltage(self, sampling_count=32, round_count=3):
        raw_value = sum(
            [self._battery_adc.read()
             for _ in range(sampling_count)]) / sampling_count
        voltage = raw_value * self._battery_resistance_num / 1000
        return round(voltage, round_count)

    def deinit(self):
        """ Deinitialize the battery pin ADC """
        self._battery_adc.deinit()
Beispiel #3
0
class Light:

    def __init__(self, port):
        from machine import ADC, Pin
        self.adc = ADC(port[1])
        self.adc.atten(ADC.ATTN_11DB)
        self.d_pin = Pin(port[0], Pin.IN, Pin.PULL_UP)

    @property
    def analogValue(self):
        data = 0
        max = 0
        min = 4096
        for i in range(0, 10):
            newdata = 4095 - self.adc.readraw()
            data += newdata
            if newdata > max:
                max = newdata
            if newdata < min:
                min = newdata
        data -= (max + min)
        data >>= 3
        return round(1024 * data / 4095, 2)
    
    @property
    def digitalValue(self):
        return self.d_pin.value()
    
    def deinit(self):
        self.adc.deinit()
Beispiel #4
0
class Angle:
    def __init__(self, port):
        from machine import ADC
        self.adc = ADC(port[1])
        self.adc.atten(ADC.ATTN_11DB)

    def deinit(self):
        self.adc.deinit()

    def readraw(self):
        return 4095 - self.adc.readraw()

    def read(self):
        data = 0
        max = 0
        min = 4096
        for i in range(0, 10):
            newdata = 4095 - self.adc.readraw()
            data += newdata
            if newdata > max:
                max = newdata
            if newdata < min:
                min = newdata
        data -= (max + min)
        data >>= 3
        return round(1024 * data / 4095, 2)
Beispiel #5
0
class ANGLE():  # 1
    def __init__(self, port=PORTB):
        from machine import ADC
        self.adc = ADC(36)
        self.adc.atten(ADC.ATTN_11DB)

    def deinit(self):
        self.adc.deinit()

    def readraw(self):
        return 4095 - self.adc.readraw()

    def read(self):
        data = 0
        max = 0
        min = 4096
        for i in range(0, 10):
            newdata = 4095 - self.adc.readraw()
            data += newdata
            if newdata > max:
                max = newdata
            if newdata < min:
                min = newdata
        data -= (max + min)
        data >>= 3
        return 100 * data / 4095
Beispiel #6
0
def adc():
    adc = ADC()
    adc.init(bits=12)
    #adc_c = adc.channel(pin='P13',attn=ADC.ATTN_11DB)  #ADC pin input range is 0-3.3V with 11DB.
    adc_c = adc.channel(pin='P13')                      #ADC pin input range is 0-1.1V.
    for cycles in range(10): # stop after 10 cycles
        #pycom.rgbled(0x007f00) # green
        Vx= adc_c.value()
        #pycom.rgbled(0x7f7f00) # yellow
        print("ADC value:", Vx)
        time.sleep(1)
    adc.deinit()
    return Vx
Beispiel #7
0
class MQ131:
    #Sensor datasheet has a graphical representation of ppm of gas by Rs/R0. By obtaining this ratio and using the graphical funcion one can obtain the gas density in ppm
    #Rs is the resistance of the sensor that changes depending on the concentration of gas
    #R0 is the resistance of the sensor at a know concentration without the presence of gases (fresh air)
    #Rs/R0 of fresh air is 1 so R0=Rs/1
    #2 points of the gas function are selected (1.2 at 10ppm) and (8 at 1000ppm)
    #another point is used to find the intersect (6 at 500ppm)
    READ_SAMPLE_INTERVAL = const(500)
    READ_SAMPLE_TIMES = const(10)

    def __init__(self, pin, R0):
        self.pin = pin
        self.R0 = R0
        self.adc = ADC(bits=12)
        self.adc.vref_to_pin('P22')
        self.apin = self.adc.channel(pin=self.pin, attn=ADC.ATTN_11DB)

    def deinit(self):
        self.apin.deinit()
        self.adc.deinit()

    def MQRead(self):
        v=float(0)
        for i in range(READ_SAMPLE_TIMES):
            v += self.apin()
            sleep(READ_SAMPLE_INTERVAL/1000)
        return ((v/READ_SAMPLE_TIMES)*3.3/4096) #3.3v - ATTN_11DB & 4096 - 12bits

    def MQCalibrate_R0(self, volts):
        #Rs = (Vc * RL)/VRL - RL
        if (volts==0):
            return 0
        RS_air = ((5.0*10.0)/volts)-10.0
        R0_air = RS_air/1   #from graph, needs to be replaced with real data
        return R0_air

    def MQGet_PPB(self, volts):
        if (volts==0):
            return 0
        Rs = ((5.0*10.0)/volts)-10.0
        m=AdvMath.log10(1.2/10)/AdvMath.log10(8/1000)
        b=AdvMath.log10(6)-(m*AdvMath.log10(500))
        if (Rs==0):
            return 0
        return pow(10,(((AdvMath.log10(Rs/self.R0))-b)/m))
Beispiel #8
0
class linear_encoder:
    def __init__(self, adc_pin, a, b):

        from machine import ADC, Pin

        self.a = a
        self.b = b
        self.adc_in = ADC(Pin(adc_pin))
        self.adc_in.atten(ADC.ATTN_11DB)
        self.adc_in.width(ADC.WIDTH_12BIT)

    def read(self):
        x = self.adc_in.read()
        y = self.a * x + self.b
        return y

    def deinit(self):
        self.adc_in.deinit()
Beispiel #9
0
class Battery(object):
    """
    Expansion board has battery on GP3
    The ADC measures between 0-1.4V
    It is 12bit (0-4095)
    It is measuring off a 56k/(56k+115k) voltage divider - 0.32
    """
    MINIMUM = 3180 # 3.64V measured
    CHARGED = 3600 # Using 4.15V
    RANGE = (CHARGED - MINIMUM)

    def __init__(self):
        self.adc = ADC()
        self.battery_raw = self.adc.channel(pin='GP3')

    def __del__(self):
        self.battery_raw.deinit()
        self.adc.deinit()

    def safe(self):
        """
        Is battery at operating voltage?
        :return: True/False
        """
        return self.battery_raw() >= Battery.MINIMUM

    def value(self):
        """
        Battery percentage
        :return: 0-100
        """
        val = (self.battery_raw() - Battery.MINIMUM) * 100
        val = val // Battery.RANGE
        if val > 100:
            val = 100
        if val < 0:
            val = 0
        return val
class SEN0219:
    #Sensor datasheet has a graphical representation of ppm of gas by V in a linear function. By using the graphical funcion one can obtain the gas density in ppm
    #2 points of the gas function are used to find the slope of the linear function (2V at 5000ppm) and (0.4 at 0ppm)
    #To Calibrate the Sensor by Hardware, one should place it in a CO2 free enviroment and then wire to ground both pin 8 and 20 of the Sensor for 7 seconds
    #To Calibrate the Sensor by Software, one should place it in a enviroment close to average CO2 (400ppm), measure the voltage output, and use that value as R0
    READ_SAMPLE_INTERVAL = const(500)
    READ_SAMPLE_TIMES = const(10)

    def __init__(self, pin, offset):
        self.pin = pin
        self.offset = offset
        self.adc = ADC(bits=12)
        self.apin = self.adc.channel(pin=self.pin, attn=ADC.ATTN_11DB)

    def deinit(self):
        self.apin.deinit()
        self.adc.deinit()

    def SENRead(self):
        v=float(0)
        for i in range(READ_SAMPLE_TIMES):
            v += self.apin()
            sleep(READ_SAMPLE_INTERVAL/1000)
        return ((v/READ_SAMPLE_TIMES)*3.3/4096)   #3.3v - ATTN_11DB & 4096 - 12bits

    def SENCalibrate_offset(self, volts):
        # 0,528V -> 400 ppm
        if (volts<=0.528):
            return 0
        offset = (((volts-0.4)*5000)/1.6) - 400
        return offset

    def SENGet_PPM(self, volts):
        if (volts<=0.4):
            return False
        ppm=(((volts-0.4)*5000)/1.6)-self.offset   #0.4 = Zero & (5000-0)/(2-0.4) = Linear Function
        return ppm
Beispiel #11
0
class gameESP():
    max_vol = 6
    duty = {0: 0, 1: 0.05, 2: 0.1, 3: 0.5, 4: 1, 5: 2, 6: 70}
    tones = {
        'c4': 262,
        'd4': 294,
        'e4': 330,
        'f4': 349,
        'f#4': 370,
        'g4': 392,
        'g#4': 415,
        'a4': 440,
        "a#4": 466,
        'b4': 494,
        'c5': 523,
        'c#5': 554,
        'd5': 587,
        'd#5': 622,
        'e5': 659,
        'f5': 698,
        'f#5': 740,
        'g5': 784,
        'g#5': 831,
        'a5': 880,
        'b5': 988,
        'c6': 1047,
        'c#6': 1109,
        'd6': 1175,
        ' ': 0
    }

    def __init__(self):
        # True =  SPI display, False = I2C display
        self.ESP32 = True
        self.paddle2 = False
        self.useSPI = True
        self.timer = 0
        self.vol = int(self.max_vol / 2) + 1
        seed(ticks_us())
        self.btnU = 1 << 1
        self.btnL = 1 << 2
        self.btnR = 1 << 3
        self.btnD = 1 << 4
        self.btnA = 1 << 5
        self.btnB = 1 << 6
        self.btnUval = 0
        self.btnDval = 0
        self.btnLval = 0
        self.btnRval = 0
        self.btnAval = 0
        self.btnBval = 0
        self.frameRate = 30
        self.screenW = 128
        self.screenH = 64
        self.Btns = 0
        self.lastBtns = 0

        self.PinBuzzer = Pin(26, Pin.OUT)

        # configure oled display SPI SSD1306
        self.spi = SPI(2,
                       baudrate=14500000,
                       sck=Pin(18),
                       mosi=Pin(23),
                       miso=Pin(19))
        #        display = Display(spi, rst=Pin(4), dc=Pin(21), cs=Pin(5), )
        #DC, RES, CS
        self.display = SSD1306_SPI(128, 64, self.spi, Pin(21), Pin(4), Pin(5))

        self.PinBtnA = Pin(32, Pin.IN, Pin.PULL_UP)
        self.PinBtnB = Pin(33, Pin.IN, Pin.PULL_UP)
        self.adcX = ADC(34)
        self.adcY = ADC(35)
        self.adc = ADC(39)
        self.adcX.atten(ADC.ATTN_11DB)
        self.adcY.atten(ADC.ATTN_11DB)
        self.adc.atten(ADC.ATTN_11DB)

    def deinit(self):
        self.adc.deinit()
        self.adcX.deinit()
        self.adcY.deinit()
        if self.useSPI:
            self.spi.deinit()

    def getPaddle(self):
        # ESP32 - 142 to 3155
        return max(min(int(self.adc.read() / 2.935) - 48, 1023), 0)

    def pressed(self, btn):
        return (self.Btns & btn)

    def justPressed(self, btn):
        return (self.Btns & btn) and not (self.lastBtns & btn)

    def justReleased(self, btn):
        return (self.lastBtns & btn) and not (self.Btns & btn)

    def getBtn(self):

        self.btnAval = not self.PinBtnA.value()
        self.btnBval = not self.PinBtnB.value()

        val = self.adcX.read()
        self.btnLval = 1 if val > 2500 else 0
        self.btnRval = 1 if 1500 < val < 2000 else 0

        val = self.adcY.read()
        self.btnUval = 1 if val > 2500 else 0
        self.btnDval = 1 if 1500 < val < 2000 else 0

        self.lastBtns = self.Btns
        self.Btns = 0
        self.Btns = self.Btns | self.btnUval << 1 | self.btnLval << 2 | self.btnRval << 3 | self.btnDval << 4 | self.btnAval << 5 | self.btnBval << 6
        return self.Btns
        print(self.Btns)

    def setVol(self):
        if self.pressed(self.btnB):
            if self.justPressed(self.btnU):
                self.vol = min(self.vol + 1, self.max_vol)
                self.playTone('c4', 100)
                return True
            elif self.justPressed(self.btnD):
                self.vol = max(self.vol - 1, 0)
                self.playTone('d4', 100)
                return True

        return False

    def playTone(self, tone, tone_duration, rest_duration=0):
        beeper = PWM(self.PinBuzzer,
                     freq=self.tones[tone],
                     duty=self.duty[self.vol])
        sleep_ms(tone_duration)
        beeper.deinit()
        sleep_ms(rest_duration)

    def playSound(self, freq, tone_duration, rest_duration=0):
        beeper = PWM(self.PinBuzzer, freq, duty=self.duty[self.vol])
        sleep_ms(tone_duration)
        beeper.deinit()
        sleep_ms(rest_duration)

    def random(self, x, y):
        return getrandbits(20) % (y - x + 1) + x

    def display_and_wait(self):
        self.display.show()
        timer_dif = int(1000 / self.frameRate) - ticks_diff(
            ticks_ms(), self.timer)
        if timer_dif > 0:
            sleep_ms(timer_dif)
        self.timer = ticks_ms()
Beispiel #12
0
from machine import Pin, ADC
import utime

# variabelen
PIN_ADC = 36  # pin SVP

# ADC pin initialiseren
adc = ADC(Pin(PIN_ADC))
# 11 dB attenuation means full 0 - 3.3V range
adc.atten(adc.ATTN_11DB)

# min en max opslaan in calibratie bestand
try:
    # lus meetwaarden
    while True:
        # ophalen meetwaarde
        licht = adc.read()
        # berekenen procent
        spanning = 3.3 * licht / 4095
        # toon resultaat
        print('Meetwaarde: %d - Spanning: %0.2fV' % (licht, spanning))
        # even wachten
        utime.sleep_ms(1000)

except Exception as e:
    print('Probleem met bestand %s' % e)

finally:
    adc.deinit()
Beispiel #13
0
class SystemVoltage(AbstractSystemSensor):
    """
    Read the a voltage level by sampling the ADC on a pin connected
    to a voltage divider. As the Pycom expansion board is using
    Pin 16 for battery voltage, this is also used on other boards
    as kind of a convention.
    
    Implementation
    ==============
    Written by Dominik Kapusta <https://github.com/ayoy>. Thanks!
    Improved by Andreas Motl <https://github.com/amotl>.
    
    License
    =======
    The MIT License (MIT)
    
    Copyright (c) 2018 Dominik Kapusta
    
    - https://kapusta.cc/2018/02/02/air-quality-monitor-revisited/
    - https://github.com/ayoy/upython-aq-monitor/blob/lora/lib/adc.py
    
    Documentation
    =============
    - https://docs.pycom.io/firmwareapi/pycom/machine/adc
    - https://docs.pycom.io/tutorials/all/adc
    
    More resources
    ==============
    - https://forum.pycom.io/topic/3776/adc-use-to-measure-battery-level-vin-level
    - https://github.com/hiveeyes/terkin-datalogger/issues/5
    - https://community.hiveeyes.org/t/batterieuberwachung-voltage-divider-und-attenuation-fur-microypthon-firmware/2128


    """

    # How many times to sample the ADC for making a reading.
    adc_sample_count = const(1000)

    def __init__(self, settings):
        """
        Initialized ADC unit.
        """

        super().__init__(settings)

        # ADC Pin to sample from.
        self.pin = None

        # Main resistor value (R1).
        self.resistor_r1 = None

        # Resistor between input pin and ground (R2).
        self.resistor_r2 = None

        # Reference to platform ADC object.
        self.adc = None

        self.setup()

    def setup(self):
        """
        - Configure the appropriate resistor values for computing the voltage.
        - Setup ADC for sampling.
        """

        self.pin = self.settings.get('pin')
        self.resistor_r1 = self.settings.get('resistor_r1')
        self.resistor_r2 = self.settings.get('resistor_r2')
        self.adc_attenuation_db = self.settings.get('adc_attenuation_db', 6.0)
        self.reading_key = self.settings.get('type')

        assert type(
            self.pin) is str, 'VCC Error: Voltage divider ADC pin invalid'
        assert type(
            self.resistor_r1
        ) is int, 'VCC Error: Voltage divider resistor value "resistor_r1" invalid'
        assert type(
            self.resistor_r2
        ) is int, 'VCC Error: Voltage divider resistor value "resistor_r2" invalid'
        assert type(
            self.adc_attenuation_db
        ) is float, 'VCC Error: ADC attenuation value "adc_attenuation_db" invalid'

        # ADC channel used for sampling the raw value.
        from machine import ADC

        if self.adc_attenuation_db == 0.0:
            self.adc_atten = ADC.ATTN_0DB
        elif self.adc_attenuation_db == 2.5:
            self.adc_atten = ADC.ATTN_2_5DB
        elif self.adc_attenuation_db == 6.0:
            self.adc_atten = ADC.ATTN_6DB
        elif self.adc_attenuation_db == 11.0:
            self.adc_atten = ADC.ATTN_11DB
        else:
            raise ValueError(
                'ADC attenuation value (adc_attenuation_db) not allowed : {}'.
                format(self.adc_attenuation_db))

        if platform_info.vendor == platform_info.MICROPYTHON.Vanilla:
            from machine import Pin
            self.adc = ADC(Pin(int(self.pin[1:])))

        elif platform_info.vendor == platform_info.MICROPYTHON.Pycom:
            self.adc = ADC(id=0)

        else:
            raise NotImplementedError('Reading the ADC is '
                                      'not implemented on this platform')

    def read(self):
        """Acquire voltage reading by sampling ADC."""
        # Todo: Make attenuation factor configurable.

        from machine import ADC
        # Sample ADC a few times.
        adc_samples = [0.0] * self.adc_sample_count
        adc_mean = 0.0
        i = 0
        log.debug('Reading voltage level on pin {} with voltage divider {}/{}'.
                  format(self.pin, self.resistor_r1, self.resistor_r2))

        # read samples
        if platform_info.vendor == platform_info.MICROPYTHON.Vanilla:
            self.adc.atten(self.adc_atten)
            irq_state = disable_irq()
            while i < self.adc_sample_count:
                adc_samples[i] = self.adc.read()
                adc_mean += adc_samples[i]
                i += 1
            enable_irq(irq_state)

        elif platform_info.vendor == platform_info.MICROPYTHON.Pycom:
            self.adc.init()
            adc_channel = self.adc.channel(attn=self.adc_atten, pin=self.pin)
            irq_state = disable_irq()
            while i < self.adc_sample_count:
                sample = adc_channel()
                adc_samples[i] = sample
                adc_mean += sample
                i += 1
            enable_irq(irq_state)

        else:
            raise NotImplementedError('Reading the ADC is '
                                      'not implemented on this platform')

        adc_mean /= self.adc_sample_count
        adc_variance = 0.0
        for sample in adc_samples:
            adc_variance += (sample - adc_mean)**2
        adc_variance /= (self.adc_sample_count - 1)

        if platform_info.vendor == platform_info.MICROPYTHON.Vanilla:
            # FIXME: Make this work for vanilla ESP32.
            raw_voltage = 0.0
            mean_voltage = 0.0

        elif platform_info.vendor == platform_info.MICROPYTHON.Pycom:
            raw_voltage = adc_channel.value_to_voltage(4095)
            mean_voltage = adc_channel.value_to_voltage(int(adc_mean))

        mean_variance = (adc_variance * 10**6) // (adc_mean**2)

        # log.debug("ADC readings. count=%u:\n%s" %(self.adc_sample_count, str(adc_samples)))
        log.debug("SystemVoltage: Mean of ADC readings (0-4095) = %15.13f" %
                  adc_mean)
        log.debug(
            "SystemVoltage: Mean of ADC voltage readings (0-%dmV) = %15.13f" %
            (raw_voltage, mean_voltage))
        log.debug("SystemVoltage: Variance of ADC readings = %15.13f" %
                  adc_variance)
        log.debug(
            "SystemVoltage: 10**6*Variance/(Mean**2) of ADC readings = %15.13f"
            % mean_variance)

        resistor_sum = self.resistor_r1 + self.resistor_r2
        if platform_info.vendor == platform_info.MICROPYTHON.Pycom:
            voltage_millivolt = (adc_channel.value_to_voltage(
                int(adc_mean))) * resistor_sum / self.resistor_r2
        else:
            # FIXME: Make this work for vanilla ESP32.
            voltage_millivolt = 0.0
        voltage_volt = voltage_millivolt / 1000.0

        # Shut down ADC channel.
        if platform_info.vendor == platform_info.MICROPYTHON.Pycom:
            adc_channel.deinit()

        log.debug('Voltage level: {}'.format(voltage_volt))

        reading = {self.reading_key: voltage_volt}
        return reading

    def power_off(self):
        """Shut down ADC."""
        log.info('Turning off ADC')
        self.adc.deinit()
Beispiel #14
0
print(apin)
apin = adc.channel(id=adc_channel)
print(apin)
apin = adc.channel(adc_channel, pin=adc_pin)
print(apin)
apin = adc.channel(id=adc_channel, pin=adc_pin)
print(apin)

print(apin.value() > 3000)
print(apin() > 3000)

# de-init must work
apin.deinit()
print(apin)

adc.deinit()
print(adc)
print(apin)
adc.init()
print(adc)
print(apin)
apin.init()
print(apin)
print(apin() > 3000)

# check for memory leaks...
for i in range (0, 1000):
    adc = ADC()
    apin = adc.channel(adc_channel)

# next ones should raise
            np.set(0,P,0,0)
            time.sleep(0.1)
            np.set(0,0,0,0)
            time.sleep(0.1)

    # Wait
    for i in range (0,25):
        np.set(0, 2 * i, 0, 0)
        time.sleep(0.03)
    for i in range (26,100):
        np.set(0, 2 * i, 0, 0)
        time.sleep(0.0033)
    np.set(0,0,0,0)

mqtt.disconnect()
acs712.deinit()














Beispiel #16
0
def calibration(mode, vref):
    # mode => 0 adc calibration
    # mode => 1 sensor calibration
    from peripheral_query import _get_filtered_mvolts
    import time
    import ujson
    import uio
    from machine import Pin
    from machine import ADC
    from peripheral_query import GasData

    print('[4]===================')

    calibration_frequency = 1  # seconds
    calibration_times = 10

    calibration_NH3 = []
    calibration_SO2 = []
    calibration_H2S = []

    iter_calibration = 0

    while iter_calibration < calibration_times:
        adc0 = ADC(id=0)

        outer_iter = 0
        outer_iter_times = 20
        outer_buff_NH3 = []
        outer_buff_SO2 = []
        outer_buff_H2S = []

        while outer_iter < outer_iter_times:
            filtered_mvolts = _get_filtered_mvolts(adc0, vref)
            outer_buff_NH3.append(filtered_mvolts.NH3)
            outer_buff_SO2.append(filtered_mvolts.SO2)
            outer_buff_H2S.append(filtered_mvolts.H2S)
            outer_iter = outer_iter + 1
        buff_nh3 = sum(outer_buff_NH3) / outer_iter_times
        buff_so2 = sum(outer_buff_SO2) / outer_iter_times
        buff_h2s = sum(outer_buff_H2S) / outer_iter_times
        print('[4]sample #: ' + ('%d' % (iter_calibration + 1)) + ' / ' +
              ('%d' % (calibration_times)))
        print('[4]sample NH3: ' + ('%.1f' % (buff_nh3)))
        print('[4]sample SO2: ' + ('%.1f' % (buff_so2)))
        print('[4]sample H2S: ' + ('%.1f' % (buff_h2s)))

        calibration_NH3.append(buff_nh3)
        calibration_SO2.append(buff_so2)
        calibration_H2S.append(buff_h2s)

        adc0.deinit()
        iter_calibration = iter_calibration + 1
        time.sleep(calibration_frequency)

    cfg_nh3 = sum(calibration_NH3) / calibration_times
    cfg_so2 = sum(calibration_SO2) / calibration_times
    cfg_h2s = sum(calibration_H2S) / calibration_times

    with uio.open('/flash/configure.json', 'r', encoding="utf-8") as handle:
        psd_json = ujson.load(handle)
    if mode == 0:
        psd_json["calibration"]["sensor_nh3"]["bias"] = round(cfg_nh3, 1)
        psd_json["calibration"]["sensor_so2"]["bias"] = round(cfg_so2, 1)
        psd_json["calibration"]["sensor_h2s"]["bias"] = round(cfg_h2s, 1)
        print('[4]Calibration finished...')
        print('[4]NH3 bias: ' + ('%.1f' % (cfg_nh3)))
        print('[4]SO2 bias: ' + ('%.1f' % (cfg_so2)))
        print('[4]H2S bias: ' + ('%.1f' % (cfg_h2s)))
    elif mode == 1:
        psd_json["calibration"]["sensor_nh3"]["i0"] = round(
            (cfg_nh3 - psd_json["calibration"]["sensor_nh3"]["bias"]) / 624, 1)
        psd_json["calibration"]["sensor_so2"]["i0"] = round(
            (cfg_so2 - psd_json["calibration"]["sensor_so2"]["bias"]) / 624, 1)
        psd_json["calibration"]["sensor_h2s"]["i0"] = round(
            (cfg_h2s - psd_json["calibration"]["sensor_h2s"]["bias"]) / 624, 1)
        print('[4]Calibration finished...')
        print('[4]NH3 zero-drift: ' + ('%.1f' % (
            (cfg_nh3 - psd_json["calibration"]["sensor_nh3"]["bias"]) / 624)))
        print('[4]SO2 zero-drift: ' + ('%.1f' % (
            (cfg_so2 - psd_json["calibration"]["sensor_so2"]["bias"]) / 624)))
        print('[4]H2S zero-drift: ' + ('%.1f' % (
            (cfg_h2s - psd_json["calibration"]["sensor_h2s"]["bias"]) / 624)))

    with uio.open('/flash/configure.json', 'w', encoding="utf-8") as handle:
        json_r_str = ujson.dumps(psd_json)
        handle.write(json_r_str)
        print('[4]Configure file written...')
Beispiel #17
0
class SystemBatteryLevel:
    """
    Read the battery level by sampling the ADC on a pin connected
    to a voltage divider. As the Pycom expansion board is using
    Pin 16, this is also used on other boards as kind of a convention.

    Implementation
    ==============
    Written by Dominik Kapusta <https://github.com/ayoy>. Thanks!
    Improved by Andreas Motl <https://github.com/amotl>.

    License
    =======
    The MIT License (MIT)

    Copyright (c) 2018 Dominik Kapusta

    - https://kapusta.cc/2018/02/02/air-quality-monitor-revisited/
    - https://github.com/ayoy/upython-aq-monitor/blob/lora/lib/adc.py

    Documentation
    =============
    - https://docs.pycom.io/firmwareapi/pycom/machine/adc
    - https://docs.pycom.io/tutorials/all/adc

    More resources
    ==============
    - https://forum.pycom.io/topic/3776/adc-use-to-measure-battery-level-vin-level
    - https://github.com/hiveeyes/hiveeyes-micropython-firmware/issues/5
    - https://community.hiveeyes.org/t/batterieuberwachung-voltage-divider-und-attenuation-fur-microypthon-firmware/2128

    """

    # How many times to sample the ADC for making a reading.
    adc_sample_count = const(1000)

    def __init__(self):
        """
        Initialized ADC unit.
        """

        # ADC Pin to sample from.
        self.pin = None

        # Main resistor value (R1).
        self.resistor_r1 = None

        # Resistor between input pin and ground (R2).
        self.resistor_r2 = None

        # Reference to platform ADC object.
        self.adc = None

    def setup(self, settings):

        self.pin = settings.get('sensors.system.vcc.pin')
        self.resistor_r1 = settings.get('sensors.system.vcc.resistor_r1')
        self.resistor_r2 = settings.get('sensors.system.vcc.resistor_r2')

        assert type(
            self.pin) is str, 'VCC Error: Voltage divider ADC pin invalid'
        assert type(
            self.resistor_r1
        ) is int, 'VCC Error: Voltage divider resistor value "resistor_r1" invalid'
        assert type(
            self.resistor_r2
        ) is int, 'VCC Error: Voltage divider resistor value "resistor_r2" invalid'

        # ADC channel used for sampling the raw value.
        from machine import ADC
        try:
            self.adc = ADC(id=0)
        except TypeError:
            from machine import Pin
            self.adc = ADC(Pin(self.pin))

    def read(self):
        """
        Acquire vbatt reading by sampling ADC.
        """

        # Power on ADC.
        self.adc.init()

        log.debug('Reading battery level on pin {} with voltage divider {}/{}'.
                  format(self.pin, self.resistor_r1, self.resistor_r2))

        # Sample ADC a few times.
        # Todo: Make attenuation factor configurable.
        from machine import ADC
        adc_channel = self.adc.channel(attn=ADC.ATTN_6DB, pin=self.pin)
        adc_samples = [0.0] * self.adc_sample_count
        adc_mean = 0.0
        i = 0
        irq_state = disable_irq()
        while i < self.adc_sample_count:
            sample = adc_channel()
            adc_samples[i] = sample
            adc_mean += sample
            i += 1
        enable_irq(irq_state)

        adc_mean /= self.adc_sample_count
        adc_variance = 0.0
        for sample in adc_samples:
            adc_variance += (sample - adc_mean)**2
        adc_variance /= (self.adc_sample_count - 1)

        raw_voltage = adc_channel.value_to_voltage(4095)
        mean_voltage = adc_channel.value_to_voltage(int(adc_mean))
        mean_variance = (adc_variance * 10**6) // (adc_mean**2)

        # log.debug("ADC readings. count=%u:\n%s" %(self.adc_sample_count, str(adc_samples)))
        log.debug(
            "SystemBatteryLevel: Mean of ADC readings (0-4095) = %15.13f" %
            adc_mean)
        log.debug(
            "SystemBatteryLevel: Mean of ADC voltage readings (0-%dmV) = %15.13f"
            % (raw_voltage, mean_voltage))
        log.debug("SystemBatteryLevel: Variance of ADC readings = %15.13f" %
                  adc_variance)
        log.debug(
            "SystemBatteryLevel: 10**6*Variance/(Mean**2) of ADC readings = %15.13f"
            % mean_variance)

        resistor_sum = self.resistor_r1 + self.resistor_r2
        voltage_millivolt = (adc_channel.value_to_voltage(
            int(adc_mean))) * resistor_sum / self.resistor_r2
        voltage_volt = voltage_millivolt / 1000.0

        # Shut down ADC channel.
        adc_channel.deinit()

        log.debug('Battery level: {}'.format(voltage_volt))

        reading = {'system.voltage': voltage_volt}
        return reading

    def power_off(self):
        """
        Shut down ADC.
        """
        log.info('Turning off ADC')
        self.adc.deinit()
Beispiel #18
0
#
# Copyright (c) 2006-2019, RT-Thread Development Team
#
# SPDX-License-Identifier: MIT License
#
# Change Logs:
# Date           Author       Notes
# 2019-06-13     SummerGift   first version
#

from machine import ADC  # Import the ADC class from machine

# adc channel 5 :  PB23
# adc channel 6 :  PB24
# adc channel 7 :  PB25
# adc channel 8 :  PB26

adc = ADC(
    "adc", 5
)  # Creates an ADC object that currently uses the 5 channel(PB23) of an ADC device name "adc"
value = (
    adc.read() - 8192.0
) / 8192 * 2.25 / 1.2 + 1.584  # Gets the ADC object sampling value and change to voltage value
print("Voltage Value: %.3f" % value)  # print voltage value
adc.deinit()  # Close ADC object
adc.init(5)  # Open and reconfigure the ADC object
class gameOGO():
    max_vol = 6
    duty = {0: 0, 1: 0.05, 2: 0.1, 3: 0.5, 4: 1, 5: 2, 6: 70}
    tones = {
        'c4': 262,
        'd4': 294,
        'e4': 330,
        'f4': 349,
        'f#4': 370,
        'g4': 392,
        'g#4': 415,
        'a4': 440,
        "a#4": 466,
        'b4': 494,
        'c5': 523,
        'c#5': 554,
        'd5': 587,
        'd#5': 622,
        'e5': 659,
        'f5': 698,
        'f#5': 740,
        'g5': 784,
        'g#5': 831,
        'a5': 880,
        'b5': 988,
        'c6': 1047,
        'c#6': 1109,
        'd6': 1175,
        ' ': 0
    }

    def __init__(self):
        # True =  SPI display, False = I2C display

        self.ESP32 = True
        self.useSPI = True
        self.displayTimer = ticks_ms()
        self.vol = int(self.max_vol)
        seed(ticks_us())
        self.btnU = 1 << 1
        self.btnL = 1 << 2
        self.btnR = 1 << 3
        self.btnD = 1 << 4
        self.btnA = 1 << 5
        self.btnB = 1 << 6
        self.btnMenu = 1 << 7
        self.btnVol = 1 << 8
        self.btnSel = 1 << 9
        self.btnSt = 1 << 10

        self.btnUval = 0
        self.btnDval = 0
        self.btnLval = 0
        self.btnRval = 0
        self.btnAval = 0
        self.btnBval = 0
        self.btnMenuval = 0
        self.btnVolval = 0
        self.btnSelval = 0
        self.btnStval = 0
        self.frameRate = 30
        self.maxBgm = 1
        self.bgm = 1
        self.songIndex = 0
        self.songStart = -1
        self.songEnd = -2
        self.songLoop = -3
        self.silence = 0
        self.songSpeed = 1
        self.timeunit = 1
        self.notes = False
        self.songBuf = []
        self.Btns = 0
        self.lastBtns = 0

        self.dac_pin = Pin(25, Pin.OUT, value=1)  # switch speaker on
        self.PinBuzzer = Pin(26, Pin.OUT)
        self.beeper = PWM(self.PinBuzzer, 500, duty=0)
        self.beeper2 = PWM(self.PinBuzzer, 500, duty=0)
        self.timerInitialized = False
        self.tft = display.TFT()
        self.tft.init(self.tft.ILI9341,
                      width=240,
                      height=320,
                      speed=40000000,
                      backl_pin=14,
                      backl_on=1,
                      miso=19,
                      mosi=23,
                      clk=18,
                      cs=5,
                      dc=21,
                      hastouch=False)
        self.tft.clear(self.tft.BLACK)
        self.tft.orient(self.tft.LANDSCAPE_FLIP)
        self.screenW, self.screenH = self.tft.screensize()
        ''' fonts available in ili9341
        tft.FONT_Small, 8x12
        tft.FONT_Default, 13x13
        tft.FONT_7seg, 18x31
        tft.FONT_Ubuntu, 15x16
        tft.FONT_Comic, 25x28
        tft.FONT_Tooney, 32x37
        tft.FONT_Minya, 20x24
        '''
        self.tft.font(self.tft.FONT_Ubuntu, rotate=0)

        self.PinBtnA = Pin(BUTTON_A_PIN, Pin.IN, Pin.PULL_UP)
        self.PinBtnB = Pin(BUTTON_B_PIN, Pin.IN, Pin.PULL_UP)
        self.PinBtnMenu = Pin(BUTTON_MENU_PIN, Pin.IN, Pin.PULL_UP)
        self.PinBtnVol = Pin(BUTTON_VOLUME_PIN, Pin.IN, Pin.PULL_UP)
        self.PinBtnSel = Pin(BUTTON_SELECT_PIN, Pin.IN, Pin.PULL_UP)
        self.PinBtnSt = Pin(BUTTON_START_PIN, Pin.IN)

        self.adcX = ADC(BUTTON_JOY_X_PIN)
        self.adcY = ADC(BUTTON_JOY_Y_PIN)
        #self.adc = ADC(PADDLE_PIN)
        self.adcX.atten(ADC.ATTN_11DB)
        self.adcY.atten(ADC.ATTN_11DB)
        #self.adc.atten(ADC.ATTN_11DB)

    def deinit(self):
        #self.adc.deinit()

        self.beeper.deinit()
        self.beeper2.deinit()
        self.adcX.deinit()
        self.adcY.deinit()
        self.tft.deinit()
        self.songIndex = 0
        if self.timerInitialized:
            self.timer.deinit()

    def getPaddle(self):
        return 512
        # ESP32 - 142 to 3155
        # return max ( min (int (self.adc.read() / 2.935) - 48, 1023),0)

    def pressed(self, btn):
        return (self.Btns & btn)

    def justPressed(self, btn):
        return (self.Btns & btn) and not (self.lastBtns & btn)

    def justReleased(self, btn):
        return (self.lastBtns & btn) and not (self.Btns & btn)

    def getBtn(self):

        self.btnAval = not self.PinBtnA.value()
        self.btnBval = not self.PinBtnB.value()
        self.btnMenuval = not self.PinBtnMenu.value()
        self.btnVolval = not self.PinBtnVol.value()
        self.btnSelval = not self.PinBtnSel.value()
        self.btnStval = not self.PinBtnSt.value()

        val = self.adcX.read()
        self.btnLval = 1 if val > 2500 else 0
        self.btnRval = 1 if 1500 < val < 2000 else 0

        val = self.adcY.read()
        self.btnUval = 1 if val > 2500 else 0
        self.btnDval = 1 if 1500 < val < 2000 else 0

        self.lastBtns = self.Btns
        self.Btns = 0
        self.Btns = self.Btns | self.btnUval << 1 | self.btnLval << 2 | self.btnRval << 3 | self.btnDval << 4 | self.btnAval << 5 | self.btnBval << 6
        self.Btns = self.Btns | self.btnMenuval << 7 | self.btnVolval << 8 | self.btnSelval << 9 | self.btnStval << 10

        return self.Btns

    def setVol(self):
        if self.pressed(self.btnVol):
            if self.justPressed(self.btnU):
                self.vol = min(self.vol + 1, self.max_vol)
                self.playTone('c4', 100)
                return True
            elif self.justPressed(self.btnD):
                self.vol = max(self.vol - 1, 0)
                self.playTone('d4', 100)
                return True

        return False

    def setFrameRate(self):
        if self.pressed(self.btnSel):
            if self.justPressed(self.btnU):
                self.frameRate = self.frameRate + 5 if self.frameRate < 120 else 5
                self.playTone('e4', 100)
                return True
            elif self.justPressed(self.btnD):
                self.frameRate = self.frameRate - 5 if self.frameRate > 5 else 120
                self.playTone('f4', 100)
                return True
        return False

    def center_msg(self, msg, color_fg, color_bg):
        self.tft.set_bg(color_bg)
        self.tft.textClear((self.screenW - self.tft.textWidth(msg)) // 2,
                           self.screenH // 2, msg, color_bg)
        self.tft.text((self.screenW - self.tft.textWidth(msg)) // 2,
                      self.screenH // 2, msg, color_fg)

    def display_msg(self, x, y, msg, color_fg, color_bg):
        self.tft.set_bg(color_bg)
        self.tft.textClear(x, y, msg, color_bg)
        self.tft.text(x, y, msg, color_fg)

    def display_vol(self):
        fontW, fontH = self.tft.fontSize()
        self.tft.rect(self.screenW - fontW * self.max_vol, 0,
                      self.max_vol * fontW, fontH, self.tft.GREEN,
                      self.tft.BLACK)
        self.tft.rect(self.screenW - fontW * self.max_vol + 1, 1,
                      self.vol * fontW - 2, fontH - 2, self.tft.RED,
                      self.tft.RED)

    def playTone(self, tone, tone_duration, rest_duration=0):

        self.beeper = PWM(self.PinBuzzer, self.tones[tone],
                          self.duty[self.vol])
        sleep_ms(tone_duration)
        self.beeper.deinit()
        sleep_ms(rest_duration)

    def playSound(self, freq, tone_duration, rest_duration=0):

        self.beeper = PWM(self.PinBuzzer, freq, self.duty[self.vol])
        sleep_ms(tone_duration)
        self.beeper.deinit()
        sleep_ms(rest_duration)

    def handleInterrupt(self, timer):
        self.beeper2.deinit(
        )  # note has been played logn enough, now stop sound

        if self.songBuf[self.songIndex] == self.songLoop:
            self.songIndex = 3  # repeat from first note

        if self.songBuf[self.songIndex] >= 0:
            if self.songBuf[self.songIndex] == 0:
                self.beeper2 = PWM(self.PinBuzzer, 100, 0)
            elif self.notes:
                self.beeper2 = PWM(self.PinBuzzer,
                                   self.tones[self.songBuf[self.songIndex]],
                                   self.duty[self.vol])
            else:
                self.beeper2 = PWM(self.PinBuzzer,
                                   self.songBuf[self.songIndex],
                                   self.duty[self.vol])
            self.timer.init(period=int(self.songBuf[self.songIndex + 1] *
                                       self.timeunit * self.songSpeed),
                            mode=Timer.ONE_SHOT,
                            callback=self.handleInterrupt)
            self.songIndex += 2

    def startSong(self, songBuf=None):
        if self.bgm:
            if songBuf != None:
                self.songBuf = songBuf
            if self.songBuf[0] != self.songStart:
                print("Cannot start Song, Invalid songBuf")
                return False
            self.notes = self.songBuf[1]
            self.timeunit = self.songBuf[2]
            self.songIndex = 3
            if not self.timerInitialized:
                self.timerInitialized = True
                self.timer = Timer(1)
            self.timer.init(period=100,
                            mode=Timer.ONE_SHOT,
                            callback=self.handleInterrupt)

    def stopSong(self):
        self.songIndex = 0

    def random(self, x, y):
        return randint(x, y)

    def wait(self):
        timer_dif = int(1000 / self.frameRate) - ticks_diff(
            ticks_ms(), self.displayTimer)
        if timer_dif > 0:
            sleep_ms(timer_dif)
        self.displayTtimer = ticks_ms()
def peripheral_query(is_init, p_out_ctrla, p_out_ctrlb):
    import pycom
    import time
    import socket
    import binascii
    import struct
    import gc
    import sys
    import os
    import uio
    import ujson

    from machine import UART
    from machine import ADC
    from machine import I2C
    from machine import SPI
    from machine import Pin
    from tsl2591 import TSL2591

    with uio.open('/flash/configure.json', 'r', encoding="utf-8") as hdl:
        parsed_json = ujson.load(hdl)

    sht31 = parsed_json["firmware"]["sht31"]

    bias_nh3 = parsed_json["calibration"]["sensor_nh3"]["bias"]
    bias_so2 = parsed_json["calibration"]["sensor_so2"]["bias"]
    bias_h2s = parsed_json["calibration"]["sensor_h2s"]["bias"]

    di_nh3 = parsed_json["calibration"]["sensor_nh3"]["di"]
    di_so2 = parsed_json["calibration"]["sensor_so2"]["di"]
    di_h2s = parsed_json["calibration"]["sensor_h2s"]["di"]

    i0_nh3 = parsed_json["calibration"]["sensor_nh3"]["i0"]
    i0_so2 = parsed_json["calibration"]["sensor_so2"]["i0"]
    i0_h2s = parsed_json["calibration"]["sensor_h2s"]["i0"]

    vref = parsed_json["calibration"]["vref"]

    p_data = PeripheralData()
    print('[2]===================')

    adc0 = ADC(id=0)

    outer_iter = 0
    outer_iter_times = 20
    outer_buff_NH3 = []
    outer_buff_SO2 = []
    outer_buff_H2S = []

    while outer_iter < outer_iter_times:
        filtered_mvolts = _get_filtered_mvolts(adc0, vref)
        outer_buff_NH3.append(filtered_mvolts.NH3)
        outer_buff_SO2.append(filtered_mvolts.SO2)
        outer_buff_H2S.append(filtered_mvolts.H2S)
        outer_iter = outer_iter + 1
    buff_nh3 = sum(outer_buff_NH3) / outer_iter_times
    buff_so2 = sum(outer_buff_SO2) / outer_iter_times
    buff_h2s = sum(outer_buff_H2S) / outer_iter_times

    buff_nh3 = round((buff_nh3 - bias_nh3 - i0_nh3 * 47 * 0.624) * 50 /
                     (di_nh3 * 47 * 0.624), 1)
    adc0_str = '%.1f' % ((buff_nh3))
    p_data.NH3 = (buff_nh3)
    print('[2]NH3: ' + adc0_str)

    buff_so2 = round((buff_so2 - bias_so2 - i0_so2 * 47 * 0.624) * 20 /
                     (di_so2 * 47 * 0.624), 1)
    adc1_str = '%.1f' % ((buff_so2))
    p_data.SO2 = ((buff_so2))
    print('[2]SO2: ' + adc1_str)

    buff_h2s = round((buff_h2s - bias_h2s - i0_h2s * 47 * 0.624) * 50 /
                     (di_h2s * 47 * 0.624), 1)
    adc2_str = '%.1f' % ((buff_h2s))
    p_data.H2S = ((buff_h2s))
    print('[2]H2S: ' + adc2_str)
    adc0.deinit()
    time.sleep(0.01)

    adc3 = ADC(id=0)  # create an ADC object
    apin3 = adc3.channel(pin='P16')  # create an analog pin on P16
    adc3.vref(vref)
    adc3_str = '%.2f' % (apin3() * 220 / 4096)
    p_data.current = apin3() * 220 / 4096
    print('[2]Current@5V: ' + adc3_str + 'mA')
    adc3.deinit()

    p_out_ctrla.value(0)
    p_out_ctrlb.value(1)

    uart_mul = UART(1, baudrate=9600, pins=('P3', 'P4'))
    time.sleep(0.1)

    co2_set = is_init
    while co2_set == 0:
        uart_mul.write('K 2\r\n')
        time.sleep(0.05)
        dumm = uart_mul.readline()
        if dumm == bytes([]):
            print('[2]CO2 sensor no respose!')
            break
        else:
            dumm_str = dumm.decode('utf-8')
            if dumm_str == ' K 00002\r\n':
                print('[2]CO2 sensor polling set successfully...')
                time.sleep(0.05)
                co2_set = 1
            else:
                print('[2]CO2 sensor polling resetting...')
                time.sleep(0.05)
            uart_mul.write('M 00006\r\n')
            time.sleep(0.05)
            dumm_str = uart_mul.readall().decode('utf-8')
            if dumm_str == ' M 00006\r\n':
                print('[2]CO2 sensor key set successfully...')
            time.sleep(0.05)
    time.sleep(0.05)

    number = 0
    while number != 18:
        dummy = uart_mul.readall()
        uart_mul.write('Q\r\n')
        time.sleep(0.1)
        number = uart_mul.any()

    data_str = uart_mul.readall().decode("utf-8")
    print('[2]CO2_Filtered: ' + data_str[4:8])
    print('[2]CO2_Instant: ' + data_str[12:16])
    p_data.CO2 = int(data_str[4:8]) * 100 - 1600
    print('[2]CO2: ' + ('%d' % (p_data.CO2)))

    i2c = I2C(0, I2C.MASTER)
    i2c.init(I2C.MASTER, baudrate=100000, pins=('P9', 'P10'))
    time.sleep(0.05)
    #print(i2c.scan())

    if sht31 == 0:
        i2c.writeto(0x40, bytes([0xF3]))
        time.sleep(0.1)
        temperature_data = i2c.readfrom(0x40, 3)
        #print(temperature_data)
        time.sleep(0.1)
        temperature_value = _get_temperature_from_buffer(temperature_data)
        p_data.temp = temperature_value
        time.sleep(0.1)
        i2c.writeto(0x40, bytes([0xF5]))
        time.sleep(0.05)
        humidity_data = i2c.readfrom(0x40, 3)
        humidity_value = _get_humidity_from_buffer(humidity_data)
        p_data.humd = humidity_value

        humidity_value_str = '%.2f' % humidity_value
        temperature_value_str = '%.2f' % temperature_value
        print('[2]Humidity: ' + humidity_value_str)
        print('[2]Temperature: ' + temperature_value_str)
    else:
        i2c.writeto(0x44, bytes([0x24, 0x00]))
        time.sleep(0.02)
        combined_data = i2c.readfrom(0x44, 6)

        temperature_value = _get_sht31_temp_from_buffer(combined_data)
        p_data.temp = temperature_value

        humidity_value = _get_sht31_humidity_from_buffer(combined_data)
        p_data.humd = humidity_value

        humidity_value_str = '%.2f' % humidity_value
        temperature_value_str = '%.2f' % temperature_value
        print('[2]Humidity (SHT31): ' + humidity_value_str)
        print('[2]Temperature (SHT31): ' + temperature_value_str)

    lux_sensor = TSL2591(i2c)
    lux_flt = lux_sensor.lux
    p_data.lux = lux_flt
    print('[2]Light: ' + '%.2f' % lux_flt + 'lux')

    uart_mul = UART(1, baudrate=9600, pins=('P3', 'P4'))
    p_out_ctrla.value(1)
    p_out_ctrlb.value(0)
    time.sleep(0.1)
    ggflag = 0
    ddflag = 0
    while ggflag == 0 or ddflag == 0:
        while uart_mul.any() == 0:
            time.sleep(0.1)
        nmealine_bytes = uart_mul.readall()
        #print(nmealine_bytes)
        time.sleep(0.1)
        nmealine_all = nmealine_bytes.decode('utf-8')
        nmealine_all_split = nmealine_all.split('\r\n')
        for nmealine in nmealine_all_split:
            if (nmealine[0:6] == '$GNGGA') and (len(nmealine.split(',')) >=
                                                15) and (ggflag == 0):
                nmea_fields = nmealine.split(',')
                #print(nmea_fields)
                print('[2]Time: ' + nmea_fields[1])
                if nmea_fields[1] != '':
                    p_data.time = float(nmea_fields[1])
                print('[2]Lat: ' + nmea_fields[2] + nmea_fields[3])
                if nmea_fields[2] != '':
                    p_data.lat = float(nmea_fields[2])
                if nmea_fields[3] == 'S':
                    p_data.lat *= -1
                print('[2]Lon: ' + nmea_fields[4] + nmea_fields[5])
                if nmea_fields[4] != '':
                    p_data.Lon = float(nmea_fields[4])
                if nmea_fields[5] == 'W':
                    p_data.lon *= -1
                print('[2]Fix: ' + nmea_fields[6])
                print('[2]#Sat: ' + nmea_fields[7])
                print('[2]HDOP: ' + nmea_fields[8])
                print('[2]Alt: ' + nmea_fields[9])
                if nmea_fields[9] != '':
                    p_data.alt = float(nmea_fields[9])
                ggflag = 1
            elif (nmealine[0:6]
                  == '$GNRMC') and (len(nmealine.split(',')) >= 13) and (ddflag
                                                                         == 0):
                nmea_fields = nmealine.split(',')
                print('[2]Date: ' + nmea_fields[9])
                if nmea_fields[9] != '':
                    p_data.date = int(nmea_fields[9])
                ddflag = 1
    dummy = uart_mul.readall()
    p_data_bytes = PeripheralBytes(p_data)
    print('[2]===================')
    time.sleep(0.01)
    gc.collect()
    print(gc.mem_free())
    return p_data_bytes