Skip to content

Commit 51683b2

Browse files
ArduinoBotcanchebagurjhansson-ardjcarolinaresjacobhylen
authored
[PC-1225] - Getting started with MicroPython on the Portenta C33 (#1788)
* Content update (boards installation C33) * Content update (boards installation C33) * Update content/micropython/01.basics/02.board-installation/board-installation.md * Content update (C33 pinout, GPIO, PWM) * Content update (ADC, RTC) * Content update (C33 pinout) * Update content/micropython/01.basics/02.board-installation/board-installation.md Content update (Josefine's review) Co-authored-by: Josefine Hansson <[email protected]> * Content update (Julian's review) Co-authored-by: Julián Caro Linares <[email protected]> * Content update (Hanne's, Josefine's and Julián's review) * Update content/micropython/01.basics/02.board-installation/board-installation.md * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Jacob Hylén <[email protected]> * Update content/micropython/01.basics/06.board-examples/board-examples.md Co-authored-by: Jacob Hylén <[email protected]> --------- Co-authored-by: José Antonio Bagur Nájera <[email protected]> Co-authored-by: Josefine Hansson <[email protected]> Co-authored-by: Julián Caro Linares <[email protected]> Co-authored-by: Julián Caro Linares <[email protected]> Co-authored-by: Jacob Hylén <[email protected]>
1 parent 8ba4c45 commit 51683b2

File tree

6 files changed

+348
-1
lines changed

6 files changed

+348
-1
lines changed
Loading
Loading
Loading

Diff for: content/micropython/01.basics/02.board-installation/board-installation.md

+26-1
Original file line numberDiff line numberDiff line change
@@ -277,4 +277,29 @@ Do not disconnect your board during this part of the process, watch the progress
277277

278278
Once complete, you're all set and you're ready to start programming the board in MicroPython.
279279

280-
Go to the Arduino Lab MicroPython IDE and press connect in the top left corner, choose the port and you are ready to load scripts to your board.
280+
Go to the Arduino Lab MicroPython IDE and press connect in the top left corner, choose the port and you are ready to load scripts to your board.
281+
282+
## Portenta C33
283+
284+
To install the MicroPython firmware to the Portenta C33 board, you can use the **Arduino MicroPython Installer**. This tool lets you plug in the board, select it from a menu, and automatically flash the latest firmware or a custom one of your choice to the board. You can download the [Arduino MicroPython Installer here](https://labs.arduino.cc/en/labs/micropython-installer).
285+
286+
***The Arduino MicroPython Installer is part of [Arduino Labs](https://labs.arduino.cc) and is considered experimental software.***
287+
288+
Before installing the MicroPython firmware, **ensure you have installed the latest Portenta Renesas board package**. To install the board package for the Portenta C33 board, navigate to **Tools > Board > Boards Manager** or click the Boards Manager icon in the left tab of the IDE. In the Boards Manager tab, search for `renesas` and install the latest `Arduino Renesas Portenta Boards` version.
289+
290+
291+
![Installing the Arduino Renesas Portenta Board Package in the Arduino IDE](./assets/portenta-c33-1.png)
292+
293+
294+
With the latest board package installed, open the Arduino MicroPython Installer and plug your board into your computer; your board should appear ready to be selected, as shown in the image below. If your board does not appear in the installer, try putting it in bootloader mode by double-tapping your board's reset button.
295+
296+
297+
298+
![Portenta C33 board detected on the Arduino MicroPython Installer](./assets/portenta-c33-2.png)
299+
300+
To install the MicroPython firmware, press the **INSTALL MICROPYTHON** button and wait a few seconds while the installer tool takes care of everything else. When finished, you should see a message in the image below.
301+
302+
![Firmware successfully uploaded to the Portenta C33 board](./assets/portenta-c33-3.png)
303+
304+
305+
Now you are ready to use MicroPython with your Portenta C33 board.
Loading

Diff for: content/micropython/01.basics/06.board-examples/board-examples.md

+322
Original file line numberDiff line numberDiff line change
@@ -1546,3 +1546,325 @@ If you need to stop the audio streaming, you can call `.stop_streaming()`.
15461546
```python
15471547
audio.stop_streaming()
15481548
```
1549+
1550+
## Portenta C33
1551+
1552+
### Pinout Mapping
1553+
1554+
The Portenta C33 has two ways its pins are physically available: through its MKR-styled connectors and its High-Density connectors. Most pins are referred to via their port name or function. In the image below, the Portenta C33 MKR-styled connectors pinout is shown.
1555+
1556+
![Portenta C33 MKR-styled connectors pinout](assets/portenta33_MKR_pinout.png)
1557+
1558+
The MKR-styled connectors pinout is mapped in MicroPython as follows:
1559+
1560+
| **Arduino Pin Mapping** | **MicroPython Pin Mapping** |
1561+
|:-----------------------:|:---------------------------:|
1562+
| `P006`/`A0` | `P006` |
1563+
| `P005`/`A1` | `P005` |
1564+
| `P004`/`A2` | `P004` |
1565+
| `P002`/`A3` | `P002` |
1566+
| `P001`/`A4` | `P001` |
1567+
| `P015`/`A5` | `P015` |
1568+
| `P014`/`A6` | `P014` |
1569+
| `P105`/`D0` | `P105` |
1570+
| `P106`/`D1` | `P106` |
1571+
| `P111`/`D2` | `P111` |
1572+
| `P303`/`D3` | `P303` |
1573+
| `P401`/`D4` | `P401` |
1574+
| `P210`/`D5` | `P210` |
1575+
| `P602` | `P602` |
1576+
| `P110` | `P110` |
1577+
| `P408` | `P408` |
1578+
| `P407` | `P407` |
1579+
| `P315` | `P315` |
1580+
| `P204` | `P204` |
1581+
| `P900` | `P900` |
1582+
| `P402` | `P402` |
1583+
| `P601` | `P601` |
1584+
1585+
The complete MicroPython pinout is available [here](https://github.com/micropython/micropython/blob/master/ports/renesas-ra/boards/ARDUINO_PORTENTA_C33/pins.csv).
1586+
1587+
### Input/Output Pins
1588+
1589+
The `Pin` class in the `machine` module is essential for controlling Input/Output (I/O) pins of the Portenta C33 board. These pins are crucial for a wide range of applications, including reading sensor data, controlling actuators, and interfacing with other hardware components.
1590+
1591+
#### Pin Initialization
1592+
1593+
To begin using an I/O pin of the Portenta C33 board with MicroPython, you need to initialize it using the `Pin` class from the `machine` module. This involves specifying the pin identifier and its mode (input, output, etc.).
1594+
1595+
```python
1596+
from machine import Pin
1597+
1598+
# Initializing pin P107 as an output
1599+
p107 = Pin('P107', Pin.OUT)
1600+
```
1601+
1602+
#### Configuring Pin Modes
1603+
1604+
You can configure a pin as an input or output. For input pins, it's often useful to activate an internal pull-up or pull-down resistor. This helps to stabilize the input signal, especially in cases where the pin is reading a mechanical switch or a button.
1605+
1606+
```python
1607+
# Configuring pin P105 as an input with its pull-up resistor enabled
1608+
p105 = Pin('P105', Pin.IN, Pin.PULL_UP)
1609+
```
1610+
1611+
#### Reading from and Writing to Pins
1612+
1613+
To read a digital value from a pin, use the `.value()` method without any arguments. This is particularly useful for input pins. Conversely, to write a digital value, use the `.value()` method with an argument. Passing `1` sets the pin to `HIGH`, while `0` sets it to `LOW`. This is applicable to output pins.
1614+
1615+
```python
1616+
# Reading from P105
1617+
pin_value = p105.value()
1618+
1619+
# Writing to P107
1620+
p107.value(1) # Set p2 to high
1621+
```
1622+
1623+
#### Advanced Pin Configuration
1624+
1625+
The Pin class allows dynamic reconfiguration of pins and setting up interrupt callbacks. This feature is essential for creating responsive and interactive applications.
1626+
1627+
```python
1628+
# Reconfiguring P105 as an input with a pull-down resistor
1629+
p105.init(Pin.IN, Pin.PULL_DOWN)
1630+
1631+
# Setting up an interrupt on P105
1632+
p105.irq(lambda p: print("- IRQ triggered!", p))
1633+
```
1634+
1635+
#### Practical Example
1636+
1637+
In this example, we will configure one pin as an input to read the state of a button and another pin as an output to control an LED. The LED will turn on when the button is pressed and off when it's released.
1638+
1639+
```python
1640+
from machine import Pin
1641+
import time
1642+
1643+
# Configure pin P107 as an output (for the LED)
1644+
led = Pin('P107', Pin.OUT_PP)
1645+
1646+
# Configure pin P105 as input with pull-up resistor enabled (for the button)
1647+
button = Pin('P105', Pin.IN, Pin.PULL_UP)
1648+
1649+
while True:
1650+
# Read the state of the button
1651+
button_state = button.value()
1652+
if button_state == 0:
1653+
# Turn on LED if button is pressed (button_state is LOW)
1654+
led.value(1)
1655+
else:
1656+
# Turn off LED if button is not pressed (button_state is HIGH)
1657+
led.value(0)
1658+
1659+
# Short delay to debounce the button
1660+
time.sleep(0.1)
1661+
```
1662+
1663+
This practical example demonstrates controlling an LED based on a button's state. The LED, connected to pin `P107` (configured as an output), is turned on or off depending on the button's input read from pin `P105` (set as an input with a pull-up resistor). The main loop continually checks the button's state; pressing the button fixes the LED on while releasing it turns the LED off. A brief delay is included for debouncing, ensuring stable operation without false triggers from the button.
1664+
1665+
### Analog to Digital Converter
1666+
1667+
The `ADC` class in MicroPython provides an interface for the Analog-to-Digital (ADC) converter of the Portenta C33 board, enabling the measurement of continuous voltages and their conversion into discrete digital values. This functionality is crucial for applications that, for example, require reading from analog sensors. The `ADC` class represents a single endpoint for sampling voltage from an analog pin and converting it to a digital value.
1668+
1669+
The available ADC pins of the Portenta C33 board in MicroPython are the following:
1670+
1671+
| **Available ADC Pins** |
1672+
|:----------------------:|
1673+
| `P006` |
1674+
| `P005` |
1675+
| `P004` |
1676+
| `P002` |
1677+
| `P001` |
1678+
| `P015` |
1679+
| `P014` |
1680+
| `P000` |
1681+
1682+
#### Initializing the ADC
1683+
1684+
First, to use an ADC of the Portenta C33 board, create an ADC object associated with a specific pin. This pin will be used to read analog values.
1685+
1686+
```python
1687+
from machine import ADC
1688+
1689+
# Create an ADC object on a specific pin
1690+
adc = ADC(pin)
1691+
```
1692+
1693+
#### Reading Analog Values
1694+
1695+
You can read analog values as raw values using the `read_u16()` method. This method returns a raw integer from 0-65535, representing the analog reading.
1696+
1697+
```python
1698+
# Reading a raw analog value
1699+
val = adc.read_u16()
1700+
```
1701+
1702+
#### Practical Example
1703+
1704+
This example demonstrates the use of the `ADC` class to read values from a potentiometer on the Portenta C33 board. First, connect your potentiometer to the Portenta C33 board. One outer pin goes to `GND`, the other to `3V3`, and the middle pin to an analog-capable I/O pin, such as `P006`. This setup creates a variable voltage divider, with the voltage at the center pin changing as you adjust the potentiometer.
1705+
1706+
```python
1707+
from machine import ADC, Pin
1708+
import time
1709+
1710+
# Initialize the ADC on the potentiometer-connected pin
1711+
pot_pin = Pin('P006')
1712+
pot_adc = ADC(pot_pin)
1713+
1714+
while True:
1715+
# Read the raw analog value
1716+
raw_value = pot_adc.read_u16()
1717+
print("- Potentiometer raw value:", raw_value)
1718+
1719+
# Delay for readability
1720+
time.sleep(0.1)
1721+
```
1722+
The example starts by importing the necessary modules and setting up the ADC on a pin connected to a potentiometer (`P006`). The ADC object (`pot_adc`) is used to interface with the potentiometer. Inside the loop, the analog value from the potentiometer is continuously read using the `read_u16()` method that provides a raw integer value scaled between `0` and `65535`, reflecting the potentiometer's position. The analog value value is printed to the console, and a short delay is included in the loop to ensure the output is readable.
1723+
1724+
### Pulse Width Modulation
1725+
1726+
Pulse Width Modulation (PWM) is a method to emulate an analog output using a digital pin. It does this by rapidly toggling the pin between low and high states. Two primary aspects define PWM behavior:
1727+
1728+
- **Frequency**: This is the speed at which the pin toggles between low and high states. A higher frequency means the pin toggles faster.
1729+
- **Duty cycle**: This refers to the ratio of the high state duration to the total cycle duration. A 100% duty cycle means the pin remains high all the time, while a 0% duty cycle means it stays low.
1730+
1731+
The available PWM pins of the Portenta C33 board in MicroPython are the following:
1732+
1733+
| **Available PWM Pins** |
1734+
|:----------------------:|
1735+
| `P105` |
1736+
| `P106` |
1737+
| `P111` |
1738+
| `P303` |
1739+
| `P401` |
1740+
| `P601` |
1741+
1742+
#### Setting Up PWM
1743+
1744+
To use PWM, start by initializing a pin and then creating a PWM object associated with that pin.
1745+
1746+
```python
1747+
import machine
1748+
1749+
# Initialize a pin for PWM (e.g., pin P105)
1750+
p105 = machine.Pin('P105')
1751+
pwm1 = machine.PWM(p105)
1752+
```
1753+
1754+
#### Configuring PWM Parameters
1755+
1756+
The frequency and duty cycle of the PWM signal are set based on the specific needs of your application:
1757+
1758+
```python
1759+
# Set the frequency to 500 Hz
1760+
pwm1.freq(500)
1761+
1762+
# Adjusting the duty cycle to 50 for 50% duty
1763+
pwm1.duty(50)
1764+
```
1765+
1766+
#### Checking PWM Configuration
1767+
1768+
You can check the current configuration of the PWM object by printing it:
1769+
1770+
```python
1771+
# Will show the current frequency and duty cycle
1772+
print(pwm1)
1773+
```
1774+
1775+
Retrieve the frequency and duty cycle values:
1776+
1777+
```python
1778+
current_freq = pwm1.freq()
1779+
current_duty = pwm1.duty()
1780+
```
1781+
1782+
#### Deinitializing PWM
1783+
1784+
When PWM is no longer needed, the pin can be deinitialized:
1785+
1786+
```python
1787+
pwm1.deinit()
1788+
```
1789+
1790+
#### Practical Example
1791+
1792+
In this example, we will use PWM to control the brightness of an LED connected to pin `P105` of the Portenta C33 board.
1793+
1794+
```python
1795+
import machine
1796+
import time
1797+
1798+
# Configure the LED pin and PWM
1799+
led_pin = machine.Pin('P105')
1800+
led_pwm = machine.PWM(led_pin)
1801+
led_pwm.freq(500)
1802+
1803+
# Loop to vary brightness
1804+
while True:
1805+
# Increase brightness
1806+
for duty in range(100):
1807+
led_pwm.duty(duty)
1808+
time.sleep(0.001)
1809+
1810+
# Decrease brightness
1811+
for duty in range(100, -1, -1):
1812+
led_pwm.duty(duty)
1813+
time.sleep(0.001)
1814+
```
1815+
1816+
### Real-Time Clock
1817+
1818+
The `RTC` class in MicroPython provides a way to manage and utilize the Real-Time Clock (RTC) of the Portenta C33 board. This feature is essential for applications that require accurate timekeeping, even when the main processor is not active. The RTC maintains accurate time and date, functioning independently from the main system. It continues to keep track of the time even when the board is powered off, as long as it's connected to a power source like a battery.
1819+
1820+
#### Initializing the RTC
1821+
1822+
To use the RTC, first create an RTC object. This object is then used to set or read the current date and time.
1823+
1824+
1825+
```python
1826+
import machine
1827+
1828+
# Create an RTC object
1829+
rtc = machine.RTC()
1830+
```
1831+
1832+
#### Setting and Getting Date and Time
1833+
1834+
The RTC allows you to set and retrieve the current date and time. The date and time are represented as an 8-tuple format.
1835+
1836+
```python
1837+
# Setting the RTC date and time
1838+
rtc.datetime((2024, 1, 4, 4, 20, 0, 0, 0))
1839+
1840+
# Getting the current date and time
1841+
current_datetime = rtc.datetime()
1842+
print("- Current date and time:", current_datetime)
1843+
```
1844+
1845+
The 8-tuple for the date and time follows the format `(year, month, day, weekday, hours, minutes, seconds, subseconds)`.
1846+
1847+
#### Practical Example
1848+
1849+
A practical use case for the RTC is to add timestamps to sensor data readings. By setting the current time on the RTC, you can then append an accurate timestamp each time a sensor value is logged.
1850+
1851+
```python
1852+
import machine
1853+
1854+
# Initialize the RTC and set the current datetime
1855+
rtc.datetime((2024, 1, 4, 4, 20, 0, 0, 0))
1856+
1857+
# Function to read a sensor value (placeholder)
1858+
def read_sensor():
1859+
# Replace with actual sensor reading logic
1860+
return 42
1861+
1862+
# Read sensor value and get the current time
1863+
sensor_value = read_sensor()
1864+
timestamp = rtc.datetime()
1865+
1866+
# Output the sensor value with its timestamp
1867+
print("- Sensor value at ", timestamp, ":", sensor_value)
1868+
```
1869+
1870+
In this example, every sensor reading is accompanied by a timestamp, which can be crucial for data analysis or logging purposes. The RTC's ability to maintain time independently of the main system's power status makes it reliable for time-sensitive applications.

0 commit comments

Comments
 (0)