Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 21:12 12 Nov 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Armmite vs MicroPython performance

Author Message
sawasdee01
Newbie

Joined: 23/12/2016
Location: United Kingdom
Posts: 33
Posted: 12:31pm 15 Apr 2019
Copy link to clipboard 
Print this post

Hi All,

I have been testing both Micropython and Armmite images on the Nucleo STM32L476RG board in an attempt to gain an insight into the relative performance of the two languages on an identical hardware platform. For interest, I have some early results for your perusal, below.

A quick disclaimer, first:- I would describe myself as an 'absolute beginner' with respect to Micropython. Also, I have not taken any steps with either platform to optimise code, etc - although, I have used Integer variables, throughout (ie no floats, etc).

Versions

Armmite Version:- 2019-03-19_232030_Armmite_L4

MicroPython Version:- NUCLEO_L476RG-20190330-v1.10-247-g0fb15fc3f_00


Approach
In order to keep the testing technique as 'non-invasive' as possible, I used a Bitscope BS5U oscilloscope attached to PA5 (pin 21). Each test was performed within a Do While(1) loop. The first instruction inside the loop set Port pin PA5 high. After the measurement period, the Port pin PA5 was set low. Time measurements were read from the oscilloscope


Test Number 1 - Simple Toggle Port Pins

Armmite Code

CONST PA5=21
SETPIN PA5,DOUT
DO WHILE(1)
Pin(PA5)=1
Pin(PA5)=0
LOOP


Micropython Code

(note LED_GREEN is on PA5 and is already defined in the board Micropython package)

import machine
import sys
led = machine.Pin('LED_GREEN',machine.Pin.OUT)
led.value(1)
while True:
led.value(1)
led.value(0)

Results

MicroPython
PA5 high time = 17 microSecs PA5 low time 17 microSecs

Armmite
PA5 high time = 58 microSecs PA5 low time 92 microSecs



Test Number 2 - Toggle Port Pins with Integer Add

Armmite Code

DIM A%=42
DIM B%=6
DIM C%=10
DIM D%=2
DIM SUM%
CONST PA5=21
SETPIN PA5,DOUT
DO WHILE(1)
Pin(PA5)=1
SUM%=A%+B%
Pin(PA5)=0
SUM%=C%+D%
LOOP

Micropython Code

import machine
import sys
a=int(42)
b=int(6)
c=int(10)
d=int(2)
x=int(0)
y=int(0)
led = machine.Pin('LED_GREEN',machine.Pin.OUT)
led.value(1)
while True:
led.value(1)
x=a+b
led.value(0)
y=c+d

MicroPython
PA5 high time = 29 microSecs PA5 low time 29 microSecs

Armmite
PA5 high time = 133 microSecs PA5 low time 164 microSecs


Note:- I repeated the test using subtraction, instead of addition. On the Micropython board, the results were identical to the above. I did not repeat the test on the Armmite board.



Test Number 3 - Toggle Port Pins with Integer Divide

The previous test was repeated with integer divides (eg x=a/b). The following results were obtained:-

MicroPython
PA5 high time = 32 microSecs PA5 low time 32 microSecs

Armmite
PA5 high time = 155 microSecs PA5 low time 193 microSecs



Test Number 4 - Toggle Port Pins with empty FOR NEXT loop

Armmite Code

DIM A%
DIM B%
CONST PA5=21
SETPIN PA5,DOUT
DO WHILE(1)
Pin(PA5)=1
FOR A%=0 TO 5
NEXT
Pin(PA5)=0
FOR B%=0 TO 5
NEXT
LOOP

Micropython Code

import machine
import sys
x=int(0)
y=int(0)
led = machine.Pin('LED_GREEN',machine.Pin.OUT)
led.value(1)
while True:
led.value(1)
for x in range(5):
pass

led.value(0)
for y in range(5):
pass



MicroPython
PA5 high time = 93 microSecs PA5 low time 93 microSecs

Armmite
PA5 high time = 207 microSecs PA5 low time 244 microSecs


Conclusion

I suspect that Micropython behaves somewhat differently to Armmite, as there may be a partial, or even full compilation to bytecode, when programs are downloaded over the USB / REPL (ie serial) link to the board. This MAY explain some of the speed improvements. I would be very interested to hear thoughts, views, etc.

On a more general note, although Micropython is eminently usable, the overall user experience does seem a little 'rough and ready' at times. For instance, uPyCraft seems to be the 'go to' simple IDE for Micropython, at the moment. Although, uPyCraft works, it seems pretty basic and unpolished when compared to MMEdit. I suspect that Python (as opposed to MicroPython) has far better tools.

I am a bit of a fan of Eclipse and at some point, I will load up the PyDev Eclipse plugin and see if I can get a better MicroPython dev environment.

One final thought - IMHO the use of white space instead of code block start and end chars is a gimmick, which is already coming back to bite bottoms. The moment that code has to be uploaded across a serial connection, as in the case of Micropython, which is inevitably developed on a serially connected host, the problems start. This may be why there appear to be so few good IDEs for Micropython (as opposed to Python). My suspicion is that the original authors wanted something to make Python stick out from the crowd (especially, javascript), so the tabs/whitespace thing was invented. Now everyone seems to think that it is a wonderful way to enforce proper structure in programs.

Interestingly, just placing the Micropython code into this post royally b*****s the code indentation / whitespace - meaning that the code posted here won't actually work!

I wonder what size of trousers the emperor is wearing, today?

Sawasdee





 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10572
Posted: 12:48pm 15 Apr 2019
Copy link to clipboard 
Print this post

Interesting. Did you set CPU 80 on the Armmite? I assume Micropython is running the uP at full speed?

Did you have to build Micropython? I keep meaning to have a play but can't be bothered setting up a build environment - just need a .bin file to load.
The whole support environment for Micropython seems a bit opaque but this may be just me being lazy.
 
JohnL
Senior Member

Joined: 10/01/2014
Location: Seychelles
Posts: 128
Posted: 01:40pm 15 Apr 2019
Copy link to clipboard 
Print this post


Link to more popular binaries.

STM upload is in DFU serial bootloader mode.

http://micropython.org/download

http://micropython.org/

 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9755
Posted: 11:23pm 15 Apr 2019
Copy link to clipboard 
Print this post

If MicroPython compiles down to C, then it will run much faster then MMBASIC, which will always have the interpreter overhead to slow things down.

However, MMBASIC on the Arm processor is so fast as to not be a problem for all but the fastest of requirements.
Smoke makes things work. When the smoke gets out, it stops!
 
sawasdee01
Newbie

Joined: 23/12/2016
Location: United Kingdom
Posts: 33
Posted: 12:57am 16 Apr 2019
Copy link to clipboard 
Print this post

Hi All,

Ref "Interesting. Did you set CPU 80 on the Armmite?" in Matherp's post.

Excellent point and many thanks. I have repeated the tests with CPU 80 placed at the front of each Armmite test fragment and the new results are below:-

(Note:- please see test code used in the first post of this topic)


Results with CPU 80 added to Armmite


Test Number 1 - Simple Toggle Port Pins

MicroPython
PA5 high time = 17 microSecs PA5 low time 17 microSecs

Armmite
PA5 high time = 40 microSecs PA5 low time 65 microSecs



Test Number 2 - Toggle Port Pins with Integer Add

MicroPython
PA5 high time = 29 microSecs PA5 low time 29 microSecs

Armmite
PA5 high time = 90 microSecs PA5 low time 114 microSecs



Test Number 3 - Toggle Port Pins with Integer Divide

MicroPython
PA5 high time = 32 microSecs PA5 low time 32 microSecs

Armmite
PA5 high time = 108 microSecs PA5 low time 133 microSecs



Test Number 4 - Toggle Port Pins with empty FOR NEXT loop

MicroPython
PA5 high time = 93 microSecs PA5 low time 93 microSecs

Armmite
PA5 high time = 142 microSecs PA5 low time 165 microSecs


Conclusion

Setting the the Armmite CPU to 80 Mhz definitely helps to close the gap, but Micropython is still faster.

I had a quick look at the Nucleo 476RG board specific C source code on the micropython.org github. Unfortunately, whilst I found many #defines for setting the HSE and HSI, I could not see which of these #defines were actually being used in the Nucleo L476RG implementation. The comments seem to suggest that this is all done in a file called something like RCC HAL. I could not find anything that looked like RCC HAL. At some point, I will load the project up into Eclipse/Atollic and do a 'search project' to find out where these #defines are being used.

However, sense would suggest that Micropython runs at full clock speed on this Micropython implementation - so, my guess is that the performance comparison is now fair.

BTW Apparently. I can use the Micropython machine.freq() call to find out the configured CPU frequency and I will do this when I next load up the uPython image.


Ref "The whole support environment for Micropython seems a bit opaque" in Matherp's post.

From my early experiences, I think that this is a fair comment. I quite like the language itself - there is a lot of functionality and the functionality is presented in a fairly understandable and clear implementation.

At first, the Micropython.org website documentation looks promising, but you soon realise that it assumes that you already have a very strong foundation knowledge of Python. Eg, the second topic in the section called 'The Micropython Language' is 'Writing Interrupt Handlers' ..... gulp!

Additionally, while there are a number of core micropython libraries provided for (eg) Spi, I2C, etc. The moment that you want to connect to (for example) a TFT display, you are most likely into googling for and then downloading a TFT hardware specific driver that some bloke called Fred wrote for the ESP8266 in 2016, in the vague hope that it might port onto your hardware and (presumably) talk nicely to the Micropython spi and framebuffer libraries.

So, at the moment, I think that MMBasic / Armmite etc is leagues ahead in the 'ease of use / everything in one place / good documentation' game.

A company called Pycom.io has recognised this and seems to be heading in a good direction - but unfortunately, their platform locks you into their ESP32 based hardware, which is not much good if you want to use the STM32L476/496.

Personally, a big win for Micropython seems to be the ability to relatively easily (yeah, right!) extend Micropython using C. Like many languages, this requires a complete re-compilation of the source.

At some point in the near future, I will try to load up the Nucleo 476RG Micropython source into my Atollic STM32 C compiler and see if I can re-compile it. In theory, this should work, as Atollic is based on GCC. If not, I will have to load up Linux to get the recommended GCC cross development environment.

Best wishes.

Sawasdee



 
sawasdee01
Newbie

Joined: 23/12/2016
Location: United Kingdom
Posts: 33
Posted: 01:16am 16 Apr 2019
Copy link to clipboard 
Print this post

Hi Grogster,

I am fairly sure that Micropython does not compile to either C or machine code, as it is billed as an interpreted / script like language.

There are obviously big differences between Python and Micropython, as Micropython implies a cross-development platform (ie non-native). However, from the fairly limited information that I have been able to find, it would seem that Micropython is compiled to a bytecode representation (maybe, when passed over the REPL?), which is then executed by some form of Micropython VM, running on the target.

This may explain why I can't seem to find anything that looks like the Basic LIST command, on the target.

At a very raw guess, the results for a fully compiled (to machine code) version of Test 1 (Simple Toggle Ports) would be PA5 high time < 1 microSecs PA5 low time < 1 microSecs

This would seem to support the notion that Micropython is having to execute a bytecode -> VM architecture.

Best wishes and many thanks.

Sawasdee
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025