Source code for findylab.sensor

"""Pulse counting (ULP co-processor).

The :class:`counter` class below is **verbatim** from the device
firmware (``firmware_core.py`` of Logger Pro v9).

Analog measurement note:
    There is no separate analog-sensor class in the firmware. Raw ADC
    conversions are done by :meth:`findylab.core.fw.adcMeasure` and the
    4-20 mA scaling happens inline in the user-editable ``measure()``
    hook in ``last.py``::

        ina1 = round(self.adcMeasure(b'\x90') / 100, 2)      # mA
        qty = (ina1 - sensor_min) * ((qty_max - qty_min) /
                                     (sensor_max - sensor_min))

    with the calibration values read from parameters 553-556 (AIN1) or
    578-581 (AIN2) - see :doc:`/datatypes/system-ids`.
"""

import time
import utime
import struct

import machine
from machine import mem32


[docs] class counter(object): """ULP pulse counting on the two digital inputs (IO4/IO14). Verbatim class from ``firmware_core.py``. The ESP32 ULP co-processor samples the inputs every few milliseconds and counts debounced edges - including during deep sleep. Never instantiated; the methods take no ``self``:: counter.getSamplings() Note: Requires ``ulp_main.bin`` in the device filesystem - without it :meth:`initCounter` raises ``OSError`` (``ENOENT``). """
[docs] def valFromMem(val): """Reads one counter value from ULP memory. Edge counters count both edges, so the raw value is halved. Args: val (int): ULP memory address. Returns: int: Pulse count (raw edge count // 2). """ from machine import mem32 return (mem32[val] & 0xFFFF)//2
[docs] def printAllSamplings(): """Dumps the ULP sample memory to the console (debug aid).""" from machine import mem32 aa = 0x500002a0 #the addition of 8 is to keep a visible guard area io4 = [] io14 = [] even = True while aa < ( 0x500002a0 + ( (0x168 - 0x10)*4)) : print(str(hex(aa)) + " = "+ hex(mem32[aa])) aa +=4
[docs] def getSamplings(): """Collects the pulse deltas since the previous wakeup. Verifies the ULP is alive (restarts it and clears the tracking parameters when frozen), reads both edge counters, computes the deltas with 15-bit overflow handling, accumulates them into parameters 437/439 and appends the deltas to ring-buffers 540/541. """ ulp_edge_count = 0x50000228 ulp_edge_count1 = 0x5000022c ulp_alive_counter = 0x5000023c ulp_save_counter=0x50000244 ulp_memory_pointer=0x50000248 ulp_max_memory_pointer = 0x5000024c alive = hex(mem32[ulp_alive_counter]) time.sleep(0.2) #print("Alive Counter") #print(hex(mem32[ulp_alive_counter])) # Reset if there's no activity from the ULP ulpReset = False if alive == hex(mem32[ulp_alive_counter]): print("ULP is not working") counter.initCounter() db.write('532','0') db.write('533','0') time.sleep(1) ulpReset = True #Calculate the difference of the edge counter and handle overflow currentEdge4 = counter.valFromMem(ulp_edge_count) currentEdge14 = counter.valFromMem(ulp_edge_count1) #print("Current Edge 4 = ",currentEdge4) #print("Current Edge 14 = ",currentEdge14) previousEdge4 = int(db.read('532')) previousEdge14 = int(db.read('533')) counter4 = int(db.read('437')) counter14 = int(db.read('439')) #print("Previous Edge 4 = ",previousEdge4) #print("Previous Edge 14 = ",previousEdge14) if ulpReset: print("ULP Reset exit!") currentEdge14 = previousEdge14 currentEdge4 = previousEdge4 return if currentEdge4 < previousEdge4: print("!!!Overflow 4 !!!") delta4 = (32767-previousEdge4) + currentEdge4 #currentEdge4 = (32767-previousEdge4) + previousEdge4 + currentEdge4 #print("New Current ", currentEdge4) else: delta4 = currentEdge4-previousEdge4 if currentEdge14 < previousEdge14: print("!!!Overflow 14 !!!") delta14 = (32767-previousEdge14) + currentEdge14 #currentEdge4 = (32767-previousEdge4) + previousEdge4 + currentEdge4 #print("New Current ", currentEdge4) else: delta14 = currentEdge14-previousEdge14 #print("Delta4 = ",delta4) #print("Delta14 = ",delta14) old4 = counter4 old14 = counter14 counter4 = counter4+delta4 newEdgge4 = currentEdge4 + delta4 db.write('437',counter4) db.write('532',currentEdge4) counter14 = counter14+delta14 newEdgge14 = currentEdge14 + delta14 db.write('439',counter14) db.write('533',currentEdge14) moment4 = counter4-old4 moment14 = counter14 - old14 #buffer.put('540',struct.pack("B", moment4) + b'\xff\xff') # #buffer.put('541',struct.pack("B", moment14) + b'\xff\xff') buffer.put('540',moment4.to_bytes(2, 'big') ) buffer.put('541',moment14.to_bytes(2, 'big')) return
[docs] def initCounter(): """Loads and starts the ULP counting program. Loads ``ulp_main.bin``, configures the input pins, debounce, wakeup pulse count and the save period (from parameter 421), starts the co-processor and opens fresh ring-buffer slots. Raises: OSError: When ``ulp_main.bin`` is missing (``ENOENT``). """ import esp32 from machine import mem32 from machine import Pin ulp_debounce_counter = 0x5000021c ulp_debounce_counter1 = 0x50000220 ulp_debounce_max_count = 0x50000224 ulp_edge_count = 0x50000228 ulp_edge_count1 = 0x5000022c ulp_io_number = 0x50000234 ulp_io_number2 = 0x50000238 ulp_edge_count_to_wake_up = 0x50000230 ulp_alive_counter = 0x5000023c ulp_save_period=0x50000240 ulp_save_counter=0x50000244 ulp_memory_pointer=0x50000248 ulp_max_memory_pointer = 0x5000024c u = esp32.ULP() f = open('ulp_main.bin','rb') binary = f.read() # 5000 = 5ms. Pulse = wakeUp_period*debounce*2 u.set_wakeup_period(0, 13888) u.load_binary(0,binary) #IO 4 mem32[ulp_io_number] = 10 #IO 14 mem32[ulp_io_number2] = 16 #How many edges at the same level have been caught mem32[ulp_debounce_counter] = 5 mem32[ulp_debounce_counter1] = 5 #How many times the same value must occur to accept a pulse mem32[ulp_debounce_max_count] = 2 #Pulse count - edge Counter/2 mem32[ulp_edge_count] = 0 mem32[ulp_edge_count1] = 0 #After how many pulses it should wake us up mem32[ulp_edge_count_to_wake_up] = 10 #how many times it has woken up, whether the ULP is working (5ms) mem32[ulp_alive_counter] = 0 #Every how many wakeups to save a value. 12000 -> a minute. Max -> 65000 #wakeup * Save #mem32[ulp_save_period] = 60000 period = db.read('421') #square(900/5000) #square(desired time/5000) #write frequency = pow(savePeriod*ulpTime (5000)) mem32[ulp_save_period] = 72*int(period)#6000 #Don't touch mem32[ulp_memory_pointer] = 0x10 mem32[ulp_max_memory_pointer] = 0x168 u.run(0) timestamp = device.getTimestamp() #db.write('443',timestamp) #timestamp = device.setTimestamp() #db.write('443',timestamp) buffer.create('540') buffer.create('541')