Tufty 2040 > code > Tufty 2350

On my Tufty2040 I run the following:
It’s flashed with the new V2 with filesystem uf2 file.

import time
import machine
import micropython
import picographics

from picographics import PicoGraphics, DISPLAY_TUFTY_2040, PEN_RGB332
display = PicoGraphics(display=DISPLAY_TUFTY_2040, rotate=180, pen_type=PEN_RGB332)
display.set_backlight(0.5)
display.set_font("bitmap8")

A = 1
C = 1

BACKLIGHT_LOW = micropython.const(0.35)
BACKLIGHT_HIGH = micropython.const(1.0)
LUMINANCE_LOW = micropython.const(800)
LUMINANCE_HIGH = micropython.const(3072)  # 65535 to use the full range.

from breakout_bme280 import BreakoutBME280
from pimoroni_i2c import PimoroniI2C
i2c = PimoroniI2C(sda=(4), scl=(5))
bme = BreakoutBME280(i2c)
temperature, pressure, humidity = bme.read()
time.sleep(0.5)

from breakout_rtc import BreakoutRTC
from machine import RTC
RV3028 = BreakoutRTC(i2c)
rtc = BreakoutRTC(i2c)
if rtc.is_12_hour:
    rtc.set_24_hour()
if rtc.read_periodic_update_interrupt_flag():
    rtc.clear_periodic_update_interrupt_flag()
if rtc.update_time():
    rtc_date = rtc.string_date()
    rtc_time = rtc.string_time()

from machine import ADC, Pin
vbat_adc = ADC(29)
vref_adc = ADC(28)
vref_en = Pin(27)
vref_en.init(Pin.OUT)
vref_en.value(0)
usb_power = Pin(24, Pin.IN)
full_battery = 4.5
empty_battery = 2.5

lux_vref_pwr = Pin(27, Pin.OUT)
lux = ADC(26)

from pimoroni import Button
button_a = Button(7, invert=False)
button_b = Button(8, invert=False)
button_c = Button(9, invert=False)
button_up = Button(22, invert=False)
button_down = Button(6, invert=False)
button_boot = Button(23, invert=True)

t_color = display.create_pen(0,255,0)
h_color = display.create_pen(0,255,0)
p_color = display.create_pen(0,255,0)
white = display.create_pen(255,255,255)
black = display.create_pen(0,0,0)
red = display.create_pen(255,0,0)
green = display.create_pen(0,255,0)
blue = display.create_pen(0,0,255)
yellow = display.create_pen(255,255,0)
orange = display.create_pen(255,140,0)
cyan = display.create_pen(0,255,255)

WIDTH, HEIGHT = display.get_bounds()
display.set_pen(black)
display.clear()

def describe_temperature(t):
    global t_color
    if t < -10:
        description = "Very Cold"
        t_color = white
    elif -10 <= t <= 0:
        description = "Cold"
        t_color = blue
    elif 0 < t <= 12:
        description = "Cool"
        t_color = yellow
    elif 12 < t <= 16:
        description = "OK"
        t_color = green
    elif 16 < t <= 24:
        description = "Warm"
        t_color = green      
    elif 24 < t <= 27:
        description = "Hot"
        t_color = orange
    elif t > 27:
        description = "Very Hot"
        t_color = red
    return description

def describe_humidity(h):
    global h_color
    if h < 30:
        description = "Low"
        h_color = red
    elif 30 <= h <= 60:
        description = "OK"
        h_color = green
    elif 60 < h < 80:
        description = "High"
        h_color = yellow
    elif h >= 80:
        description = "Very High"
        h_color = orange        
    return description

def describe_pressure(p):
    global p_color
    if p < 982:
        description = "Very Low"
        p_color = red
    elif 982 <= p < 1004:
        description = "Low"
        p_color = yellow
    elif 1004 <= p < 1026:
        description = "OK"
        p_color = green
    elif 1026 <= p < 1048:
        description = "High"
        p_color = blue
    elif p >= 1048:
        description = "Very High"
        p_color = orange
    return description

def draw_graph(temp_value, press_value, humid_value):
    
    if C == 1:
        scaled_temp = int(t * 10)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310

        describe_temperature(t)
        display.set_pen(yellow)
        display.rectangle(9,89,116,19)
        display.set_pen(white)
        display.circle(9,98,9)
        display.set_pen(green)
        display.rectangle(127,89,111,19)
        display.set_pen(orange)
        display.rectangle(240,89,28,19)
        display.set_pen(red)
        display.rectangle(270,89,44,19)
        display.circle(310,98,9)
        display.set_pen(black)
        display.circle((scaled_temp),98,9)
        display.set_pen(white)
        display.circle((scaled_temp),98,5)        
    
    if C == 0:    
        scaled_temp = int((t * 5) + 160)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310        
    
        describe_temperature(t)
        display.set_pen(blue)
        display.circle(9, 98, 9)
        display.rectangle(12, 89, 92, 19)
        display.set_pen(white)
        display.rectangle(106, 89, 53, 19)
        display.set_pen(yellow)
        display.rectangle(161,89,58,19)
        display.set_pen(green)
        display.rectangle(221,89,58,19)
        display.set_pen(orange)
        display.rectangle(281,89,13,19)
        display.set_pen(red)
        display.rectangle(296,89,15,19)
        display.circle(310,98,9)
        display.set_pen(black)
        display.circle((scaled_temp),98,9)
        display.set_pen(white)
        display.circle((scaled_temp),98,5)    
        display.set_pen(t_color)
    
    scaled_humid = int(h * (320 / 100))
    if scaled_humid <= 9:
        scaled_humid =9
    if scaled_humid >= 310:
        scaled_humid =310        
    
    describe_humidity(h)
    display.set_pen(red)
    display.circle(9, 164, 9)
    display.rectangle(12,155,82,19)
    display.set_pen(green)
    display.rectangle(96,155,94,19)
    display.set_pen(yellow)
    display.rectangle(192,155,62,19)
    display.set_pen(orange)
    display.rectangle(256,155,55,19)
    display.circle(310,164,9)
    display.set_pen(black)
    display.circle((scaled_humid),164,9)
    display.set_pen(white)
    display.circle((scaled_humid),164,5)
    display.set_pen(h_color)
    display.text(describe_humidity(h),130,125,scale=3)
    
    scaled_press = int((p - 960) * 3)
    if scaled_press <= 9:
        scaled_press =9
    if scaled_press >= 310:
        scaled_press =310        
    
    describe_pressure(p)
    display.set_pen(red)
    display.circle(9, 230, 9)
    display.rectangle(12,221,50,19)
    display.set_pen(yellow)
    display.rectangle(64,221,62,19)
    display.set_pen(green)
    display.rectangle(128,221,62,19)
    display.set_pen(blue)
    display.rectangle(192,221,62,19)
    display.set_pen(orange)
    display.rectangle(256,221,52,19)
    display.circle(310, 230, 9)
    display.set_pen(black)
    display.line(127,221,127,240)    
    display.circle((scaled_press),230,9)
    display.set_pen(white)
    display.circle((scaled_press),230,5)
    display.set_pen(p_color)
    display.text(describe_pressure(p),130,191,scale=3) 

def describe_month(month):
    
    month = rtc.get_month()
    if month == 1:
        description = "Jan"
    elif month == 2:
        description = "Feb"  
    elif month == 3:
        description = "Mar"
    elif month == 4:
        description = "Apr"              
    elif month == 5:
        description = "May"              
    elif month == 6:
        description = "Jun"              
    elif month == 7:
        description = "Jul"              
    elif month == 8:
        description = "Aug"              
    elif month == 9:
        description = "Sep"
    elif month == 10:
        description = "Oct"             
    elif month == 11:
        description = "Nov"              
    elif month == 12:
        description = "Dec"            
    return description

def describe_date(date):
 
    date = rtc.get_date()
    if date == 1:
        description = "st"
    elif date == 2:
        description = "nd"     
    elif date == 3:
        description = "rd" 
    elif date == 21:
        description = "st"      
    elif date == 22:
        description = "nd"  
    elif date == 23:
        description = "rd"
    elif date == 31:
        description = "st"
    else:
        description = "th"
    return description

def auto_brightness(previous: float) -> (float, float):
    
    luminance = lux.read_u16()
    luminance_frac = max(0.0, float(luminance - LUMINANCE_LOW))
    luminance_frac = min(1.0, luminance_frac / (LUMINANCE_HIGH - LUMINANCE_LOW))
    backlight = BACKLIGHT_LOW + (luminance_frac * (BACKLIGHT_HIGH - BACKLIGHT_LOW))
    backlight_diff = backlight - previous
    backlight = previous + (backlight_diff * (1.0 / 8.0))
    return (luminance, backlight)

backlight = BACKLIGHT_LOW

start_time = time.time()

display.set_pen(black)
display.clear()
display.update()
        
def set_pico_time():
    # set the Pico's RTC from the RTC breakout
    RV3028.update_time()
    RTC().datetime([RV3028.get_year(), RV3028.get_month(), RV3028.get_date(),
                    RV3028.get_weekday(), RV3028.get_hours(), RV3028.get_minutes(),
                    RV3028.get_seconds(), 0])
    print(f"Pico RTC set to breakout time: {RV3028.string_date()} {RV3028.string_time()}")

temperature, pressure, humidity = bme.read()
time.sleep(0.5)

temperature, pressure, humidity = bme.read()
time.sleep(0.5)

t = round(temperature)
min_temperature = t
max_temperature = t


while True:
    
    display.set_pen(black)
    display.clear()
    
    if usb_power.value() == 1:
        BACKLIGHT_LOW = micropython.const(0.35)
    else:
        BACKLIGHT_LOW = micropython.const(0.4)
        
    
    vref_en.value(1)
    vdd = 1.24 * (65535 / vref_adc.read_u16())
    vbat = (
        (vbat_adc.read_u16() / 65535) * 3 * vdd
    )
    vref_en.value(0)

    percentage = 100 * ((vbat - empty_battery) / (full_battery - empty_battery))
    if percentage > 100:
        percentage = 100
    if percentage < 0:
        percentage = 0
    
    if A == 1:
        lux_vref_pwr.value(1)
        (luminance, backlight) = auto_brightness(backlight)
        lux_vref_pwr.value(0)
        display.set_backlight(backlight)
 
    time_elapsed = time.time() - start_time
    hours = rtc.get_hours()
    minutes = rtc.get_minutes()
    month = rtc.get_month()
    date = rtc.get_date()
    weekday = rtc.get_weekday()
     
    if rtc.read_periodic_update_interrupt_flag():
        rtc.clear_periodic_update_interrupt_flag()

        if rtc.update_time():
            rtc_date = rtc.string_date()
            rtc_time = rtc.string_time()
    
    if button_a.is_pressed:
        A = 1
        
    if button_b.is_pressed:
        if percentage > 100:
            percentage = 100
        if percentage < 0:
            percentage = 0
        
        if percentage >= 50:
            display.set_pen(green)
            display.text("Battery",0,9,scale=3)
            display.text("{:0.2f}v".format(vbat),150,9,scale=3)
            display.text("{:0.0f}%".format(percentage),265,9,scale=3)
        elif 50 > percentage > 20:   
            display.set_pen(yellow)
            display.text("Battery",0,9, scale=3)
            display.text("{:0.2f}v".format(vbat),150,9,scale=3)
            display.text("{:0.0f}%".format(percentage),265,9,scale=3)
        elif percentage <= 20:    
            display.set_pen(red)
            display.text("Battery",0,9,scale=3)
            display.text("{:0.2f}v".format(vbat),150,9,scale=3)
            display.text("{:0.0f}%".format(percentage),265,9,scale=3)
    else:
        display.set_pen(white)
        weekday = rtc.get_weekday()
    
        if weekday == 0:
            display.text("Mon",0,9,scale=3)        
        if weekday == 1:
            display.text("Tue",0,9,scale=3)
        if weekday == 2:
            display.text("Wed",0,9,scale=3)
        if weekday == 3:
            display.text("Thu",0,9,scale=3)
        if weekday == 4:
            display.text("Fri",0,9,scale=3)
        if weekday == 5:
            display.text("Sat",0,9, scale=3)
        if weekday == 6:
            display.text("Sun",0,9, scale=3)                        
         
        display.text(f"{describe_month(month)} {date}{describe_date(date)}",60,9,scale=3)

        if hours == 0:
            display.text(f"{12}:{minutes:02} AM",190,9,scale=3)
        elif 0 < hours < 10:
            display.text(f"{hours:1}:{minutes:02} AM",190,9,scale=3)            
        elif 10 <= hours < 12:
            display.text(f"{hours:2}:{minutes:02} AM",190,9,scale=3)
        elif hours == 12:
            display.text(f"{hours:2}:{minutes:02} PM",190,9,scale=3)    
        elif hours >12:
            hours = hours - 12
            if hours <10:
                display.text(f"{hours:1}:{minutes:02} PM",190,9,scale=3)
            elif 10 <= hours < 12:
                display.text(f"{hours:2}:{minutes:02} PM",190,9,scale=3)
            elif hours == 12:
                display.text(f"{hours:2}:{minutes:02} AM",190,9,scale=3)

    if button_c.is_pressed:
        C = 1        
        min_temperature = t
        max_temperature = t
        time.sleep(0.2)              

        
    if button_up.is_pressed:
        A = 0
        display.set_backlight(1.0)
                        
    if button_down.is_pressed:
        A = 0
        display.set_backlight(0.0) 
                
    if button_boot.is_pressed:
        set_pico_time()
             
    temperature, pressure, humidity = bme.read()
    pressuremb = pressure / 100
    
    t = round(temperature)
    h = round(humidity)
    p = round(pressuremb)
    
    if t <= 0:
        C = 0
        
    if t >= 12:
        C = 1
    
    display.set_pen(white)
    display.text("{:0.0f}°C" .format(t), 5, 52, scale=4)
    display.text("{:0.0f}%".format(h), 5, 118, scale=4)
    display.text("{:0.0f}mb".format(p), 5, 184, scale=4)
   
    draw_graph(temperature, pressure, humidity)
    
    if t >= max_temperature:
        max_temperature = t
    if t <= min_temperature:
        min_temperature = t

    display.set_pen(cyan)
    display.text(f"Min {min_temperature:.0f}", 110, 57, WIDTH, scale=3)
    display.set_pen(cyan)
    display.text(f"Max {max_temperature:.0f}", 225, 57, WIDTH, scale=3)
    
    temperature, pressure, humidity = bme.read()
    display.update()
    time.sleep(0.25)

Which gets me this:

I’ve been tying to port it over to my new Tufty2350.
where I’m currently stuck is getting the date and time from the onboard RTC.
And the API isn’t helping?

Meet Badger, Tufty, and Blinky - the Digital Badge Crew

Here is my current code and the error message I’m getting.

import time
import math
import machine
import micropython
from badgeware import State, rtc
from breakout_bme280 import BreakoutBME280
from machine import RTC
from machine import I2C

A = 1
C = 1

temperature_sensor = BreakoutBME280(I2C())
reading = temperature_sensor.read()
reading = [round(r, 0) for r in reading]
temperature, pressure, humidity = reading

time.sleep(0.5)

def describe_temperature(t):
    global t_color
    if t < -10:
        description = "Very Cold"
        t_color = white
    elif -10 <= t <= 0:
        description = "Cold"
        t_color = blue
    elif 0 < t <= 12:
        description = "Cool"
        t_color = yellow
    elif 12 < t <= 16:
        description = "OK"
        t_color = green
    elif 16 < t <= 24:
        description = "Warm"
        t_color = green      
    elif 24 < t <= 27:
        description = "Hot"
        t_color = orange
    elif t > 27:
        description = "Very Hot"
        t_color = red
    return description

def describe_humidity(h):
    global h_color
    if h < 30:
        description = "Low"
        h_color = red
    elif 30 <= h <= 60:
        description = "OK"
        h_color = green
    elif 60 < h < 80:
        description = "High"
        h_color = yellow
    elif h >= 80:
        description = "Very High"
        h_color = orange        
    return description

def describe_pressure(p):
    global p_color
    if p < 982:
        description = "Very Low"
        p_color = red
    elif 982 <= p < 1004:
        description = "Low"
        p_color = yellow
    elif 1004 <= p < 1026:
        description = "OK"
        p_color = green
    elif 1026 <= p < 1048:
        description = "High"
        p_color = blue
    elif p >= 1048:
        description = "Very High"
        p_color = orange
    return description

def draw_graph(temp_value, press_value, humid_value):
    
    if C == 1:
        scaled_temp = int(t * 10)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310

        describe_temperature(t)
        screen.pen = (yellow)
        screen.rectangle(9,89,116,19)
        screen.pen = (white)
        screen.circle(9,98,9)
        screen.pen = (green)
        screen.rectangle(127,89,111,19)
        screen.pen = (orange)
        screen.rectangle(240,89,28,19)
        screen.pen = (red)
        screen.rectangle(270,89,44,19)
        screen.circle(310,98,9)
        screen.pen = (black)
        screen.circle((scaled_temp),98,9)
        screen.pen = (white)
        screen.circle((scaled_temp),98,5)        
    
    if C == 0:    
        scaled_temp = int((t * 5) + 160)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310        
    
        describe_temperature(t)
        screen.pen = (blue)
        screen.circle(9, 98, 9)
        screen.rectangle(12, 89, 92, 19)
        screen.pen = (white)
        screen.rectangle(106, 89, 53, 19)
        screen.pen = (yellow)
        screen.rectangle(161,89,58,19)
        screen.pen = (green)
        screen.rectangle(221,89,58,19)
        screen.pen = (orange)
        screen.rectangle(281,89,13,19)
        screen.pen = (red)
        screen.rectangle(296,89,15,19)
        screen.circle(310,98,9)
        screen.pen = (black)
        screen.circle((scaled_temp),98,9)
        screen.pen = (white)
        screen.circle((scaled_temp),98,5)    
        screen.pen = (t_color)
    
    scaled_humid = int(h * (320 / 100))
    if scaled_humid <= 9:
        scaled_humid =9
    if scaled_humid >= 310:
        scaled_humid =310        
    
    describe_humidity(h)
    screen.pen = (red)
    screen.circle(9, 164, 9)
    screen.rectangle(12,155,82,19)
    screen.pen = (green)
    screen.rectangle(96,155,94,19)
    screen.pen = (yellow)
    screen.rectangle(192,155,62,19)
    screen.pen = (orange)
    screen.rectangle(256,155,55,19)
    screen.circle(310,164,9)
    screen.pen = (black)
    screen.circle((scaled_humid),164,9)
    screen.pen = (white)
    screen.circle((scaled_humid),164,5)
    screen.pen = (h_color)
    screen.text(describe_humidity(h),130,125,scale=3)
    
    scaled_press = int((p - 960) * 3)
    if scaled_press <= 9:
        scaled_press =9
    if scaled_press >= 310:
        scaled_press =310        
    
    describe_pressure(p)
    screen.pen = (red)
    screen.circle(9, 230, 9)
    screen.rectangle(12,221,50,19)
    screen.pen = (yellow)
    screen.rectangle(64,221,62,19)
    screen.pen = (green)
    screen.rectangle(128,221,62,19)
    screen.pen = (blue)
    screen.rectangle(192,221,62,19)
    screen.pen = (orange)
    screen.rectangle(256,221,52,19)
    screen.circle(310, 230, 9)
    screen.pen = (black)
    screen.line(127,221,127,240)    
    screen.circle((scaled_press),230,9)
    screen.pen = (white)
    screen.circle((scaled_press),230,5)
    screen.pen = (p_color)
    screen.text(describe_pressure(p),130,191,scale=3) 

def describe_month(month):
    
    month = rtc.datetime[1]
    if month == 1:
        description = "Jan"
    elif month == 2:
        description = "Feb"  
    elif month == 3:
        description = "Mar"
    elif month == 4:
        description = "Apr"              
    elif month == 5:
        description = "May"              
    elif month == 6:
        description = "Jun"              
    elif month == 7:
        description = "Jul"              
    elif month == 8:
        description = "Aug"              
    elif month == 9:
        description = "Sep"
    elif month == 10:
        description = "Oct"             
    elif month == 11:
        description = "Nov"              
    elif month == 12:
        description = "Dec"            
    return description

def describe_date(date):
 
    day = rtc.datetime[2]
    if day == 1:
        description = "st"
    elif day == 2:
        description = "nd"     
    elif day == 3:
        description = "rd" 
    elif day == 21:
        description = "st"      
    elif day == 22:
        description = "nd"  
    elif day == 23:
        description = "rd"
    elif day == 31:
        description = "st"
    else:
        description = "th"
    return description
        
temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

while True:
    screen.pen = color.black
    screen.clear()
    
    rtc.datetime() # <<<< Line 331
    
    '''
    year = rtc.datetime[0]
    month = rtc.datetime[1]
    day = rtc.datetime[2] 
    hour = rtc.datetime[3]
    minute = rtc.datetime[4]
    seconds = rtc.datetime[5]
    '''     
    
    
    if badge.pressed(BUTTON_A):
        A = 1
  
    if badge.pressed(BUTTON_B):
 
    else:
        screen.pen = color.white
        weekday = dow
    
        if weekday == 0:
            screen.text("Mon",0,9)        
        if weekday == 1:
            screen.text("Tue",0,9)
        if weekday == 2:
            screen.text("Wed",0,9)
        if weekday == 3:
            screen.text("Thu",0,9)
        if weekday == 4:
            screen.text("Fri",0,9)
        if weekday == 5:
            screen.text("Sat",0,9)
        if weekday == 6:
            sreen.text("Sun",0,9)                        
         
        screen.text(f"{describe_month(month)} {date}{describe_date(date)}",60,9,)

        if hours == 0:
            screen.text(f"{12}:{minutes:02} AM",190,9)
        elif 0 < hours < 10:
            screen.text(f"{hours:1}:{minutes:02} AM",190,9)            
        elif 10 <= hours < 12:
            screen.text(f"{hours:2}:{minutes:02} AM",190,9)
        elif hours == 12:
            screen.text(f"{hours:2}:{minutes:02} PM",190,9)    
        elif hours >12:
            hours = hours - 12
            if hours <10:
                screen.text(f"{hours:1}:{minutes:02} PM",190,9)
            elif 10 <= hours < 12:
                screen.text(f"{hours:2}:{minutes:02} PM",190,9)
            elif hours == 12:
                screen.text(f"{hours:2}:{minutes:02} AM",190,9)

    if badge.pressed(BUTTON_C):
        C = 1        
        min_temperature = t
        max_temperature = t
        time.sleep(0.2)              

        
    if badge.pressed(BUTTON_UP):
        A = 0
        screen.set_backlight(1.0)
                        
    if badge.pressed(BUTTON_DOWN):
        A = 0
        screen.set_backlight(0.0) 
                
    temperature, pressure, humidity = bme.read()
    pressuremb = pressure / 100
    
    
    if t <= 0:
        C = 0
        
    if t >= 12:
        C = 1
    
    screen.pen = (white)
    screen.text("{:0.0f}°C" .format(t), 5, 52)
    screen.text("{:0.0f}%".format(h), 5, 118)
    screen.text("{:0.0f}mb".format(p), 5, 184)
   
    #draw_graph(temperature, pressure, humidity)
    
    if t >= max_temperature:
        max_temperature = t
    if t <= min_temperature:
        min_temperature = t

    screen.pen = (cyan)
    screen.text(f"Min {min_temperature:.0f}", 110, 57, WIDTH)
    screen.pen = (cyan)
    screen.text(f"Max {max_temperature:.0f}", 225, 57, WIDTH)
    
    temperature, pressure, humidity = bme.read()
    screen.update()
    time.sleep(0.25)
>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Traceback (most recent call last):
  File "<stdin>", line 331, in <module>
TypeError: 'module' object isn't callable

Ok this:

rtc = RTC()

    rtc.datetime()
    year, month, day, weekday, hour, minute, second, subsecs = rtc.datetime()
    print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
         

Gets me this:

MPY: soft reboot
2026-02-28 18:33:53
Traceback (most recent call last):
  File "<stdin>", line 347, in <module>
  File "<stdin>", line 168, in draw_graph
TypeError: function doesn't take keyword arguments

Line 168 is
screen.text(describe_humidity(h),130,125,scale=3)
and line 347 is
draw_graph(temperature, pressure, humidity)

Current full file is as follows.

import time
import math
import machine
import micropython
from badgeware import State, rtc
from breakout_bme280 import BreakoutBME280
from machine import RTC
from machine import I2C

rtc = RTC()

A = 1
C = 1

temperature_sensor = BreakoutBME280(I2C())
reading = temperature_sensor.read()
reading = [round(r, 0) for r in reading]
temperature, pressure, humidity = reading

time.sleep(0.5)

palette = [
  color.black, color.grape, color.navy, color.grey,
  color.brown, color.green, color.red, color.taupe,
  color.blue, color.orange, color.smoke, color.lime,
  color.latte, color.cyan, color.yellow, color.white
]

WIDTH = 320
HEIGHT = 280

def describe_temperature(t):
    global t_color
    if t < -10:
        description = "Very Cold"
        t_color = color.white
    elif -10 <= t <= 0:
        description = "Cold"
        t_color = color.blue
    elif 0 < t <= 12:
        description = "Cool"
        t_color = color.yellow
    elif 12 < t <= 16:
        description = "OK"
        t_color = color.green
    elif 16 < t <= 24:
        description = "Warm"
        t_color = color.green      
    elif 24 < t <= 27:
        description = "Hot"
        t_color = color.orange
    elif t > 27:
        description = "Very Hot"
        t_color = color.red
    return description

def describe_humidity(h):
    global h_color
    if h < 30:
        description = "Low"
        h_color = color.red
    elif 30 <= h <= 60:
        description = "OK"
        h_color = color.green
    elif 60 < h < 80:
        description = "High"
        h_color = color.yellow
    elif h >= 80:
        description = "Very High"
        h_color = color.orange        
    return description

def describe_pressure(p):
    global p_color
    if p < 982:
        description = "Very Low"
        p_color = color.red
    elif 982 <= p < 1004:
        description = "Low"
        p_color = color.yellow
    elif 1004 <= p < 1026:
        description = "OK"
        p_color = color.green
    elif 1026 <= p < 1048:
        description = "High"
        p_color = color.blue
    elif p >= 1048:
        description = "Very High"
        p_color = color.orange
    return description

def draw_graph(temp_value, press_value, humid_value):
    
    if C == 1:
        scaled_temp = int(t * 10)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310

        describe_temperature(t)
        screen.pen = color.yellow
        screen.rectangle(9,89,116,19)
        screen.pen = color.white
        screen.circle(9,98,9)
        screen.pen = color.green
        screen.rectangle(127,89,111,19)
        screen.pen = color.orange
        screen.rectangle(240,89,28,19)
        screen.pen = color.red
        screen.rectangle(270,89,44,19)
        screen.circle(310,98,9)
        screen.pen = color.black
        screen.circle((scaled_temp),98,9)
        screen.pen = color.white
        screen.circle((scaled_temp),98,5)        
    
    if C == 0:    
        scaled_temp = int((t * 5) + 160)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310        
    
        describe_temperature(t)
        screen.pen = color.blue
        screen.circle(9, 98, 9)
        screen.rectangle(12, 89, 92, 19)
        screen.pen = color.white
        screen.rectangle(106, 89, 53, 19)
        screen.pen = color.yellow
        screen.rectangle(161,89,58,19)
        screen.pen = color.green
        screen.rectangle(221,89,58,19)
        screen.pen = color.orange
        screen.rectangle(281,89,13,19)
        screen.pen = color.red
        screen.rectangle(296,89,15,19)
        screen.circle(310,98,9)
        screen.pen = color.black
        screen.circle((scaled_temp),98,9)
        screen.pen = color.white
        screen.circle((scaled_temp),98,5)    
        screen.pen = (t_color)
    
    scaled_humid = int(h * (320 / 100))
    if scaled_humid <= 9:
        scaled_humid =9
    if scaled_humid >= 310:
        scaled_humid =310        
    
    describe_humidity(h)
    screen.pen = color.red
    screen.circle(9, 164, 9)
    screen.rectangle(12,155,82,19)
    screen.pen = color.green
    screen.rectangle(96,155,94,19)
    screen.pen = color.yellow
    screen.rectangle(192,155,62,19)
    screen.pen = color.orange
    screen.rectangle(256,155,55,19)
    screen.circle(310,164,9)
    screen.pen = color.black
    screen.circle((scaled_humid),164,9)
    screen.pen = color.white
    screen.circle((scaled_humid),164,5)
    screen.pen = (h_color)
    screen.text(describe_humidity(h),130,125,scale=3)
    
    scaled_press = int((p - 960) * 3)
    if scaled_press <= 9:
        scaled_press =9
    if scaled_press >= 310:
        scaled_press =310        
    
    describe_pressure(p)
    screen.pen = color.red
    screen.circle(9, 230, 9)
    screen.rectangle(12,221,50,19)
    screen.pen = color.yellow
    screen.rectangle(64,221,62,19)
    screen.pen = color.green
    screen.rectangle(128,221,62,19)
    screen.pen = color.blue
    screen.rectangle(192,221,62,19)
    screen.pen = color.orange
    screen.rectangle(256,221,52,19)
    screen.circle(310, 230, 9)
    screen.pen = color.black
    screen.line(127,221,127,240)    
    screen.circle((scaled_press),230,9)
    screen.pen = color.white
    screen.circle((scaled_press),230,5)
    screen.pen = (p_color)
    screen.text(describe_pressure(p),130,191,scale=3) 

def describe_month(month):
    
    #month = rtc.get_month()
    if month == 1:
        description = "Jan"
    elif month == 2:
        description = "Feb"  
    elif month == 3:
        description = "Mar"
    elif month == 4:
        description = "Apr"              
    elif month == 5:
        description = "May"              
    elif month == 6:
        description = "Jun"              
    elif month == 7:
        description = "Jul"              
    elif month == 8:
        description = "Aug"              
    elif month == 9:
        description = "Sep"
    elif month == 10:
        description = "Oct"             
    elif month == 11:
        description = "Nov"              
    elif month == 12:
        description = "Dec"            
    return description

def describe_day(day):
 
    #day = rtc.get_day()
    if day == 1:
        description = "st"
    elif day == 2:
        description = "nd"     
    elif day == 3:
        description = "rd" 
    elif day == 21:
        description = "st"      
    elif day == 22:
        description = "nd"  
    elif day == 23:
        description = "rd"
    elif day == 31:
        description = "st"
    else:
        description = "th"
    return description

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

pressuremb = pressure / 100
t = round(temperature)
h = round(humidity)
p = round(pressuremb)

min_temperature = t
max_temperature = t

while True:
    screen.pen = color.black
    screen.clear()
    
    rtc.datetime()
    year, month, day, weekday, hour, minute, second, subsecs = rtc.datetime()
    print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
         
    
    
    if badge.pressed(BUTTON_A):
        A = 1
  
    if badge.pressed(BUTTON_B):
        print ("Button B pressed")     
    else:
        screen.pen = color.white
        #weekday = rtc.get_weekday()
    
        if weekday == 0:
            screen.text("Mon",0,9)        
        if weekday == 1:
            screen.text("Tue",0,9)
        if weekday == 2:
            screen.text("Wed",0,9)
        if weekday == 3:
            screen.text("Thu",0,9)
        if weekday == 4:
            screen.text("Fri",0,9)
        if weekday == 5:
            screen.text("Sat",0,9)
        if weekday == 6:
            sreen.text("Sun",0,9)                        
         
        screen.text(f"{describe_month(month)} {day}{describe_day(day)}",60,9,)

        if hour == 0:
            screen.text(f"{12}:{minute:02} AM",190,9)
        elif 0 < hour < 10:
            screen.text(f"{hour:1}:{minute:02} AM",190,9)            
        elif 10 <= hour < 12:
            screen.text(f"{hour:2}:{minute:02} AM",190,9)
        elif hour == 12:
            screen.text(f"{hour:2}:{minute:02} PM",190,9)    
        elif hour >12:
            hour = hour - 12
            if hour <10:
                screen.text(f"{hour:1}:{minute:02} PM",190,9)
            elif 10 <= hour < 12:
                screen.text(f"{hour:2}:{minute:02} PM",190,9)
            elif hour == 12:
                screen.text(f"{hour:2}:{minute:02} AM",190,9)

    if badge.pressed(BUTTON_C):
        C = 1        
        min_temperature = t
        max_temperature = t
        time.sleep(0.2)              

        
    if badge.pressed(BUTTON_UP):
        A = 0
        screen.set_backlight(1.0)
                        
    if badge.pressed(BUTTON_DOWN):
        A = 0
        screen.set_backlight(0.0) 
                
    temperature, pressure, humidity = temperature_sensor.read()
    pressuremb = pressure / 100

    t = round(temperature)
    h = round(humidity)
    p = round(pressuremb)
    
    if t <= 0:
        C = 0
        
    if t >= 12:
        C = 1
    
    screen.pen = (color.white)
    screen.text("{:0.0f}°C" .format(t), 5, 52)
    screen.text("{:0.0f}%".format(h), 5, 118)
    screen.text("{:0.0f}mb".format(p), 5, 184)
   
    draw_graph(temperature, pressure, humidity)
    
    if t >= max_temperature:
        max_temperature = t
    if t <= min_temperature:
        min_temperature = t

    screen.pen = (color.smoke)
    screen.text(f"Min {min_temperature:.0f}", 110, 57, WIDTH)
    screen.pen = (color.smoke)
    screen.text(f"Max {max_temperature:.0f}", 225, 57, WIDTH)
    
    temperature, pressure, humidity = temperature_sensor.read()
    time.sleep(0.25)
    

Still plugging along.

import time
import math
import machine
import micropython
from badgeware import State, rtc
from breakout_bme280 import BreakoutBME280
from machine import RTC
from machine import I2C

rtc = RTC()

A = 1
C = 1

temperature_sensor = BreakoutBME280(I2C())
reading = temperature_sensor.read()
temperature, pressure, humidity = reading
pressuremb = pressure / 100
t = round(temperature)
h = round(humidity)
p = round(pressuremb)
print (t, h, p)
min_temperature = t
max_temperature = t

screen.pen = color.white
t_color = screen.pen
h_color = screen.pen
p_color = screen.pen

WIDTH = 320
HEIGHT = 280

def describe_temperature(t):
    global t_color
    if t < -10:
        description = "Very Cold"
        t_color = color.white
    elif -10 <= t <= 0:
        description = "Cold" # <<<< Line 40
        t_color = color.blue
    elif 0 < t <= 12:
        description = "Cool"
        t_color = color.yellow
    elif 12 < t <= 16:
        description = "OK"
        t_color = color.green
    elif 16 < t <= 24:
        description = "Warm"
        t_color = color.green      
    elif 24 < t <= 27:
        description = "Hot" # <<< Line 52
        t_color = color.orange
    elif t > 27:
        description = "Very Hot"
        t_color = color.red
    return description

def describe_humidity(h):
    global h_color
    if h < 30:
        description = "Low"
        h_color = color.red
    elif 30 <= h <= 60:
        description = "OK"
        h_color = color.green
    elif 60 < h < 80:
        description = "High"
        h_color = color.yellow
    elif h >= 80:
        description = "Very High"
        h_color = color.orange        
    return description

def describe_pressure(p):
    global p_color
    if p < 982:
        description = "Very Low"
        p_color = color.red
    elif 982 <= p < 1004:
        description = "Low"
        p_color = color.yellow
    elif 1004 <= p < 1026:
        description = "OK"
        p_color = color.green
    elif 1026 <= p < 1048:
        description = "High"
        p_color = color.blue
    elif p >= 1048:
        description = "Very High"
        p_color = color.orange
    return description

def draw_graph(temp_value, press_value, humid_value):
    
    if C == 1:
        scaled_temp = int(t * 10)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310

        describe_temperature(t)
        screen.pen = color.yellow
        screen.rectangle(9,89,116,19)
        screen.pen = color.white
        screen.circle(9,98,9)
        screen.pen = color.green
        screen.rectangle(127,89,111,19)
        screen.pen = color.orange
        screen.rectangle(240,89,28,19)
        screen.pen = color.red
        screen.rectangle(270,89,44,19)
        screen.circle(310,98,9)
        screen.pen = color.black
        screen.circle((scaled_temp),98,9)
        screen.pen = color.white
        screen.circle((scaled_temp),98,5)        
    
    if C == 0:    
        scaled_temp = int((t * 5) + 160)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310        
    
        describe_temperature(t)
        screen.pen = color.blue
        screen.circle(9, 98, 9)
        screen.rectangle(12, 89, 92, 19)
        screen.pen = color.white
        screen.rectangle(106, 89, 53, 19)
        screen.pen = color.yellow
        screen.rectangle(161,89,58,19)
        screen.pen = color.green
        screen.rectangle(221,89,58,19)
        screen.pen = color.orange
        screen.rectangle(281,89,13,19)
        screen.pen = color.red
        screen.rectangle(296,89,15,19)
        screen.circle(310,98,9)
        screen.pen = color.black
        screen.circle((scaled_temp),98,9)
        screen.pen = color.white
        screen.circle((scaled_temp),98,5)    
        screen.pen = (t_color)
    
    scaled_humid = int(h * (320 / 100))
    if scaled_humid <= 9:
        scaled_humid =9
    if scaled_humid >= 310:
        scaled_humid =310        
    
    describe_humidity(h)
    screen.pen = color.red
    screen.circle(9, 164, 9)
    screen.rectangle(12,155,82,19)
    screen.pen = color.green
    screen.rectangle(96,155,94,19)
    screen.pen = color.yellow
    screen.rectangle(192,155,62,19)
    screen.pen = color.orange
    screen.rectangle(256,155,55,19)
    screen.circle(310,164,9)
    screen.pen = color.black
    screen.circle((scaled_humid),164,9)
    screen.pen = color.white
    screen.circle((scaled_humid),164,5)
    screen.pen = (h_color)
    screen.text(describe_humidity(h),130,125)
    
    scaled_press = int((p - 960) * 3)
    if scaled_press <= 9:
        scaled_press =9
    if scaled_press >= 310:
        scaled_press =310        
    
    describe_pressure(p)
    screen.pen = color.red
    screen.circle(9, 230, 9)
    screen.rectangle(12,221,50,19)
    screen.pen = color.yellow
    screen.rectangle(64,221,62,19)
    screen.pen = color.green
    screen.rectangle(128,221,62,19)
    screen.pen = color.blue
    screen.rectangle(192,221,62,19)
    screen.pen = color.orange
    screen.rectangle(256,221,52,19)
    screen.circle(310, 230, 9)
    screen.pen = color.black
    screen.line(127,221,127,240)    
    screen.circle((scaled_press),230,9)
    screen.pen = color.white
    screen.circle((scaled_press),230,5)
    screen.pen = (p_color)
    screen.text(describe_pressure(p),130,191) 

def describe_month(month):
    
    if month == 1:
        description = "Jan"
    elif month == 2:
        description = "Feb"  
    elif month == 3:
        description = "Mar"
    elif month == 4:
        description = "Apr"              
    elif month == 5:
        description = "May"              
    elif month == 6:
        description = "Jun"              
    elif month == 7:
        description = "Jul"              
    elif month == 8:
        description = "Aug"              
    elif month == 9:
        description = "Sep"
    elif month == 10:
        description = "Oct"             
    elif month == 11:
        description = "Nov"              
    elif month == 12:
        description = "Dec"            
    return description

def describe_day(day):

    if day == 1:
        description = "st"
    elif day == 2:
        description = "nd"     
    elif day == 3:
        description = "rd" 
    elif day == 21:
        description = "st"      
    elif day == 22:
        description = "nd"  
    elif day == 23:
        description = "rd"
    elif day == 31:
        description = "st"
    else:
        description = "th"
    return description

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

reading = temperature_sensor.read()
temperature, pressure, humidity = reading
pressuremb = pressure / 100
t = round(temperature)
h = round(humidity)
p = round(pressuremb)
min_temperature = t
max_temperature = t

def update():
    screen.pen = color.black
    screen.clear()
    
    rtc.datetime()
    year, month, day, weekday, hour, minute, second, subsecs = rtc.datetime()
    print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
    
    if badge.pressed(BUTTON_A):
        A = 1
  
    if badge.pressed(BUTTON_B):
        print ("Button B pressed")     
    else:
        screen.pen = color.white
    
        if weekday == 0:
            screen.text("Mon",0,9)        
        if weekday == 1:
            screen.text("Tue",0,9)
        if weekday == 2:
            screen.text("Wed",0,9)
        if weekday == 3:
            screen.text("Thu",0,9)
        if weekday == 4:
            screen.text("Fri",0,9)
        if weekday == 5:
            screen.text("Sat",0,9)
        if weekday == 6:
            screen.text("Sun",0,9)                        
         
        screen.text(f"{describe_month(month)} {day}{describe_day(day)}",60,9,)

        if hour == 0:
            screen.text(f"{12}:{minute:02} AM",190,9)
        elif 0 < hour < 10:
            screen.text(f"{hour:1}:{minute:02} AM",190,9)            
        elif 10 <= hour < 12:
            screen.text(f"{hour:2}:{minute:02} AM",190,9)
        elif hour == 12:
            screen.text(f"{hour:2}:{minute:02} PM",190,9)    
        elif hour >12:
            hour = hour - 12
            if hour <10:
                screen.text(f"{hour:1}:{minute:02} PM",190,9)
            elif 10 <= hour < 12:
                screen.text(f"{hour:2}:{minute:02} PM",190,9)
            elif hour == 12:
                screen.text(f"{hour:2}:{minute:02} AM",190,9)

    if badge.pressed(BUTTON_C):
        C = 1        
        min_temperature = t
        max_temperature = t
        time.sleep(0.2)              
        
    if badge.pressed(BUTTON_UP):
        A = 0
        screen.set_backlight(1.0)
                        
    if badge.pressed(BUTTON_DOWN):
        A = 0
        screen.set_backlight(0.0) 
                
    temperature, pressure, humidity = temperature_sensor.read()
    pressuremb = pressure / 100
    t = round(temperature)
    h = round(humidity)
    p = round(pressuremb)
    
    if t <= 0:
        C = 0
        
    if t >= 12:
        C = 1
    
    screen.pen = (color.white)
    screen.text("{:0.0f}°C" .format(t), 5, 52)
    screen.text("{:0.0f}%".format(h), 5, 118)
    screen.text("{:0.0f}mb".format(p), 5, 184)
   
    draw_graph(temperature, pressure, humidity)
    
    if t >= max_temperature: # <<<< Line 345 
        max_temperature = t
    if t <= min_temperature:
        min_temperature = t

    screen.pen = (color.smoke)
    screen.text(f"Min {min_temperature:.0f}", 110, 57, WIDTH)
    screen.pen = (color.smoke)
    screen.text(f"Max {max_temperature:.0f}", 225, 57, WIDTH)
    
    temperature, pressure, humidity = temperature_sensor.read()
    time.sleep(0.25)
    
run(update)

I’ve mucked something up but can’t see it?

>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
22 75 661
2026-03-01 09:06:43
Traceback (most recent call last):
  File "<stdin>", line 358, in <module>
  File "badgeware/__init__.py", line 40, in __init__
  File "badgeware/__init__.py", line 52, in __call__
  File "<stdin>", line 345, in update
NameError: local variable referenced before assignment

Line 345 is if t >= max_temperature:

I dont have one of these badgeware things but as I saw a simple python error that I could comment on, your Line 345 … on line 346 it does indeed try to assign a value to a max_temperature variable, which is treated as a local variable for assignment purposes as you’ve not declared it as a global variable. (you can read global variable without declaring them as global, but you cannot assign a value to them)

But I then glance at the rest of your code as I think you have probably been overdoing the cut and paste :-) Time for a break and a cup’o tea. I see you import rtc from badgeware, only to immediately reassign the rtc to referencing the machine.RTC. I see a min_temperature and a max_temperature both assigned to the temperature value which seems strange. You have used screen.pen etc. but you have not imported a ‘screen’ from any module as far as I can see. But that was just a quick glance and I probably need to drink that cuppa myself.

But of interest what do you use your badgeware screens for, surely you don’t wander about the place wearing the screen pinned to your cardigan to show the temperature settings to all who may greet you. Perhaps I’m missing out on the latest social interaction trends. Mine would display ‘milk no sugar please’

I do on occasion take my Tufty2040 with me on my morning walk with my faithful companion. I carry it in my hand and like to see just how cold it is outside. The Tufty2350 makes this even easier, I’ll just hang it around my neck. I can also just sit it on my desk, and or take it out on my deck in the summer to see how hot and sticky it is outside.

My coding skill is at best average. That being said mistakes were made. ;)
Plus every thing seems to be different / new on the Tufty 2350. All the edits to what was working code is driving me mad. =( I’ve been hours and hours and hours at this, and I’m just about at the throw in the towel stage. There are no examples to go by. There is minimal, and I mean minimal info in the API documentation. So I’ve been delving into the included apps for info on how you do what and when. Thing is they do so much it’s hard to filter out just the code you need. What can I say, I am very very frustrated at this point.

I will go over what you posted and have another go at getting this working. But I’m getting less and less enthused by trying to make my App work.

Thankyou very much for trying to help. :)

Doing the rtc = RTC() was the only way I could read the date time?
It let me do this:

    rtc.datetime()
    year, month, day, weekday, hour, minute, second, subsecs = rtc.datetime()
    print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
    

The min_temperature = t and max_temperature = t is to set them to the current temperature. There is likely a better wat to do it? They get changed latter on to track the lowest and highest temps, until reset with a button press.

but you have not imported a ‘screen’ from any module as far as I can see.

I wondered about that but couldn’t figure it out? I am getting things displayed on the LCD but its like its magnified? or the resolution is set wrong?

That Global Variable thing has caught me out in the past, thanks for pointing that out. I’ll have a rethink on that and see if I can fix it.

Quite a bit of the basic level running of the badge is builtin and won’t need importing. I’ve found this has worked fine as a pretty minimal way of importing and displaying time:

def update():
    year, month, day, hour, minute, second, _ = rtc.datetime()
    time_text = f"{day}/{month}/{year} {hour}:{minute}:{second}"
    screen.text(time_text, 0, 0)

run(update)

That is from the badge’s external RTC, accessed with the builtin rtc, rather than the 2350’s internal RTC.

Meet Badger, Tufty, and Blinky - the Digital Badge Crew This is the reference for RTC methods on Badgeware.

Similarly, there’s no need to import the screen or anything, screen is a builtin instance of the image class and as such you can do anything with it that you would an image. You can simply write to the image as you are doing already.

1 Like

@alphanumeric Yes, I see that that sort of use for a Tufty badge type of screen could be useful. For me much would depend on it having some docking arrangement to plonk it on when you return to your desk to keep the thing charged up without too much fiddling about.

I had a quick look at the doc’s and I see the firmware is rather different than being just micropython with a screen driver. Clearly a different approach than using normal’ micropython. It seems you will have to forget simply porting your application to your new Tufty but rewrite it within the constraints of the badger firmware, once you’ve ploughed through learning this new environment.

And indeed to doc’s are a bit sparse, and I’ve not perused any example code as I doubt the likes of a Tufty is for me.

I’m reminded a bit of getting the Presto. I had not used the Pimorini graphics lib before and found the docs on the vector graphics to be rather minimal, though easy enough to get going with. But they don’t really cover the full picture. I forget where I picked up the fact that the Presto screen driver could be set to work directly with the micropython framebuffer, but it was not in the Pirmoroni docs.

Working directly with the framebuffer enabled me to easily port over some of my widget libraries I had working for other screens. I was surprised when I found that whatever I wrote to the framebuffer got immediately plonked on the screen whereas for other screens I had to update the famebuffer to the screen. Working with this new paradigm (to me) was not a problem though doc’s on the Presto screen driver relating to this sort of thing is not to be found.

But I suppose these days products have short life spans and producing comprehensive doc’s are just not worth the effort in a commercial sense. But perhaps muddling by is half the fun :-)

I’ve got most of it working now. The basic functions are working , temp, humidity, pressure text and my graphs etc. It’s usable as is, assuming it will run as an app from the menu.
All that’s left is the min max temperature and battery state functionality to work out.
I have the badge.mode(HIRES) and I’m using the screen.font = rom_font.ignore.
I will ply around with the vector fonts at some point. I’d like to get my day date time a little bigger on the screen.

Thankyou to all that have helped. I am starting to see the light at the end of the tunnel. I don’t hear any train whistles, but there a coyote with a Wiley smile on his face and a bucket of black paint in his hand at the entrance. :P

When I read about all this, I am very glad that my work-horse is CircuitPython. It has a stable API, has a clean API documentation, has many, many learning guides, has simple (!) example programs for every driver. And it has a big and vivid community.

I ported the Badger2350 to CP, and now I can run all my programs without any large porting effort. In fact, anyone who took care not to hard-code screen-dimensions can just run their programs without rewriting the code.

The excellent hardware would really profit from a big community, but with all this “PimoroniPython” it isn’t even simple for long time Pimoroni customers to follow along.

It won’t run as an App from the menu, I’ve botched something up there. The screen goes black / blank for an instant, then just returns to the App Menu. :(
My neck (chronic pain) is killing me from all this coding so I’ll likely have to let things go for another day.

APP_DIR = "/system/apps/tricorder"

import time
import math
import machine
import micropython
from badgeware import State, rtc
from breakout_bme280 import BreakoutBME280
from machine import RTC
from machine import I2C
import sys
import os
sys.path.insert(0, "/system/apps/tricorder")
os.chdir("/system/apps/tricorder")
rtc = RTC()

badge.mode(HIRES)

A = 1
C = 1

temperature_sensor = BreakoutBME280(I2C())
reading = temperature_sensor.read()
temperature, pressure, humidity = reading
pressuremb = pressure / 100
t = round(temperature)
h = round(humidity)
p = round(pressuremb)

min_temperature = 100
max_temperature = -100
#screen.font = rom_font.IndieFlower-Regular
screen.font = rom_font.ignore

screen.pen = color.white
h_color = screen.pen
p_color = screen.pen

def describe_humidity(h):
    global h_color
    if h < 30:
        description = "Low"
        h_color = color.red
    elif 30 <= h <= 60:
        description = "OK"
        h_color = color.green
    elif 60 < h < 80:
        description = "High"
        h_color = color.yellow
    elif h >= 80:
        description = "Very High"
        h_color = color.orange        
    return description

def describe_pressure(p):
    global p_color
    if p < 982:
        description = "Very Low"
        p_color = color.red
    elif 982 <= p < 1004:
        description = "Low"
        p_color = color.yellow
    elif 1004 <= p < 1026:
        description = "OK"
        p_color = color.green
    elif 1026 <= p < 1048:
        description = "High"
        p_color = color.blue
    elif p >= 1048:
        description = "Very High"
        p_color = color.orange
    return description

def draw_graph(temp_value, press_value, humid_value):
    
    if C == 1:
        scaled_temp = int(t * 10)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310

        screen.pen = color.yellow
        screen.rectangle(9,89,116,19)
        screen.pen = color.white
        screen.circle(9,98,9)
        screen.pen = color.green
        screen.rectangle(127,89,111,19)
        screen.pen = color.orange
        screen.rectangle(240,89,28,19)
        screen.pen = color.red
        screen.rectangle(270,89,44,19)
        screen.circle(310,98,9)
        screen.pen = color.black
        screen.circle((scaled_temp),98,9)
        screen.pen = color.white
        screen.circle((scaled_temp),98,5)        
    
    if C == 0:    
        scaled_temp = int((t * 5) + 160)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310        
    
        screen.pen = color.blue
        screen.circle(9, 98, 9)
        screen.rectangle(12, 89, 92, 19)
        screen.pen = color.white
        screen.rectangle(106, 89, 53, 19)
        screen.pen = color.yellow
        screen.rectangle(161,89,58,19)
        screen.pen = color.green
        screen.rectangle(221,89,58,19)
        screen.pen = color.orange
        screen.rectangle(281,89,13,19)
        screen.pen = color.red
        screen.rectangle(296,89,15,19)
        screen.circle(310,98,9)
        screen.pen = color.black
        screen.circle((scaled_temp),98,9)
        screen.pen = color.white
        screen.circle((scaled_temp),98,5)    
            
    scaled_humid = int(h * (320 / 100))
    if scaled_humid <= 9:
        scaled_humid =9
    if scaled_humid >= 310:
        scaled_humid =310        
    
    describe_humidity(h)
    screen.pen = color.red
    screen.circle(9, 164, 9)
    screen.rectangle(12,155,82,19)
    screen.pen = color.green
    screen.rectangle(96,155,94,19)
    screen.pen = color.yellow
    screen.rectangle(192,155,62,19)
    screen.pen = color.orange
    screen.rectangle(256,155,55,19)
    screen.circle(310,164,9)
    screen.pen = color.black
    screen.circle((scaled_humid),164,9)
    screen.pen = color.white
    screen.circle((scaled_humid),164,5)
    screen.pen = (h_color)
    screen.text(describe_humidity(h),130,118)
    
    scaled_press = int((p - 960) * 3)
    if scaled_press <= 9:
        scaled_press =9
    if scaled_press >= 310:
        scaled_press =310        
    
    describe_pressure(p)
    screen.pen = color.red
    screen.circle(9, 230, 9)
    screen.rectangle(12,221,50,19)
    screen.pen = color.yellow
    screen.rectangle(64,221,62,19)
    screen.pen = color.green
    screen.rectangle(128,221,62,19)
    screen.pen = color.blue
    screen.rectangle(192,221,62,19)
    screen.pen = color.orange
    screen.rectangle(256,221,52,19)
    screen.circle(310, 230, 9)
    screen.pen = color.black
    screen.line(127,221,127,240)    
    screen.circle((scaled_press),230,9)
    screen.pen = color.white
    screen.circle((scaled_press),230,5)
    screen.pen = (p_color)
    screen.text(describe_pressure(p),130,184) 

def describe_month(month):
    
    if month == 1:
        description = "Jan"
    elif month == 2:
        description = "Feb"  
    elif month == 3:
        description = "Mar"
    elif month == 4:
        description = "Apr"              
    elif month == 5:
        description = "May"              
    elif month == 6:
        description = "Jun"              
    elif month == 7:
        description = "Jul"              
    elif month == 8:
        description = "Aug"              
    elif month == 9:
        description = "Sep"
    elif month == 10:
        description = "Oct"             
    elif month == 11:
        description = "Nov"              
    elif month == 12:
        description = "Dec"            
    return description

def describe_day(day):

    if day == 1:
        description = "st"
    elif day == 2:
        description = "nd"     
    elif day == 3:
        description = "rd" 
    elif day == 21:
        description = "st"      
    elif day == 22:
        description = "nd"  
    elif day == 23:
        description = "rd"
    elif day == 31:
        description = "st"
    else:
        description = "th"
    return description

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

temperature, pressure, humidity = temperature_sensor.read()
time.sleep(0.5)

reading = temperature_sensor.read()
temperature, pressure, humidity = reading
pressuremb = pressure / 100
t = round(temperature)
h = round(humidity)
p = round(pressuremb)
min_temperature = 100
max_temperature = -100

def update():
    

    
    screen.pen = color.black
    screen.clear()

    reading = temperature_sensor.read()
    temperature, pressure, humidity = reading
    pressuremb = pressure / 100
    t = round(temperature)
    h = round(humidity)
    p = round(pressuremb)
    #print (t, h, p)
    
    rtc.datetime()
    year, month, day, weekday, hour, minute, second, subsecs = rtc.datetime()
    #print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
    
    screen.pen = color.white
    
    if weekday == 0:
        screen.text("Mon",0,9)        
    if weekday == 1:
        screen.text("Tue",0,9)
    if weekday == 2:
        screen.text("Wed",0,9)
    if weekday == 3:
        screen.text("Thu",0,9)
    if weekday == 4:
        screen.text("Fri",0,9)
    if weekday == 5:
        screen.text("Sat",0,9)
    if weekday == 6:
        screen.text("Sun",0,9)                        
         
    screen.text(f"{describe_month(month)} {day}{describe_day(day)}",60,9,)

    if hour == 0:
        screen.text(f"{12}:{minute:02} AM",190,9)
    elif 0 < hour < 10:
        screen.text(f"{hour:1}:{minute:02} AM",190,9)            
    elif 10 <= hour < 12:
        screen.text(f"{hour:2}:{minute:02} AM",190,9)
    elif hour == 12:
        screen.text(f"{hour:2}:{minute:02} PM",190,9)    
    elif hour >12:
        hour = hour - 12
        if hour <10:
            screen.text(f"{hour:1}:{minute:02} PM",190,9)
        elif 10 <= hour < 12:
            screen.text(f"{hour:2}:{minute:02} PM",190,9)
        elif hour == 12:
            screen.text(f"{hour:2}:{minute:02} AM",190,9)
    
    if t <= 0:
        C = 0
        
    if t >= 12:
        C = 1
    
    screen.pen = (color.white)
    screen.text("{:0.0f}°C" .format(t), 5, 52)
    screen.text("{:0.0f}%".format(h), 5, 118)
    screen.text("{:0.0f}mb".format(p), 5, 184)
   
    draw_graph(temperature, pressure, humidity)
    
    time.sleep(2)
    
run(update)
>>> %Run -c $EDITOR_CONTENT

MPY: soft reboot
Traceback (most recent call last):
  File "<stdin>", line 11, in <module>
  File "badgeware/__init__.py", line 40, in __init__
  File "badgeware/__init__.py", line 52, in __call__
  File "<stdin>", line 7, in update
TypeError: 'module' object isn't callable
>>> 
screen.font = rom_font.IndieFlower-Regular

 %Run -c $EDITOR_CONTENT

MPY: soft reboot
Traceback (most recent call last):
  File "<stdin>", line 32, in <module>
  File "badgeware/text.py", line 214, in __getattr__
  File "badgeware/text.py", line 221, in _load_font
AttributeError: Font IndieFlower not found!
 

The vector fonts aren’t stored in ROM like the pixel fonts are (the pixel fonts are also duplicated in the folder you show, for convenience). To load one in from that folder, you can use the following path:

indieflower = font.load("/system/assets/fonts/IndieFlower-Regular.af")

I’m not sure what’s up with the RTC code there, if you’re saying that that’s giving the error shown when you run it on your unit. The code I listed worked for me as the sole contents of main.py. Are you definitely running the 2.0.0 or higher firmware? There were a lot of changes in it, much of it based on feedback from these forums, and part of it included reorganising the RTC into its own module.

From the code you’ve posted here there’s any number of things, but the first thing I noticed is that both RTCs are being imported, and then you’re overwriting one with the other. You can completely lose rtcfrom from badgeware import State, rtc, and completely get rid of from machine import RTC and rtc = RTC().

Then in update() you’ve got this:

    rtc.datetime()
    year, month, day, weekday, hour, minute, second, subsecs = rtc.datetime()

The first line of that is unnecessary and can be cut, the second should then give you the variables you want - although the return values are slightly different on the badge RTC so it would want to be altered to year, month, day, hour, minute, second, weekday = rtc.datetime()

Can’t say if that’s causing you the problem with the app returning to the menu without more info, but it’ll help with the RTC bits anyway.

EDIT: Had a quick look, and your code runs fine on the unit I’ve got in front of me - I don’t have a BME280 breakout to hand but I used a multi sensor stick which has a BME280 on it. You can streamline your imports a great deal, lines 1-15 can be taken down to just:

import time
from breakout_bme280 import BreakoutBME280
from machine import I2C

You could lose import time too if you wanted - time.sleep() generally isn’t the best way to put things on a delay, as it stops anything else from happening while that sleep is active. I tend to use badge.ticks() to count out times like that - you can find that in the documentation’s Dashboard tutorial, in this section.

I don’t think it is a good idea to automagically import modules. That is just not the way that Python is designed to work. It makes it hard to read and understand programs, because you can no longer tell if there is an error or not. Secondly, if memory is tight, you don’t want to import things you don’t need. And useless imports also unnecessarily eat up power from your battery.

    year, month, day, hour, minute, second, weekday = rtc.datetime()
    print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d} {weekday:01d}")

Gets me

MPY: soft reboot
2026-03-03 08:49:22  1
2026-03-03 08:49:24  1
2026-03-03 08:49:26  1
2026-03-03 08:49:28  1

So that’s the rtc - time sorted. =)

And

indieflower = font.load("/system/assets/fonts/IndieFlower-Regular.af")
screen.font = indieflower

Appears to also get me that font. The screen placement seems a bit messed up? I’ll read up on it and double check my code.

Vector fonts are a little tricky to place - for a start whenever you’re drawing text you now have to specify its height in pixels - that’s easy with screen.text(), you just add it in as another parameter after the x and y coordinates - as well as needing placement that takes into account the full glyph size.

See, the height of the font as a whole is generally higher than the height of the letters you see, as the former is going to be the height of the very highest glyph in that font. That’ll include capitals with accents and diacritics, so you’ll generally find a bit of a gap between the location you’ve specified for the text and the top of the actual letters. That’s going to differ between fonts, so really it’s often a matter of tweaking it till its right. The same dashboard tutorial that has the info about the timer also has a method to specify the baseline of the text rather than the top, which might make life easier.

There are ways to get the height of the actual text you’ve written, but that generally involves storing heights for each glyph individually and it’s way more hardcore than we can sensibly do on a low-power platform like the 2350.

@BillyTPilgrim has kindly tidied up my code for me. Many many thank’s to him.
The following run’s just fine from Thonny. And will run as main.py. But doesn’t run as _init_.py from the app folder. I can select it from the App Menu, but all I get is a blank scree fro a second of so, and then it exits out back to the App Menu.

from breakout_bme280 import BreakoutBME280
from machine import I2C

badge.mode(HIRES)

temperature_sensor = BreakoutBME280(I2C())
last_ticks = badge.ticks

t = 0
p = 0
h = 0
C = 1

min_temperature = 100
max_temperature = -100

# screen.font = font.load("/system/assets/fonts/IndieFlower-Regular.af")
screen.font = rom_font.ignore

screen.pen = color.white
h_color = screen.pen
p_color = screen.pen


def describe_humidity(h):
    global h_color
    if h < 30:
        description = "Low"
        h_color = color.red
    elif 30 <= h <= 60:
        description = "OK"
        h_color = color.green
    elif 60 < h < 80:
        description = "High"
        h_color = color.yellow
    elif h >= 80:
        description = "Very High"
        h_color = color.orange        
    return description


def describe_pressure(p):
    global p_color
    if p < 982:
        description = "Very Low"
        p_color = color.red
    elif 982 <= p < 1004:
        description = "Low"
        p_color = color.yellow
    elif 1004 <= p < 1026:
        description = "OK"
        p_color = color.green
    elif 1026 <= p < 1048:
        description = "High"
        p_color = color.blue
    elif p >= 1048:
        description = "Very High"
        p_color = color.orange
    return description


def draw_graph():
    # Everything that was common to both of these has been moved outside the if statement
    if C == 1:
        scaled_temp = int(t * 10)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310

        screen.pen = color.yellow
        screen.rectangle(9,89,116,19)
        screen.pen = color.white
        screen.circle(9,98,9)
        screen.pen = color.green
        screen.rectangle(127,89,111,19)
        screen.pen = color.orange
        screen.rectangle(240,89,28,19)
        screen.pen = color.red
        screen.rectangle(270,89,44,19)
        screen.circle(310,98,9)    
    
    if C == 0:    
        scaled_temp = int((t * 5) + 160)
        if scaled_temp <= 9:
            scaled_temp =9
        if scaled_temp >= 310:
            scaled_temp =310
    
        screen.pen = color.blue
        screen.circle(9, 98, 9)
        screen.rectangle(12, 89, 92, 19)
        screen.pen = color.white
        screen.rectangle(106, 89, 53, 19)
        screen.pen = color.yellow
        screen.rectangle(161,89,58,19)
        screen.pen = color.green
        screen.rectangle(221,89,58,19)
        screen.pen = color.orange
        screen.rectangle(281,89,13,19)
        screen.pen = color.red
        screen.rectangle(296,89,15,19)
        screen.circle(310,98,9)
            
    scaled_humid = int(h * (320 / 100))
    if scaled_humid <= 9:
        scaled_humid =9
    if scaled_humid >= 310:
        scaled_humid =310

    humidity_text = describe_humidity(h)
    screen.pen = (h_color)
    screen.text(humidity_text,130,118)
    
    scaled_press = int((p - 960) * 3)
    if scaled_press <= 9:
        scaled_press =9
    if scaled_press >= 310:
        scaled_press =310

    pressure_text = describe_pressure(p)
    screen.pen = (p_color)
    screen.text(pressure_text,130,184) 
    
    screen.pen = color.red
    screen.circle(9, 230, 9)
    screen.circle(9, 164, 9)
    screen.rectangle(12,221,50,19)
    screen.rectangle(12,155,82,19)

    screen.pen = color.yellow
    screen.rectangle(64,221,62,19)
    screen.rectangle(192,155,62,19)

    screen.pen = color.green
    screen.rectangle(128,221,62,19)
    screen.rectangle(96,155,94,19)

    screen.pen = color.blue
    screen.rectangle(192,221,62,19)

    screen.pen = color.orange
    screen.rectangle(256,221,52,19)
    screen.circle(310, 230, 9)
    screen.rectangle(256,155,55,19)
    screen.circle(310,164,9)

    screen.pen = color.black
    screen.line(127,221,127,240)
    screen.circle((scaled_temp),98,9)
    screen.circle((scaled_humid),164,9)
    screen.circle((scaled_press),230,9)

    screen.pen = color.white
    screen.circle((scaled_temp),98,5)
    screen.circle((scaled_humid),164,5)
    screen.circle((scaled_press),230,5)


def describe_month(month):
    if month == 1:
        description = "Jan"
    elif month == 2:
        description = "Feb"  
    elif month == 3:
        description = "Mar"
    elif month == 4:
        description = "Apr"              
    elif month == 5:
        description = "May"              
    elif month == 6:
        description = "Jun"              
    elif month == 7:
        description = "Jul"              
    elif month == 8:
        description = "Aug"              
    elif month == 9:
        description = "Sep"
    elif month == 10:
        description = "Oct"             
    elif month == 11:
        description = "Nov"              
    elif month == 12:
        description = "Dec"            
    return description


def describe_day(day):
    if day == 1:
        description = "st"
    elif day == 2:
        description = "nd"     
    elif day == 3:
        description = "rd" 
    elif day == 21:
        description = "st"      
    elif day == 22:
        description = "nd"  
    elif day == 23:
        description = "rd"
    elif day == 31:
        description = "st"
    else:
        description = "th"
    return description

def get_reading():
    global t, p, h
    temperature, pressure, humidity = temperature_sensor.read()
    pressuremb = pressure / 100
    t = round(temperature)
    h = round(humidity)
    p = round(pressuremb)

def update():
    global last_ticks

    screen.pen = color.black
    screen.clear()

    # it's just updating the values that's happening every two seconds,
    # everything else happens every frame
    if badge.ticks - last_ticks >= 2000:
        last_ticks = badge.ticks
        get_reading()
    
    year, month, day, hour, minute, second, weekday = rtc.datetime()
    #print(f"{year:04d}-{month:02d}-{day:02d} {hour:02d}:{minute:02d}:{second:02d}")
    
    screen.pen = color.white
    
    if weekday == 0:
        weekday_text = "Mon"
    if weekday == 1:
        weekday_text = "Tue"
    if weekday == 2:
        weekday_text = "Wed"
    if weekday == 3:
        weekday_text = "Thu"
    if weekday == 4:
        weekday_text = "Fri"
    if weekday == 5:
        weekday_text = "Sat"
    if weekday == 6:
        weekday_text = "Sun"                      

    if hour == 0:
        time_text = f"{12}:{minute:02} AM"
    elif 0 < hour < 10:
        time_text = f"{hour:1}:{minute:02} AM"         
    elif 10 <= hour < 12:
        time_text = f"{hour:2}:{minute:02} AM"
    elif hour == 12:
        time_text = f"{hour:2}:{minute:02} PM"   
    elif hour >12:
        hour = hour - 12
        if hour <10:
            time_text = f"{hour:1}:{minute:02} PM"
        elif 10 <= hour < 12:
            time_text = f"{hour:2}:{minute:02} PM"
        elif hour == 12:
            time_text = f"{hour:2}:{minute:02} AM"

    screen.text(f"{weekday_text} {describe_month(month)} {day}{describe_day(day)} {time_text}",0,9)
    
    if t <= 0:
        C = 0

    if t >= 12:
        C = 1

    screen.text("{:0.0f}°C" .format(t), 5, 52)
    screen.text("{:0.0f}%".format(h), 5, 118)
    screen.text("{:0.0f}mb".format(p), 5, 184)
   
    draw_graph()
    
run(update)