optimising memory usage - crashes

All ESP8266 boards running MicroPython.
Official boards are the Adafruit Huzzah and Feather boards.
Target audience: MicroPython users with an ESP8266 board.
Post Reply
jarekd
Posts: 13
Joined: Mon Aug 21, 2017 3:54 pm

optimising memory usage - crashes

Post by jarekd » Tue Sep 25, 2018 2:26 pm

Hi. I'm trying to optimise memory usage in my code because sometimes I get memory allocation errors.
The main part is pasted below. I'm interested if it could be done better: memory errors are showing up mostly when I'm replacing parts of html_content. I need that part, as server is updating html with current variable values while running.
"l" (in "l.set_power()", ...) is class instance of my led driver.

Also I'm trying to save memory by importing only needed things from libraries, for example "from machine import Pin, PWM, Timer" instead of just "import machine" - does this give much savings?

Code: Select all

#--------------------------------------
gc.collect()
f = open('index.html')
html_content = f.read()
f.close()
content = ''

def main():
	global html_content, content

	s = socket.socket()
	addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
	s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
	s.bind(addr)
	s.listen(5)
	print('Listening, connect your browser to http://'+str(wifi.wifi.ifconfig()[0])+':80/')

	while True:
		conn, address = s.accept()
		# read request
		req = conn.readline().decode('utf-8')
		# read rest of the request ...
		while True:
			line = conn.readline()
			if not line or line == b'\r\n':
				break
		# and discard it
		del line
		print(str(req))
		# send header
		conn.send('HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n')
		# check the request
		match = ure.search('smooth', req)
		if match:
			match = ure.search('power=[0-9]+', req)
			if match:
				l.set_power( int( match.group(0).split('=')[1] ) )
			match = ure.search('balance=[0-9]+', req)
			if match:
				l.set_balance( int( match.group(0).split('=')[1] ) )
		# if no parameters found, serve main webpage
		else:
			content = html_content.replace('{power}', str( l.get_power() ) )
			content = content.replace('{balance}', str( l.get_balance() ) )
			content = content.replace('{time}', str( l.get_time() ) )
			content = content.replace('{ip_address}', str( wifi.wifi.ifconfig()[0] ) )
			#content = html_content.format( power=l.get_power(), balance=l.get_balance(), time=l.get_time, ip_address=wifi.wifi.ifconfig()[0] )
			# send web page in smaller parts
			i = 0
			while i<len(content)-1:
				if len(content)-1<256:
					i += conn.send(content[i:])
					print("Data sent: "+str(i))
				else:
					i += conn.send(content[i:i+256])
					print("Data sent: "+str(i))
		# close connection
		conn.close()
		# update leds
		l.smooth()
		# a little cleanup
		gc.collect()
main()

kevinkk525
Posts: 969
Joined: Sat Feb 03, 2018 7:02 pm

Re: optimising memory usage - crashes

Post by kevinkk525 » Tue Sep 25, 2018 2:43 pm

I don't know much about webserver but I can tell you, that importing parts of a module still imports the complete module and therefore it does not save RAM.
But "machine" is a built-in module and does not use any RAM.
Importing "machine" should not make a difference.

I guess your problem is with modifying big strings and that needs a lot of RAM.

One improvement would be to load the html_content only when you need. This is a bit slower but would free the RAM that html_content consumes.
Also you could try to read it line by line, replace needed things inside this line and then send the line. This saves a lot of RAM compared to reading the whole file, replacing thins and then sending it in small parts.


But that's just some ideas, maybe I missed a crucial point in your project that prevents some improvements from being useful.
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode

Post Reply