class ADXL362_MotionSensor(ADXL362): def __init__(self, csPIN, ISRPin, ActivityThreshold=70, ActivityTime=5, InactivityThreshold=1000, InactivityTime=5): self.steps = 0 ADXL362.__init__(self, csPIN) self.isrpin = Pin(ISRPin, mode=Pin.IN) self.isrpin.callback(trigger=Pin.IRQ_RISING, handler=self._isr_handler) self.setupDCActivityInterrupt(ActivityThreshold, ActivityTime) self.setupDCInactivityInterrupt(InactivityThreshold, InactivityTime) #ACTIVITY/INACTIVITY CONTROL REGISTER self.SPIwriteOneRegister( 0x27, 0B111111 ) #B111111 Link/Loop:11 (Loop Mode), Inactive Ref Mode:1,Inactive Enable (under threshold):1,Active Ref Mode:1, Active Enable (over threshold):1 #MAP INTERRUPT 1 REGISTER. self.SPIwriteOneRegister( 0x2A, 0B10010000 ) #B00010000 0=HIGH on ISR,AWAKE:0,INACT:0,ACT:1,FIFO_OVERRUN:0,FIFO_WATERMARK:0,FIFO_READY:0,DATA_READY:0 #POWER CONTROL REGISTER self.SPIwriteOneRegister( 0x2D, 0B1110 ) #B1011 Wake-up:1,Autosleep:0,measure:11=Reserved (Maybe works better) self.beginMeasure() time.sleep_ms(100) def _isr_handler(self, id): self.steps += 1
class Encoder(object): # create encoder for pins pa and pb and attach interrupt handlers def __init__(self, pin_x, pin_y): self._count = 0 self.x = Pin(pin_x, mode=Pin.IN) self.y = Pin(pin_y, mode=Pin.IN) self.x.callback(Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=self.x_callback) self.y.callback(Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=self.y_callback) def x_callback(self, _): self._count += 1 if self.x() ^ self.y() else -1 def y_callback(self, _): self._count += 1 if self.x() ^ self.y() ^ 1 else -1 @property def count(self): return self._count @property def count_and_reset(self): c = self._count self._count = 0 return c def reset(self): self._count = 0
class ResetButton: def __init__(self, pin): self._pin = Pin(pin, mode=Pin.IN, pull=Pin.PULL_UP) self._pin.callback(Pin.IRQ_FALLING, self._pin_handler) self._alarm = None self._alarm_step = .2 self._alarm_thres = 3 self._pressed = 0 def _press_handler(self, alarm): # if button is still pressed if not self._pin(): self._pressed += self._alarm_step print('pressed for {} seconds already'.format(self._pressed)) if self._pressed >= self._alarm_thres: self._pressed = 0 alarm.cancel() enter_provisioning_mode() else: self._pressed = 0 alarm.cancel() reset() def _pin_handler(self, pin): # print('got an interrupt on pin {}, value {}'.format(pin.id(), pin.value())) if not pin.value(): self._pressed = 0 if self._alarm: self._alarm.cancel() self._alarm = Timer.Alarm(self._press_handler, self._alarm_step, periodic=True)
def hardwareInit(switch): #init gc.disable() gc.enable() power_fail = Pin(POWER_FAIL_PIN, mode=Pin.IN, pull=Pin.PULL_UP) power_fail.callback(Pin.IRQ_RISING, _powerFail_cb) pf_state = debouncedPFSignal(power_fail) display = Pin('P8', mode=Pin.OUT) if pf_state == False: display.value(1) LED_OUT = Pin(LED_OUT_PIN, mode=Pin.OUT) LED_OUT.value(0) SWITCH_VDD = Pin('P20', mode=Pin.OUT) # old H/W version SWITCH_VCTL = Pin('P19', mode=Pin.OUT) SWITCH_VDD.value(1) SWITCH_VCTL.value(switch) power_fail_semaphore.acquire(0) # locked the sem return pf_state
class ButtonSensor(EventSensor): def __init__(self, queue, pinstr=BUTTON_PIN): self.pin = Pin(pinstr, mode=Pin.IN, pull=Pin.PULL_UP) self.pin.callback(Pin.IRQ_FALLING, self._event_handler) EventSensor.__init__(self, queue) pass def _event_handler(self, pin): self.printout('Button pressed') EventSensor._event_handler(self)
class ENCODEUR: def __init__(self, Enc_voieA_pin, Enc_voieB_pin, Pont_H_moteur): # Affectation des broches des encodeurs self.Enc_voieA_pin = Enc_voieA_pin self.Enc_voieB_pin = Enc_voieB_pin self.Pont_H_moteur = Pont_H_moteur self.EncodeurA = Pin(self.Enc_voieA_pin, mode=Pin.IN, pull=Pin.PULL_UP) self.EncodeurB = Pin(self.Enc_voieB_pin, mode=Pin.IN, pull=Pin.PULL_UP) # Définition des modalités d'IT et d'appel des routines d'IT associées aux encodeurs self.EncodeurA.callback( Pin.IRQ_RISING | Pin.IRQ_FALLING, self.IT_EncodeurA) # Interruption sur fronts montant et descendant self.EncodeurB.callback( Pin.IRQ_RISING | Pin.IRQ_FALLING, self.IT_EncodeurB) # Interruption sur fronts montant et descendant self.ticks_voieA = 0 self.ticks_voieB = 0 self.ticks_voieA_pid = 0 self.ticks_voieB_pid = 0 self.ticks_voieA_odometrie = 0 self.ticks_voieB_odometrie = 0 #--------------------------------------------------------------------------- # Fonction de gestion des encodeurs moteurs : gestion par IT def IT_EncodeurA(self, arg): self.ticks_voieA += 1 self.ticks_voieA_pid += 1 if (self.Pont_H_moteur.sens == SENS_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_DROIT_Flag) or ( self.Pont_H_moteur.sens == SENS_ANTI_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_GAUCHE_Flag): self.ticks_voieA_odometrie += 1 elif (self.Pont_H_moteur.sens == SENS_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_GAUCHE_Flag) or ( self.Pont_H_moteur.sens == SENS_ANTI_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_DROIT_Flag): self.ticks_voieA_odometrie -= 1 def IT_EncodeurB(self, arg): self.ticks_voieB += 1 self.ticks_voieB_pid += 1 if (self.Pont_H_moteur.sens == SENS_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_DROIT_Flag) or ( self.Pont_H_moteur.sens == SENS_ANTI_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_GAUCHE_Flag): self.ticks_voieB_odometrie += 1 elif (self.Pont_H_moteur.sens == SENS_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_GAUCHE_Flag) or ( self.Pont_H_moteur.sens == SENS_ANTI_HORAIRE and self.Pont_H_moteur.moteur_dg == MOTEUR_DROIT_Flag): self.ticks_voieB_odometrie -= 1
class TRIG: def __init__(self, pin1, pin2): self.result_p10 = None self.result_p25 = None self.start_p10 = 0 self.start_p25 = 0 if pin1 is not None: self.pin_p10 = Pin(pin1, Pin.IN, pull = Pin.PULL_UP) self.pin_p10.callback(Pin.IRQ_RISING | Pin.IRQ_FALLING, self.trig_p10) if pin2 is not None: self.pin_p25 = Pin(pin2, Pin.IN, pull = Pin.PULL_UP) self.pin_p25.callback(Pin.IRQ_RISING | Pin.IRQ_FALLING, self.trig_p25) def trig_p10(self, pin): if self.pin_p10.value() == 1: self.start_p10 = time.ticks_us() elif self.start_p10 is not 0: self.result_p10 = time.ticks_diff(self.start_p10, time.ticks_us()) self.start_p10 = 0 def trig_p25(self, pin): if self.pin_p25.value() == 1: self.start_p25 = time.ticks_us() elif self.start_p25 is not 0: self.result_p25 = time.ticks_diff(self.start_p25, time.ticks_us()) self.start_p25 = 0 def getDust_pm10(self): if self.result_p10 is None: return None else: result = self.result_p10 self.result_p10 = None return result def getDust_pm25(self): if self.result_p25 is None: return None else: result = self.result_p25 self.result_p25 = None return result
class encoder: def __init__(self, hallsensorApin, hallsensorBpin): self.count = 0 self.hallsensorA = Pin(hallsensorApin, mode=Pin.IN, pull=Pin.PULL_UP) self.hallsensorB = Pin('P21', mode=Pin.IN, pull=Pin.PULL_UP) self.count_max = 450 #This is the amount of pulses per revolution self.count_min = 0 def rencoder(self, direction): if direction == 'CW': self.count += 1 # if self.count==self.count_max: # self.count=0 elif direction == 'CCW': self.count -= 1 # if self.count==self.count_min: # self.count=1800 def reset_count(self): self.count = 0 def get_count(self): encoder.count def trigger(self, direction): # self.direction = direction # if self.direction =='CW': # self.hallsensorA.callback(Pin.IRQ_RISING, self.rencoder(direction), arg=None) # elif self.direction =='CCW': # self.hallsensorB.callback(Pin.IRQ_FALLING, self.rencoder(direction), arg=None) self.direction = direction if self.direction == 'CW': self.hallsensorA.callback(Pin.IRQ_RISING, self.rencoder(direction), arg=None) elif self.direction == 'CCW': self.hallsensorB.callback(Pin.IRQ_FALLING, self.rencoder(direction), arg=None)
class Button: def __init__(self, id): self.pressed = False self.btn = Pin(id, mode=Pin.IN, pull=Pin.PULL_UP) def on(self): self.btn.callback(Pin.IRQ_FALLING | Pin.IRQ_RISING, self._handler) def off(self): self.btn.callback(Pin.IRQ_FALLING | Pin.IRQ_RISING, None) def _handler(self, pin): value = pin.value() if not value and not self.pressed: print('Button pushed') self.pressed = True elif value and self.pressed: print('Button released') self.pressed = False else: pass
class BUTTON: def __init__(self,pid='P12',longms=1000): self.longms = longms self.butms = utime.ticks_ms() self.ticks_sign = utime.ticks_diff(1, 2) # get the sign of ticks_diff, e.g. in init code. self.pin = Pin(pid, mode=Pin.IN, pull=Pin.PULL_UP) self.pin.callback(Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self.press) def long(self): pass def short(self): print("short") pass def press(self,pin): #print("press :{}".format(pin)) #print("time :{}".format((utime.ticks_diff(self.butms, utime.ticks_ms()) * self.ticks_sign))) if (utime.ticks_diff(self.butms, utime.ticks_ms()) * self.ticks_sign) > 300 : self.short() self.butms = utime.ticks_ms() gc.collect()
class LIS2HH12: ACC_I2CADDR = const(30) PRODUCTID_REG = const(0x0F) ACT_THS = const(0x1E) ACT_DUR = const(0x1F) CTRL1_REG = const(0x20) CTRL2_REG = const(0x21) CTRL3_REG = const(0x22) CTRL4_REG = const(0x23) CTRL5_REG = const(0x24) CTRL6_REG = const(0x25) CTRL7_REG = const(0x26) STATUS_REG = const(0x27) ACC_X_L_REG = const(0x28) ACC_X_H_REG = const(0x29) ACC_Y_L_REG = const(0x2A) ACC_Y_H_REG = const(0x2B) ACC_Z_L_REG = const(0x2C) ACC_Z_H_REG = const(0x2D) FIFO_CTRL_REG = const(0x2E) FIFO_SRC_REG = const(0x2F) SCALES = {FULL_SCALE_2G: 4000, FULL_SCALE_4G: 8000, FULL_SCALE_8G: 16000} ODRS = [0, 10, 50, 100, 200, 400, 800] def __init__(self, pysense=None, sda='P22', scl='P21'): if pysense is not None: self.i2c = pysense.i2c else: from machine import I2C self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl)) self.odr = 0 self.full_scale = 0 self.x = 0 self.y = 0 self.z = 0 self.int_pin = None self.act_dur = 0 self.debounced = False self._user_handler = None # reboot the accelerometer, to be sure it works as expected self.force_reboot() whoami = self.i2c.readfrom_mem(ACC_I2CADDR, PRODUCTID_REG, 1) if (whoami[0] != 0x41): raise ValueError("LIS2HH12 not found") # enable acceleration readings at 50Hz self.set_odr(ODR_50_HZ) # change the full-scale to 4g self.set_full_scale(FULL_SCALE_4G) # set the interrupt pin as active low and open drain self.set_register(CTRL5_REG, 3, 0, 3) # make a first read self.acceleration() FIFO_EN = const(0x01 << 7) # CTRL3: FIFO enable. Default value 0. (0: disable; 1: enable) INT1_OVR = const(0x01 << 2) # FIFO overrun signal on INT1 FMODE = const(0x01 << 5) # FIFO_CTRL: FIFO mode selection: FIFO mode. Stops collecting data when FIFO is full def setup_fifo(self): # set the register to enable the FIFO self.set_register(CTRL3_REG, (FIFO_EN | INT1_OVR), 0, (FIFO_EN | INT1_OVR)) # set mode to FIFO mode self.set_register(FIFO_CTRL_REG, FMODE, 0, FMODE) def restart_fifo(self): # set mode to FIFO mode self.set_register(FIFO_CTRL_REG, 0, 0, FMODE) self.set_register(FIFO_CTRL_REG, FMODE, 0, FMODE) def enable_fifo_interrupt(self, handler=None): # enable the interrupt, which occurs, when fifo is full and set the corresponding handler self._user_handler = handler self.int_pin = Pin('P13', mode=Pin.IN) self.int_pin.callback(trigger=Pin.IRQ_FALLING, handler=self._int_handler) def acceleration(self): x = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_X_L_REG, 2) self.x = struct.unpack('<h', x) y = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_Y_L_REG, 2) self.y = struct.unpack('<h', y) z = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_Z_L_REG, 2) self.z = struct.unpack('<h', z) _mult = self.SCALES[self.full_scale] / ACC_G_DIV return (self.x[0] * _mult), (self.y[0] * _mult), (self.z[0] * _mult) def roll(self): x, y, z = self.acceleration() rad = math.atan2(-x, z) return (180 / math.pi) * rad def pitch(self): x, y, z = self.acceleration() rad = -math.atan2(y, (math.sqrt(x * x + z * z))) return (180 / math.pi) * rad def get_register(self, register): return self.i2c.readfrom_mem(ACC_I2CADDR, register, 1) def get_all_register(self): reg = bytearray(self.i2c.readfrom_mem(ACC_I2CADDR, CTRL1_REG, 8)) print(ubinascii.hexlify(reg)) def set_register(self, register, value, offset, mask): reg = bytearray(self.i2c.readfrom_mem(ACC_I2CADDR, register, 1)) reg[0] &= ~(mask << offset) reg[0] |= ((value & mask) << offset) self.i2c.writeto_mem(ACC_I2CADDR, register, reg) def set_full_scale(self, scale): self.set_register(CTRL4_REG, scale, 4, 3) self.full_scale = scale def set_odr(self, odr): self.set_register(CTRL1_REG, odr, 4, 7) self.odr = odr def set_high_pass(self, hp): # set FDS bit 0: internal filter bypassed; 1: data from internal filter sent to output register and FIFO self.set_register(CTRL2_REG, 1 if hp else 0, 2, 1) # set DFC[1:0] bits: High-pass filter cutoff frequency # 00=ODR/50, 01=ODR/100, 10=ODR/9, 11=ODR/400 self.set_register(CTRL2_REG, 3, 5, 2) def force_reboot(self): # set the BOOT bit and Force reboot, cleared as soon as the reboot is finished. Active high wait_loops = 0 self.set_register(CTRL6_REG, 1, 7, 1) while self.get_register(CTRL6_REG) >= b'\x80': time.sleep(0.1) wait_loops += 1 if wait_loops > 100: raise Exception("Timeout while waiting for read status") def enable_activity_interrupt(self, threshold, duration, handler=None): # Threshold is in mg, duration is ms self.act_dur = duration if threshold > self.SCALES[self.full_scale]: error = "threshold %d exceeds full scale %d" % (threshold, self.SCALES[self.full_scale]) print(error) raise ValueError(error) if threshold < self.SCALES[self.full_scale] / 128: error = "threshold %d below resolution %d" % (threshold, self.SCALES[self.full_scale] / 128) print(error) raise ValueError(error) if duration > 255 * 1000 * 8 / self.ODRS[self.odr]: error = "duration %d exceeds max possible value %d" % (duration, 255 * 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) if duration < 1000 * 8 / self.ODRS[self.odr]: error = "duration %d below resolution %d" % (duration, 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) _ths = int(127 * threshold / self.SCALES[self.full_scale]) & 0x7F _dur = int((duration * self.ODRS[self.odr]) / 1000 / 8) self.i2c.writeto_mem(ACC_I2CADDR, ACT_THS, _ths) self.i2c.writeto_mem(ACC_I2CADDR, ACT_DUR, _dur) # enable the activity/inactivity interrupt self.set_register(CTRL3_REG, 1, 5, 1) self._user_handler = handler self.int_pin = Pin('P13', mode=Pin.IN) self.int_pin.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self._int_handler) # return actual used threshold and duration return (_ths * self.SCALES[self.full_scale] / 128, _dur * 8 * 1000 / self.ODRS[self.odr]) def activity(self): if not self.debounced: time.sleep_ms(self.act_dur) self.debounced = True if self.int_pin(): return True return False def _int_handler(self, pin_o): if self._user_handler is not None: self._user_handler(pin_o) else: if pin_o(): print('Activity interrupt') else: print('Inactivity interrupt')
class BUTTON: def __init__(self, sensor, node, manager, status_alert=0, pid='P10', longms=1000): self.manager = manager self.pressms = 0 self.longms = longms self.pin = Pin(pid, mode=Pin.IN, pull=Pin.PULL_DOWN) self.pin.callback(Pin.IRQ_RISING, self.press) self.sensor = sensor self.node = node self.status_alert = status_alert self.args = (self.sensor, self.node, self.status_alert) print("Button setup!") def check_delay(self): return self.manager.can_press() def long(self): pass def short(self): pass def press(self, pin): print("{} pressed!".format(pin)) # state = disable_irq() # If never pressed, store press time if self.pressms == 0: self.pressms = ticks_ms() else: # If pressed within 500 ms of first press, discard (button bounce) if ticks_diff(self.pressms, ticks_ms()) < 500: return # Wait for value to stabilize for 10 ms i = 0 while i < 10: sleep_ms(1) if self.pin() == 0: i = 0 else: i += 1 if not self.check_delay(): self.manager.button_pressed() print("CANT PRESS YET! HAHA") print("button done") print('-------------------') print('\n') # enable_irq(state) rgb.blink_red(1, 1, 1) self.manager.button_depressed() return self.manager.button_pressed() # Measure button press duration while self.pin() == 1: i += 1 if i > self.longms: break sleep_ms(1) # Trigger short or long press if i > self.longms: start_new_thread(self.long, self.args) else: start_new_thread(self.short, self.args) # Wait for button release. while self.pin() == 1: pass self.pressms = 0 # enable_irq(state) rgb.blink_green(3) self.manager.button_depressed() gc.collect() print("button done!!") return 0
def create_button(): button = Pin("G17", Pin.IN, pull=Pin.PULL_UP) button.callback(Pin.IRQ_RISING, button_handler) # Interrupt on raising signal return button
from machine import Pin import time # Pin: P14 for Pysense board # Pin: G17 for Extension board is_pressed = False def handler(pin): global is_pressed value = pin.value() if not value and not is_pressed: print('Button pressed') is_pressed = True elif value and is_pressed: print('Button released') is_pressed = False else: pass btn = Pin("G17", mode=Pin.IN, pull=Pin.PULL_UP) btn.callback(Pin.IRQ_FALLING | Pin.IRQ_RISING, handler)
class LIS2HH12: ACC_I2CADDR = const(30) PRODUCTID_REG = const(0x0F) CTRL1_REG = const(0x20) CTRL2_REG = const(0x21) CTRL3_REG = const(0x22) CTRL4_REG = const(0x23) CTRL5_REG = const(0x24) ACC_X_L_REG = const(0x28) ACC_X_H_REG = const(0x29) ACC_Y_L_REG = const(0x2A) ACC_Y_H_REG = const(0x2B) ACC_Z_L_REG = const(0x2C) ACC_Z_H_REG = const(0x2D) ACT_THS = const(0x1E) ACT_DUR = const(0x1F) def __init__(self, pysense=None, sda='P22', scl='P21'): if pysense is not None: self.i2c = pysense.i2c else: from machine import I2C self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl)) self.reg = bytearray(1) self.odr = 0 self.full_scale = 0 self.x = 0 self.y = 0 self.z = 0 self.int_pin = None self.act_dur = 0 self.debounced = False self.scales = { FULL_SCALE_2G: 4000, FULL_SCALE_4G: 8000, FULL_SCALE_8G: 16000 } self.odrs = [0, 10, 50, 100, 200, 400, 800] whoami = self.i2c.readfrom_mem(ACC_I2CADDR, PRODUCTID_REG, 1) if (whoami[0] != 0x41): raise ValueError("LIS2HH12 not found") # enable acceleration readings at 50Hz self.set_odr(ODR_50_HZ) # change the full-scale to 4g self.set_full_scale(FULL_SCALE_4G) # set the interrupt pin as active low and open drain self.i2c.readfrom_mem_into(ACC_I2CADDR, CTRL5_REG, self.reg) self.reg[0] |= 0b00000011 self.i2c.writeto_mem(ACC_I2CADDR, CTRL5_REG, self.reg) # make a first read self.acceleration() def acceleration(self): x = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_X_L_REG, 2) self.x = struct.unpack('<h', x) y = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_Y_L_REG, 2) self.y = struct.unpack('<h', y) z = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_Z_L_REG, 2) self.z = struct.unpack('<h', z) _mult = self.scales[self.full_scale] / ACC_G_DIV return (self.x[0] * _mult, self.y[0] * _mult, self.z[0] * _mult) def roll(self): x, y, z = self.acceleration() rad = math.atan2(-x, z) return (180 / math.pi) * rad def pitch(self): x, y, z = self.acceleration() rad = -math.atan2(y, (math.sqrt(x * x + z * z))) return (180 / math.pi) * rad def set_full_scale(self, scale): self.i2c.readfrom_mem_into(ACC_I2CADDR, CTRL4_REG, self.reg) self.reg[0] &= ~0b00110000 self.reg[0] |= (scale & 3) << 4 self.i2c.writeto_mem(ACC_I2CADDR, CTRL4_REG, self.reg) self.full_scale = scale def set_odr(self, odr): self.i2c.readfrom_mem_into(ACC_I2CADDR, CTRL1_REG, self.reg) self.reg[0] &= ~0b01110000 self.reg[0] |= (odr & 7) << 4 self.i2c.writeto_mem(ACC_I2CADDR, CTRL1_REG, self.reg) self.odr = odr def enable_activity_interrupt(self, threshold, duration, handler=None): # Threshold is in mg, duration is ms self.act_dur = duration _ths = int( (threshold * self.scales[self.full_scale]) / 2000 / 128) & 0x7F _dur = int((duration * self.odrs[self.odr]) / 1000 / 8) self.i2c.writeto_mem(ACC_I2CADDR, ACT_THS, _ths) self.i2c.writeto_mem(ACC_I2CADDR, ACT_DUR, _dur) # enable the activity/inactivity interrupt self.i2c.readfrom_mem_into(ACC_I2CADDR, CTRL3_REG, self.reg) self.reg[0] |= 0b00100000 self.i2c.writeto_mem(ACC_I2CADDR, CTRL3_REG, self.reg) self._user_handler = handler self.int_pin = Pin('P13', mode=Pin.IN) self.int_pin.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self._int_handler) def activity(self): if not self.debounced: time.sleep_ms(self.act_dur) self.debounced = True if self.int_pin(): return True return False def _int_handler(self, pin_o): if self._user_handler is not None: self._user_handler(pin_o) else: if pin_o(): print('Activity interrupt') else: print('Inactivity interrupt')
blue_wire_oe_n = Pin('P11', mode=Pin.OUT, pull=Pin.PULL_UP) blue_wire_oe_n.value(1) uart1 = UART(1, 25000) uart1.init(25000, bits=8, parity=None, stop=1) ow = OneWire(Pin('P8', mode=Pin.OUT)) up_pin = Pin('P23', mode=Pin.IN, pull=Pin.PULL_DOWN) down_pin = Pin('P20', mode=Pin.IN, pull=Pin.PULL_DOWN) left_pin = Pin('P22', mode=Pin.IN, pull=Pin.PULL_DOWN) right_pin = Pin('P21', mode=Pin.IN, pull=Pin.PULL_DOWN) middle_pin = Pin('P19', mode=Pin.IN, pull=Pin.PULL_DOWN) up_pin.callback(Pin.IRQ_RISING, handler=button_handler, arg="up") down_pin.callback(Pin.IRQ_RISING, handler=button_handler, arg="down") left_pin.callback(Pin.IRQ_RISING, handler=button_handler, arg="left") right_pin.callback(Pin.IRQ_RISING, handler=button_handler, arg="right") middle_pin.callback(Pin.IRQ_RISING, handler=button_handler, arg="middle") displayType = lcd.kDisplayI2C128x64 lcd.initialize(displayType) temperature_update_thread = _thread.start_new_thread( get_update_temperature, (1, 1)) # Check to see if another device is communicating on the UART. If it is # we assume that there is an OEM controller connnected and we only sniff. # we only do this for SNIFF_PERIOD start_time = time.ticks_ms()
class MPU(object): def __init__(self, scl=None, sda=None, intr=None, led=None, rate=None, address=None): self.scl = scl if scl is not None else default_pin_scl self.sda = sda if sda is not None else default_pin_sda self.intr = intr if intr is not None else default_pin_intr self.led = led if led is not None else default_pin_led self.rate = rate if rate is not None else default_sample_rate self.WOM_handler = None self.address = address if address else MPU6050_DEFAULT_ADDRESS self.buffer = bytearray(16) self.bytebuf = memoryview(self.buffer[0:1]) self.wordbuf = memoryview(self.buffer[0:2]) self.sensors = bytearray(14) self.calibration = [0] * 7 self.filter = cfilter.ComplementaryFilter() self.init_pins() self.init_led() self.init_i2c() self.init_device() def write_byte(self, reg, val): self.bus.writeto_mem(self.address, reg, bytes([val])) def read_byte(self, reg): buf = bytearray(1) self.bus.readfrom_mem_into(self.address, reg, buf) return buf[0] def set_bitfield(self, reg, pos, length, val): old = self.read_byte(reg) shift = pos - length + 1 mask = (2**length - 1) << shift new = (old & ~mask) | (val << shift) self.write_byte(reg, new) def read_word(self, reg): buf = bytearray(2) self.bus.readfrom_mem_into(self.address, reg, buf) return unpack('>h', buf)[0] def init_i2c(self): l.debug('* initializing i2c') self.bus = I2C(0, mode=I2C.MASTER, pins=(self.pin_sda, self.pin_scl)) def init_pins(self): l.debug('* initializing pins') self.pin_sda = Pin(self.sda) self.pin_scl = Pin(self.scl) self.pin_intr = Pin(self.intr, mode=Pin.IN) #self.pin_led = PWM(Pin(self.led, mode=Pin.OUT)) def set_state_uncalibrated(self): #self.pin_led.freq(1) #self.pin_led.duty(500) pass def set_state_calibrating(self): #self.pin_led.freq(10) #self.pin_led.duty(500) pass def set_state_calibrated(self): #self.pin_led.freq(1000) #self.pin_led.duty(500) pass def set_state_disabled(self): #self.pin_led.duty(0) pass def init_led(self): #self.set_state_uncalibrated() pass def identify(self): l.debug('* identifying i2c device') val = self.read_byte(MPU6050_RA_WHO_AM_I) if val != MPU6050_ADDRESS_AD0_LOW: raise OSError("No mpu6050 at address {}".format(self.address)) def reset(self): l.debug('* reset') ''' self.write_byte(MPU6050_RA_PWR_MGMT_1, ( (1 << MPU6050_PWR1_DEVICE_RESET_BIT) )) time.sleep_ms(100) ''' self.write_byte(MPU6050_RA_SIGNAL_PATH_RESET, ((1 << MPU6050_PATHRESET_GYRO_RESET_BIT) | (1 << MPU6050_PATHRESET_ACCEL_RESET_BIT) | (1 << MPU6050_PATHRESET_TEMP_RESET_BIT))) time.sleep_ms(100) def init_device(self): l.debug('* initializing mpu') self.identify() # disable sleep mode and select clock source self.write_byte(MPU6050_RA_PWR_MGMT_1, MPU6050_CLOCK_PLL_XGYRO) # enable all sensors self.write_byte(MPU6050_RA_PWR_MGMT_2, 0) # set sampling rate self.write_byte(MPU6050_RA_SMPLRT_DIV, self.rate) # enable dlpf self.write_byte(MPU6050_RA_CONFIG, 1) # explicitly set accel/gyro range self.set_accel_range(MPU6050_ACCEL_FS_2) self.set_gyro_range(MPU6050_GYRO_FS_250) def set_gyro_range(self, fsr): self.gyro_range = gyro_range[fsr] self.set_bitfield(MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, fsr) def set_accel_range(self, fsr): self.accel_range = accel_range[fsr] self.set_bitfield(MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, fsr) def read_sensors(self): self.bus.readfrom_mem_into(self.address, MPU6050_RA_ACCEL_XOUT_H, self.sensors) data = unpack('>hhhhhhh', self.sensors) # apply calibration values return [data[i] + self.calibration[i] for i in range(7)] def read_sensors_scaled(self): data = self.read_sensors() data[0:3] = [x / (65536 // self.accel_range // 2) for x in data[0:3]] data[4:7] = [x / (65536 // self.gyro_range // 2) for x in data[4:7]] return data def read_position(self): self.filter.input(self.read_sensors_scaled()) return [ self.filter.filter_pos, self.filter.accel_pos, self.filter.gyro_pos, ] def set_dhpf_mode(self, bandwidth): self.set_bitfield(MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_ACCEL_HPF_BIT, MPU6050_ACONFIG_ACCEL_HPF_LENGTH, bandwidth) def set_motion_detection_threshold(self, threshold): self.write_byte(MPU6050_RA_MOT_THR, threshold) def set_motion_detection_duration(self, duration): self.write_byte(MPU6050_RA_MOT_DUR, duration) def set_int_motion_enabled(self, enabled): self.set_bitfield(MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_MOT_BIT, 1, enabled) def get_sensor_avg(self, samples, softstart=100): '''Return the average readings from the sensors over the given number of samples. Discard the first softstart samples to give things time to settle.''' sample = self.read_sensors() counters = [0] * 7 for i in range(samples + softstart): # the sleep here is to ensure we read a new sample # each time time.sleep_ms(2) sample = self.read_sensors() if i < softstart: continue for j, val in enumerate(sample): counters[j] += val return [x // samples for x in counters] stable_reading_timeout = 10 max_gyro_variance = 5 def wait_for_stable(self, numsamples=10): l.debug('* waiting for gyros to stabilize') gc.collect() time_start = time.time() samples = [] while True: now = time.time() if now - time_start > self.stable_reading_timeout: raise CalibrationFailure() # the sleep here is to ensure we read a new sample # each time time.sleep_ms(2) sample = self.read_sensors() samples.append(sample[4:7]) if len(samples) < numsamples: continue samples = samples[-numsamples:] totals = [0] * 3 for cola, colb in zip(samples, samples[1:]): deltas = [abs(a - b) for a, b in zip(cola, colb)] totals = [a + b for a, b in zip(deltas, totals)] avg = [a / numsamples for a in totals] l.debug("* delta = {}".format(avg)) if all(x < self.max_gyro_variance for x in avg): break now = time.time() l.debug('* gyros stable after {:0.2f} seconds'.format(now - time_start)) def calibrate(self, numsamples=None, accel_deadzone=None, gyro_deadzone=None): old_calibration = self.calibration self.calibration = [0] * 7 numsamples = (numsamples if numsamples is not None else default_calibration_numsamples) accel_deadzone = (accel_deadzone if accel_deadzone is not None else default_calibration_accel_deadzone) gyro_deadzone = (gyro_deadzone if gyro_deadzone is not None else default_calibration_gyro_deadzone) l.debug('* start calibration') self.set_state_calibrating() try: self.wait_for_stable() gc.collect() # calculate offsets between the expected values and # the average value for each sensor reading avg = self.get_sensor_avg(numsamples) off = [ 0 if expected[i] is None else expected[i] - avg[i] for i in range(7) ] accel_ready = False gyro_read = False for passno in range(20): self.calibration = off avg = self.get_sensor_avg(numsamples) check = [ 0 if expected[i] is None else expected[i] - avg[i] for i in range(7) ] l.debug('- pass {}: {}'.format(passno, check)) # check if current values are within acceptable offsets # from the expected values accel_ready = all(abs(x) < accel_deadzone for x in check[0:3]) gyro_ready = all(abs(x) < gyro_deadzone for x in check[4:7]) if accel_ready and gyro_ready: break if not accel_ready: off[0:3] = [ off[i] + check[i] // accel_deadzone for i in range(3) ] if not gyro_ready: off[4:7] = [ off[i] + check[i] // gyro_deadzone for i in range(4, 7) ] else: raise CalibrationFailure() except CalibrationFailure: self.calibration = old_calibration l.info('! calibration failed') self.set_state_uncalibrated() return l.info('* calibrated!') self.set_state_calibrated() def _WakeOnMotionINT(self, pin_o): l.debug("interrupt ok") l.info("got an interrupt in pin %s" % (pin_o.id())) a = mpu.read_byte(MPU6050_RA_INT_STATUS) #Reset Interrupts if self.WOM_handler is not None: self.WOM_handler(pin_o) def WakeOnMotion(self, threshold=0x14, duration=0x01, handler=None): # see doc : http://www.4tronix.co.uk/arduino/specs/mpu6050.pdf pg 33 # The sensor has a high-pass filter necessary to invoke to allow the sensor motion detection algorithms work properly # Motion detection occurs on free-fall (acceleration below a threshold for some time for all axes), motion (acceleration # above a threshold for some time on at least one axis), and zero-motion toggle (acceleration on each axis less than a # threshold for some time sets this flag, motion above the threshold turns it off). The high-pass filter takes gravity out # consideration for these threshold evaluations otherwise, the flags would be set all the time! self.WOM_handler = handler #self.pin_intr.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self._WakeOnMotionINT) self.pin_intr.callback(trigger=Pin.IRQ_RISING, handler=self._WakeOnMotionINT) a = mpu.read_byte(MPU6050_RA_INT_STATUS) #INT_OPEN When this bit is equal to 0, the INT pin is configured as push-pull. #LATCH_INT_EN When this bit is equal to 1, the INT pin is held high until the interrupt is cleared. mpu.write_byte(MPU6050_RA_INT_PIN_CFG, mpu.read_byte(MPU6050_RA_INT_PIN_CFG) & ~0xF8) mpu.write_byte(MPU6050_RA_INT_PIN_CFG, mpu.read_byte(MPU6050_RA_INT_PIN_CFG) | 0x20) #Set sleep and cycle bits [5:6] to zero to make sure accelerometer is running mpu.write_byte(MPU6050_RA_PWR_MGMT_1, mpu.read_byte(MPU6050_RA_PWR_MGMT_1) & ~0x60) #Set XA, YA, and ZA bits [3:5] to zero to make sure accelerometer is running mpu.write_byte(MPU6050_RA_PWR_MGMT_2, mpu.read_byte(MPU6050_RA_PWR_MGMT_2) & ~0x38) #Set ACCEL_HPF to 0 reset mode disbaling high-pass filter mpu.write_byte(MPU6050_RA_ACCEL_CONFIG, mpu.read_byte(MPU6050_RA_ACCEL_CONFIG) & ~0x07) #Set DLPD_CFG to 0 260 Hz bandwidth, 1 kHz rate mpu.write_byte(MPU6050_RA_CONFIG, mpu.read_byte(MPU6050_RA_CONFIG) & ~0x07) #Enable motion threshold (bits 5) interrupt only mpu.write_byte(MPU6050_RA_INT_ENABLE, 0x40) #Set motion detect duration to 1 ms LSB is 1 ms @ 1 kHz rate mpu.write_byte( MPU6050_RA_MOT_DUR, duration ) # Set motion detect duration to 1 ms LSB is 1 ms @ 1 kHz rate # Set motion detection to 20 LSB mpu.write_byte(MPU6050_RA_MOT_THR, threshold) # # Add delay for accumulation of samples time.sleep_ms(100) #Set ACCEL_HPF to 7 hold the initial accleration value as a referance mpu.write_byte(MPU6050_RA_ACCEL_CONFIG, mpu.read_byte(MPU6050_RA_ACCEL_CONFIG) | 0x07) #Set wakeup frequency to 5 Hz, and disable XG, YG, and ZG gyros (bits [0:2]) mpu.write_byte(MPU6050_RA_CONFIG, mpu.read_byte(MPU6050_RA_CONFIG) & ~0xC7) mpu.write_byte(MPU6050_RA_CONFIG, mpu.read_byte(MPU6050_RA_CONFIG) | 0x40 | 0x07) #Set cycle bit 5 to begin low power accelerometer motion interrupts mpu.write_byte(MPU6050_RA_PWR_MGMT_1, mpu.read_byte(MPU6050_RA_PWR_MGMT_1) & ~0x48) mpu.write_byte(MPU6050_RA_PWR_MGMT_1, mpu.read_byte(MPU6050_RA_PWR_MGMT_1) | 0x20) def enable_activity_interrupt(self, threshold, duration, handler=None): # Threshold is in mg, duration is ms # A faire mpu.write_byte( MPU6050_RA_INT_PIN_CFG, 0x20 ) #write register 0x37 to select how to use the interrupt pin. For an active high, push-pull signal that stays until register (decimal) 58 is read, write 0x20. self.set_dhpf_mode(MPU6050_DHPF_5) self.set_motion_detection_threshold(threshold) self.set_motion_detection_duration(duration) #self.set_int_motion_enabled(1) self.set_bitfield(MPU6050_RA_INT_ENABLE, MPU6050_INTERRUPT_FIFO_OFLOW_BIT, 1, 1) self._user_handler = handler self.pin_intr.callback(trigger=Pin.IRQ_RISING, handler=self._user_handler) a = mpu.read_byte(MPU6050_RA_INT_STATUS) @property def temperature(self): """Reads the temperature from the onboard temperature sensor of the MPU-6050. Returns the temperature in degrees Celcius. """ # Get the raw data raw_temp = self.read_word(MPU6050_RA_TEMP_OUT_H) # Get the actual temperature using the formule given in the # MPU-6050 Register Map and Descriptions revision 4.2, page 30 actual_temp = (raw_temp / 340) + 36.53 # Return the temperature return actual_temp @property def gyro(self): """Gyroscope X, Y, and Z axis data in º/s""" raw_data = bytearray(6) self.bus.readfrom_mem_into(self.address, MPU6050_RA_GYRO_XOUT_H, raw_data) raw = unpack('>hhh', raw_data) # setup range dependant scaling gyro_x = raw[0] / (65536 // self.gyro_range // 2) gyro_y = raw[1] / (65536 // self.gyro_range // 2) gyro_z = raw[2] / (65536 // self.gyro_range // 2) return (gyro_x, gyro_y, gyro_z) @property def acceleration(self): """Gyroscope X, Y, and Z axis data in º/s""" raw_data = bytearray(6) self.bus.readfrom_mem_into(self.address, MPU6050_RA_ACCEL_XOUT_H, raw_data) raw = unpack('>hhh', raw_data) # setup range dependant scaling accel_x = raw[0] / (65536 // self.accel_range // 2) accel_y = raw[1] / (65536 // self.accel_range // 2) accel_z = raw[2] / (65536 // self.accel_range // 2) return (accel_x, accel_y, accel_z)
class RFM69(RFM69_CONST_VARS): def __init__(self, cspin, ISRPin, nodeID, networkID, freqBand=868, isRFM69HW=False): RFM69_CONST_VARS.__init__(self) self._isRFM69HW = isRFM69HW tREG_FRFMSB = self.RF_FRFMSB_868 tREG_FRFMID = self.RF_FRFMID_868 tREG_FRFLSB = self.RF_FRFLSB_868 if freqBand==433: tREG_FRFMSB = self.RF_FRFMSB_433 tREG_FRFMID = self.RF_FRFMID_433 tREG_FRFLSB = self.RF_FRFLSB_433 if freqBand==315: tREG_FRFMSB = self.RF_FRFMSB_315 tREG_FRFMID = self.RF_FRFMID_315 tREG_FRFLSB = self.RF_FRFLSB_315 if freqBand==915: tREG_FRFMSB = self.RF_FRFMSB_915 tREG_FRFMID = self.RF_FRFMID_915 tREG_FRFLSB = self.RF_FRFLSB_915 self.CONFIG = [[self.REG_OPMODE, self.RF_OPMODE_SEQUENCER_ON | self.RF_OPMODE_LISTEN_OFF | self.RF_OPMODE_STANDBY], [self.REG_DATAMODUL, self.RF_DATAMODUL_DATAMODE_PACKET | self.RF_DATAMODUL_MODULATIONTYPE_FSK | self.RF_DATAMODUL_MODULATIONSHAPING_00], [self.REG_BITRATEMSB, self.RF_BITRATEMSB_55555], [self.REG_BITRATELSB, self.RF_BITRATELSB_55555], [self.REG_FDEVMSB, self.RF_FDEVMSB_50000], [self.REG_FDEVLSB, self.RF_FDEVLSB_50000], [self.REG_FRFMSB, tREG_FRFMSB ], [self.REG_FRFMID, tREG_FRFMID], [self.REG_FRFLSB, tREG_FRFLSB], [self.REG_RXBW, self.RF_RXBW_DCCFREQ_010 | self.RF_RXBW_MANT_16 | self.RF_RXBW_EXP_2 ], [self.REG_DIOMAPPING1, self.RF_DIOMAPPING1_DIO0_01], [self.REG_DIOMAPPING2, self.RF_DIOMAPPING2_CLKOUT_OFF], [self.REG_IRQFLAGS2, self.RF_IRQFLAGS2_FIFOOVERRUN], [self.REG_RSSITHRESH, 220], [self.REG_SYNCCONFIG, self.RF_SYNC_ON | self.RF_SYNC_FIFOFILL_AUTO | self.RF_SYNC_SIZE_2 | self.RF_SYNC_TOL_0], [self.REG_SYNCVALUE1, 0x2D], [self.REG_SYNCVALUE2, networkID ], [self.REG_PACKETCONFIG1, self.RF_PACKET1_FORMAT_VARIABLE | self.RF_PACKET1_DCFREE_OFF | self.RF_PACKET1_CRC_ON | self.RF_PACKET1_CRCAUTOCLEAR_ON | self.RF_PACKET1_ADRSFILTERING_OFF], [self.REG_FIFOTHRESH, self.RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | self.RF_FIFOTHRESH_VALUE], [self.REG_PACKETCONFIG2, self.RF_PACKET2_RXRESTARTDELAY_2BITS | self.RF_PACKET2_AUTORXRESTART_ON | self.RF_PACKET2_AES_OFF], [self.REG_TESTDAGC, self.RF_DAGC_IMPROVED_LOWBETA0]] self.cspin = Pin(cspin, mode=Pin.OUT) self.cspin.value(1) self.isrpin = Pin(ISRPin, mode=Pin.IN) self.isrpin.callback(trigger=Pin.IRQ_RISING, handler=self.isr0) self.spi = SPI(0, mode=SPI.MASTER, baudrate=1000000, polarity=0, phase=0, firstbit=SPI.MSB) start = millis() timeout = 50 while millis()-start < timeout: self.writeReg(self.REG_SYNCVALUE1, 0xAA) if self.readReg(self.REG_SYNCVALUE1) == 0xaa: break start = utime.ticks_ms() while utime.ticks_ms()-start < timeout: self.writeReg(self.REG_SYNCVALUE1, 0x55) if self.readReg(self.REG_SYNCVALUE1) == 0x55: break for item in self.CONFIG: self.writeReg(item[0], item[1]) self.encrypt(0) def getFrequency(self): return self.RF69_FSTEP * (self.readReg(self.REG_FRFMSB) << 16) + self.readReg(self.REG_FRFMID) + self.readReg(self.REG_FRFLSB) def setFrequency(self, freqHz): oldMode = self._mode if oldMode == self.RF69_MODE_TX: self.setMode(self.RF69_MODE_RX) freqHz /= self.RF69_FSTEP self.writeReg(self.REG_FRFMSB, freqHz >> 16) self.writeReg(self.REG_FRFMID, freqHz >> 8) self.writeReg(self.REG_FRFLSB, freqHz) if oldMode == self.RF69_MODE_RX: self.setMode(self.RF69_MODE_SYNTH) self.setMode(oldMode) def setMode(self, new_mode): if self._mode == new_mode: return if new_mode == self.RF69_MODE_TX: self.writeReg(self.REG_OPMODE, (self.readReg(self.REG_OPMODE) & 0xE3) | self.RF_OPMODE_TRANSMITTER) if self._isRFM69HW: self.setHighPowerRegs(True) if new_mode == self.RF69_MODE_RX: self.writeReg(self.REG_OPMODE, (self.readReg(self.REG_OPMODE) & 0xE3) | self.RF_OPMODE_RECEIVER) if self._isRFM69HW: self.setHighPowerRegs(False) if new_mode == self.RF69_MODE_SYNTH: self.writeReg(self.REG_OPMODE, (self.readReg(self.REG_OPMODE) & 0xE3) | self.RF_OPMODE_SYNTHESIZER) if new_mode == self.RF69_MODE_STANDBY: self.writeReg(self.REG_OPMODE, (self.readReg(self.REG_OPMODE) & 0xE3) | self.RF_OPMODE_STANDBY) if new_mode == self.RF69_MODE_SLEEP: self.writeReg(self.REG_OPMODE, (self.readReg(self.REG_OPMODE) & 0xE3) | self.RF_OPMODE_SLEEP) while self._mode == self.RF69_MODE_SLEEP and (self.readReg(self.REG_IRQFLAGS1) & self.RF_IRQFLAGS1_MODEREADY) == 0x00: pass self._mode = new_mode def sleep(self): self.setMode(self.RF69_MODE_SLEEP) def setAddress(self, addr): self._address = addr; self.writeReg(self.REG_NODEADRS, self._address) def setNetwork(self, networkID): self.writeReg(self.REG_SYNCVALUE2, networkID) def setPowerLevel(self, powerLevel): self._powerLevel = powerLevel if self._powerLevel > 31: self._powerLevel = 31 self.writeReg(self.REG_PALEVEL, (self.readReg(self.REG_PALEVEL) & 0xE0) | self._powerLevel); def canSend(self): if self._mode == self.RF69_MODE_RX and self.PAYLOADLEN == 0 and self.readRSSI() < self.CSMA_LIMIT: self.setMode(self.RF69_MODE_STANDBY) return True return False def send(self, toAddress, buffer, bufferSize, requestACK): self.writeReg(self.REG_PACKETCONFIG2, (self.readReg(self.REG_PACKETCONFIG2) & 0xFB) | self.RF_PACKET2_RXRESTART) now = millis() while self.canSend()==False and millis() - now < self.RF69_CSMA_LIMIT_MS: self.receiveDone() self.sendFrame(toAddress, buffer, bufferSize, requestACK, False) def sendWithRetry(self, toAddress, buffer, bufferSize, retries, retryWaitTime): for i in range(retries+1): self.send(toAddress, buffer, bufferSize, False) sentTime = millis() while millis() - sentTime < retryWaitTime: if self.ACKReceived(toAddress): return True return False def ACKReceived(self, fromNodeID): if self.receiveDone(): return (self.SENDERID == fromNodeID or fromNodeID == self.RF69_BROADCAST_ADDR) and self.ACK_RECEIVED return False def ACKRequested(self): return self.ACK_REQUESTED and (self.TARGETID != self.RF69_BROADCAST_ADDR) def sendACK(self, buffer, bufferSize): self.ACK_REQUESTED = 0 sender = self.SENDERID _RSSI = self.RSSI self.writeReg(self.REG_PACKETCONFIG2, (self.readReg(self.REG_PACKETCONFIG2) & 0xFB) | self.RF_PACKET2_RXRESTART) now = millis() while not self.canSend() and millis() - now < self.RF69_CSMA_LIMIT_MS: self.receiveDone() self.SENDERID = sender self.sendFrame(sender, buffer, bufferSize, False, True) self.RSSI = _RSSI def sendFrame(self, toAddress, buffer, bufferSize, requestACK, sendACK): self.setMode(self.RF69_MODE_STANDBY) while self.readReg(self.REG_IRQFLAGS1) & self.RF_IRQFLAGS1_MODEREADY == 0x00: pass self.writeReg(self.REG_DIOMAPPING1, self.RF_DIOMAPPING1_DIO0_00) if bufferSize > self.RF69_MAX_DATA_LEN: bufferSize = self.RF69_MAX_DATA_LEN CTLbyte = 0x00; if sendACK: CTLbyte = self.RFM69_CTL_SENDACK else: if requestACK: CTLbyte = self.RFM69_CTL_REQACK self.select(); self.spi.write(self.REG_FIFO | 0x80) self.spi.write(bufferSize + 3) self.spi.write(toAddress) self.spi.write(self._address) self.spi.write(CTLbyte) for i in range(bufferSize): self.spi.write(buffer[i]) self.unselect() self.setMode(self.RF69_MODE_TX) txStart = millis(); while (self.isrpin.value() == 0 and millis() - txStart < self.RF69_TX_LIMIT_MS): pass self.setMode(self.RF69_MODE_STANDBY); def interruptHandler(self, id): if self._mode == self.RF69_MODE_RX and (self.readReg(self.REG_IRQFLAGS2) & self.RF_IRQFLAGS2_PAYLOADREADY): self.setMode(self.RF69_MODE_STANDBY) self.select() self.spi.write(self.REG_FIFO & 0x7F) self.PAYLOADLEN = self.spi.read(1) self.PAYLOADLEN = self.PAYLOADLEN if self.PAYLOADLEN > 66: self.PAYLOADLEN = 66 self.TARGETID = self.spi.read(1) if not (self._promiscuousMode or self.TARGETID == self._address or self.TARGETID == self.RF69_BROADCAST_ADDR) or self.PAYLOADLEN < 3: self.PAYLOADLEN = 0 self.unselect() self.receiveBegin() return self.DATALEN = self.PAYLOADLEN - 3 self.SENDERID = self.spi.read(1) CTLbyte = self.spi.read(1) self.ACK_RECEIVED = CTLbyte & self.RFM69_CTL_SENDACK self.ACK_REQUESTED = CTLbyte & self.RFM69_CTL_REQACK self.interruptHook(CTLbyte) for i in range(self.DATALEN): self.DATA[i] = self.spi.read(1) if self.DATALEN < self.RF69_MAX_DATA_LEN: self.DATA[self.DATALEN] = 0 self.unselect() self.setMode(self.RF69_MODE_RX) self.RSSI = self.readRSSI() def isr0(self, id): self._inISR=True self.interruptHandler(id) self._inISR=False def receiveBegin(self): self.DATALEN = 0 self.SENDERID = 0 self.TARGETID = 0 self.PAYLOADLEN = 0 self.ACK_REQUESTED = 0 self.ACK_RECEIVED = 0 self.RSSI = 0 if self.readReg(self.REG_IRQFLAGS2) & self.RF_IRQFLAGS2_PAYLOADREADY: self.writeReg(self.REG_PACKETCONFIG2, (self.readReg(self.REG_PACKETCONFIG2) & 0xFB) |self.RF_PACKET2_RXRESTART) self.writeReg(self.REG_DIOMAPPING1, self.RF_DIOMAPPING1_DIO0_01) self.setMode(self.RF69_MODE_RX) def receiveDone(self): noInterrupts() if self._mode == self.RF69_MODE_RX and self.PAYLOADLEN > 0: self.setMode(self.RF69_MODE_STANDBY) return True else: if self._mode==self.RF69_MODE_RX: interrupts() return False self.receiveBegin() return False def encrypt(self, key): self.setMode(self.RF69_MODE_STANDBY) if key != 0: self.select() self.spi.write(self.REG_AESKEY1 | 0x80) for i in range(16): self.spi.write(key[i]) self.unselect() val = 1 if key==None: val = 0 self.writeReg(self.REG_PACKETCONFIG2, (self.readReg(self.REG_PACKETCONFIG2) & 0xFE) | val) def readRSSI(self, forceTrigger): rssi = 0 if forceTrigger: self.writeReg(self.REG_RSSICONFIG, self.RF_RSSI_START) while (self.readReg(self.REG_RSSICONFIG) & self.RF_RSSI_DONE) == 0x00: pass rssi = -self.readReg(self.REG_RSSIVALUE) rssi = rssi >> 1 return rssi def readReg(self, addr): self.select() self.spi.write(addr & 0x7F) regValue = self.spi.read(1) self.unselect() return regValue def writeReg(self, addr, value): self.select() self.spi.write(addr | 0x80) self.spi.write(value) self.unselect() def select(self): self.cspin.value(0) def unselect(self): self.cspin.value(1) def promiscuous(self, onOff): self._promiscuousMode = onOff def setHighPower(self, onOff): self._isRFM69HW = onOff if self._isRFM69HW: self.writeReg(self.REG_OCP, self.RF_OCP_OFF) self.writeReg(self.REG_PALEVEL, (self.readReg(self.REG_PALEVEL) & 0x1F) | self.RF_PALEVEL_PA1_ON | self.RF_PALEVEL_PA2_ON) else: self.writeReg(self.REG_OCP, self.RF_OCP_ON) self.writeReg(self.REG_PALEVEL, self.RF_PALEVEL_PA0_ON | self.RF_PALEVEL_PA1_OFF | self.RF_PALEVEL_PA2_OFF | self._powerLevel) def setHighPowerRegs(self, onOff): if onOff: self.writeReg(self.REG_TESTPA1, 0x5D) self.writeReg(self.REG_TESTPA2, 0x7C) else: self.writeReg(self.REG_TESTPA1, 0x55) self.writeReg(self.REG_TESTPA2, 0x70) def setCS(self, newSPISlaveSelect): self._slaveSelectPin = newSPISlaveSelect self.cspin = Pin(self._slaveSelectPin, mode=Pin.OUT) self.cspin.value(1) def readAllRegs(self): regVal = 0 print("Address - HEX - BIN") for regAddr in range(1, 0x4F): self.select() self.spi.write(regAddr & 0x7F) regVal = self.spi.read(1) self.unselect() print(regAddr, " - ", regVal) def readTemperature(self, calFactor): self.setMode(self.RF69_MODE_STANDBY); self.writeReg(self.REG_TEMP1, self.RF_TEMP1_MEAS_START) while self.readReg(self.REG_TEMP1) & self.RF_TEMP1_MEAS_RUNNING: pass return ~self.readReg(self.REG_TEMP2) + self.COURSE_TEMP_COEF + calFactor def rcCalibration(self): self.writeReg(self.REG_OSC1, self.RF_OSC1_RCCAL_START) while (self.readReg(self.REG_OSC1) & self.RF_OSC1_RCCAL_DONE) == 0x00: pass def maybeInterrupts(self): if not self._inISR: interrupts() def initialize(self): pass
class LIS2HH12: ACC_I2CADDR = const(30) #1E PRODUCTID_REG = const(0x0F) CTRL1_REG = const(0x20) CTRL2_REG = const(0x21) CTRL3_REG = const(0x22) CTRL4_REG = const(0x23) CTRL5_REG = const(0x24) ACC_X_L_REG = const(0x28) ACC_X_H_REG = const(0x29) ACC_Y_L_REG = const(0x2A) ACC_Y_H_REG = const(0x2B) ACC_Z_L_REG = const(0x2C) ACC_Z_H_REG = const(0x2D) ACT_THS = const(0x1E) ACT_DUR = const(0x1F) FIFO_CTRL = const(0x2E) FIFO_SRC = const(0x2F) SCALES = {FULL_SCALE_2G: 4000, FULL_SCALE_4G: 8000, FULL_SCALE_8G: 16000} ODRS = [0, 10, 50, 100, 200, 400, 800] def __init__(self, pysense = None, sda = 'P22', scl = 'P21'): if pysense is not None: self.i2c = pysense.i2c else: from machine import I2C self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl)) self.odr = 0 self.full_scale = 0 self.x = 0 self.y = 0 self.z = 0 self.int_pin = None self.act_dur = 0 self.debounced = False whoami = self.i2c.readfrom_mem(ACC_I2CADDR , PRODUCTID_REG, 1) if (whoami[0] != 0x41): raise ValueError("LIS2HH12 not found") # enable acceleration readings at 800Hz self.set_odr(ODR_800_HZ) # change the full-scale to 2g self.set_full_scale(FULL_SCALE_2G) # set the interrupt pin as active low and open drain self.set_register(CTRL5_REG, 3, 0, 3) # set FIFO control registry (FIFO_MODE) set_register(self, register, value, offset, mask): self.set_register(FIFO_CTRL, FIFO_STREAM_MODE, 5, 7) # set FIFO control registry (FIFO_FTH) set_register(self, register, value, offset, mask): self.set_register(FIFO_CTRL, FTH_10_SAMPLE, 0, 4) #FIFO Enable: #config_Reg3 = b'\xc2' #11000010 - Enable FIFO and set FIFO threshold signal on INT1 config_Reg3 = b'\xc1' #11000001 - Enable FIFO and data ready on INT1 self.i2c.writeto_mem(ACC_I2CADDR, CTRL3_REG, config_Reg3) #control3 = bytearray(0x01010101) #self.i2c.writeto_mem(ACC_I2CADDR, CTRL3_REG, control3) #self.set_register(CTRL3_REG, 0, 0, 8) # Enable activity interrupt: # make a first read; comment this out, makes the readings go slow. #self.acceleration() def acceleration(self): x = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_X_L_REG, 2) self.x = struct.unpack('<h', x) y = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_Y_L_REG, 2) self.y = struct.unpack('<h', y) z = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_Z_L_REG, 2) self.z = struct.unpack('<h', z) _mult = self.SCALES[self.full_scale] / ACC_G_DIV return (self.x[0] * _mult, self.y[0] * _mult, self.z[0] * _mult) #return(self.x, self.y, self.z) def accelerationOneGoRaw(self): xyz = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_X_L_REG, 6) #Reading 6byte after 0x28, 2byte for each direction return (xyz) def fifoControlRead(self): fifo_output = self.i2c.readfrom_mem(ACC_I2CADDR , FIFO_CTRL, 1) return (fifo_output) def fifoSourceRead(self): fifo_output = self.i2c.readfrom_mem(ACC_I2CADDR , FIFO_SRC, 1) return (fifo_output) def fifoDataRead(self, samples): fifo_output = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_X_L_REG, 6*samples) return (fifo_output) def roll(self): x,y,z = self.acceleration() rad = math.atan2(-x, z) return (180 / math.pi) * rad def pitch(self): x,y,z = self.acceleration() rad = -math.atan2(y, (math.sqrt(x*x + z*z))) return (180 / math.pi) * rad def set_register(self, register, value, offset, mask): reg = bytearray(self.i2c.readfrom_mem(ACC_I2CADDR, register, 1)) reg[0] &= ~(mask << offset) reg[0] |= ((value & mask) << offset) self.i2c.writeto_mem(ACC_I2CADDR, register, reg) def set_full_scale(self, scale): self.set_register(CTRL4_REG, scale, 4, 3) self.full_scale = scale def set_odr(self, odr): self.set_register(CTRL1_REG, odr, 4, 7) self.odr = odr def set_high_pass(self, hp): self.set_register(CTRL2_REG, 1 if hp else 0, 2, 1) def enable_activity_interrupt(self, threshold, duration, handler=None): # Threshold is in mg, duration is ms self.act_dur = duration if threshold > self.SCALES[self.full_scale]: error = "threshold %d exceeds full scale %d" % (threshold, self.SCALES[self.full_scale]) print(error) raise ValueError(error) if threshold < self.SCALES[self.full_scale] / 128: error = "threshold %d below resolution %d" % (threshold, self.SCALES[self.full_scale]/128) print(error) raise ValueError(error) if duration > 255 * 1000 * 8 / self.ODRS[self.odr]: error = "duration %d exceeds max possible value %d" % (duration, 255 * 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) if duration < 1000 * 8 / self.ODRS[self.odr]: error = "duration %d below resolution %d" % (duration, 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) _ths = int(127 * threshold / self.SCALES[self.full_scale]) & 0x7F _dur = int((duration * self.ODRS[self.odr]) / 1000 / 8) self.i2c.writeto_mem(ACC_I2CADDR, ACT_THS, _ths) self.i2c.writeto_mem(ACC_I2CADDR, ACT_DUR, _dur) # enable the activity/inactivity interrupt # self.set_register(CTRL3_REG, 1, 5, 1) self._user_handler = handler self.int_pin = Pin('P13', mode=Pin.IN) self.int_pin.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self._int_handler) # return actual used threshold and duration return (_ths * self.SCALES[self.full_scale] / 128, _dur * 8 * 1000 / self.ODRS[self.odr]) def activity(self): if not self.debounced: time.sleep_ms(self.act_dur) self.debounced = True if self.int_pin(): return True return False def _int_handler(self, pin_o): if self._user_handler is not None: self._user_handler(pin_o) else: if pin_o(): print('Activity interrupt') else: print('Inactivity interrupt')
global blinking blinking = False def bothLights(): global inLaneLed global outLaneLed global timeON inLaneLed.value(1) outLaneLed.value(1) time.sleep(timeON) inLaneLed.value(0) outLaneLed.value(0) def bounceCheck(timeStamp): global bounceTime if time.ticks_diff(utime.ticks_ms(), timeForLastSwitch) < bounceTime: print('to soon probably a bounce') return True return False print('after functions') laneSwitchButton.callback(Pin.IRQ_FALLING, laneSwitch) startButton.callback(Pin.IRQ_FALLING, startFunction)
def pin_handler(arg): print("got an interrupt in pin %s" % (arg.id())) #machine.disable_irq() #machine. #time.sleep_ms(200) #machine.enable_irq() #def timer_handler(arg): # print ("i") #t = Timer.Alarm(timer_handler, 0, 0, 1, None, True) p_in = Pin('P8', mode=Pin.IN, pull=Pin.PULL_UP) p_in.callback(Pin.IRQ_FALLING, pin_handler) #Antenna first!!!!!!!! #sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ1) #s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW) #s.setblocking(True) #s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False) #s.send(bytes([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])) #==================================================================================================== #HX711 & Temp #==================================================================================================== #DS18B20 data line connected to pin P9 ow = OneWire(Pin('P9')) temp = DS18X20(ow)
walklight[1].value(1) utime.sleep_ms(500) # Stop=green, walk=red walklight[1].value(0) walklight[0].value(1) utime.sleep_ms(500) # Give the pedestrian a chance to see it stoplight[0].value(0) stoplight[2].value(1) # Create callback for the button def button_pressed(line): cur_value = button.value() active = 0 while (active < 50): if button.value() != cur_value: active += 1 else: active = 0 utime.sleep_ms(1) print("") if active: cycle_lights() else: print("False press") # Create an interrupt for the button button.callback(Pin.IRQ_FALLING, button_pressed)
pycom.heartbeat(False) client = MQTTClient(id, "io.adafruit.com", user="******", password="******", port=1883, keepalive=keepalive) client.set_last_will(LOG_TOPIC, id + b' is down') client.set_callback(sub_cb) client.connect() client.subscribe(topic=LED_STATE_TOPIC) button = Pin('P14', mode=Pin.IN, pull=None) button.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=button_cb) client.publish(topic=LOG_TOPIC, msg=id + b' is up') last_message = time.time() while True: client.check_msg() if button_changed == True: button_changed = False if button() == 0: msg = "ON" else: msg = "OFF"
class BQ25895: I2CADDR = const(0x6A) def __init__(self, sda='P9', scl='P10', intr='P19', handler=None): from machine import I2C self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl)) self._user_handler = handler self.reset() self.pg_stat_last = self.read_byte(0x0B) & 0b00000100 self.pin_intr = Pin(intr, mode=Pin.IN, pull=Pin.PULL_UP) self.pin_intr.callback(trigger=Pin.IRQ_FALLING, handler=self._int_handler) def _int_handler(self, pin_o): l.info("BQ>BQ25895 interrupt") REG0C1 = self.read_byte( 0x0C) #1st read reports the pre-existing fault register REG0C2 = self.read_byte( 0x0C) #2nd read reports the current fault register status REG0B = self.read_byte( 0x0B) #2nd read reports the current fault register status l.debug("0x0C1st:{:08b} 0x0C2nd:{:08b} 0x0B:{:08b}".format( REG0C1, REG0C2, REG0B)) if self.pg_stat_last != REG0B & 0b00000100: self.pg_stat_last = REG0B & 0b00000100 if REG0B & 0b00000100 > 1: print("RAZ pwr_uAH ") pycom.nvs_set("pwr_uAH", 0) if self._user_handler is not None: self._user_handler(REG0C1, REG0C2, REG0B) def _setBit(self, reg, values): if len(values) == 8: values.reverse() regVal = self.i2c.readfrom_mem(I2CADDR, reg, 1)[0] regValOld = regVal for i, value in enumerate(values): if value == 1: mask = 1 << i regVal = (regVal | mask) elif value == 0: mask = ~(1 << i) regVal = (regVal & mask) if regValOld != regVal: self.i2c.writeto_mem(I2CADDR, reg, regVal) l.debug("BQ>write : {} > {} to {:02X}".format( values, bin(regVal), reg)) def read_byte(self, reg): regVal = self.i2c.readfrom_mem(I2CADDR, reg, 1)[0] return regVal def reset(self): self._setBit( 0x14, [1, None, None, None, None, None, None, None]) #reset chip self._setBit(0x02, [ None, 1, None, None, None, None, None, None ]) #ADC Conversion Rate Selection – Start 1s Continuous Conversion self._setBit( 0x07, [None, None, 0, 0, None, None, None, None]) #disable watchdog #self._setBit(0x00,[None,1,1,1,1,1,1,1]) #self._setBit(0x04,[1,None,None,None,None,None,None,None]) #enable current pulse control #self._setBit(0x04,[None,None,None,None,None,None,1,None]) #enable current pulse control UP & DN def charge_enable(self, enable): self._setBit( 0x03, [None, None, None, 1 if enable == True else 0, None, None, None]) pass def vbus_type(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x0B, 1) return ret[0] >> 5 def vbus_type_str(self): ret = self.vbus_type() return VBUS_TYPE[ret] def chrg_stat(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x0B, 1) return (ret[0] & 0b00011000) >> 3 def chrg_stat_str(self): ret = self.chrg_stat() return CHRG_STAT[ret] def read_battery_percent(self): if self.chrg_stat(): ret = 100 else: vbat = self.read_battery_volt() if vbat >= 4200: ret = 100 elif vbat <= 2800: ret = 0 else: ret = int((vbat - 2800) / 1400 * 100) return ret def pg_stat(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x0B, 1) l.debug("ret:{}".format(ret)) return (ret[0] & 0b00000100) >> 2 def pg_stat_str(self): ret = self.pg_stat() l.debug("ret:{}".format(ret)) return PG_STAT[ret] def vsys_stat(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x0B, 1) return (ret[0] & 0b00000001) def vsys_stat_str(self): ret = self.pg_stat() return "Regulation" if ret == 1 else "Not Regulation" def read_battery_volt(self): #in mv ret = self.i2c.readfrom_mem(I2CADDR, 0x0E, 1) volt = 2304 + (int(ret[0] & 0b01111111) * 20) return volt def read_sys_volt(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x0F, 1) volt = 2304 + (int(ret[0] & 0b01111111) * 20) return volt def read_TS_per(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x10, 1) volt = 21 + (int(ret[0] & 0b01111111) * 0.465) return volt def read_stat(self): ret1 = self.i2c.readfrom_mem(I2CADDR, 0x0B, 1) ret2 = self.i2c.readfrom_mem(I2CADDR, 0x0C, 1) #print("0x0B:{:08b}, 0x0C:{:08b}".format(ord(ret1),ord(ret2))) return [ret1, ret2] def read_vbus_volt(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x11, 1) volt = 2600 + (int(ret[0] & 0b01111111) * 100) return volt def read_temperature(self): #??????????? ret = self.i2c.readfrom_mem(I2CADDR, 0x10, 1) temp = 21 + (int(ret[0] & 0b01111111) * 0.465) return temp def read_charge_current(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x12, 1) amp = 0 + (int(ret[0] & 0b01111111) * 50) return amp def set_charge_current(self, m_A): if m_A > 5056: m_A = 5056 regVal = int(m_A / 64) _setBit(0x04, [ None, 1 if (regVal & 0b01000000) > 0 else 0, 1 if (regVal & 0b00100000) > 0 else 0, 1 if (regVal & 0b00010000) > 0 else 0, 1 if (regVal & 0b00001000) > 0 else 0, 1 if (regVal & 0b00000100) > 0 else 0, 1 if (regVal & 0b00000010) > 0 else 0, 1 if (regVal & 0b00000001) > 0 else 0 ]) def read_input_current_max(self): ret = self.i2c.readfrom_mem(I2CADDR, 0x00, 1) amp = (100 + int(ret[0] & 0b00111111) * 50) return amp def set_input_current_max(self, m_A): if m_A > 3250: m_A = 3250 elif m_A < 100: m_A = 100 regVal = int((m_A - 100) / 50) self._setBit(0x00, [ None, None, 1 if (regVal & 0b00100000) > 0 else 0, 1 if (regVal & 0b00010000) > 0 else 0, 1 if (regVal & 0b00001000) > 0 else 0, 1 if (regVal & 0b00000100) > 0 else 0, 1 if (regVal & 0b00000010) > 0 else 0, 1 if (regVal & 0b00000001) > 0 else 0 ]) #inner class #Uniquement avec un ESP32 pour mesurer le courant d'entrée class POWER: # voltage taken from ILIM and amplified by an ampli op def __init__(self, bq25895): self._bq25895 = bq25895 self.adc = ADC() self.p_SHDN_ = Pin('P21', mode=Pin.OUT) #shutdown/enable ampli op self.pwr_ticks = utime.ticks_us() try: pycom.nvs_get("pwr_uAH") except Exception as e: pycom.nvs_set("pwr_uAH", 0) self.pwr_nAH = 0 self.__alarm = Timer.Alarm(self.mesure, 1, periodic=True) def __del__(self): self.__alarm.cancel() self.__alarm = None def reset(self): l.debug("BQ>reset chip") self.pwr_nAH = 0 pycom.nvs_set("pwr_uAH", 0) def getPWR(self): #en RILIM = 130 KILIM = 365 GAIN = 12.12 self.p_SHDN_.value(1) utime.sleep_us(10) #Enable Delay Time from Shutdown #ADC.ATTN_0DB (0-1), ADC.ATTN_2_5DB(0-1.33), ADC.ATTN_6DB(0-2), ADC.ATTN_11DB(0-3.55) ILIM = VILIM = 0 ADC_GAIN = [0, 1.334, 1.995, 3.548] for i, e in reversed(list(enumerate(ADC_GAIN))): adc_ILIM = self.adc.channel(attn=i, pin='P20') ILIM = adc_ILIM() if ILIM < 2000 and i > 0: pass else: VILIM = adc_ILIM.voltage() break if ILIM > 0: PWIN_I = (KILIM * (VILIM / GAIN)) / (RILIM * 0.8) elif self._bq25895.pg_stat( ) > 0: #PYCOM mais prob avec ADC ESP32 pour faible valeur PWIN_I = 60.0 else: PWIN_I = 0 #print("ADC : {}, ADC_v = {}, PWIN_I : {}".format(adc_ILIM(), VILIM, PWIN_I) ) self.p_SHDN_.value(0) l.debug("BQ>ATTN:{}, ILIM:{}, PWIN_I:{}".format( ADC_GAINstr[i], ILIM, PWIN_I)) return PWIN_I def mesure(self, alarm): old = self.pwr_ticks self.pwr_ticks = utime.ticks_us() delta = utime.ticks_diff(self.pwr_ticks, old) self.pwr_nAH = self.pwr_nAH + int(self.getPWR() * delta / 3600) uAH = self.pwr_nAH // 1000 #print("nAH : {}, uAH : {}".format(self.pwr_nAH, uAH)) if uAH > 0: self.pwr_nAH = self.pwr_nAH - (uAH * 1000) uAH = pycom.nvs_get("pwr_uAH") + uAH #print("pwr_uAH :{}".format(uAH)) pycom.nvs_set("pwr_uAH", uAH) @property def pwr_uAH(self): return pycom.nvs_get("pwr_uAH") @property def pwr_mAH(self): return int(round(pycom.nvs_get("pwr_uAH") / 1000))
led = Pin('G16', mode=Pin.OUT) # initialize GP17 in gpio mode and make it an input with the # pull-up enabled button = Pin('G17', mode=Pin.IN, pull=Pin.PULL_UP) counter = 0 def callback(p): global counter print('pin change. counter', counter) led.toggle() counter = counter + 1 button.callback(trigger=Pin.IRQ_FALLING, handler=callback) pycom.heartbeat(False) print('stating test 1.3') print(os.uname()) #while True: for cycles in range(5): # stop after 5 cycles # send some data print('diod: green ', cycles) pycom.rgbled(0x007f00) # green time.sleep(2) print('diod: red ', cycles) pycom.rgbled(0x7f0000) # red time.sleep(2) print('diod: blue ', cycles) pycom.rgbled(0x00007f) # blue
return(ris) # initialize display oled # https://docs.pycom.io/pycom_esp32/library/machine.I2C.html i2c = I2C(0, I2C.MASTER, baudrate=100000) # use grove oled display grove_oled_display = SSD1308_I2C(objI2C=i2c) display = Writer(grove_oled_display, myfont) gc.collect() # free ram Writer.set_clip(True, True) print("Start measurement:") alarmTimer = Timer.Alarm(seconds_handler, 1, periodic=True) # buzTimer = Timer.Alarm(buzzerON_timer, us=1000, periodic=True) # alarmTimer = Timer.Alarm(minutes_handler, 60, periodic=True) sigBg51.callback(Pin.IRQ_RISING, riseBg51) fBuzzer = False while True: gc.collect() # free ram # check if new minute if utime.ticks_diff(tm_start, tm_end) >= 60000: # changed minutes tm_start = tm_end # ---------------------------------------------------- # here log data or transfer info # end # ---------------------------------------------------- # spostato in minutes_handler countsMin = 0
class LIS2HH12: ACC_I2CADDR = const(30) PRODUCTID_REG = const(0x0F) CTRL1_REG = const(0x20) CTRL2_REG = const(0x21) CTRL3_REG = const(0x22) CTRL4_REG = const(0x23) CTRL5_REG = const(0x24) ACC_X_L_REG = const(0x28) ACC_X_H_REG = const(0x29) ACC_Y_L_REG = const(0x2A) ACC_Y_H_REG = const(0x2B) ACC_Z_L_REG = const(0x2C) ACC_Z_H_REG = const(0x2D) ACT_THS = const(0x1E) ACT_DUR = const(0x1F) SCALES = {FULL_SCALE_2G: 4000, FULL_SCALE_4G: 8000, FULL_SCALE_8G: 16000} ODRS = [0, 10, 50, 100, 200, 400, 800] def __init__(self, pysense = None, sda = 'P22', scl = 'P21'): if pysense is not None: self.i2c = pysense.i2c else: from machine import I2C self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl)) self.odr = 0 self.full_scale = 0 self.x = 0 self.y = 0 self.z = 0 self.int_pin = None self.act_dur = 0 self.debounced = False whoami = self.i2c.readfrom_mem(ACC_I2CADDR , PRODUCTID_REG, 1) if (whoami[0] != 0x41): raise ValueError("LIS2HH12 not found") # enable acceleration readings at 50Hz self.set_odr(ODR_50_HZ) # change the full-scale to 4g self.set_full_scale(FULL_SCALE_4G) # set the interrupt pin as active low and open drain self.set_register(CTRL5_REG, 3, 0, 3) # make a first read self.acceleration() def acceleration(self): x = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_X_L_REG, 2) self.x = struct.unpack('<h', x) y = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_Y_L_REG, 2) self.y = struct.unpack('<h', y) z = self.i2c.readfrom_mem(ACC_I2CADDR , ACC_Z_L_REG, 2) self.z = struct.unpack('<h', z) _mult = self.SCALES[self.full_scale] / ACC_G_DIV return (self.x[0] * _mult, self.y[0] * _mult, self.z[0] * _mult) def roll(self): x,y,z = self.acceleration() rad = math.atan2(-x, z) return (180 / math.pi) * rad def pitch(self): x,y,z = self.acceleration() rad = -math.atan2(y, (math.sqrt(x*x + z*z))) return (180 / math.pi) * rad def set_register(self, register, value, offset, mask): reg = bytearray(self.i2c.readfrom_mem(ACC_I2CADDR, register, 1)) reg[0] &= ~(mask << offset) reg[0] |= ((value & mask) << offset) self.i2c.writeto_mem(ACC_I2CADDR, register, reg) def set_full_scale(self, scale): self.set_register(CTRL4_REG, scale, 4, 3) self.full_scale = scale def set_odr(self, odr): self.set_register(CTRL1_REG, odr, 4, 7) self.odr = odr def set_high_pass(self, hp): self.set_register(CTRL2_REG, 1 if hp else 0, 2, 1) def enable_activity_interrupt(self, threshold, duration, handler=None): # Threshold is in mg, duration is ms self.act_dur = duration if threshold > self.SCALES[self.full_scale]: error = "threshold %d exceeds full scale %d" % (thresold, self.SCALES[self.full_scale]) print(error) raise ValueError(error) if threshold < self.SCALES[self.full_scale] / 128: error = "threshold %d below resolution %d" % (thresold, self.SCALES[self.full_scale]/128) print(error) raise ValueError(error) if duration > 255 * 1000 * 8 / self.ODRS[self.odr]: error = "duration %d exceeds max possible value %d" % (duration, 255 * 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) if duration < 1000 * 8 / self.ODRS[self.odr]: error = "duration %d below resolution %d" % (duration, 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) _ths = int(127 * threshold / self.SCALES[self.full_scale]) & 0x7F _dur = int((duration * self.ODRS[self.odr]) / 1000 / 8) self.i2c.writeto_mem(ACC_I2CADDR, ACT_THS, _ths) self.i2c.writeto_mem(ACC_I2CADDR, ACT_DUR, _dur) # enable the activity/inactivity interrupt self.set_register(CTRL3_REG, 1, 5, 1) self._user_handler = handler self.int_pin = Pin('P13', mode=Pin.IN) self.int_pin.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self._int_handler) # return actual used thresold and duration return (_ths * self.SCALES[self.full_scale] / 128, _dur * 8 * 1000 / self.ODRS[self.odr]) def activity(self): if not self.debounced: time.sleep_ms(self.act_dur) self.debounced = True if self.int_pin(): return True return False def _int_handler(self, pin_o): if self._user_handler is not None: self._user_handler(pin_o) else: if pin_o(): print('Activity interrupt') else: print('Inactivity interrupt')
import network import time from config import Config from wlanmanager import WLanManager from machine import Pin def toggle_wlan_mode(arg): print('Toggle wlan') getattr(arg, 'toggle')() if __name__ == '__main__': # Set up Button on Ext Board to toggle WLan AP wlan = WLanManager() button_s1 = Pin('P10', mode=Pin.IN, pull=Pin.PULL_UP) button_s1.callback(Pin.IRQ_RISING, handler=toggle_wlan_mode, arg=wlan)
from loggingpycom import DEBUG from LoggerFactory import LoggerFactory from UserButton import UserButton # Initialise LoggerFactory and status logger logger_factory = LoggerFactory() status_logger = logger_factory.create_status_logger( 'status_logger', level=DEBUG, terminal_out=True, filename='status_log.txt') # Initialize button interrupt on pin 14 for user interaction user_button = UserButton(status_logger) pin_14 = Pin("P14", mode=Pin.IN, pull=Pin.PULL_DOWN) pin_14.callback(Pin.IRQ_RISING | Pin.IRQ_FALLING, user_button.button_handler) # Mount SD card sd = SD() os.mount(sd, '/sd') except Exception as e: print(str(e)) reboot_counter = 0 while True: blink_led((0x550000, 0.5, True)) # blink red LED reboot_counter += 1 if reboot_counter >= 180: reset() try:
class LIS2HH12: ACC_I2CADDR = const(30) PRODUCTID_REG = const(0x0F) CTRL1_REG = const(0x20) CTRL2_REG = const(0x21) CTRL3_REG = const(0x22) CTRL4_REG = const(0x23) CTRL5_REG = const(0x24) ACC_X_L_REG = const(0x28) ACC_X_H_REG = const(0x29) ACC_Y_L_REG = const(0x2A) ACC_Y_H_REG = const(0x2B) ACC_Z_L_REG = const(0x2C) ACC_Z_H_REG = const(0x2D) ACT_THS = const(0x1E) ACT_DUR = const(0x1F) SCALES = {FULL_SCALE_2G: 4000, FULL_SCALE_4G: 8000, FULL_SCALE_8G: 16000} ODRS = [0, 10, 50, 100, 200, 400, 800] def __init__(self, pysense=None, sda='P22', scl='P21'): if pysense is not None: self.i2c = pysense.i2c else: from machine import I2C self.i2c = I2C(0, mode=I2C.MASTER, pins=(sda, scl)) self.odr = 0 self.full_scale = 0 self.x = 0 self.y = 0 self.z = 0 self.int_pin = None self.act_dur = 0 self.debounced = False whoami = self.i2c.readfrom_mem(ACC_I2CADDR, PRODUCTID_REG, 1) if (whoami[0] != 0x41): raise ValueError("LIS2HH12 not found") # enable acceleration readings at 50Hz self.set_odr(ODR_50_HZ) # change the full-scale to 4g self.set_full_scale(FULL_SCALE_4G) # set the interrupt pin as active low and open drain self.set_register(CTRL5_REG, 3, 0, 3) # make a first read self.acceleration() def acceleration(self): x = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_X_L_REG, 2) self.x = struct.unpack('<h', x) y = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_Y_L_REG, 2) self.y = struct.unpack('<h', y) z = self.i2c.readfrom_mem(ACC_I2CADDR, ACC_Z_L_REG, 2) self.z = struct.unpack('<h', z) _mult = self.SCALES[self.full_scale] / ACC_G_DIV return (self.x[0] * _mult, self.y[0] * _mult, self.z[0] * _mult) def roll(self): x, y, z = self.acceleration() rad = math.atan2(-x, z) return (180 / math.pi) * rad def pitch(self): x, y, z = self.acceleration() rad = -math.atan2(y, (math.sqrt(x * x + z * z))) return (180 / math.pi) * rad def set_register(self, register, value, offset, mask): reg = bytearray(self.i2c.readfrom_mem(ACC_I2CADDR, register, 1)) reg[0] &= ~(mask << offset) reg[0] |= ((value & mask) << offset) self.i2c.writeto_mem(ACC_I2CADDR, register, reg) def set_full_scale(self, scale): self.set_register(CTRL4_REG, scale, 4, 3) self.full_scale = scale def set_odr(self, odr): self.set_register(CTRL1_REG, odr, 4, 7) self.odr = odr def set_high_pass(self, hp): self.set_register(CTRL2_REG, 1 if hp else 0, 2, 1) def enable_activity_interrupt(self, threshold, duration, handler=None): # Threshold is in mg, duration is ms self.act_dur = duration if threshold > self.SCALES[self.full_scale]: error = "threshold %d exceeds full scale %d" % ( threshold, self.SCALES[self.full_scale]) print(error) raise ValueError(error) if threshold < self.SCALES[self.full_scale] / 128: error = "threshold %d below resolution %d" % ( threshold, self.SCALES[self.full_scale] / 128) print(error) raise ValueError(error) if duration > 255 * 1000 * 8 / self.ODRS[self.odr]: error = "duration %d exceeds max possible value %d" % ( duration, 255 * 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) if duration < 1000 * 8 / self.ODRS[self.odr]: error = "duration %d below resolution %d" % (duration, 1000 * 8 / self.ODRS[self.odr]) print(error) raise ValueError(error) _ths = int(127 * threshold / self.SCALES[self.full_scale]) & 0x7F _dur = int((duration * self.ODRS[self.odr]) / 1000 / 8) self.i2c.writeto_mem(ACC_I2CADDR, ACT_THS, _ths) self.i2c.writeto_mem(ACC_I2CADDR, ACT_DUR, _dur) # enable the activity/inactivity interrupt self.set_register(CTRL3_REG, 1, 5, 1) self._user_handler = handler self.int_pin = Pin('P13', mode=Pin.IN) self.int_pin.callback(trigger=Pin.IRQ_FALLING | Pin.IRQ_RISING, handler=self._int_handler) # return actual used threshold and duration return (_ths * self.SCALES[self.full_scale] / 128, _dur * 8 * 1000 / self.ODRS[self.odr]) def activity(self): if not self.debounced: time.sleep_ms(self.act_dur) self.debounced = True if self.int_pin(): return True return False def _int_handler(self, pin_o): if self._user_handler is not None: self._user_handler(pin_o) else: if pin_o(): print('Activity interrupt') else: print('Inactivity interrupt')
class DAVIS7911(object): 'Davis 7911 sensor library for Pycom LoPy' # Constants ADC_MAX = 4000 ADC_MIN = 150 PIN_SPEED = 'P11' PIN_DIR = 'G3' rotations = 0 timeout = None adc = None # Pins pin_speed = None pin_dir = None def __init__(self): self.timeout = time() try: self.pin_speed = Pin(self.PIN_SPEED, mode = Pin.IN, pull = Pin.PULL_UP) self.pin_speed.callback(Pin.IRQ_RISING, self.rotations_handler) self.adc = ADC() self.pin_dir = self.adc.channel(pin = self.PIN_DIR) except Exception as e: # Should throw exception to stop execution pass def rotations_handler(self, arg): self.rotations = self.rotations + 1 def mph_to_ms(self, mph): return mph * 0.447 def dir_to_deg(self, dir): #pc2 = (dir - self.ADC_MIN) / ((self.ADC_MAX - self.ADC_MIN) / 360) pc = (dir - self.ADC_MIN) / (self.ADC_MAX - self.ADC_MIN) return pc * 360 def dir_to_dir(self, dir): if dir < 333: return 0 elif dir < 760: return 45 elif dir < 1190: return 90 elif dir < 1490: return 135 elif dir < 1930: return 180 elif dir < 2330: return 225 elif dir < 3020: return 270 elif dir < 3780: return 315 else: return 0 def get_windspeed(self): delta_time = (time() - self.timeout) try: mph = self.rotations * (2.25 / delta_time) except Exception as e: mph = 0 self.rotations = 0 self.timeout = time() return round(self.mph_to_ms(mph), 1) def get_dir(self): try: dir = self.pin_dir.value() except Exception as e: dir = 0 return self.dir_to_dir(dir)
#button_depressed() gc.collect() return 0 node = setup_node() py = Pytrack() acc = LIS2HH12() gps = gps_setup.setup_gps() manager = Manager(acc, node, 1) # manager.alarm_func = send_coords_alarm # manager.alarm = manager.set_alarm() # manager.alarm.cancel() p1 = Pin('P8', mode=Pin.IN, pull=Pin.PULL_DOWN) p1.callback(Pin.IRQ_RISING, press) # p2 = Pin('P11', mode=Pin.IN, pull=Pin.PULL_DOWN) # p2.callback(Pin.IRQ_RISING, press) # p3 = Pin('P9', mode=Pin.IN, pull=Pin.PULL_DOWN) # p3.callback(Pin.IRQ_RISING, press) # button_1 = BUTTON(acc, node, manager, pid='P8', status_alert=1) # print("Button_1 value is " + str(button_1.pin())) # button_1.short = send_coords_button1 # button_1.long = send_coords_button1 # # button_2 = BUTTON(acc, node, manager, pid='P11', status_alert=2) # print("Button_2 value is " + str(button_2.pin())) # button_2.short = send_coords_button2 # button_2.long = send_coords_button2 #
if wlan.isconnected(): rtc.ntp_sync(NTP_SERVER) if rtc.synced(): ntp_synced = True if HAVE_EXTERNAL_SENSORS: # initialise Ultrasonic Sensor pins us_trigger_pin = Pin("P4", mode=Pin.OUT) us_echo_pin = Pin("P10", mode=Pin.IN, pull=Pin.PULL_DOWN) # Initialise flow sensors rate_pin = Pin("P11", mode=Pin.IN, pull=Pin.PULL_UP) # Lopy4 specific: Pin('P20', mode=Pin.IN) rate_pin_id = rate_pin.id() # Pin seems to occasionally get 'stuck' on low so we just measure a # transition and log that, as it doens't matter if it's going 1->0 or 0->1 rate_pin.callback(Pin.IRQ_FALLING, rate_pin_cb) # Setup SD card try: sd = SD() HAVE_SD = True except OSError: print("No disk available") if HAVE_SD: uos.mount(sd, MOUNTPOINT) readings = take_readings(3, have_external_sensors=HAVE_EXTERNAL_SENSORS) print("Setting up logfile") logfile = init_logfile(readings, SENSOR_STATION_ID) rate_count = 0