Search code examples
javascriptmicropythonbbc-microbit

write_analog in microPython on BBC micro:bit does not do anything


I have a simple one line of micro:bit javascript that works, but the same line in microPython does not.

I have a potentiometer wired to the micro:bit and the readings from the potentiometer are sent to a pin attached to an LED in order to control the brightness of the LED. The javascript code

        pins.analogWritePin(AnalogPin.P1, pins.analogReadPin(AnalogPin.P0))

which is the result of the block code works fine and the brightness of the LED changes as the potentiometer is changed.

But using a similar line of microPython

    pin1.write_analog(pin0.read_analog())

does not change the intensity of the LED.

Any ideas of what is going on here?


Solution

  • Your line of micropython code is fine, in isolation. In isolation, it works for me to do one read and one write, and as a result proportionally dims an LED connected to pin 1 and ground, once. But there is context to consider.

    Are you executing the line repeatedly in a tight loop with no sleep (and no other time-consuming operations)? Like this?

    #This will not work
    from microbit import *
    while True:
        pin1.write_analog(pin2.read_analog())
    

    When I test the above, the LED fails to dim. This is resolved simply by adding a sleep of say 50-100 milliseconds to the loop.

    #This will work
    from microbit import *
    while True:
        pin1.write_analog(pin2.read_analog()) 
        sleep(50)
    

    Note that this is the same as the solution above from user analog.

    pin1.write_analog(v) doesn't actually set an analog voltage on the pin, it simulates it by using a PWM waveform which is high for a percentage of its cycle, proportional to your desired 'analog' voltage, and low for the rest of the cycle.

    I suspect that you're not allowing time for this waveform to complete a cycle before you call write_analog() on it again, and so you're never seeing a whole waveform. It is possible that the PWM waveform starts over with high again every time write_analog() is called - I do not know. If it is so, it would mean you're seeing a waveform which is constantly being set high, so just 3.3v constant. Not what you want.

    Leaving a sleep between calls to the same analog_write() would get you the dimming you expect. (Alternatively, find another way to avoid calling analog_write() so frequently.)

    Perhaps your javascript version doesn't have this problem because it executes slow enough to let the PWM waveform repeat before you change it again.

    Note that you could speed up the PWM waveform by giving it a period of 1ms: pin1.set_analog_period(1). In my testing, this improves things somewhat but is not nearly as good a solution as simply leaving more time between calls to write_analog. You'd still need to leave at least 1ms between calls.

    Here's documentation on the micro:bit IO pins and PWM http://microbit-micropython.readthedocs.io/en/latest/pin.html