bbcmicrobit / micropython

Port of MicroPython for the BBC micro:bit
https://microbit-micropython.readthedocs.io
Other
602 stars 284 forks source link

Setting Pull-Down on io pins !? #288

Closed cefn closed 7 years ago

cefn commented 8 years ago

There seems to be a software capability to set pull-up, pull-down or pull-none on digital pins... http://lancaster-university.github.io/microbit-docs/ubit/io/#setpull ...as also explored in this thread... https://mail.python.org/pipermail/microbit/2016-May/001100.html

The micropython version I have access to through microbit.co.uk seems to default to pull-down whenever I make a digital_read() call which confused and confounded me for some time.

I was searching explicitly for some indication there was pull-down capability used, and the default choice doesn't seem to be documented anywhere. The absence of a pull-mode API signature anywhere in python made me assume no pull behaviour was employed, and made me check and re-check the board I soldered together as I couldn't fathom where the short was :)

Is default pull-down as expected? Is it in your control or set by the DAL? Certainly seems to violate the principle of least surprise for me, and apparently the authors of these platforms...

dpgeorge commented 8 years ago

AFAIK we are just following how the other editors work (TouchDevelop, etc). It's the DAL that provides this behaviour of default pull-down. I don't know why it defaults to pull down but that's the behaviour that people now expect (rightly or wrongly).

I think we should provide a function to change the pull mode. And I guess we need to document that it's pull down by default.

markshannon commented 8 years ago

@cefn What would you consider to be the "obvious" default for the pull resistor?

cefn commented 8 years ago

Sadly I agree with @dpgeorge that the micro:bit platform should be consistent across languages, so if all other languages have pull-down as default, then that forces your hand.

However, given a time machine back to the meeting where that was decided, I would say pull-none is the obvious engineering and educational STEM default, as chosen by both Arduino and Raspberry PI, with pull being a concept which is optionally introduced, not forced into the frame and having to work around. That's because...

finneyj commented 8 years ago

I'll try and dig out the original BBC rationale for this, but I think it went along the lines of:

Completely agree that this should be configurable, but we should have a consistent default across all languages or risk a lot of confusion. Change is possible, but costly and we'd need widespread consensus from all languages that this is indeed a good idea.

microbit-dal doesn't force a change in pull mode on every read operation - only if that read operation changes the mode of pin to a digital input. If this is happening, there's a bug that needs fixing. Please report if this is the case.

I think there's perhaps a distinction here between early years teaching and more experienced maker communities expecting different things... Extending but not breaking APIs to allow more obvious configuration is perhaps the best way forward.

sparkslabs commented 8 years ago

Hi Joe,

You won't find pull-down specified in the specifications/docs I wrote for the reference implementation /prototype hardware/software implementation that we tested in schools. The aim of the original DAL was to provide as "vanilla" device as possible - the key principle there was for the hardware and DAL to provide functionality (and services - like display) not policies (ie the core concept in nano- or pico-kernels).

Setting a pull down as a default which can't be changed by end users would've breached that principle. I'd be curious to know where it came from. (I can make some guesses but that wouldn't be useful :) )

(If you're hunting - this is to save you hunting in docs I wrote :-) )

Michael.

On 3 June 2016 at 09:34, Joe Finney notifications@github.com wrote:

I'll try and dig out the original BBC rationale for this, but I think it went along the lines of:

-

kids reading a digital input that was not connected to anything, and expecting a logic low, and the fact that PullNone is basically non-deterministic. You get unpredictable results. I guess explaining the concept of floating voltages to young kids being not much fun.

the default ability to create positive logic switches etc. with no external discrete components. One of the ideas behind micro:bit is to not need discretes, breadboard etc. unless kids get to the stage where they want to get into electronics. i.e. separate digital logic from digital electronics. teachers reported not liking having these sorts of bits around the classroom unless necessary, as they spend their whole time debugging loose wires etc. etc.

Completely agree that this should be configurable, but we should have a consistent default across all languages or risk a lot of confusion. Change is possible, but costly and we'd need widespread consensus from all languages that this is indeed a good idea.

microbit-dal doesn't force a change in pull mode on every read operation - only if that read operation changes the mode of pin to a digital input. If this is happening, there's a bug that needs fixing. Please report if this is the case.

I think there's perhaps a distinction here between early years teaching and more experienced maker communities expecting different things... Extending but not breaking APIs to allow more obvious configuration is perhaps the best way forward.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/bbcmicrobit/micropython/issues/288#issuecomment-223522217, or mute the thread https://github.com/notifications/unsubscribe/AAIDg1-AUy0UGU15aPmGr3Xq5onQXS9yks5qH-cIgaJpZM4Ip-q_ .

cefn commented 8 years ago

Can you indicate the correct sequence for an 'experienced maker' to be able to take control of this behaviour? From your description, I think it amounts to throwing away the first read operation, and following it up with a pull-mode invocation before future reads, is that right?

Strikes me as counter-intuitive and creates a cliff for 'learners' making it through to be 'experienced makers' I fear. My major worry associated with this is the need for a learner OR maker to deal with, investigate and discover design decisions made by the DAL engineering team as opposed to learning about electronics. This is especially given nothing has leaked out about this decision into the API or documentation. That's in some ways MUCH harder than dealing with or learning about the reality of physics, especially given that mainstream electronics materials on the internet will be contradicted by a circuit with a secret pull-down.

Strikes me the ability to create switches with no discrete components remains there whatever the default is in the language. It just means that classroom builds without discrete components would have an explicit pull, which is no bad thing. There is no digital reading without software invocations anyway, and the way a 'default' is implemented for learners is as much a question of designing the learning materials and examples as an API question.

A colleague suggested a mandatory pinMode call before making any kind of read rather than rolling implied, hidden mode-setting and rewiring into the first read call. However I don't know enough about the forms of failure reporting which are expected/allowed in the different languages. I suspect runtime failure is only considered an option in python (error-reporting to scroll), which limits the options for 'throwing' when a digital read is attempted which wasn't pre-configured.

Given no runtime throws are allowed, a pull argument as part of digital read (with a default?) might have made it through to the derived languages. This means that each invocation would be explicit about the pull logic and for those who were comfortable with the shortcut in lessons (@ShrimpingIt wouldn't) the pull could be wired in software. If learners encountering digital read were led to decide if something was pulled, then the documentation and tooltips associated with that decision would be a home for learning/deciding about pull, as well as voltage, resistance etc.

Personally I'm disappointed that the floating input wasn't understood by decision makers as a fundamental learning point. Where eliminating complexity eliminates learning I can't help wondering what the true objective is, but then the @ShrimpingIt pedagogical position on this is well-known and possibly controversial :) ... https://twitter.com/ShrimpingIt/status/729643692198342656

finneyj commented 8 years ago

Clearly something that can't be changed by end users is a very bad idea, and was never anyone's intention. Hence the setPull() API function... defining a default state for some hardware is quite different from removing functionality. I don't think anyone would agree to the latter.

@sparkslabs - don't worry, I'm quite sure you didn't specify anything like this. It never even crossed my mind to check!

Now, If you're suggesting that a getDigitalValue() operation should have an additional (that now pretty much has to be optional) argument that allows the pull mode to be defined at that point, then i completely agree with you. This is then both backward compatible and provides the expressiveness we need. This is exactly what I was suggesting with "extending but not breaking APIs", and I'd be more than happy to see this change implemented.

if you're looking for my opinion, I'd simply go with maintaining the current API, adding a getDigitalValue/1 that defines pullmode (but still defaults to PullDown for backward compatibility) and ensuring that setPull() settings are not overwritten by a subsequent getDigitalValue/0 call. The default modes should be well documented.

if we feel really strongly that PullNone is vital as the default (at a technical level, I have no strong feelings either way, provided that the power is given to the users to change the default), then we should start an inclusive, evidence based discussion with all the other languages to look at changing it.

Also remember that just because something is different, it doesn't necessarily make it wrong...

cefn commented 8 years ago

Looks like I'm not the only one... https://twitter.com/ryanteck/status/738482835070259200 ...but sounds like a practical short term intervention to stream the getDigitalValue call with the extra 'pull' arg and with defaults as you say until agreement can be struck downstream on preferred pull.

Fixes the problem for DAL in the short term, offers a workaround for other languages in the medium term, and pushes the pull-down debate into a less urgent and evidence-based question as you say.

johndela1 commented 8 years ago

I have a pull request that implements this at: https://github.com/bbcmicrobit/micropython/pull/304

markshannon commented 7 years ago

Fixed by #345

PSLLSP commented 6 years ago

It seems this issue was fixed in 2016 but I still cannot use set_pull(). It is 2018. I need to activate pull-up mode to read line sensors on pin 15 and 16.

https://www.kitronik.co.uk/5624-lf-line-following-add-on-for-move-mini.html

It looks like I cannot work with this module with Python. :-(

AttributeError: 'MicroBitDigitalPin' object has no attribute 'set_pull'
MicroPython v1.7-9-gbe020eb on 2016-04-18; micro:bit with nRF51822
>>> dir(pin15)
['write_digital', 'read_digital', 'write_analog', 'set_analog_period', 'set_analog_period_microseconds', 'get_analog_period_microseconds']
dpgeorge commented 6 years ago

@PSLLSP it looks like you might be using an old version of the firmware. If you do import os and then os.uname() what does it print? Maybe try the latest version.

PSLLSP commented 6 years ago
>>> import os
>>> os.uname()
(sysname='microbit', nodename='microbit', release='1.0', version='v1.7-9-gbe020eb on 2016-04-18', machine='micro:bit with nRF51822')

It is possible I use old version and the fix is in some new version for long time. The problem is that the new release is in GIT and was not released to "production".

I use MU for Linux, from here https://codewith.mu/

And I tried with online python from https://python.microbit.org/v/1

MrYsLab commented 6 years ago

@PSLLSP I think there may be a lack of bandwidth for the micro:bit team to keep all the tools in sync. For me, this caused a lot of confusion. In self-defense, I have moved over to using PyCharm for creating micro:bit applications and have added the latest version of the tools, such as uflash to make sure I am using the latest and greatest. I put together a tutorial on how to do this. It uses my pseudo-microbit to provide type hinting specifically for micro:bit MicroPython. I hope this helps.

dpgeorge commented 6 years ago

Mu should have the latest version built in. Did you get the latest Mu?

@carlosperate what is the link for the latest .hex firmware version on python.microbit.org?

MrYsLab commented 6 years ago

Downloading mu from https://github.com/mu-editor/mu/releases/download/v0.9.13/mu-0.9.13.linux.bin, MicroPython v1.7-9 is loaded. If I install from pypi, then v1.9.2 is installed.

carlosperate commented 6 years ago

Right now the Python online editor entry point (http://python.microbit.org/) redirects to http://python.microbit.org/v/1 . This is the current version 1.0 of the online editor, which contains what we are calling micro:bit MicroPython v0.9. The specific hex file is this one: https://github.com/bbcmicrobit/PythonEditor/blob/master/firmware.hex And that version of the hex has been created at this MicroPython commit: https://github.com/bbcmicrobit/micropython/commit/effc07c2571bf8c388bf25ee1392cc8a1f535aac

This version predates the addition of the PULL feature.


The beta version of the online editor is hosted at http://python.microbit.org/v/beta This version of the online editor is updated informally for testing purposes. This one rolls the latest MicroPython master, a beta version of microbit Micropython v1.0, at the moment that would be: e10a5ffdbaf1cc40a82a665d79343c7b6b78d13b (4th May 2018)

This hex file can be found in: https://github.com/microbit-carlos/PythonEditor/blob/cb5d0fe229cf25f46da93a80994b37e28915f41b/firmware.hex

The history of how/when/what was updated in this version of the online editor can be seen in https://github.com/bbcmicrobit/PythonEditor/pull/57.

This version does contain the PULL feature.


Mu version 0.9.13, which is the version available from http://codewith.mu, is built from commit: https://github.com/mu-editor/mu/commit/c2a0f23e1bd1c5245f877d9c6274dc87bda50b8f

This version of Mu includes version 1.0.5 of uFlash: https://github.com/mu-editor/mu/blob/c2a0f23e1bd1c5245f877d9c6274dc87bda50b8f/mu/contrib/uflash.py

This version of uFlash is from commit: https://github.com/ntoll/uflash/commit/fe26fe8ea0b7943674cb8165e6939cba3ef0dc88

Not sure which MicroPython commit was used to build this version of uFlash. Based on the date of the 23rd of October 2016. So it's probably slightly ahead of the MicroPython v0.9 in http://python.microbit.org/v/1 , but just for a few days.

This version predates the addition of the PULL feature as well.


The latest version of Mu are the beta releases, currently at beta 15, these contain relatively new versions of microbit MicroPython.

The latest master branch contains a new version of MicroPython than beta 15, which can be installed via pip, but there isn't a specific installer to download (there are a few, but all for testing purposes).

Beta 15 contains uFlash version 1.0.8 https://github.com/mu-editor/mu/blob/2a33437666483ec6e24f2bf588a13608c07db082/mu/contrib/uflash.py I'm not quite sure which commit of MicroPython this includes (although it should be relatively easy to find out by seeing the output of os.uname()), but this would be a version around October 2017.

The beta 15 and newer version of Mu will contain this feature as well.

dpgeorge commented 6 years ago

Thanks for the details @carlosperate . Maybe it's worth putting some of this info in the root README.md of this repo to point users in the right direction if they want the latest version?