bbcmicrobit / bbcmicrobit/micropython
Strategies for memory usage reduction?
- Dominant language
- C
- Stars
- 646
- Forks
- 290
- PR merge metrics
- No merged PRs in 30d
Description
Have had a random question come in, where a user is asking how to reduce their memory footprint for the code below. I know asking you to say "how can this run" is unfair - I've copied the code below to make it clearer about the sort of contents I mean. Specifically they have a collection of i2c devices they're working with and trying to read from some, output/control others. (I don't have those devices and don't expect you to either obviously :) )
Hence the question is really about strategies for reducing memory usage.
( I'd be happy to collate the strategies as something you could include with micropython / mu / etc. )
Any feedback welcome.
Michael.
from microbit import *
#----Snippet for OLED----
OLED_ADDR = 0x3c
oled_screen = bytearray('b\x40') + bytearray(512)
def oled_initialize():
for c in ([0xae], [0xa4], [0xd5, 0xf0], [0xa8, 0x3f], [0xd3, 0x00], [0 | 0x0], [0x8d, 0x14], [0x20, 0x00], [0x21, 0, 127], [0x22, 0, 63], [0xa0 | 0x1], [0xc8], [0xda, 0x12], [0x81, 0xcf], [0xd9, 0xf1], [0xdb, 0x40], [0xa6], [0xd6, 1], [0xaf]):
i2c.write(OLED_ADDR, b'\x00' + bytearray(c))
def oled_set_pos(col=0, page=0):
i2c.write(OLED_ADDR, b'\x00' + bytearray([0xb0 | page]))
c1, c2 = col * 2 & 0x0F, col >> 3
i2c.write(OLED_ADDR, b'\x00' + bytearray([0x00 | c1]))
i2c.write(OLED_ADDR, b'\x00' + bytearray([0x10 | c2]))
def oled_clear_screen(c=0):
global oled_screen
oled_set_pos()
for i in range(1, 513):
oled_screen[i] = 0
oled_draw_screen()
def oled_draw_screen():
global oled_screen
oled_set_pos()
i2c.write(OLED_ADDR, oled_screen)
def oled_add_text(x, y, text):
global oled_screen
for i in range(0, min(len(text), 12 - x)):
for c in range(0, 5):
col = 0
for r in range(1, 6):
p = Image(text[i]).get_pixel(c, r - 1)
col = col | (1 << r) if (p != 0) else col
ind = x * 10 + y * 128 + i * 10 + c * 2 + 1
oled_screen[ind], oled_screen[ind + 1] = col, col
oled_set_pos(x * 5, y)
ind0 = x * 10 + y * 128 + 1
i2c.write(OLED_ADDR, b'\x40' + oled_screen[ind0 : (ind+1)])
oled_initialize()
oled_clear_screen()
oled_add_text(0,0,"Start")
#----Snippet for RTC----
RTC_ADDR = 0x68
def bcd2bin(v):
return v - 6 * (v >> 4)
def bin2bcd(v):
return v + 6 * (v // 10)
def rtc_gettime():
i2c.write(RTC_ADDR, b'\x00')
value = i2c.read(RTC_ADDR, 7)
ss = bcd2bin(value[0] & 0x7F)
mm = bcd2bin(value[1])
hh = bcd2bin(value[2])
d = bcd2bin(value[4])
m = bcd2bin(value[5])
y = bcd2bin(value[6]) + 2000
return [y, m, d, hh, mm, ss]
def rtc_settime(y, m, d, hh, mm, ss):
value = []
value.append(bin2bcd(ss))
value.append(bin2bcd(mm))
value.append(bin2bcd(hh))
value.append(bin2bcd(0))
value.append(bin2bcd(d))
value.append(bin2bcd(m))
value.append(bin2bcd(y - 2000))
i2c.write(RTC_ADDR, b'\x00' + bytearray(value))
# rtc_gettime()
# rtc_settime(2017, 5, 22, 14, 23, 0)
# rtc_gettime() -> [2017, 5, 22, 14, 23, 0]
#----My Code----
def control(x): #user-defined function to set the brightness of LED display light
light=[x for i in range (5)]
img=((''.join(light)+":")*5)[0: -1]
img=Image(img)
display.show(img)
rtc_settime(2017, 6, 2, 13, 00, 0)
mode=0
counterB=0
brightness=0
while True:
time=rtc_gettime()[3:-1] #[hh,mm]
oled_add_text(0,1,'Time:%s'%str(time))
oled_add_text(0,3,'BRT:'+str(brightness))
if button_a.was_pressed(): #Push Lock E-Switch connected to pin5 GPIO shared with button_a
oled_clear_screen()
mode+=button_a.get_presses() # odd = manual, even = auto
if mode%2==0: #mode=auto
oled_add_text(0,0,'Automatic')
reading_photoresistor=pin2.read_analog()//113 #floor division to make into int
reading_motion=pin12.read_digital()
reading_rain=pin0.read_analog()
if (time[0]>=19 and time[1]>=30) or reading_photoresistor<3:
brightness=9-reading_photoresistor
if reading_motion == 0 and brightness > 5: #no motion
brightness=5 #cap brightness at 5 if there is no motion
if reading_rain>500:#actual=900, lowered to work with touch
brightness=9 #max brightness when raining.
else: #mode=manual (maintenance mode)
oled_add_text(0,0,'Manual')
counterB+=button_b.get_presses()
if (counterB%3)==0: #Push Button connected to pin11 GPIO shared with button_b
oled_add_text(0,2,'LDR:%s(%s) '%(str(pin2.read_analog()), str(pin2.read_analog()//113)))#LDR:1024(9)
elif (counterB%3)==1:
oled_add_text(0,2,'Rain:%s '%str(pin0.read_analog()))#Rain:1024
else:
oled_add_text(0,2,'PIR:%s '%str(pin12.read_digital()))#PIR:1
reading_potentiometer=pin1.read_analog()
brightness=reading_potentiometer//113 #floor division to make into int
control(str(brightness))#str to use in control()/join func
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.