Dynamically assign pin numbers for

Questions and discussion about running MicroPython on a micro:bit board.
Target audience: MicroPython users with a micro:bit.
Siriushardware
Posts: 20
Joined: Wed Nov 01, 2017 8:00 pm

Dynamically assign pin numbers for

Post by Siriushardware » Wed Nov 01, 2017 8:49 pm

Hi Folkss, new to the forum and straight in with a question or two: Apologies if this has been covered somewhere in previous threads, but if so I obviously didn't use the right search terms.

Consider the code below, an example from a Micro:Bit website: (Ignore the fact that the indentation is incorrect).

while True:
if pin0.read_digital():
display.show(Image.HAPPY)
else:
display.show(Image.SAD)

I have an application in which the number of the pin being read from needs to be variable, rather than absolute. In other words, I need to be able to replace the syntax of the above code with something like:

PinNumber=1

while True:
if pin(PinNumber).read_digital():
display.show(Image.HAPPY)
else:
display.show(Image.SAD)

Is it possible to input from a digital pin / output to a digital pin using a variable to supply the pin number, rather than stating the pin number absolutely? If so, what is the Micro:Bit Micropython syntax for such an action?

The background to this is that I'm looking to use a Micro:Bit as a tester for a number of different sized row/column matrix keypads, ranging in size from (3 columns by 3 rows) up to (4 columns by 5 rows).

The integral 5*5 LED display array is what makes the Micro:Bit ideal for this purpose. When a keypad of a given size (let's say 4 by 4) is selected, the Micro:Bit will represent the overall layout of the keypad by dimly illuminating a 4 * 4 grid of LEDs. When a key (say the top-left key) on the keypad is pressed down, the top-left LED on the dim 4 * 4 grid will illuminate to full brightness.

The software will do this (show pressed keys by illuminating the corresponding LEDs to full brightness) even when there are two or more keys pressed at the same time.

The various different keypads bring their row / column lines to different pins on their single-inline connectors. On one keypad, pin 1 of the edge connector may be key row 1, but on another keypad, key row 1 may be on pin four of the connector. I therefore need to be able to dynamically redefine which of the physical inputs on the Micro:Bit are used to read Key row 1, Key row 2, Key row 4, key row 5, key column 1, key column 2.... and so on.

The idea is to use just one physical single inline connector into which all keypads to be tested will be plugged. The Micro:Bit will reassign the pins used for keypad column drive / keypad row sensing according to the type of keypad selected for testing. On certain keypads the row or column connections on the keypad connector are not even in the logical ascending order that you might expect, so I need to be able to reassign any Micro:Bit input or output to be any keypad row or column line, possibly by using a look up table of rows and columns to Micro:Bit pin assignments for each type of Keypad supported.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Dynamically assign pin numbers for

Post by deshipu » Thu Nov 02, 2017 12:42 am

There are many options, but the simplest (I think) is to just put the pins in a list:

Code: Select all

pins = [microbit.pin0, microbit.pin1, microbit.pin2]
and then just use an index in that list:

Code: Select all

if pins[0].read_digital():
    ...

Siriushardware
Posts: 20
Joined: Wed Nov 01, 2017 8:00 pm

Re: Dynamically assign pin numbers for

Post by Siriushardware » Thu Nov 02, 2017 8:33 pm

I certainly would not have guessed that solution for myself, so thanks for that.

What I've got working at the moment is much cruder, with a block of code to check each row/column intersection individually.

Not pretty.

One other problem I had was that I chose, arbitrarily, to have my column drive lines normally high, lowering each one in turn and reading the state of the row lines. I did it this way because I would expect that digital inputs which are not pulled up or down would normally float high and although the intention was to put pullup resistors on the row lines eventually, I hoped I could get away without them for initial testing.

In the event, it turned out that the pins I'm using to read the row inputs behave as though they are pulled down by default and because of this, require a surprisingly low value for the pullup resistors, since those pullups are apparently having to overcome the effect of the invisible (presumably internal) pulldown resistors.

Now that I've realised this I have removed my external pullup resistors and inverted the logic of the key scanning operation, so that the column drive lines are now normally low and go high when a particular column is to be scanned. The row reading lines now return a high, rather than a low, if there is a keyswitch making a connection between the activated column drive line and the row line being read.

If it's really the case that pins used for read_digital have internal pulldowns enabled by default, what was the rationale behind that? I would normally expect the use of pullups to be a conscious choice like it is on, ie, Arduino.

Whether it is the default or not, is it then possible to define input pullups as 'none' / 'pulled up' / 'pulled down' either globally or on a by-pin basis when using the Mu IDE? (which is what I'm using).

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Dynamically assign pin numbers for

Post by deshipu » Thu Nov 02, 2017 9:57 pm

Please read the last two paragraphs at http://microbit-micropython.readthedocs ... t/pin.html

Siriushardware
Posts: 20
Joined: Wed Nov 01, 2017 8:00 pm

Re: Dynamically assign pin numbers for

Post by Siriushardware » Thu Nov 02, 2017 10:56 pm

I did, but, after revealing the tantalising information that there is something called set_pull which can redefine the default pulldown behaviour of a digital input, the page then fails to give an example of how to use this feature.

Furthermore, a search of that website only comes up with one reference to set_pull, which is the one in the paragraph you pointed me to. It is literally an undocumented feature, at least as far as that website is concerned.

I'll try searching for it on other websites, now that you have brought it to my attention. Hopefully I will at least find some code which includes that expression, from which I'll be able to see the syntax for using that feature.

Edit: Just found this on another website where a user was also pointing out the lack of information about set_pull in the official documentation. One response was this information:
To change the value, use: pin.set_pull(pin.PULL_UP), or PULL_DOWN or NO_PULL.
I don't see anywhere in that expression to supply a pin number to which this action will be applied, so does that mean the setting is applied globally across all inputs being used as digital inputs?

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Dynamically assign pin numbers for

Post by dhylands » Thu Nov 02, 2017 11:17 pm

It would be applied to the pin object that you call set_pull on (i.e. replace 'pin' with the pin object you're trying to manipulate)

Siriushardware
Posts: 20
Joined: Wed Nov 01, 2017 8:00 pm

Re: Dynamically assign pin numbers for

Post by Siriushardware » Thu Nov 02, 2017 11:32 pm

Thanks for that clarification, although I'm still not sure in which part of the expression I should replace 'pin' with a real Micro:Bit pin name such as 'pin0'.

You mean like this?

pin0.set_pull(pin0.PULL_UP)

or this:

pin0.set_pull(pin.PULL_UP)

or this:

pin.set_pull(pin0.PULL_UP)

Unfortunately I forgot to bring my Micro:Bit home with me, otherwise I would just be able to try it various ways until it worked. But it would be more generally useful, in any case, if we could have a specific example here for others with the same question to find in the future. The set_pull feature really isn't well documented anywhere else.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Dynamically assign pin numbers for

Post by dhylands » Fri Nov 03, 2017 12:08 am

I've not written any code for the microbit, so I wasn't 100% sure myself. I found an example here:
https://github.com/DFRobot/microbit-mic ... ins.py#L65

So it looks like you can do

Code: Select all

from microbit import *

pin0.set_pull(pin0.PULL_UP)

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Dynamically assign pin numbers for

Post by deshipu » Fri Nov 03, 2017 11:18 am

Siriushardware wrote:
Thu Nov 02, 2017 10:56 pm
I did, but, after revealing the tantalising information that there is something called set_pull which can redefine the default pulldown behaviour of a digital input, the page then fails to give an example of how to use this feature.
Yes, the documentation is, as well as the code, written by volunteers in their free time, and thus not necessarily complete. If you have the time and the will, you can help improving it: in the upper-right corner of the page there is a "edit on github" link, which will let you make a pull request proposing a change to the documentation. You can add the description of this function and an example, and the people working on that project will review your proposed change, help you get it right, and eventually incorporate it into the documentation.

Siriushardware
Posts: 20
Joined: Wed Nov 01, 2017 8:00 pm

Re: Dynamically assign pin numbers for

Post by Siriushardware » Fri Nov 03, 2017 6:18 pm

I'd be happy to edit the documentation, but of course I need to have my facts straight in order to do so, and I am in the curious situation where not even the official documentation tells me what I need to know, so I can't edit the official documentation to say what it should say.

It may be that I can guess my way into the correct syntax for set_pull and if I manage that, may consider myself sufficiently well informed to amend the official documentation.

But really - and I can appreciate that this is all done by volunteers and when time allows - amendments like this really should be done by the people who implemented the feature, as only they can definitively explain how it works.

dhylands, thanks for the suggestion on the syntax - I will try mixing it up with that syntax and see if I can get it working. I remembered to recover the MB today so I'll try to have a bash at it over the weekend.

In theory, I should be able to make an INPUT generate a slow square wave output by going around in a loop periodically switching it from pulldown to pullup mode and back with a suitable pause in between each change.

Post Reply