pheriperal indexing start from O || 1

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
torwag
Posts: 220
Joined: Fri Dec 13, 2013 9:25 am

pheriperal indexing start from O || 1

Post by torwag » Fri May 09, 2014 1:18 pm

Hi,

I played around a bit with the new micropython boards. Nice ... REALLY NICE! Congrats to everyone who was involved.
Just noticed a little glitch. Shouldn't we start to count peripherals starting from 0?
This is how python does indexing and I believe it would be more "in-line" doing the same for peripherals.
Thus, one can do:

Code: Select all

for i in range(4):
   pyb.LED(i).off()
or

Code: Select all

leds = [pyb.LED(i) for i in range(4)]
It starts to become more obvious if you start to mix python lists with peripherals addressing.

Code: Select all

feedback = ['blue','red','orange','green']
for i in range(4):
   print(text[i])
   pyb.LED(i+1).on()
I believe the i+1 thing will be a trap for a lot of people.
Sure you could get around this by using dictionaries or some other (smarter) way to deal with it. However, since micropython novice might be python beginners too, I wonder if we should try avoid this situation?
It is only a small difference and maybe you find it completely unimportant. We are just at the beginning and hence can still change this (not much live threaten code is written yet)
If there is an argument for doing it vice versa, I would love to hear that ;)

pfalcon
Posts: 1155
Joined: Fri Feb 28, 2014 2:05 pm

Re: pheriperal indexing start from O || 1

Post by pfalcon » Fri May 09, 2014 2:08 pm

I'm +1 on the general idea that if there's explicit numeric indexing, then it should start from 0.

But:
It is only a small difference and maybe you find it completely unimportant. We are just at the beginning and hence can still change this (not much live threaten code is written yet)
I don't think that's the case, and think it's too late. There was a lot of time to tackle such stuff - before boards started to ship. Now that's they are in the process of shipping, it's at all bad time to change stuff - it won't do if some people get board behaving in one way, while others - in another. Neither it's good if folks who have just started to master programming MicroPython board, reflashed it, and found that whatever code they had is now broken. Finally, think about Damien's position - he tries to document well what's there now, and requests coming to change it right away, should he maintain 2, 3, 10 documentation versions?

I personally gave up on "pyb" module some time ago, after trying to affect how its API is created. I just accepted that its purpose is to provide pragmatic, easy-to-use, simplified (and yet with bits of superfluous features) API to let people do cute and useful things with PyBoard ASAP - not to be formally perfect API one couldn't criticize. Thus, I think realistic way forward is to take a feature-by-feature from "pyb" module, elaborate it, and put in a separate set of modules (or well structure package), kinda "pyb2", but first change of course would be to come up with good generic name for it.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

bloater
Posts: 3
Joined: Thu May 01, 2014 10:48 pm
Location: Edinburgh, UK

Re: pheriperal indexing start from O || 1

Post by bloater » Fri May 09, 2014 3:47 pm

Hi :)

I too am having great fun with my new pyboard (and I'd like to echo torwarg's congratulations to all involved - you've really accomplished something great here) but I too find myself wishing for some API changes to pyb. (I'm another +1 for 0-based indexing.)

However, as pointed out by pfalcon, it's probably too late to influence pyb. Changing things now that pyboards are out in the wild and people are just starting to try to get to grips with programming them using pyb and the initial (quite comprehensive) documentation is likely to upset a lot of people.

Following on from your suggestion to create a 'pyb2' [insert better name here] - maybe we should collect a list of API changes and we could work on this collectively?

The changes I'd been thinking about were simple things making more use of properties (e.g. make things like pyb.LED.intensity and pyb.Switch.callback properties).

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

Re: pheriperal indexing start from O || 1

Post by dhylands » Fri May 09, 2014 3:52 pm

At the datasheet level, all of the peripherals are numbered starting from 1.

So you have I2C1, I2C2, SPI1, SPI2, UART1, UART2, TIM1, etc.

The Led isn't really a datasheet item, but if you're trying to rationalize stuff from the datasheet to python its easier if there isn't a +1/-1 to always deal with. So I think that starting from 1 is to remain consistent with the other peripherals.

pfalcon
Posts: 1155
Joined: Fri Feb 28, 2014 2:05 pm

Re: pheriperal indexing start from O || 1

Post by pfalcon » Fri May 09, 2014 6:29 pm

dhylands wrote:At the datasheet level, all of the peripherals are numbered starting from 1.

So you have I2C1, I2C2, SPI1, SPI2, UART1, UART2, TIM1, etc.
That's why I said "if there's explicit numeric indexing", i.e. if access is on the form peripheral[index] (or abstracted as a function peripheral_factory(index) ). If a peripheral is defined symbolically, then yeah, it makes sense to follow the datasheet, but the only outcome of that can be that on some vendor's platform a thing will be called "I2C1", and on another - "I2C0" (and on another "IICFIRST", etc, etc.)
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

torwag
Posts: 220
Joined: Fri Dec 13, 2013 9:25 am

Re: pheriperal indexing start from O || 1

Post by torwag » Sun May 11, 2014 8:48 am

Well, I can see both sides.
Form a programming point of view it would be better starting from 0. Albeit, I know very well that people with no programming background sometimes have problems to get the idea that something is counted starting from 0.

From the datasheet and accountant-way of counting people have to address an unit calling "foo1" by 0 which gives a little twist on the documentation. I think Damien had similar thoughts. It seems somewhere internally, we have already a subtraction by 1. There is an indexing error for -1 if you try to address a LED[0].

I don't think it is to late to change it. There is most likely not a single project out there which is much longer then 100 lines of code.
I would ship the boards as they are now but (if it is decided to do so) make an announcement for a later release that this behavior changes.
Those things happened in similar projects too (Arduino and Co.) and nobody should expect a API written in stone at this stage.

However, as I wrote above, we will hit one or the other problem. Telling people to address a deviceX by X-1 or telling them that a range needs to start by 1 and most likely the need to add +1 here and there in the code. Both ways will leave a group of people complaining in one or the other direction.
One idea would be to start counting from 0 in the same way python does but introduce a general unit initializer-function which will get a string with the same name as it is written on sillk / in the datasheet of a specific board.

Thus,

Code: Select all

a = peripheral("LED1") 
would be a great way for people following silkscreen or datasheets to get an object of a specific peripheral.
Those strings could be completely different among different boards but there would be a common way to access them among all boards.
I know this is most likely complete the opposite direction of pfalcons approach trying to keep stuff as modular as possible (sorry for that pfalcon ;) ).
I think at the end, we might need something rather modular, but having a thin wrapper around all this for beginners to make it easy accessible in an uniform way. Guess this all goes into the HAL direction.

For the time being, we might help our-self a little by wrapping some try and catch arguments around any peripheral indexing code and create suitable error-messages whenever someone tries to address a peripheral by out of its index boundary. Something like

Code: Select all

print("{0} need to be indexed between {1} and {2}".format(peripheral.name(), peripheral.index.min(), peripheral.index.max()))

Post Reply