Hello,
In order to make a teacher's presentation of micro:bit and to compare C language for arduino and micropython for micro:bit, I'd simply like to generate a square wave as Arduino can easily make it, and to supply a buzzer
[code]
void setup() {
pinMode(9, OUTPUT);
Serial.begin(9600); // Set serial out if we want debugging
}
void loop() {
digitalWrite(9,HIGH);
delayMicroseconds(1136);
digitalWrite(9, LOW);
delayMicroseconds(1136);
}
[/code]
I have tried with what I thought equivalent in micropython:
[code]
from microbit import *
import utime
while True:
pin0.write_digital(1)
utime.sleep_us(1136)
pin0.write_digital(0)
utime.sleep_us(1136)
[/code]
unfortunately, it seems that the functions write_digital and sleep_us are too slow to generate a clean signal and moreover buzzer's frequency is not accurate at all (15% less than expected).
Have you got any solution? I precise that the goal is to decompose the signal generation, not to use high level functions like music.pith or even set_analog_period_microseconds.
Thank you for your help.
square signal for buzzer
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: square signal for buzzer
Please note I have no experience of programming the micro:bit.
The 15% reduction corresponds to a function call overhead of 85μs. This is slow compared to the Pyboards but probably reflects the micro:bit hardware performance.
On Pyboards and many other MicroPython platforms it is possible to achieve high frequency accuracy in at least two ways: by using a callback from a hardware timer, or by using PWM. I don't know if the micro:bit supports these options.
The 15% reduction corresponds to a function call overhead of 85μs. This is slow compared to the Pyboards but probably reflects the micro:bit hardware performance.
On Pyboards and many other MicroPython platforms it is possible to achieve high frequency accuracy in at least two ways: by using a callback from a hardware timer, or by using PWM. I don't know if the micro:bit supports these options.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: square signal for buzzer
For Arduino, the code in the sketch is the only that's running.
Using Micropython, there are quite a few background tasks active, including the communication stack. This causes a "square" wave loop like yours not being regular and the average execution time per loop being extended. 85µs for a function call seems a little bit too long, compared to 2-4µs on Pyboard.
Peter mentioned the methods to ensure better timing precision. But you seem not like to use them for your educational purpose.
Using Micropython, there are quite a few background tasks active, including the communication stack. This causes a "square" wave loop like yours not being regular and the average execution time per loop being extended. 85µs for a function call seems a little bit too long, compared to 2-4µs on Pyboard.
Peter mentioned the methods to ensure better timing precision. But you seem not like to use them for your educational purpose.
Re: square signal for buzzer
Thanks for your replies. This issue seems to be a limit of micropython, nevertheless it is interesting for my presentation to illustrate with such an easy physical example the difference between the two kind of language.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: square signal for buzzer
Indeed. If I were presenting the topic I'd illustrate the C code, straight Python as per your sample, and timer-driven Python to illustrate a way to achieve high frequency precision.
In the latter solution any latency in issuing the callback is cancelled out because it is the same for each output transition. If latency is constant you should see an exact frequency with a 1:1 m/s ratio.
In the latter solution any latency in issuing the callback is cancelled out because it is the same for each output transition. If latency is constant you should see an exact frequency with a 1:1 m/s ratio.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
-
- Posts: 847
- Joined: Mon Nov 20, 2017 10:18 am
Re: square signal for buzzer
Create local instances of the 2 function u need to be called with low latency
e.g
e.g
local_pin_write = pin0.write_digital()
local_sleep = utime.sleep_us()
while True:
local_pin_write(1)
local_sleep(1136)
local_pin_write(0)
local_sleep(1136)
Re: square signal for buzzer
to pythoncoder,
unfortunately, micro:bit doesn't seem to have a timer such as pyboard, its machine module is not so complete:
https://microbit-micropython.readthedoc ... chine.html
so I can't make a timer object for callback
to Outofthebots,
defining functions as you suggest seems to improve a bit the frequency, but still far away from expected.
anyway, Thanks.
unfortunately, micro:bit doesn't seem to have a timer such as pyboard, its machine module is not so complete:
https://microbit-micropython.readthedoc ... chine.html
so I can't make a timer object for callback
to Outofthebots,
defining functions as you suggest seems to improve a bit the frequency, but still far away from expected.
anyway, Thanks.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: square signal for buzzer
@vchaps You're right: lacking a timer you could measure the latency and take it into account. Something along these lines:
Code: Select all
from utime import ticks_us, ticks_diff
toggle = lambda : pin0.write_digital(not pin0.read_digital())
t = ticks_us()
toggle()
latency = ticks_diff(ticks_us(), t)
delta = 1136 - latency
while True:
t = ticks_us()
while ticks_diff(ticks_us(), t) < delta:
pass
toggle()
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.