Skip to content

Commit

Permalink
Merge pull request #12 from brainelectronics/feature/add-support-for-…
Browse files Browse the repository at this point in the history
…gpio-module

Add support for GPIO module
  • Loading branch information
brainelectronics authored Jul 30, 2022
2 parents af4f5e0 + 0c5f0da commit 4a6fade
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 2 deletions.
9 changes: 8 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ r"^\#\# \[\d{1,}[.]\d{1,}[.]\d{1,}\] \- \d{4}\-\d{2}-\d{2}$"
-->

## Released
## [0.9.0] - 2022-07-30
### Added
- Support GPIO usage with [`nextion_gpio`](nextion/nextion_gpio.py)
- [Usage example](examples/gpio/main.py) of GPIO

## [0.8.0] - 2022-07-30
### Added
- Support all class specific functions of
Expand Down Expand Up @@ -137,8 +142,10 @@ r"^\#\# \[\d{1,}[.]\d{1,}[.]\d{1,}\] \- \d{4}\-\d{2}-\d{2}$"
- [Example HMI file](examples/everything.HMI) to be used for all examples

<!-- Links -->
[Unreleased]: https://github.com/brainelectronics/micropython-nextion/compare/0.7.1...develop
[Unreleased]: https://github.com/brainelectronics/micropython-nextion/compare/0.9.0...develop

[0.9.0]: https://github.com/brainelectronics/micropython-nextion/tree/0.9.0
[0.8.0]: https://github.com/brainelectronics/micropython-nextion/tree/0.8.0
[0.7.1]: https://github.com/brainelectronics/micropython-nextion/tree/0.7.1
[0.7.0]: https://github.com/brainelectronics/micropython-nextion/tree/0.7.0
[0.6.0]: https://github.com/brainelectronics/micropython-nextion/tree/0.6.0
Expand Down
2 changes: 1 addition & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
| [Crop](crop) | NexCrop | :x: |
| [DualButton](dual_button) | NexDual | :heavy_check_mark: |
| [Gauge](gauge) | NexGauge | :heavy_check_mark: |
| [Gpio](gpio) | NexGpio | :x: |
| [Gpio](gpio) | NexGpio | :heavy_check_mark: |
| [Hardware](hardware) | NexHardware | :heavy_check_mark: |
| [Hotspot](hotspot) | NexHotspot | :x: |
| [Number](number) | NexNumber | :heavy_check_mark: |
Expand Down
123 changes: 123 additions & 0 deletions examples/gpio/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

"""
Main script
Do your stuff here, this file is similar to the loop() function on Arduino
Example on how to interact with the Nextion display GPIO pins
"""

# system packages
from random import randint
import time

# custom packages
from nextion import NexGpio, NexHardware

# define communication pins for Nextion display
tx_pin = 21
rx_pin = 22

# create Nextion hardware interface
nh = NexHardware(rx_pin=rx_pin, tx_pin=tx_pin)

# init nextion communication interface
nh.nexInit()

# create a button instance
gpio = NexGpio(nh)

# ============================================================================
# ============================== Example values ==============================
# new values of GPIOs
pwm_pin = 7 # only GPIO4 and GPIO7 support PWM
pwm_frequency = 500 # Hz, all PWM pins have same frequency
pwm_value = randint(0, 100) # 0 is LOW (off), 100 is HIGH (on)

# ============================================================================
# ============================= Pinmode functions ============================
# set all GPIOs as outputs
print('Set all pins as digital output')
for pin in range(0, 8):
# outputs are HIGH by default
gpio.pin_mode(pin, NexGpio.OUTPUT)
print()

time.sleep(1)

# ============================================================================
# =========================== Digital IO functions ===========================
# toggle all pins 5 times LOW/HIGH
print('Toggle all pins 5 times LOW/HIGH with 0.5 sec delay between a change')
for _ in range(0, 5):
for pin in range(0, 8):
# set pin LOW
gpio.digital_write(pin, 0)
time.sleep(0.5)
# set pin HIGH
gpio.digital_write(pin, 1)
time.sleep(0.5)
print()

time.sleep(1)

# set all GPIOs as inputs
print('Set all pins as digital input')
for pin in range(0, 8):
gpio.pin_mode(pin, NexGpio.INPUT_PULL_UP)
print()

print('Read all pins state')
for pin in range(0, 8):
state = gpio.digital_read(pin)
print('Pin "{}" value is: "{}"'.format(pin, state))
print()

time.sleep(1)

# ============================================================================
# =============================== PWM functions ==============================
# only GPIO4 and GPIO7 support PWM
print('Set GPIO7 pin as PWM output (Buzzer of Expansion Board)')
gpio.pin_mode(pwm_pin, NexGpio.PWM)

# request the PWM frequency
print('Requesting PWM frequency ...')
response = gpio.get_pwmfreq()
print('PWM frequency is: "{}"'.format(response))
print()

time.sleep(1)

# modify PWM frequency to 500 Hz
print('Set PWM frequency to "{}"'.format(pwm_frequency))
gpio.set_pwmfreq(pwm_frequency)
print()

time.sleep(1)

# request the PWM frequency again
print('Requesting PWM frequency ...')
response = gpio.get_pwmfreq()
print('PWM frequency is: "{}"'.format(response))
print()

# sanity check
if response != pwm_frequency:
print('WARNING: GET value did not match SET value')

time.sleep(1)

# modify PWM value (0, 100)[%]
print('Set PWM of "{}" to "{}"'.format(pwm_pin, pwm_value))
gpio.analog_write(pwm_pin, pwm_value)
print()

# ============================================================================
# ============================= End of example ===============================
print('Returning to REPL in 5 seconds')

# wait for 5 more seconds to safely finish the may still running threads
time.sleep(5)
1 change: 1 addition & 0 deletions nextion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .nextion_checkbox import NexCheckbox
from .nextion_dual_state_button import NexDSButton
from .nextion_gauge import NexGauge
from .nextion_gpio import NexGpio
from .nextion_number import NexNumber
from .nextion_page import NexPage
from .nextion_progressbar import NexProgressBar
Expand Down
132 changes: 132 additions & 0 deletions nextion/nextion_gpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

"""
NexGpio
Functions to interact with Nextion GPIOs
"""

# system packages
from time import sleep

# custom packages
from .common import Common


class NexGpioError(Exception):
"""Base class for exceptions in this module."""
pass


class NexGpio(Common):
"""docstring for NexGpio"""
INPUT_PULL_UP = 0 # set pin as pull up input
OUTPUT = 2 # set pin as push pull output
INPUT_BINDING = 1 # bind Nextion element to falling edge of signal
PWM = 3 # set pin as PWM output (only GPIO4 and GPIO7)

def __init__(self, nh) -> None:
"""
Init GPIO
:param nh: The Nextion hardware interface object
:type nh: NexHardware
"""
super().__init__(nh, pid=-1, cid=-1, name="gpio")

def pin_mode(self, port: int, mode: int, control_id: int = 0) -> bool:
"""
Set GPIO mode
:param port: The GPIO port number
:type port: int
:param mode: The GPIO port mode
0 - Pull on the input
1 - the control input binding
2 - Push-pull output
3 - pwm output
4 - open mode leakage
:type mode: int
:param control_id: The bound CID of other nextion element
:type control_id: int
:returns: True on success, false otherwise
:rtype: bool
"""
cmd = "cfgpio {},{},{}".format(port, mode, control_id)
self._nh.sendCommand(cmd)
return self._nh.recvRetCommandFinished()

def digital_write(self, port: int, value: int) -> bool:
"""
Write a HIGH or LOW value to a digital pin
:param port: The GPIO port number
:type port: int
:param value: The value (0 or 1)
:type value: int
:returns: True on success, false otherwise
:rtype: bool
"""
cmd = "pio{}={}".format(port, value)
self._nh.sendCommand(cmd)
return self._nh.recvRetCommandFinished()

def digital_read(self, port: int) -> int:
"""
Read a HIGH or a LOW value of a digital pin
:param port: The GPIO port number
:type port: int
:returns: Value of specified digital pin, either 1 or 0
:rtype: int
"""
cmd = "get pio{}".format(port)
self._nh.sendCommand(cmd)
sleep(0.1) # necessary, data might not be available otherwise
return self._nh.recvRetNumber()

def analog_write(self, port: int, value: int) -> bool:
"""
Set analog value (PWM wave) to a pin
:param port: The GPIO port number
:type port: int
:param value: The duty cycle value (0-100)
:type value: int
:returns: True on success, false otherwise
:rtype: bool
"""
cmd = "pwm{}={}".format(port, value)
self._nh.sendCommand(cmd)
return self._nh.recvRetCommandFinished()

def set_pwmfreq(self, value: int) -> bool:
"""
Set the PWM output frequency for all pins
:param value: The PWM frequency (1-65535)
:type value: int
:returns: True on success, false otherwise
:rtype: bool
"""
cmd = "pwmf={}".format(value)
self._nh.sendCommand(cmd)
return self._nh.recvRetCommandFinished()

def get_pwmfreq(self) -> int:
"""
Get the PWM output frequency
:returns: The PWM frequency.
:rtype: int
"""
cmd = "get pwmf"
self._nh.sendCommand(cmd)
sleep(0.1) # necessary, data might not be available otherwise
return self._nh.recvRetNumber()

0 comments on commit 4a6fade

Please sign in to comment.