class Pin – control I/O pins - Documentation

Questions and discussion about The WiPy 1.0 board and CC3200 boards.
Target audience: Users with a WiPy 1.0 or CC3200 board.
Post Reply
Oli_
Posts: 15
Joined: Sun Nov 15, 2015 1:36 am

class Pin – control I/O pins - Documentation

Post by Oli_ » Sun Nov 22, 2015 3:46 pm

Hello Daniel,

The usage models described in the 'class Pin – control I/O pins' documentation are not correct.

Here are two example to include in the documentation and usable with the expansion board.

The first one may be :

Code: Select all

from machine import Pin
led_exp = Pin('GP16', mode=Pin.OUT, pull=None, drive=Pin.MED_POWER, alt=-1)
The second one may be :

Code: Select all

from machine import Pin

def pincb(pin):
    print(pin.id())
    led_exp.toggle()

led_exp = Pin('GP16', mode=Pin.OUT)
pin_int = Pin('GP17', mode=Pin.IN, pull=Pin.PULL_UP)

pin_int_irq = pin_int.irq(trigger=Pin.IRQ_FALLING, handler=pincb)

# the callback can be triggered manually
pin_int_irq()
# to disable the callback
pin_int_irq.disable()
# to enable the callback
pin_int_irq.enable()

User avatar
danicampora
Posts: 342
Joined: Tue Sep 30, 2014 7:20 am
Contact:

Re: class Pin – control I/O pins - Documentation

Post by danicampora » Fri Nov 27, 2015 9:31 am

Hi Oli_,

Thanks! I'll correct as per your suggestions :-)

Cheers,
Daniel

undeadpony
Posts: 3
Joined: Wed Dec 02, 2015 5:24 pm

Re: class Pin – control I/O pins - Documentation

Post by undeadpony » Wed Dec 02, 2015 7:45 pm

Intro:
First, I want to give just a bit of my background for anyone who's willing to help so they have some idea of what my skill level is. The last 10 years I've been building and managing server infrastructure using Linux to run the Asterisk VOIP platform so I tend to spend 12+ hours a day working in a shell. My electronics background is far less than my tech skills though, and I consider myself quite a newb (but I've been told I tend to underrate my skills). I have been working like crazy for the past 6 months to learn Python so my goal is to use it as much as possible. My first attempt at using python with electronics came from backing the Viper IDE on Kickstarter and multiple months ago tried using it but ended up giving up due to frustration (either my Python skill was too low still or the docs were too lacking). I've recently managed to control a couple different types of stepper motors with both an Arduino Uno and an RFduino where each press of a button will move the motor a specific number of steps. I've done it with and without 3rd party libraries depending on which motor controller I was using. I've settled on using a Pololu A4988 driver as it seems like the easiest to program for, and I have plenty of them around because of owning a RepRap. My current goal is to add the ability to move the motor a number of steps every X minutes and want to switch to using my newly received WiPys from Kickstater instead of the *duinos. So far I have been able to get them upgrade to the latest firmware, enabled serial over USB on UART0 and can connect them to my home wifi. I even managed to follow the example and toggle the heartbeat led, but now I want to do more, and I just haven't been successful at finding enough examples and documentation that uses Python (especially compared to the Arduino environment) and I keep getting stuck on the most basic things.

;tldr -- I'm not a total tech retard but am pretty new when it comes to electronics and python and need help with understanding some basics.

The actual questions:
Can someone help explain how to configure a pin properly and/or provide a bit more detailed/commented example? Maybe I've missed something in the docs, or it could be due to my newbie brain not having enough basic microcontroller knowledge to understand this stuff. I'm just not sure what functionality is being shown it the examples in this thread and I haven't found an example or enough of a description to figure out what the alt parameter is for. I got particularly confused from the example that sets alt = -1. I thought alt was related to the pinout alternate functions table and it's used to designate which of those functions (listed in columns labeled A-F) the pin should perform. I expected it to mean, if I want to use GP24 with PWM (to light up an LED or power a TMP36) I should set alt=5? To use GP14 with TIM_CC6 (some sort of timer function I think) then alt=12? To use a pin as just a plain GPIO I read alt=0, is that correct?

I'm also confused about the purpose of PWM as well. My understanding is that I can use GPIO pins set to either HIGH or LOW which I thought meant a small amount of power is supplied to whatever is connected when the pin is toggled HIGH so what is the difference when using PWM? Is it just the amount of power available that is different?

One last question, in the docs I didn't notice that there were any default settings for 'mode', 'pull', 'drive', or 'alt'. If I do this:

Code: Select all

from machine import Pin
myPin = machine.Pin('GP11')
how will the pin behave?

Thanks to anyone willing to help me understand these things. I can't imagine I'm the only one confused over this stuff and if I can figure out how to get my motors to work with the WiPy I will be more that happy to provide my code as an example or write a tutorial for wiki or docs.

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

Re: class Pin – control I/O pins - Documentation

Post by dhylands » Thu Dec 03, 2015 2:23 am

undeadpony wrote:The actual questions:
Can someone help explain how to configure a pin properly and/or provide a bit more detailed/commented example? Maybe I've missed something in the docs, or it could be due to my newbie brain not having enough basic microcontroller knowledge to understand this stuff. I'm just not sure what functionality is being shown it the examples in this thread and I haven't found an example or enough of a description to figure out what the alt parameter is for. I got particularly confused from the example that sets alt = -1. I thought alt was related to the pinout alternate functions table and it's used to designate which of those functions (listed in columns labeled A-F) the pin should perform. I expected it to mean, if I want to use GP24 with PWM (to light up an LED or power a TMP36) I should set alt=5? To use GP14 with TIM_CC6 (some sort of timer function I think) then alt=12? To use a pin as just a plain GPIO I read alt=0, is that correct?
Each pin can serve multiple functions. GPIO is one mode, and one of many alternate functions is a separate mode.
To configure pin X1 as GPIO, you would use:

Code: Select all

>>> pin = pyb.Pin('X1', mode=pyb.Pin.OUT_PP)
If you look at the quick reference photo for the pyboard: http://micropython.org/resources/pybv10-pinout.jpg we can see that pin X1 can also be used for UART4, Timer 5, or Timer 2. If you call af_list() on the pin you'll see:

Code: Select all

>>> pin.af_list()
[Pin.AF1_TIM2, Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM8, Pin.AF7_USART2, Pin.AF8_UART4]
I'm not sure why AF1_TIM2 shows up twice, but I'll look into it. Also, it looks like Timer8 can be used and the quick reference doesn't mention that, so I'll check that out as well. If I then configure uart4, it will reconfigure pin X1 as a uart pin, and if I print the pin, we'll see that it's now configured using mode=AF_PP and af=Pin.AF8_UART4

Code: Select all

>>> uart = pyb.UART(4, 9600)
>>> pin
Pin(Pin.cpu.A0, mode=Pin.AF_PP, pull=Pin.PULL_UP, af=Pin.AF8_UART4)
Normally you don't need to mess with the alternate functions, but sometimes you do for specialty purposes. The af= parameter is ignored except when mode is AF_PP or AF_OD.
undeadpony wrote:I'm also confused about the purpose of PWM as well. My understanding is that I can use GPIO pins set to either HIGH or LOW which I thought meant a small amount of power is supplied to whatever is connected when the pin is toggled HIGH so what is the difference when using PWM? Is it just the amount of power available that is different?
PWM stands for Pulse Width Modulation, which allows the width of a pulse to be controlled. If you were to run this python code:

Code: Select all

import pyb

# At 20 kHz, the duty cycle should 50 usec
t2 = pyb.Timer(2, freq=20000, mode=pyb.Timer.PWM)
ch1 = t2.channel(1, pyb.Timer.PWM, pin=pyb.Pin.board.X1, pulse_width_percent=5)
ch2 = t2.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width_percent=35)
ch3 = t2.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width_percent=50)
ch4 = t2.channel(4, pyb.Timer.PWM, pin=pyb.Pin.board.X4, pulse_width_percent=95)
and do a logic analyzer capture you would see something like this:ImageThe frequency of 20kHz means that the duty cycle will be 50 usec. At 5% PWM, the signal will be high for 5% of the 50 usec (2.5usec) and low for 95% (47.5 usec).
X2 shows a PWM signal with a pulse width of 35%. X3 shows 50% and X4 shows 95%. A PWM of 0% is equivalent to setting the pin low, and a PWM of 100% is equivalent to setting the pin high.
Normally, you would use PWM to control the speed of a motor, or the brightness of an LED. The nice thing about having the hardware generate the PWM, is that once you set it, it just keeps repeating the pulse over and over (you can see 2 full cycles plus the start of a 3rd int he photo).
undeadpony wrote:One last question, in the docs I didn't notice that there were any default settings for 'mode', 'pull', 'drive', or 'alt'. If I do this:

Code: Select all

from machine import Pin
myPin = machine.Pin('GP11')
how will the pin behave?
That will return an uninitialized pin object. Looking at the documentation for pin.init: http://docs.micropython.org/en/latest/l ... l#pin.init we can see that there is no default for mode, pull defaults to Pin.PULL_NONE, and af defaults to -1. Looking at the WiPy documentation: http://micropython.org/resources/docs/e ... l#pin.init the defaults seem to be missing. Looking at the code https://github.com/micropython/micropyt ... pin.c#L534, it appears that the defaults are as follows: mode=Pin.IN, pull=None, drive=Pin.MED_POWER (4mA), alt=-1

The Pololu A4988 stepper driver has 2 inputs, a step signal, and dir signal. If you were to connect STEP up to GP11 and DIR to GP12, then you could drive it using something like:

Code: Select all

from machine import Pin
import time
step = Pin('GP11', mode=Pin.OUT)
dir = Pin('GP12', mode=Pin.OUT)
dir.value(0)
for i in range(1000):
    step.value(0)
    time.sleep_us(1000)
    step.value(1)
    time.sleep_us(1000)
that should make the stepper rotate 5 times (assuming its configured for full step mode) in about 2 seconds. If you had 1/16 microsteps then you'd need to change the range(1000) to 16000 and change the delay to time.sleep_us(63) and you should get the same 5 revolutions in approx 2 seconds.

undeadpony
Posts: 3
Joined: Wed Dec 02, 2015 5:24 pm

Re: class Pin – control I/O pins - Documentation

Post by undeadpony » Fri Dec 04, 2015 7:21 am

I think I might have discovered some of the reason I keep getting so confused. Granted, my issue with what PWM does was a pretty major brain fart, but one of my questions (asking what alt = -1 meant) I think stems from either inconsistencies in the documentation or in the source code itself. I've been reading through dhylands' nice answer and comparing it to the docs and the source code trying to understand it all, but I'm still not sure what the correct way is to initialize pins. Maybe dhylands missed the part where I said I'm using a WiPy, but I don't think that is the case since this is posted in the WiPy forum. I do believe the issue is related to inconsistencies between how the WiPy and the Pyboard are handled though.

It looks like there are different names for things, in what should be similar methods and I'm not sure which I'm supposed to use. Please see the pin.init section in each of these links:
https://micropython.org/resources/docs/ ... e.Pin.html
and
http://docs.micropython.org/en/latest/l ... l#pin.init

It looks to me like Pyboard users do:

Code: Select all

import pyb
pin = pyb.Pin('X1', mode=pyb.Pin.OUT_PP)
but WiPy users have to do this (there is no OUT_PP either):

Code: Select all

from machine import Pin
pin = Pin('GP16', mode=Pin.OUT)
When working in the REPL for my WiPy I get an error if I try to import pyb. The Pyboard pin.init() uses af for alternate functions and the WiPy uses alt. As dhylands pointed out, the defaults weren't documented and provided a link to the source code. He said there wasn't a default for mode but I think it actually says it defaults to input (at line 541 there is a comment and it looks like it is set but I don't know C at all so I might be reading it wrong). I don't know if that is just for the Pyboard though because I wasn't able to figure out where the WiPy pin.init() source code was.

I've got to give up for the night. Hopefully this is readable enough as it has gotten too late for me and my brain is shutting down. I really want to learn how to use my WiPy and MicroPython so would like to clear up some of these things and maybe even help others figure them out too.

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

Re: class Pin – control I/O pins - Documentation

Post by dhylands » Fri Dec 04, 2015 7:35 am

undeadpony wrote:I think I might have discovered some of the reason I keep getting so confused. Granted, my issue with what PWM does was a pretty major brain fart, but one of my questions (asking what alt = -1 meant) I think stems from either inconsistencies in the documentation or in the source code itself. I've been reading through dhylands' nice answer and comparing it to the docs and the source code trying to understand it all, but I'm still not sure what the correct way is to initialize pins. Maybe dhylands missed the part where I said I'm using a WiPy, but I don't think that is the case since this is posted in the WiPy forum. I do believe the issue is related to inconsistencies between how the WiPy and the Pyboard are handled though.

It looks like there are different names for things, in what should be similar methods and I'm not sure which I'm supposed to use. Please see the pin.init section in each of these links:
https://micropython.org/resources/docs/ ... e.Pin.html
and
http://docs.micropython.org/en/latest/l ... l#pin.init
I read the forum through notifications, which takes me directly to the unread post, so I don't always see which sub-forum the message was posted in. I'm more familiar with the pyboard and not as much with the wipy. I realized about halfway through my post that you were talking about the wipy, but I didn't rewrite what I had written so far.

On the pyboard, the old way is to use pyb and the new way is to use machine. machine hasn't been fully implemented yet on the pyboard, so the pyb is still used to get full functionality. But machine.Pin is implemented for the pyboard. The wipy only implements machine (since pyb will be phased out eventually on the pyboard).

So that will be contributing to some of the confusion as well.
It looks to me like Pyboard users do:

Code: Select all

import pyb
pin = pyb.Pin('X1', mode=pyb.Pin.OUT_PP)
but WiPy users have to do this (there is no OUT_PP either):

Code: Select all

from machine import Pin
pin = Pin('GP16', mode=Pin.OUT)
When working in the REPL for my WiPy I get an error if I try to import pyb. The Pyboard pin.init() uses af for alternate functions and the WiPy uses alt. As dhylands pointed out, the defaults weren't documented and provided a link to the source code. He said there wasn't a default for mode but I think it actually says it defaults to input (at line 541 there is a comment and it looks like it is set but I don't know C at all so I might be reading it wrong). I don't know if that is just for the Pyboard though because I wasn't able to figure out where the WiPy pin.init() source code was.
The interesting bits for the wipy pin init is here: https://github.com/micropython/micropyt ... pin.c#L525 and you are correct, then the default mode is IN https://github.com/micropython/micropyt ... pin.c#L543

The example I gave for controlling a stepper should still work on the wipy. I think I might have one of those steppers around someplace. If I can find it, I'll wire it up and verify with a wipy.

Post Reply