Micropython pin

Micropython pin DEFAULT

6. GPIO Pins¶

The way to connect your board to the external world, and control other components, is through the GPIO pins. Not all pins are available to use, in most cases only pins 0, 2, 4, 5, 12, 13, 14, 15, and 16 can be used.

The pins are available in the machine module, so make sure you import that first. Then you can create a pin using:

>>> pin=machine.Pin(0)

Here, the “0” is the pin that you want to access. Usually you want to configure the pin to be input or output, and you do this when constructing it. To make an input pin use:

>>> pin=machine.Pin(0,machine.Pin.IN,machine.Pin.PULL_UP)

You can either use PULL_UP or None for the input pull-mode. If it’s not specified then it defaults to None, which is no pull resistor. GPIO16 has no pull-up mode. You can read the value on the pin using:

>>> pin.value()0

The pin on your board may return 0 or 1 here, depending on what it’s connected to. To make an output pin use:

>>> pin=machine.Pin(0,machine.Pin.OUT)

Then set its value using:

>>> pin.value(0)>>> pin.value(1)

Or:

>>> pin.off()>>> pin.on()

6.1. External interrupts¶

All pins except number 16 can be configured to trigger a hard interrupt if their input changes. You can set code (a callback function) to be executed on the trigger.

Let’s first define a callback function, which must take a single argument, being the pin that triggered the function. We will make the function just print the pin:

>>> defcallback(p):... print('pin change',p)

Next we will create two pins and configure them as inputs:

>>> frommachineimportPin>>> p0=Pin(0,Pin.IN)>>> p2=Pin(2,Pin.IN)

An finally we need to tell the pins when to trigger, and the function to call when they detect an event:

>>> p0.irq(trigger=Pin.IRQ_FALLING,handler=callback)>>> p2.irq(trigger=Pin.IRQ_RISING|Pin.IRQ_FALLING,handler=callback)

We set pin 0 to trigger only on a falling edge of the input (when it goes from high to low), and set pin 2 to trigger on both a rising and falling edge. After entering this code you can apply high and low voltages to pins 0 and 2 to see the interrupt being executed.

A hard interrupt will trigger as soon as the event occurs and will interrupt any running code, including Python code. As such your callback functions are limited in what they can do (they cannot allocate memory, for example) and should be as short and simple as possible.

Sours: https://docs.micropython.org/en/latest/esp8266/tutorial/pins.html

MicroPython Tutorial

This should work on either ESP8266 or ESP32 MicroPython, but the instructions are written for ESP8266. There are minor differences, eg: the numbers of pins and their capabilities.

The number of pins, and their capabilities, varies between ESP8266 and ESP32, and not all pins are available on all boards.

Digital Outputs

To control an output pin, you must first configure it. The library makes the pins available to your Python code, and let’s you specify how you want to use that pin. To configure a pin as a digital output::

Example: ESP-12

Note: On the LoLin32Lite, used in the LoliBot, there’s an equivalent blue LED on pin 22

On the ESP-12 module, GPIO2 is connected to an on-board LED, so you should be able to turn the LED on and off:

Note that it is connected backwards: to turn the LED on, set the pin value to False and to turn it off set the pin value to True.

Of course you can do this in a loop to get ‘blinky’, the microcontroller equivalent of :

PWM Outputs

You can also turn the LED “partly on” by turning it on and off rapidly. Doing this in Python would be flickery and a waste of power, but thankfully there’s hardware support for pulse-width modulation (PWM). This just means turning the pin on and off rapidly, and it lets you set the proportion of the time the LED is on, called the ‘duty cycle’:

Duty Cycle

To configure a pin as PWM, wrap the object in a object:

sets the frequency (in Hz) and sets the duty cycle between 0 (always off) and 1023 (always on). Beyond about 30Hz, the LED will no longer appear to be flashing, instead it will be changing in perceived brightness.

This lets you fade the LED in and out like so:

Yay, it’s ‘throbby’, the microcontroller equivalent of .

Digital Inputs

Note: There isn’t an equivalent button on the LoliBot, as the button on the LoLin32Lite resets the CPU! But this should work with the reflectance sensor on GPIO4

Most ESP8266 development boards have a button attached to GPIO0. This can be used to put the device into flash mode when it is reset, but once the device has started it can be used as a general purpose input::

Analog Inputs

Note: There’s isn’t really equivalent hardware on the LoliBot, sorry

There’s also an analog input pin, sadly only one on ESP8266::

On the ESP32 there are more ADC channels available. Currently, 8 channels are available on GPIO pins 32 through 39. The ADC can be programmed with variable attenuation and resolution, shared across all the channels.

NeoPixels

Note: On the LoliBot, there’s a string of three APA106 NeoPixels on GPIO2.

“NeoPixels” is a name given to a family of coloured LEDs with an onboard controller. There’s a tiny controller in each pixel, and you can daisy chain them together to control many pixels from a single output line. There are several different versions of these chips, including RGB and RGBW varieties. Some examples:

To control them from MicroPython, use the library:

NeoPixels can be purchased from Ebay (etc) preassembled into ribbons, rings, grids and other shapes. Controlling a handful of pixels may seem like a silly thing to do when you’re used to having millions of pixels at your disposal, but it can be a lot of fun.

I2C

Note: LoliBot features an MPU-9250 accelerometer / gyrometer on pins 18 (SDA)/19 (SCL). It should work with the code below.

I2C is a shared serial bus which allows your microcontroller to communicate with multiple peripheral devices using a single pin.

It is part of the library

The I2C library is still quite low level, and using it involves a lot of reading of datasheets. However, it is quite easy to wrap I2C functions into small library functions. For the BuzzConf Rocket Surgery project we wrapped this sensor up with a very small library

Sours: http://mpy-tut.zoic.org/tut/input-and-output.html
  1. Buy apc ups
  2. Yeti steer
  3. Deuteronomy 2 11
.. currentmodule:: machine

class Pin -- control I/O pins

A pin object is used to control I/O pins (also known as GPIO - general-purpose input/output). Pin objects are commonly associated with a physical pin that can drive an output voltage and read input voltages. The pin class has methods to set the mode of the pin (IN, OUT, etc) and methods to get and set the digital logic level. For analog control of a pin, see the :class:`ADC` class.

A pin object is constructed by using an identifier which unambiguously specifies a certain I/O pin. The allowed forms of the identifier and the physical pin that the identifier maps to are port-specific. Possibilities for the identifier are an integer, a string or a tuple with port and pin number.

Usage Model:

from machine import Pin # create an output pin on pin #0 p0 = Pin(0, Pin.OUT) # set the value low then high p0.value(0) p0.value(1) # create an input pin on pin #2, with a pull up resistor p2 = Pin(2, Pin.IN, Pin.PULL_UP) # read and print the pin value print(p2.value()) # reconfigure pin #0 in input mode with a pull down resistor p0.init(p0.IN, p0.PULL_DOWN) # configure an irq callback p0.irq(lambda p:print(p))

Constructors

Methods

.. method:: Pin.init(mode=-1, pull=-1, *, value, drive, alt) Re-initialise the pin using the given parameters. Only those arguments that are specified will be set. The rest of the pin peripheral state will remain unchanged. See the constructor documentation for details of the arguments. Returns ``None``. .. method:: Pin.value([x]) This method allows to set and get the value of the pin, depending on whether the argument ``x`` is supplied or not. If the argument is omitted then this method gets the digital logic level of the pin, returning 0 or 1 corresponding to low and high voltage signals respectively. The behaviour of this method depends on the mode of the pin: - ``Pin.IN`` - The method returns the actual input value currently present on the pin. - ``Pin.OUT`` - The behaviour and return value of the method is undefined. - ``Pin.OPEN_DRAIN`` - If the pin is in state '0' then the behaviour and return value of the method is undefined. Otherwise, if the pin is in state '1', the method returns the actual input value currently present on the pin. If the argument is supplied then this method sets the digital logic level of the pin. The argument ``x`` can be anything that converts to a boolean. If it converts to ``True``, the pin is set to state '1', otherwise it is set to state '0'. The behaviour of this method depends on the mode of the pin: - ``Pin.IN`` - The value is stored in the output buffer for the pin. The pin state does not change, it remains in the high-impedance state. The stored value will become active on the pin as soon as it is changed to ``Pin.OUT`` or ``Pin.OPEN_DRAIN`` mode. - ``Pin.OUT`` - The output buffer is set to the given value immediately. - ``Pin.OPEN_DRAIN`` - If the value is '0' the pin is set to a low voltage state. Otherwise the pin is set to high-impedance state. When setting the value this method returns ``None``. .. method:: Pin.__call__([x]) Pin objects are callable. The call method provides a (fast) shortcut to set and get the value of the pin. It is equivalent to Pin.value([x]). See :meth:`Pin.value` for more details. .. method:: Pin.on() Set pin to "1" output level. .. method:: Pin.off() Set pin to "0" output level. .. method:: Pin.irq(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), *, priority=1, wake=None, hard=False) Configure an interrupt handler to be called when the trigger source of the pin is active. If the pin mode is ``Pin.IN`` then the trigger source is the external value on the pin. If the pin mode is ``Pin.OUT`` then the trigger source is the output buffer of the pin. Otherwise, if the pin mode is ``Pin.OPEN_DRAIN`` then the trigger source is the output buffer for state '0' and the external pin value for state '1'. The arguments are: - ``handler`` is an optional function to be called when the interrupt triggers. The handler must take exactly one argument which is the ``Pin`` instance. - ``trigger`` configures the event which can generate an interrupt. Possible values are: - ``Pin.IRQ_FALLING`` interrupt on falling edge. - ``Pin.IRQ_RISING`` interrupt on rising edge. - ``Pin.IRQ_LOW_LEVEL`` interrupt on low level. - ``Pin.IRQ_HIGH_LEVEL`` interrupt on high level. These values can be OR'ed together to trigger on multiple events. - ``priority`` sets the priority level of the interrupt. The values it can take are port-specific, but higher values always represent higher priorities. - ``wake`` selects the power mode in which this interrupt can wake up the system. It can be ``machine.IDLE``, ``machine.SLEEP`` or ``machine.DEEPSLEEP``. These values can also be OR'ed together to make a pin generate interrupts in more than one power mode. - ``hard`` if true a hardware interrupt is used. This reduces the delay between the pin change and the handler being called. Hard interrupt handlers may not allocate memory; see :ref:`isr_rules`. Not all ports support this argument. This method returns a callback object.

The following methods are not part of the core Pin API and only implemented on certain ports.

.. method:: Pin.low() Set pin to "0" output level. Availability: nrf, rp2, stm32 ports. .. method:: Pin.high() Set pin to "1" output level. Availability: nrf, rp2, stm32 ports. .. method:: Pin.mode([mode]) Get or set the pin mode. See the constructor documentation for details of the ``mode`` argument. Availability: cc3200, stm32 ports. .. method:: Pin.pull([pull]) Get or set the pin pull state. See the constructor documentation for details of the ``pull`` argument. Availability: cc3200, stm32 ports. .. method:: Pin.drive([drive]) Get or set the pin drive strength. See the constructor documentation for details of the ``drive`` argument. Availability: cc3200 port.

Constants

The following constants are used to configure the pin objects. Note that not all constants are available on all ports.

.. data:: Pin.IN Pin.OUT Pin.OPEN_DRAIN Pin.ALT Pin.ALT_OPEN_DRAIN Selects the pin mode. .. data:: Pin.PULL_UP Pin.PULL_DOWN Pin.PULL_HOLD Selects whether there is a pull up/down resistor. Use the value ``None`` for no pull. .. data:: Pin.LOW_POWER Pin.MED_POWER Pin.HIGH_POWER Selects the pin drive strength. .. data:: Pin.IRQ_FALLING Pin.IRQ_RISING Pin.IRQ_LOW_LEVEL Pin.IRQ_HIGH_LEVEL Selects the IRQ trigger type.
Sours: https://github.com/micropython/micropython/blob/master/docs/library/machine.Pin.rst
024 - ESP32 MicroPython: SD Card
/* * This file is part of the MicroPython project, http://micropython.org/ * * The MIT License (MIT) * * Copyright (c) 2013, 2014 Damien P. George * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE.*/#include<stdio.h>#include<stdint.h>#include<string.h>#include"py/runtime.h"#include"py/mphal.h"#include"extmod/virtpin.h"#include"pin.h"#include"extint.h"/// \moduleref pyb/// \class Pin - control I/O pins////// A pin is the basic object to control I/O pins. It has methods to set/// the mode of the pin (input, output, etc) and methods to get and set the/// digital logic level. For analog control of a pin, see the ADC class.////// Usage Model:////// All Board Pins are predefined as pyb.Pin.board.Name////// x1_pin = pyb.Pin.board.X1////// g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN)////// CPU pins which correspond to the board pins are available/// as `pyb.cpu.Name`. For the CPU pins, the names are the port letter/// followed by the pin number. On the PYBv1.0, `pyb.Pin.board.X1` and/// `pyb.Pin.cpu.B6` are the same pin.////// You can also use strings:////// g = pyb.Pin('X1', pyb.Pin.OUT_PP)////// Users can add their own names:////// MyMapperDict = { 'LeftMotorDir' : pyb.Pin.cpu.C12 }/// pyb.Pin.dict(MyMapperDict)/// g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD)////// and can query mappings////// pin = pyb.Pin("LeftMotorDir")////// Users can also add their own mapping function:////// def MyMapper(pin_name):/// if pin_name == "LeftMotorDir":/// return pyb.Pin.cpu.A0////// pyb.Pin.mapper(MyMapper)////// So, if you were to call: `pyb.Pin("LeftMotorDir", pyb.Pin.OUT_PP)`/// then `"LeftMotorDir"` is passed directly to the mapper function.////// To summarise, the following order determines how things get mapped into/// an ordinal pin number:////// 1. Directly specify a pin object/// 2. User supplied mapping function/// 3. User supplied mapping (object must be usable as a dictionary key)/// 4. Supply a string which matches a board pin/// 5. Supply a string which matches a CPU port/pin////// You can set `pyb.Pin.debug(True)` to get some debug information about/// how a particular object gets mapped to a pin.// Pin class variablesSTATIC bool pin_class_debug;voidpin_init0(void) {MP_STATE_PORT(pin_class_mapper) = mp_const_none;MP_STATE_PORT(pin_class_map_dict) = mp_const_none; pin_class_debug = false;}// C API used to convert a user-supplied pin name into an ordinal pin number.constpin_obj_t *pin_find(mp_obj_t user_obj) {constpin_obj_t *pin_obj;// If a pin was provided, then use itif (mp_obj_is_type(user_obj, &pin_type)) { pin_obj = MP_OBJ_TO_PTR(user_obj);if (pin_class_debug) {printf("Pin map passed pin ");mp_obj_print(MP_OBJ_FROM_PTR(pin_obj), PRINT_STR);printf("\n"); }return pin_obj; }if (MP_STATE_PORT(pin_class_mapper) != mp_const_none) {mp_obj_t o = mp_call_function_1(MP_STATE_PORT(pin_class_mapper), user_obj);if (o != mp_const_none) {if (!mp_obj_is_type(o, &pin_type)) {mp_raise_ValueError(MP_ERROR_TEXT("Pin.mapper didn't return a Pin object")); }if (pin_class_debug) {printf("Pin.mapper maps ");mp_obj_print(user_obj, PRINT_REPR);printf(" to ");mp_obj_print(o, PRINT_STR);printf("\n"); }returnMP_OBJ_TO_PTR(o); }// The pin mapping function returned mp_const_none, fall through to// other lookup methods. }if (MP_STATE_PORT(pin_class_map_dict) != mp_const_none) {mp_map_t *pin_map_map = mp_obj_dict_get_map(MP_STATE_PORT(pin_class_map_dict));mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP);if (elem != NULL && elem->value != MP_OBJ_NULL) {mp_obj_t o = elem->value;if (pin_class_debug) {printf("Pin.map_dict maps ");mp_obj_print(user_obj, PRINT_REPR);printf(" to ");mp_obj_print(o, PRINT_STR);printf("\n"); }returnMP_OBJ_TO_PTR(o); } }// See if the pin name matches a board pin pin_obj = pin_find_named_pin(&pin_board_pins_locals_dict, user_obj);if (pin_obj) {if (pin_class_debug) {printf("Pin.board maps ");mp_obj_print(user_obj, PRINT_REPR);printf(" to ");mp_obj_print(MP_OBJ_FROM_PTR(pin_obj), PRINT_STR);printf("\n"); }return pin_obj; }// See if the pin name matches a cpu pin pin_obj = pin_find_named_pin(&pin_cpu_pins_locals_dict, user_obj);if (pin_obj) {if (pin_class_debug) {printf("Pin.cpu maps ");mp_obj_print(user_obj, PRINT_REPR);printf(" to ");mp_obj_print(MP_OBJ_FROM_PTR(pin_obj), PRINT_STR);printf("\n"); }return pin_obj; }mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("Pin(%s) doesn't exist"), mp_obj_str_get_str(user_obj));}/// \method __str__()/// Return a string describing the pin object.STATIC voidpin_print(constmp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);// pin namemp_printf(print, "Pin(Pin.cpu.%q, mode=Pin.", self->name);uint32_t mode = pin_get_mode(self);if (mode == GPIO_MODE_ANALOG) {// analogmp_print_str(print, "ANALOG)"); } else {// IO modebool af = false; qstr mode_qst;if (mode == GPIO_MODE_INPUT) { mode_qst = MP_QSTR_IN; } elseif (mode == GPIO_MODE_OUTPUT_PP) { mode_qst = MP_QSTR_OUT; } elseif (mode == GPIO_MODE_OUTPUT_OD) { mode_qst = MP_QSTR_OPEN_DRAIN; } else { af = true;if (mode == GPIO_MODE_AF_PP) { mode_qst = MP_QSTR_ALT; } else { mode_qst = MP_QSTR_ALT_OPEN_DRAIN; } }mp_print_str(print, qstr_str(mode_qst));// pull mode qstr pull_qst = MP_QSTRnull;uint32_t pull = pin_get_pull(self);if (pull == GPIO_PULLUP) { pull_qst = MP_QSTR_PULL_UP; } elseif (pull == GPIO_PULLDOWN) { pull_qst = MP_QSTR_PULL_DOWN; }if (pull_qst != MP_QSTRnull) {mp_printf(print, ", pull=Pin.%q", pull_qst); }// AF modeif (af) {mp_uint_t af_idx = pin_get_af(self);constpin_af_obj_t *af_obj = pin_find_af_by_index(self, af_idx);if (af_obj == NULL) {mp_printf(print, ", af=%d)", af_idx); } else {mp_printf(print, ", af=Pin.%q)", af_obj->name); } } else {mp_print_str(print, ")"); } }}STATIC mp_obj_tpin_obj_init_helper(constpin_obj_t *pin, size_t n_args, constmp_obj_t *args, mp_map_t *kw_args);/// \classmethod \constructor(id, ...)/// Create a new Pin object associated with the id. If additional arguments are given,/// they are used to initialise the pin. See `init`.mp_obj_tmp_pin_make_new(constmp_obj_type_t *type, size_t n_args, size_t n_kw, constmp_obj_t *args) {mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true);// Run an argument through the mapper and return the result.constpin_obj_t *pin = pin_find(args[0]);if (n_args > 1 || n_kw > 0) {// pin mode given, so configure this GPIOmp_map_t kw_args;mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args); } else {// enable the peripheral clock so pin reading at least worksmp_hal_gpio_clock_enable(pin->gpio); }returnMP_OBJ_FROM_PTR(pin);}// fast method for getting/setting pin valueSTATIC mp_obj_tpin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, constmp_obj_t *args) {mp_arg_check_num(n_args, n_kw, 0, 1, false);pin_obj_t *self = MP_OBJ_TO_PTR(self_in);if (n_args == 0) {// get pinreturnMP_OBJ_NEW_SMALL_INT(mp_hal_pin_read(self)); } else {// set pinmp_hal_pin_write(self, mp_obj_is_true(args[0]));return mp_const_none; }}/// \classmethod mapper([fun])/// Get or set the pin mapper function.STATIC mp_obj_tpin_mapper(size_t n_args, constmp_obj_t *args) {if (n_args > 1) {MP_STATE_PORT(pin_class_mapper) = args[1];return mp_const_none; }returnMP_STATE_PORT(pin_class_mapper);}STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_mapper_fun_obj, 1, 2, pin_mapper);STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_mapper_obj, MP_ROM_PTR(&pin_mapper_fun_obj));/// \classmethod dict([dict])/// Get or set the pin mapper dictionary.STATIC mp_obj_tpin_map_dict(size_t n_args, constmp_obj_t *args) {if (n_args > 1) {MP_STATE_PORT(pin_class_map_dict) = args[1];return mp_const_none; }returnMP_STATE_PORT(pin_class_map_dict);}STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_dict_fun_obj, 1, 2, pin_map_dict);STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_map_dict_obj, MP_ROM_PTR(&pin_map_dict_fun_obj));/// \classmethod af_list()/// Returns an array of alternate functions available for this pin.STATIC mp_obj_tpin_af_list(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);mp_obj_t result = mp_obj_new_list(0, NULL);constpin_af_obj_t *af = self->af;for (mp_uint_t i = 0; i < self->num_af; i++, af++) {mp_obj_list_append(result, MP_OBJ_FROM_PTR(af)); }return result;}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_af_list_obj, pin_af_list);/// \classmethod debug([state])/// Get or set the debugging state (`True` or `False` for on or off).STATIC mp_obj_tpin_debug(size_t n_args, constmp_obj_t *args) {if (n_args > 1) { pin_class_debug = mp_obj_is_true(args[1]);return mp_const_none; }returnmp_obj_new_bool(pin_class_debug);}STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_debug_fun_obj, 1, 2, pin_debug);STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_debug_obj, MP_ROM_PTR(&pin_debug_fun_obj));// init(mode, pull=None, af=-1, *, value, alt)STATIC mp_obj_tpin_obj_init_helper(constpin_obj_t *self, size_t n_args, constmp_obj_t *pos_args, mp_map_t *kw_args) {staticconstmp_arg_t allowed_args[] = { { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE}}, { MP_QSTR_af, MP_ARG_INT, {.u_int = -1}}, // legacy { MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, { MP_QSTR_alt, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1}}, };// parse argsmp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);// get io modeuint mode = args[0].u_int;if (!IS_GPIO_MODE(mode)) {mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin mode: %d"), mode); }// get pull modeuint pull = GPIO_NOPULL;if (args[1].u_obj != mp_const_none) { pull = mp_obj_get_int(args[1].u_obj); }if (!IS_GPIO_PULL(pull)) {mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin pull: %d"), pull); }// get af (alternate function); alt-arg overrides af-argmp_int_t af = args[4].u_int;if (af == -1) { af = args[2].u_int; }if ((mode == GPIO_MODE_AF_PP || mode == GPIO_MODE_AF_OD) && !IS_GPIO_AF(af)) {mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin af: %d"), af); }// enable the peripheral clock for the port of this pinmp_hal_gpio_clock_enable(self->gpio);// if given, set the pin value before initialising to prevent glitchesif (args[3].u_obj != MP_OBJ_NULL) {mp_hal_pin_write(self, mp_obj_is_true(args[3].u_obj)); }// configure the GPIO as requested GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin = self->pin_mask; GPIO_InitStructure.Mode = mode; GPIO_InitStructure.Pull = pull; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStructure.Alternate = af;HAL_GPIO_Init(self->gpio, &GPIO_InitStructure);return mp_const_none;}STATIC mp_obj_tpin_obj_init(size_t n_args, constmp_obj_t *args, mp_map_t *kw_args) {returnpin_obj_init_helper(MP_OBJ_TO_PTR(args[0]), n_args - 1, args + 1, kw_args);}MP_DEFINE_CONST_FUN_OBJ_KW(pin_init_obj, 1, pin_obj_init);/// \method value([value])/// Get or set the digital logic level of the pin:////// - With no argument, return 0 or 1 depending on the logic level of the pin./// - With `value` given, set the logic level of the pin. `value` can be/// anything that converts to a boolean. If it converts to `True`, the pin/// is set high, otherwise it is set low.STATIC mp_obj_tpin_value(size_t n_args, constmp_obj_t *args) {returnpin_call(args[0], n_args - 1, 0, args + 1);}STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);STATIC mp_obj_tpin_off(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);mp_hal_pin_low(self);return mp_const_none;}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_off_obj, pin_off);STATIC mp_obj_tpin_on(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);mp_hal_pin_high(self);return mp_const_none;}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_on_obj, pin_on);// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING, hard=False)STATIC mp_obj_tpin_irq(size_t n_args, constmp_obj_t *pos_args, mp_map_t *kw_args) {enum { ARG_handler, ARG_trigger, ARG_hard };staticconstmp_arg_t allowed_args[] = { { MP_QSTR_handler, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, { MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_MODE_IT_RISING | GPIO_MODE_IT_FALLING} }, { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} }, };pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);if (n_args > 1 || kw_args->used != 0) {// configure irqextint_register_pin(self, args[ARG_trigger].u_int, args[ARG_hard].u_bool, args[ARG_handler].u_obj); }// TODO should return an IRQ objectreturn mp_const_none;}STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pin_irq_obj, 1, pin_irq);/// \method name()/// Get the pin name.STATIC mp_obj_tpin_name(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);returnMP_OBJ_NEW_QSTR(self->name);}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_name_obj, pin_name);/// \method names()/// Returns the cpu and board names for this pin.STATIC mp_obj_tpin_names(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);mp_obj_t result = mp_obj_new_list(0, NULL);mp_obj_list_append(result, MP_OBJ_NEW_QSTR(self->name));constmp_map_t *map = &pin_board_pins_locals_dict.map;mp_map_elem_t *elem = map->table;for (mp_uint_t i = 0; i < map->used; i++, elem++) {if (elem->value == self_in) {mp_obj_list_append(result, elem->key); } }return result;}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_names_obj, pin_names);/// \method port()/// Get the pin port.STATIC mp_obj_tpin_port(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);returnMP_OBJ_NEW_SMALL_INT(self->port);}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_port_obj, pin_port);/// \method pin()/// Get the pin number.STATIC mp_obj_tpin_pin(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);returnMP_OBJ_NEW_SMALL_INT(self->pin);}STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_pin_obj, pin_pin);/// \method gpio()/// Returns the base address of the GPIO block associated with this pin.STATIC mp_obj_tpin_gpio(mp_obj_t self_in) {pin_obj_t *self = MP_OBJ_TO_PTR(self_in);returnMP_OBJ_NEW_SMALL_INT((intptr_t)self->gpio);
Sours: https://github.com/micropython/micropython/blob/master/ports/stm32/pin.c

Pin micropython

Class Pin – control I/O pins¶

Pin objects are used to control I / O pins (also known as GPIO-general purpose input / output). Pin objects are usually associated with physical pins that can drive the output voltage and read the input voltage. The pin class has a method to set the pin mode (IN, OUT, etc.) and a method to obtain and set the digital logic level. For analog control of pins, please refer to class.

Construct a pin object by using an identifier that explicitly specifies a certain I/O pin. The allowed identifier form and the physical pin to which the identifier is mapped are port-specific。 The possibility of the identifier is an integer, a string or a tuple with port and pin number.

Example:

frommachineimportPin# create an output pin on pin #32p0=Pin(32,Pin.OUT)# set the value low then highp0.value(0)p0.value(1)# create an input pin on pin #33, with a pull up resistorp2=Pin(33,Pin.IN,Pin.PULL_UP)# configure an irq callbackp2.irq(trigger=Pin.IRQ_FALLING,handler=lambdat:print("IRQ"))

Build Object¶

class (id, mode=1, pull=1, value, drive, alt

Access the pin peripheral (GPIO pin) associated with the given. If other parameters are given in the build object, they are used to initialize the pins. Any settings not specified will maintain their previous state.

Attention

The mPython control board provides its own pin mapping, mapping pins to GPIO of ESP32.For example, the P0 pin of the control board corresponds to the IO33 of ESP32, then you can use to replace .

Parameter:

  • is mandatory and can be any object. Possible value types include:int (Internal pin identifier), str(Pin name)and tuple([port,pin] match). If you use mPython, you can use Pin.P(0~20), for example (Pin.P0)P0 pin provides mapping as GPIO.
  • specifies the pin mode, which can be one of the following:
    • - Pin is configured as input. If it is regarded as an output, the pin is in a high-impedance state.
    • - Pin is configured as (normal) output.
    • - Pin is configured as an open-drain output. The open-drain output works in the following way:If the output value is set to 0, the pin is active low; if the output value is 1, the pin is high impedance. Not all ports implement this mode, or some ports may only be implemented on certain pins.
    • - Pin configuration as open drain。

specifies whether a (weak) pull resistor is connected to the pin, which can be one of the following:

  • - No pull-up or pull-down resistors
  • - Pull-up resistor enabled
  • - Pull-down resistor enabled
  • is only valid for and modes, and specifies the initial output pin value, otherwise the state of the pin peripherals remains unchanged.

Method¶

(mode=1, pull=1, value, drive, alt

Reinitialize the pin with the given parameters. Only set the specified parameters. The rest of the pin peripheral state will remain unchanged. For detailed information about the parameters, see the build object documentation.

Return .

([x])¶

This method allows setting and getting the value of the pin, depending on whether provides the parameter.

If this parameter is omitted, the method obtains the digital logic level of the pin and returns 0 or 1 corresponding to the low voltage signal and the high voltage signal, respectively. The behavior of this method depends on the mode of the pin:

  • - This method returns the actual input value currently present on the pin.
  • - This method returns the actual input value currently present on the pin.
  • - If the pin is in state “0”, the behavior and return value of the method are undefined. Otherwise, if the pin is in state “1”, the method returns the actual input value currently present on the pin.

If parameters are provided, this method sets the digital logic level of the pin. Parameter x can be any value converted to Boolean. If converted to True, set the pin to state “1”, otherwise set it to “0” state. The behavior of this method depends on the mode of the pin:

  • - This value is stored in the output buffer of the pin. The state of the pin will not change, it is still in a high impedance state. Once changed to or mode, the stored value will be activated on the pin.
  • - The output buffer is immediately set to the given value.
  • - If the value is “0”,the pin is set to a low voltage state. Otherwise, the pin is set to high impedance.

When setting the value returned by this method .

([x])¶

Pin object is callable. The call method provides a (quick) shortcut to set and get the value of the pin. It is equivalent to Pin.value([x]). For details, see 。

()¶

Set the pin to high level

()¶

Set the pin to low level

(handler=None, trigger=(Pin.IRQ_FALLING | Pin.IRQ_RISING), wake=None

Configure the interrupt handler to be called when the trigger source of the pin is active. If the pin mode is , then the trigger source is the external value on the pin. If the pin mode is , then the trigger source is the output buffer of the pin. Otherwise, if the pin mode is , then the trigger source is the output buffer of state ‘0’ and the external pin value of state ‘1’.

Parameter:

  • is an optional function that is called when the interrupt is triggered.

  • configure events that can trigger an interrupt. Possible values are:

    • falling interruption
    • rising interruption
    • low level interruption
    • high level interruption
    • Used for wake-up function, high level trigger
    • Used for wake-up function, low level trigger

    These values can be used to perform operations together to trigger multiple events.

  • select this interrupt to wake up the power mode of the system. It can be , or . These values can also be “or” calculated together to cause pins to break in multiple power consumption modes.

This method returns a callback object.

Constant¶

The board’s own pin mapping maps of the mPython Board pins to the GPIO of ESP32 mPython

The following constants are used to configure pin objects.

Select pin mode.

Select whether there is a pull-up / pull-down resistor. Use None value.

Select IRQ trigger type.


© Copyright 2018-2021 labplus.All Rights Reserved Revision .

Built with Sphinx using a theme provided by Read the Docs.
Sours: https://mpython.readthedocs.io/en/master/library/micropython/machine/machine.Pin.html
024 - ESP32 MicroPython: SD Card

class Pin – control I/O pins¶

A pin is the basic object to control I/O pins. It has methods to set the mode of the pin (input, output, etc) and methods to get and set the digital logic level. For analog control of a pin, see the ADC class.

Usage Model:

All Board Pins are predefined as pyb.Pin.board.Name:

x1_pin=pyb.Pin.board.X1g=pyb.Pin(pyb.Pin.board.X1,pyb.Pin.IN)

CPU pins which correspond to the board pins are available as . For the CPU pins, the names are the port letter followed by the pin number. On the PYBv1.0, and are the same pin.

You can also use strings:

g=pyb.Pin('X1',pyb.Pin.OUT_PP)

Users can add their own names:

MyMapperDict={'LeftMotorDir':pyb.Pin.cpu.C12}pyb.Pin.dict(MyMapperDict)g=pyb.Pin("LeftMotorDir",pyb.Pin.OUT_OD)

and can query mappings:

pin=pyb.Pin("LeftMotorDir")

Users can also add their own mapping function:

defMyMapper(pin_name):ifpin_name=="LeftMotorDir":returnpyb.Pin.cpu.A0pyb.Pin.mapper(MyMapper)

So, if you were to call: then is passed directly to the mapper function.

To summarise, the following order determines how things get mapped into an ordinal pin number:

  1. Directly specify a pin object

  2. User supplied mapping function

  3. User supplied mapping (object must be usable as a dictionary key)

  4. Supply a string which matches a board pin

  5. Supply a string which matches a CPU port/pin

You can set to get some debug information about how a particular object gets mapped to a pin.

When a pin has the or pull-mode enabled, that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND respectively (except pin Y5 which has 11k Ohm resistors).

Now every time a falling edge is seen on the gpio pin, the callback will be executed. Caution: mechanical push buttons have “bounce” and pushing or releasing a switch will often generate multiple edges. See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed explanation, along with various techniques for debouncing.

All pin objects go through the pin mapper to come up with one of the gpio pins.

Constructors¶

class (id, ...

Create a new Pin object associated with the id. If additional arguments are given, they are used to initialise the pin. See .

Class methods¶

classmethod ([state])¶

Get or set the debugging state ( or for on or off).

classmethod ([dict])¶

Get or set the pin mapper dictionary.

classmethod ([fun])¶

Get or set the pin mapper function.

Methods¶

(mode, pull=Pin.PULL_NONE, \*, value=None, alt=-1

Initialise the pin:

  • mode can be one of:

    • - configure the pin for input;

    • - configure the pin for output, with push-pull control;

    • - configure the pin for output, with open-drain control;

    • - configure the pin for alternate function, pull-pull;

    • - configure the pin for alternate function, open-drain;

    • - configure the pin for analog.

  • pull can be one of:

    • - no pull up or down resistors;

    • - enable the pull-up resistor;

    • - enable the pull-down resistor.

  • value if not None will set the port output value before enabling the pin.

  • alt can be used when mode is or to set the index or name of one of the alternate functions associated with a pin. This arg was previously called af which can still be used if needed.

Returns: .

([value])¶

Get or set the digital logic level of the pin:

  • With no argument, return 0 or 1 depending on the logic level of the pin.

  • With given, set the logic level of the pin. can be anything that converts to a boolean. If it converts to , the pin is set high, otherwise it is set low.

()¶

Return a string describing the pin object.

()¶

Returns the currently configured alternate-function of the pin. The integer returned will match one of the allowed constants for the af argument to the init function.

()¶

Returns an array of alternate functions available for this pin.

()¶

Returns the base address of the GPIO block associated with this pin.

()¶

Returns the currently configured mode of the pin. The integer returned will match one of the allowed constants for the mode argument to the init function.

()¶

Get the pin name.

()¶

Returns the cpu and board names for this pin.

()¶

Get the pin number.

()¶

Get the pin port.

()¶

Returns the currently configured pull of the pin. The integer returned will match one of the allowed constants for the pull argument to the init function.

Constants¶

initialise the pin to alternate-function mode with an open-drain drive

initialise the pin to alternate-function mode with a push-pull drive

initialise the pin to analog mode

initialise the pin to input mode

initialise the pin to output mode with an open-drain drive

initialise the pin to output mode with a push-pull drive

enable the pull-down resistor on the pin

don’t enable any pull up or down resistors on the pin

enable the pull-up resistor on the pin

A Pin represents a physical pin on the microprocessor. Each pin can have a variety of functions (GPIO, I2C SDA, etc). Each PinAF object represents a particular function for a pin.

Usage Model:

x3=pyb.Pin.board.X3x3_af=x3.af_list()

x3_af will now contain an array of PinAF objects which are available on pin X3.

For the pyboard, x3_af would contain:

[Pin.AF1_TIM2, Pin.AF2_TIM5, Pin.AF3_TIM9, Pin.AF7_USART2]

Normally, each peripheral would configure the af automatically, but sometimes the same function is available on multiple pins, and having more control is desired.

To configure X3 to expose TIM2_CH3, you could use:

pin=pyb.Pin(pyb.Pin.board.X3,mode=pyb.Pin.AF_PP,af=pyb.Pin.AF1_TIM2)

or:

pin=pyb.Pin(pyb.Pin.board.X3,mode=pyb.Pin.AF_PP,af=1)

Methods¶

()¶

Return a string describing the alternate function.

()¶

Return the alternate function index.

()¶

Return the name of the alternate function.

()¶

Return the base register associated with the peripheral assigned to this alternate function. For example, if the alternate function were TIM2_CH3 this would return stm.TIM2


© Copyright - The MicroPython Documentation is Copyright © 2014-2021, Damien P. George, Paul Sokolovsky, and contributors Last updated on 18 Oct 2021.

Built with Sphinx using a theme provided by Read the Docs.
Sours: https://docs.micropython.org/en/latest/library/pyb.Pin.html

Similar news:

The objective of this post is to explain how to use external pin interrupts on MicroPython running on the ESP32. The tests were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.

 

Introduction

The objective of this post is to explain how to use external pin interrupts on MicroPython running on the ESP32. Please note that some of the code we are going to use here was explained in more detail on this previous post about timer interrupts.

The tests were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board. The MicroPython IDE used was uPyCraft.


The code

First of all, we will import the machine module, which we will use to configure the external interrupts.

import machine

Next we will declare a global variable that will be used by the interrupt handling function to communicate to the main program that an interrupt has occurred. This variable will be a counter, in order for us to not loose interrupts. You can check at this previous post why using a counter instead of a flag for communication between the interrupt and the main code.

Note that we should not perform long operations inside interrupt service routines (such as printing content to the serial console), and thus we will design it to execute as fast as possible. So, as mentioned the interrupt service routine will just inform the main code (by incrementing the counter) that the interrupt occurred, and it will be the main code that will actually handle it.

interruptCounter = 0

We will also use another variable to keep track of how many interrupts have occurred since the program started executing. We will increment it and print its value each time an interrupt occurs.

totalInterruptsCounter = 0

Next we will define the callback function to be executed when the interrupt occurs. This function has an input parameter in which an object of class Pin will be passed when the interrupt happens. Nonetheless, we will not use it in this tutorial.

The actual implementation of the function will consist on incrementing the previously defined interruptCounter variable. Note that this variable needs to be declared as global before we are able to modify it inside the function.

def callback(pin): global interruptCounter interruptCounter = interruptCounter+1

Next we need to create an object of class Pin, which is used to control GPIO pins in MicroPython [1]. You can check all the available parameters for the constructor here. For our program, we will need to pass as input the number of the pin we want to use, the mode of the pin and if it has a pull resistor associated.

For this example, I’m using pin 25, but you can use other. Please note that for some ESP32 boards, the ESP32 GPIO numbers may not match the ones labeled on the board.

We will also set the pin mode to input, with the IN constant of the Pin class.

Finally, we will set the pin to use its pull up resistor, which will guarantee that it will be in a known state (VCC) when no electrical signal is applied. This is done by passing the PULL_UP constant of the Pin class.

p25 = machine.Pin(25, machine.Pin.IN, machine.Pin.PULL_UP)

Next we will specify how the interrupt will be triggered and what is the callback function to execute, by calling the irq function of our Pin object.

For this example, we will specify that the interrupt should be triggered when a falling edge is detected in the input signal connected to the pin. To do it, we need to pass the IRQ_FALLING constant of the Pin class as the trigger argument of the irq function. You can check here all the trigger types available.

We will also specify the handling function by passing our previously defined interrupt function as the handler parameter.

p25.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback)

Since all the configurations are now finished, we will enter in a polling loop to check for our interruptCounter variable. Naturally, we are polling only because our program is very simple and we are not doing anything else. Nonetheless, in a real application, we would most likely be performing some computation or the board would be in sleep mode to save energy, instead of being constantly checking the value of the variable.

When we detect that its value is greater than 0, we will treat the interrupt. First, we will decrement the counter value, to signal that it is going to be handled.

Note that since this variable is shared with the interrupt service routine code, we will previously disable the interrupts, only then decrement the counter, and then re-enable the interrupts, to avoid racing conditions.

The disabling and re-enabling of interrupts is done with the disable_irq and enable_irq functions of the machine module. You can check in more detail how to use them in the previous post.

Finally, we will increment the total number of interrupts counter and print its value. In this case, since this variable is not shared with the interrupt service routine, we don’t need to disable interrupts to change its value.

The final source code for the MicroPython script can be seen below, and already includes the interrupt checking loop.

import machine interruptCounter = 0 totalInterruptsCounter = 0 def callback(pin): global interruptCounter interruptCounter = interruptCounter+1 p25 = machine.Pin(25, machine.Pin.IN, machine.Pin.PULL_UP) p25.irq(trigger=machine.Pin.IRQ_FALLING, handler=callback) while True: if interruptCounter>0: state = machine.disable_irq() interruptCounter = interruptCounter-1 machine.enable_irq(state) totalInterruptsCounter = totalInterruptsCounter+1 print("Interrupt has occurred: " + str(totalInterruptsCounter))


Testing the code

To test the code, simply upload the previous script to your ESP32 and run it. Upon running, the easiest way to trigger an interrupt without the need for external hardware is to connect and disconnect the pin where the interrupt was attached to the board’s GND pin.

Please be careful when executing this procedure to avoid connecting the GND pin to the wrong GPIO and damage the board.

You can check below at figure 1 the result from the interrupts.

ESP32 MicroPython external pin interrupt.png

Figure 1 – ESP32 MicroPython external pin interrupts.


Related posts


References

[1] http://docs.micropython.org/en/v1.8.7/esp8266/library/machine.Pin.html?highlight=pin#class-pin-control-i-o-pins

Sours: https://techtutorialsx.com/2017/10/08/esp32-micropython-external-interrupts/


16239 16240 16241 16242 16243