Raspberry Pi Pico: руководство по MicroSD-карте с примером логирования данных (MicroPython)

В этом руководстве мы покажем вам, как подключить MicroSD-карту к Raspberry Pi Pico, как создавать, записывать, читать и удалять файлы, а также создадим пример проекта для логирования данных. Raspberry Pi Pico будет программироваться с использованием MicroPython.

Raspberry Pi Pico - руководство по MicroSD-карте с примером логирования данных MicroPython

Использование MicroSD-карты может быть полезно в различных сценариях. Например, для записи большого объема данных в течение длительного периода времени.

Кроме того, вы можете легко извлечь карту из микроконтроллера и перенести данные в другую систему для последующего анализа.

Также это может быть полезно для сохранения файлов конфигурации, которые необходимо периодически изменять, без необходимости модифицировать код, работающий на Raspberry Pi Pico.

Содержание:

В этом руководстве мы рассмотрим следующие темы:

Необходимые условия – прошивка MicroPython

Для прохождения этого руководства вам необходима прошивка MicroPython, установленная на вашу плату Raspberry Pi Pico. Также вам нужна IDE для написания и загрузки кода на плату.

Рекомендуемая IDE для MicroPython на Raspberry Pi Pico – Thonny IDE. Следуйте следующему руководству, чтобы узнать, как установить Thonny IDE, прошить прошивку MicroPython и загрузить код на плату.

Знакомство с модулем MicroSD-карты

Самый простой способ подключить MicroSD-карту к микроконтроллеру – использовать модуль MicroSD-карты. Эти модули обычно включают все необходимые компоненты, такие как стабилизаторы напряжения, преобразователи уровней и подтягивающие резисторы, что упрощает подключение MicroSD-карты к микроконтроллеру.

Модуль MicroSD-карты

Вы можете обмениваться данными с MicroSD-картой, используя протоколы SPI или SDMMC. Протокол SDMMC обычно быстрее, чем SPI, но требует большего количества GPIO и обычно более сложен. На данный момент поддержка SDMMC-коммуникации с Raspberry Pi Pico недостаточна. Поэтому мы будем использовать SPI-протокол для работы с MicroSD-картой.

Модуль MicroSD-карты для Raspberry Pi Pico с интерфейсом SPI

Существуют различные модули MicroSD-карт, совместимые с Raspberry Pi Pico. Мы используем модуль MicroSD-карты, показанный на рисунке выше – он обменивается данными по протоколу SPI. Вы можете использовать любой другой модуль MicroSD-карты с интерфейсом SPI. Некоторые модули MicroSD-карт даже поддерживают оба протокола – SPI и SDMMC.

Необходимые компоненты

Для этого руководства вам понадобятся следующие компоненты:

  • Raspberry Pi Pico

  • Модуль MicroSD-карты

  • MicroSD-карта, которую можно отформатировать в FAT32

  • Макетная плата

  • Соединительные провода

Распиновка модуля MicroSD-карты – SPI-коммуникация

Вы можете подключить MicroSD-карту к любой комбинации SPI-выводов Raspberry Pi Pico. Мы будем использовать выводы, показанные в следующей таблице.

Модуль MicroSD-карты

Raspberry Pi Pico

3V3*

3V3(OUT)

CS

GPIO 5

MOSI (TX)

GPIO 3

CLK/SCK

GPIO 2

MISO (RX)

GPIO 4

GND

GND

* Модуль MicroSD-карты, который мы используем, требует только 3V3. Некоторым модулям может потребоваться 5V. В этом случае вам нужно питать их через вывод VBUS.

Вы также можете использовать следующую схему подключения в качестве справки.

Схема подключения Raspberry Pi Pico к модулю MicroSD-карты

Форматирование MicroSD-карты

Перед тем как продолжить руководство, убедитесь, что вы отформатировали MicroSD-карту в FAT32. Следуйте приведенным ниже инструкциям для форматирования MicroSD-карты или используйте программное обеспечение, такое как SD Card Formatter (совместимо с Windows и Mac OS).

1. Вставьте MicroSD-карту в компьютер. Перейдите в Мой компьютер и щелкните правой кнопкой мыши по SD-карте. Выберите Форматировать… как показано на рисунке ниже.

Форматирование MicroSD-карты Форматирование MicroSD-карты в FAT32 Windows

2. Появится новое окно. Выберите FAT32, нажмите Start, чтобы начать процесс форматирования, и следуйте инструкциям на экране. Через несколько секунд процесс будет завершен.

Загрузка модуля sdcard.py

На данный момент поддержка библиотек для использования MicroSD-карты с Raspberry Pi Pico ограничена. Мы нашли модуль sdcard.py, который отлично справляется с работой с файлами на MicroSD-карте. Следуйте приведенным ниже шагам для установки библиотеки.

  1. Нажмите здесь, чтобы скачать код библиотеки sdcard.py.

  2. Создайте новый файл в Thonny IDE и скопируйте код библиотеки.

  3. Перейдите в File > Save as и выберите Raspberry Pi Pico.

  4. Назовите файл sdcard.py и нажмите OK, чтобы сохранить файл на Raspberry Pi Pico.

Вот и всё. Библиотека загружена на вашу плату. Теперь вы можете использовать функциональность библиотеки в своем коде, импортировав её.

Тестирование MicroSD-карты

Загрузите следующий код на Raspberry Pi Pico, чтобы проверить, может ли он обмениваться данными с MicroSD-картой.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-microsd-card-micropython/

from machine import SPI, Pin
import sdcard, os

# Constants
SPI_BUS = 0
SCK_PIN = 2
MOSI_PIN = 3
MISO_PIN = 4
CS_PIN = 5
SD_MOUNT_PATH = '/sd'

try:
    # Init SPI communication
    spi = SPI(SPI_BUS,sck=Pin(SCK_PIN), mosi=Pin(MOSI_PIN), miso=Pin(MISO_PIN))
    cs = Pin(CS_PIN)
    sd = sdcard.SDCard(spi, cs)
    # Mount microSD card
    os.mount(sd, SD_MOUNT_PATH)
    # List files on the microSD card
    print(os.listdir(SD_MOUNT_PATH))

except Exception as e:
    print('An error occurred:', e)

Предыдущий код запускает SPI-коммуникацию на выводах, к которым подключена MicroSD-карта, пытается смонтировать MicroSD-карту, а затем пытается вывести список файлов на ней.

Если вы используете другие SPI-выводы, вам следует изменить код соответственно. Также обратите внимание, что в зависимости от используемых выводов вам может потребоваться изменить шину SPI. На схеме распиновки Raspberry Pi Pico вы можете увидеть, какие выводы относятся к SPI-шине 1 или 0.

SPI_BUS = 0
SCK_PIN = 2
MOSI_PIN = 3
MISO_PIN = 4
CS_PIN = 5

Примечание

Связанный контент: Raspberry Pi Pico и Pico W: руководство по распиновке GPIOs

Тестирование кода

Запустите предыдущий код на Raspberry Pi Pico, нажав на зеленую кнопку запуска в Thonny IDE.

Запуск кода в Thonny IDE

Вы должны получить похожее сообщение в Shell (см. скриншот ниже). Если это так, значит всё работает как ожидалось. Если нет, проверьте подключение, правильно ли вставлена MicroSD-карта и используете ли вы правильный номер SPI-шины для используемых выводов.

Успешное монтирование MicroSD-карты в Thonny IDE для Raspberry Pi Pico - тестирование

Создание, запись и чтение файлов на MicroSD-карте

Теперь, когда вы знаете, что Raspberry Pi Pico правильно подключен к MicroSD-карте, давайте протестируем некоторые базовые операции с файлами.

Raspberry Pi Pico с MicroSD-картой

Следующий код монтирует MicroSD-карту, создает новый файл, записывает в него данные, а затем читает его содержимое.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-microsd-card-micropython/

from machine import SPI, Pin
import sdcard, os

# Constants
SPI_BUS = 0
SCK_PIN = 2
MOSI_PIN = 3
MISO_PIN = 4
CS_PIN = 5
SD_MOUNT_PATH = '/sd'
FILE_PATH = 'sd/sd_file.txt'

try:
    # Init SPI communication
    spi = SPI(SPI_BUS,sck=Pin(SCK_PIN), mosi=Pin(MOSI_PIN), miso=Pin(MISO_PIN))
    cs = Pin(CS_PIN)
    sd = sdcard.SDCard(spi, cs)
    # Mount microSD card
    os.mount(sd, SD_MOUNT_PATH)
    # List files on the microSD card
    print(os.listdir(SD_MOUNT_PATH))

    # Create new file on the microSD card
    with open(FILE_PATH, "w") as file:
        # Write to the file
        file.write("Testing microSD Card \n")

    # Check that the file was created:
    print(os.listdir(SD_MOUNT_PATH))

    # Open the file in reading mode
    with open(FILE_PATH, "r") as file:
        # read the file content
        content = file.read()
        print("File content:", content)

except Exception as e:
    print('An error occurred:', e)

Сначала импортируем необходимые модули и классы. Нам нужно импортировать классы SPI и Pin из модуля machine, модуль os для работы с файловой системой и sdcard для взаимодействия с MicroSD-картой.

from machine import SPI, Pin
import sdcard, os

Примечание

Модуль os

В MicroPython есть модуль os, который включает широкий набор функций для управления файловыми операциями. Кроме того, он также содержит методы для таких задач, как управление директориями, доступ к переменным окружения и выполнение системных команд. Модуль os включен по умолчанию в прошивку MicroPython. Более подробная информация о модуле os доступна здесь.

Определите выводы SD-карты и номер SPI-шины, которые вы используете, в следующих строках.

SPI_BUS = 0
SCK_PIN = 2
MOSI_PIN = 3
MISO_PIN = 4
CS_PIN = 5

Создайте переменные для хранения пути к SD-карте и пути к файлу, который мы создадим.

SD_MOUNT_PATH = '/sd'
FILE_PATH = 'sd/sd_file.txt'

Затем инициализируйте SPI-коммуникацию и смонтируйте MicroSD-карту.

try:
    # Init SPI communication
    spi = SPI(SPI_BUS,sck=Pin(SCK_PIN), mosi=Pin(MOSI_PIN), miso=Pin(MISO_PIN))
    cs = Pin(CS_PIN)
    sd = sdcard.SDCard(spi, cs)
    # Mount microSD card
    os.mount(sd, SD_MOUNT_PATH)

Выведите список всех файлов в файловой системе SD-карты.

# List files on the microSD card
print(os.listdir(SD_MOUNT_PATH))

Создание файла в MicroPython так же просто, как использование функции open() и передача в качестве аргументов имени файла и режима открытия файла. Функция open() откроет файл, если он уже существует, или создаст новый файл, если его нет.

Различные режимы открытия файла: 'w', 'r' и 'a':

  • 'w': режим записи – позволяет записывать в файл, перезаписывая существующее содержимое;

  • 'r': режим чтения – позволяет читать из существующего файла;

  • 'a': режим добавления – добавляет новые данные в конец существующего файла.

Для создания нового файла мы можем использовать режим записи ('w'). Следующая строка кода создаст новый файл в файловой системе Raspberry Pi Pico с помощью метода open(). Файл называется sd_file.txt (определен ранее в переменной FILE_PATH), но вы можете переименовать его как угодно.

# Create new file on the microSD card
with open(FILE_PATH, "w") as file:

Ключевое слово with используется совместно с файловыми операциями для обеспечения правильного управления ресурсами и упрощения кода. В частности, оно часто используется с функцией open() при работе с файлами.

with open(FILE_PATH, "w") as file:

Этот синтаксис автоматически обрабатывает открытие и закрытие файла, гарантируя, что файл будет правильно закрыт после завершения работы с ним, даже если во время файловых операций возникнет исключение.

Запись в файл очень проста. Вам нужно лишь использовать метод write() для объекта файла и передать в качестве аргумента данные, которые вы хотите записать (это должна быть строка). В нашем примере:

with open(FILE_PATH, "w") as file:
    # Write to the file
    file.write("Testing microSD Card \n")

В предыдущем коде обратите внимание, что мы используем \n в конце первой строки:

file.write("Writing my first line \n")

В Python/MicroPython \n представляет символ новой строки. Он используется для обозначения конца строки в текстовом файле. Это управляющий символ, который обозначает начало новой строки текста. При работе с файлами символ новой строки полезен для форматирования текста. При записи нескольких строк в файл вы используете \n для разделения каждой строки.

После записи в файл давайте откроем его в режиме чтения, чтобы убедиться, что данные действительно были записаны. Для чтения файла используйте метод read() следующим образом.

# Open the file in reading mode
with open(FILE_PATH, "r") as file:
    # read the file content
    content = file.read()
    print("File content:", content)

Запустите предыдущий код на Raspberry Pi Pico. Вы должны получить похожее сообщение в Shell.

Файл MicroSD-карты создан в Thonny IDE

Первая строка означает, что в файловой системе MicroSD-карты нет файлов. Вторая строка показывает файл, который мы создали с помощью кода, под названием sd_file.txt. Наконец, последняя строка показывает содержимое файла sd_file.txt.

Удаление файлов

Удаление файла на MicroSD-карте так же просто, как использование команды os.remove() и передача в качестве аргумента пути к файлу.

Например, вы можете просто добавить следующую строку к предыдущему примеру, чтобы удалить файл sd_file.txt.

# Delete file from the microSD card
os.remove(FILE_PATH)

Полный код представлен ниже:

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-microsd-card-micropython/

from machine import SPI, Pin
import sdcard, os

# Constants
SPI_BUS = 0
SCK_PIN = 2
MOSI_PIN = 3
MISO_PIN = 4
CS_PIN = 5
SD_MOUNT_PATH = '/sd'
FILE_PATH = 'sd/sd_file.txt'

try:
    # Init SPI communication
    spi = SPI(SPI_BUS,sck=Pin(SCK_PIN), mosi=Pin(MOSI_PIN), miso=Pin(MISO_PIN))
    cs = Pin(CS_PIN)
    sd = sdcard.SDCard(spi, cs)
    # Mount microSD card
    os.mount(sd, SD_MOUNT_PATH)
    # List files on the microSD card
    print(os.listdir(SD_MOUNT_PATH))

    # Create new file on the microSD card
    with open(FILE_PATH, "w") as file:
        # Write to the file
        file.write("Testing microSD Card \n")

    # Check that the file was created:
    print(os.listdir(SD_MOUNT_PATH))

    # Open the file in reading mode
    with open(FILE_PATH, "r") as file:
        # read the file content
        content = file.read()
        print("File content:", content)

    # Delete file from the microSD card
    os.remove(FILE_PATH)

    # Check that the file was deleted
    print(os.listdir(SD_MOUNT_PATH))

except Exception as e:
    print('An error occurred:', e)

Мы также снова выводим список содержимого MicroSD-карты, чтобы убедиться, что файл был удален.

Тестирование кода

Запустите предыдущий код на Raspberry Pi Pico. Вы должны увидеть, что файловая система MicroSD-карты в итоге пуста. Это означает, что мы успешно удалили файл sd_file.txt.

Удаление файла с MicroSD-карты - Thonny IDE

Логирование температуры на MicroSD-карту

Логирование данных на MicroSD-карту с помощью Raspberry Pi Pico – это просто. Вам нужно лишь смонтировать MicroSD-карту, а затем использовать правильные пути к файлам для создания файлов и сохранения данных.

Raspberry Pi Pico - логирование данных на MicroSD-карту

Чтобы показать вам, как это делается, мы создадим простой проект, который сохраняет внутреннюю температуру Raspberry Pi Pico на MicroSD-карту каждые 30 секунд. Обратите внимание, что вам необходим пакет picozero, установленный на вашей плате (смотрите это руководство).

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-microsd-card-micropython/

from time import sleep
from machine import Timer, SPI, Pin
from picozero import pico_temp_sensor
import sdcard, os

# Constants
SPI_BUS = 0
SCK_PIN = 2
MOSI_PIN = 3
MISO_PIN = 4
CS_PIN = 5
SD_MOUNT_PATH = '/sd'
FILE_PATH = '/sd/temperature.txt'

# Init SPI communication
spi = SPI(SPI_BUS, sck=Pin(SCK_PIN), mosi=Pin(MOSI_PIN), miso=Pin(MISO_PIN))
cs = Pin(CS_PIN)

def mount_sdcard(spi, cs_pin):
    try:
        sd = sdcard.SDCard(spi, cs_pin)
        # Mount microSD card
        os.mount(sd, SD_MOUNT_PATH)
        # List files on the microSD card
        print(os.listdir(SD_MOUNT_PATH))

    except Exception as e:
        print('An error occurred mounting the SD card:', e)

def log_temperature(timer):
    try:
        # Read the internal temperature sensor value
        temperature = pico_temp_sensor.temp
        # Format temperature
        temperature_string = "{:.2f} °C\n".format(temperature)

        # Write to the file
        with open(FILE_PATH, 'a') as file:
            file.write(temperature_string)
            print("Temperature logged successfully.")
    except Exception as e:
        print('An error occurred accessing the file or getting temperature', e)

# Mount SD card
mount_sdcard(spi, cs)

# Log temperature when the program first runs
log_temperature(None)

# Create a timer that calls log_temperature every 30 seconds
log_timer = Timer(period=30000, mode=Timer.PERIODIC, callback=log_temperature)

# Keep the program running
try:
    while True:
        sleep(0.1)
except KeyboardInterrupt:
    # Clean up and stop the timer on keyboard interrupt
    log_timer.deinit()
    print("Keyboard Interrupt")

Мы начинаем с подключения необходимых библиотек.

from time import sleep
from machine import Timer, SPI, Pin
from picozero import pico_temp_sensor
import sdcard, os

Мы создаем функцию log_temperature(), которая будет отвечать за получение показаний внутренней температуры и запись значения в файл в файловой системе. Затем эта функция будет вызываться прерыванием таймера (поэтому функция должна иметь один параметр для таймера).

def log_temperature(timer):
    try:
        # Read the internal temperature sensor value
        temperature = pico_temp_sensor.temp
        # Format temperature
        temperature_string = "{:.2f} °C\n".format(temperature)

        # Write to the file
        with open(FILE_PATH, 'a') as file:
            file.write(temperature_string)
            print("Temperature logged successfully.")
    except Exception as e:
        print('An error occurred accessing the file or getting temperature', e)

Внутри этой функции мы начинаем с получения показаний внутреннего датчика температуры Pico:

# Read the internal temperature sensor value
temperature = pico_temp_sensor.temp

Затем создаем новую переменную для сохранения температуры в виде строки с двумя десятичными знаками и единицей измерения в градусах Цельсия. Мы также добавляем символ новой строки \n, чтобы новые данные добавлялись на следующую строку.

# Format temperature
temperature_string = "{:.2f} °C\n".format(temperature)

Открываем новый файл в режиме добавления 'a' (мы хотим добавлять новые данные в файл, а не перезаписывать его). Записываем показания температуры в файл.

# Write to the file
        with open(FILE_PATH, 'a') as file:
            file.write(temperature_string)
            print("Temperature logged successfully.")

Затем мы хотим вызвать эту функцию сразу после запуска кода, чтобы не ждать 60 секунд до первой записи, вызванной таймером. Поскольку эта функция ожидает значение, ссылающееся на таймер, мы можем просто передать None, чтобы запустить функцию сразу.

# Log temperature when the program first runs
log_temperature(None)

Настраиваем периодическое прерывание таймера, которое вызывает функцию log_temperature() каждую минуту, таким образом непрерывно логируя данные до тех пор, пока вы не остановите программу.

log_timer = Timer(period=60000, mode=Timer.PERIODIC, callback=log_temperature)

Чтобы наша программа продолжала работать, мы добавляем пустой цикл while, но вы можете добавить в цикл любые другие задачи, и он по-прежнему будет логировать температуру в нужное время.

# Keep the program running
try:
    while True:
        sleep(0.1)

Кроме того, мы также добавили исключение KeyboardInterrupt для остановки таймера, когда программа прерывается пользователем.

except KeyboardInterrupt:
    # Clean up and stop the timer on keyboard interrupt
    log_timer.deinit()
    print("Keyboard Interrupt")

Позвольте коду работать в течение значительного времени, пока вы не получите достаточно данных. Когда будете удовлетворены результатом, остановите программу.

Извлеките MicroSD-карту из Raspberry Pi Pico и откройте её на компьютере, чтобы проверить файл и его содержимое. У вас должен быть файл temperature.txt с записью внутренней температуры Raspberry Pi Pico.

Логирование температуры на MicroSD-карту - Raspberry Pi Pico

Заключение

В этом руководстве вы узнали, как подключить MicroSD-карту к Raspberry Pi Pico, программируемому на MicroPython. Мы рассмотрели, как создать файл, записать в него данные, прочитать данные из файла и как периодически логировать данные с помощью таймера.

Мы надеемся, что это руководство оказалось для вас полезным. Вместо логирования внутренней температуры Pico вы можете логировать данные с других датчиков. У нас есть руководства для других датчиков, которые могут быть вам полезны:

Спасибо за чтение.