CircuitPython на RP2040: что есть
- Поддержка RP2040: CircuitPython официально поддерживает RP2040 (Raspberry Pi Pico, RP2040-Zero и т.д.). Для Waveshare RP2040-Zero вы устанавливаете прошивку CircuitPython (версия 9.x, например, с adafruit.com). Она работает стабильно, включая UART, GPIO, и низкоуровневые операции, нужные для E220.
- UART для E220: E220-400T22D подключается через UART (пины RX/TX для данных, AUX/M0/M1 для управления). CircuitPython имеет модуль
busio.UARTдля работы с UART, что идеально для общения с E220. Пример:uart = busio.UART(board.GP0, board.GP1, baudrate=9600)(для пинов GP0/GP1 на RP2040-Zero). - Сообщество и ресурсы: CircuitPython популярен для IoT, но LoRa-проекты чаще встречаются на Arduino. Adafruit и форумы (Reddit, Discord) имеют примеры для LoRa (обычно для их модулей, вроде RFM95W), которые можно адаптировать под EBYTE.
Состояние библиотек для E220 в CircuitPython
- Прямая поддержка E220: Готовой библиотеки для EBYTE E220 под CircuitPython нет (в отличие от Arduino, где есть EByte_LoRa_E220_Series_Library от Renzo Mischianti). Однако E220 использует стандартный UART-протокол, и вы можете:
1. Портировать Arduino-библиотеку E220 (она открытая, на GitHub). Это требует перевода C++ в Python, но структура простая: отправка/чтение команд по UART + управление пинами M0/M1 для режимов (TX, RX, sleep, config).
2. Использовать низкоуровневый подход: отправлять AT-команды или сырые пакеты через busio.UART. Документация EBYTE (на сайте или в PDF от продавца на AliExpress) дает формат пакетов (например, заголовок + адрес + данные).
- Альтернативы: Библиотека Adafruit_CircuitPython_RFM9x (для LoRa-модулей RFM95/96 на SX1276) частично совместима, так как SX1262 (в E220) и SX1276 похожи по протоколу. Можно адаптировать методы отправки/приема, но настройки (регистры, частота, spreading factor) нужно подогнать под E220 (см. datasheet SX1262).
- Пример кода: На форумах (Reddit, Adafruit Discord) есть примеры для LoRa на CircuitPython с RP2040, но они чаще для RFM95. Для E220 потребуется задать параметры (433 МГц, air rate 2.4 кбит/с, мощность 22 dBm) вручную через UART.
Плюсы и минусы CircuitPython для E220 на RP2040
Плюсы:
- Простота кода: CircuitPython позволяет писать лаконично (например,
uart.write(b"\xC0\x00\x00data")для отправки пакета). - Быстрая разработка: Подключение E220 к RP2040-Zero (GP0=RX, GP1=TX, AUX/M0/M1 к GPIO, питание 3.3V) и базовая отправка/прием данных делаются за пару часов.
- Сообщество: Adafruit и CircuitPython Discord дают поддержку для IoT-задач.
- Низкое потребление: RP2040 + E220 (sleep-режим <10 мкА) подходит для батарейных проектов, а CircuitPython поддерживает deep sleep.
Минусы:
- Нет готовой библиотеки для E220: нужно писать/адаптировать код для управления E220 (режимы, WOR, настройки частоты).
- Ограниченная документация: EBYTE дает datasheet на английском/китайском, но примеров для CircuitPython мало.
- Производительность: CircuitPython медленнее Arduino для реального времени (но для передачи состояний раз в секунду/минуту это не критично).
- Отладка: Ошибки в UART или настройке LoRa (например, неверный spreading factor) требуют чтения datasheet и тестов.
Рекомендации для старта
1. Прошивка: Скачайте CircuitPython для RP2040 с adafruit.com (UF2-файл). Установите, подключив RP2040-Zero в BOOTSEL-режиме. Проверьте версию: import microcontroller; print(microcontroller.cpu).
2. Подключение E220:
- E220 VCC → 3.3V (RP2040-Zero)
- E220 GND → GND
- E220 RX → GP0 (TX на RP2040)
- E220 TX → GP1 (RX на RP2040)
- E220 AUX → GP2 (для статуса передачи)
- E220 M0 → GP3, M1 → GP4 (для режимов: 00=normal, 01=WOR, 11=sleep)
3. Базовый код (пример отправки состояния):
```python:disable-run
import busio
import digitalio
import board
import time
UART для E220
uart = busio.UART(board.GP0, board.GP1, baudrate=9600)
Пины управления
m0 = digitalio.DigitalInOut(board.GP3)
m0.direction = digitalio.Direction.OUTPUT
m1 = digitalio.DigitalInOut(board.GP4)
m1.direction = digitalio.Direction.OUTPUT
aux = digitalio.DigitalInOut(board.GP2)
aux.direction = digitalio.Direction.INPUT
Установить режим Normal (M0=0, M1=0)
m0.value = False
m1.value = False
Отправка состояния
state = {"id": 1, "status": "ON", "temp": 25.5}
data = f"{state['id']}:{state['status']}:{state['temp']}".encode()
Формат пакета E220: заголовок + адрес + канал + данные
packet = b"\xC0\x00\x00" + data # Адрес 0, канал 0 (433 МГц)
uart.write(packet)
print("Sent:", data)
time.sleep(1)
Чтение ответа
while aux.value: # Ждать, пока AUX=0 (готов к приему)
pass
if uart.in_waiting:
received = uart.read(32) # Читать до 32 байт
print("Received:", received)
Это базовый пример для отправки/приема. Для настройки (частота, мощность, SF) отправляйте команды конфигурации (см. datasheet E220, раздел UART-команд).
4. **Адаптация библиотеки**: Возьмите Arduino-библиотеку EByte_LoRa_E220_Series_Library и перепишите ключевые функции (sendFixedMessage, receiveMessage) под CircuitPython, используя `busio.UART` и `digitalio`. Это займет 1-2 дня, если знакомы с Python.
5. **Тесты**: Начните с режима transparent (все модули слышат друг друга). Для адресации задайте уникальные адреса/каналы в настройках E220 (через UART-команды или утилиту EBYTE).
### Альтернатива: Arduino
Если писать библиотеку лень, Arduino на RP2040-Zero проще: библиотека EByte_LoRa_E220_Series_Library уже готова, примеры для RP2040 есть (например, на GitHub и форумах). Установите Arduino IDE, добавьте поддержку RP2040 (Raspberry Pi Pico core), и код типа `LoRa_E220 e220ttl(&Serial1, 4, 2, 3); e220ttl.sendFixedMessage(0, 0, 23, "state:ON", 8);` заработает сразу. Но CircuitPython удобнее для быстрого прототипирования и Python-разработчиков.
### Итог
CircuitPython на RP2040 для E220-400T22D — рабочий вариант, но требует ручной настройки UART и портирования/написания кода для LoRa (около 100-200 строк для базовой отправки/приема состояний). Если готовы потратить день на изучение datasheet и адаптацию, "велосипед" будет минимальным. Для скорости и готовых решений — попробуйте Arduino. Если нужна помощь с кодом, схемой или настройкой (например, WOR для батарейного режима), уточните детали проекта (расстояние, частота передачи, размер данных)!
---------------------------------------
Полный пример кода для EBYTE E220 в CircuitPython
На основе доступной библиотеки ebyte-lora-e220-circuitpython (устанавливается через pip install ebyte-lora-e220-circuitpython), вот полный рабочий пример для RP2040 (например, Waveshare RP2040-Zero). Он включает инициализацию, настройку модуля, отправку и прием сообщений (как строк, так и словарей). Я адаптировал его для вашего случая: использование UART на пинах GP0/GP1, AUX на GP2, M0 на GP3, M1 на GP4.
Библиотека поддерживает режимы Normal, WOR, Deep Sleep, фиксированную/прозрачную передачу, RSSI и шифрование. Для теста используйте два модуля: один как отправитель, другой как получатель.
Требования
- Установите CircuitPython на RP2040 (скачайте UF2 с adafruit.com).
- Подключите E220:
- VCC → 3.3V
- GND → GND
- RX → GP0 (TX UART на RP2040)
- TX → GP1 (RX UART на RP2040)
- AUX → GP2
- M0 → GP3
- M1 → GP4
- Установите библиотеку: скопируйте её в
lib/на устройстве или используйтеpipв Thonny/Mu Editor.
Полный код (code.py)
Сохраните как code.py на устройстве — он запустится автоматически.
import time
import board
import busio
from lora_e220 import LoRaE220, Configuration, ResponseStatusCode
from lora_e220_operation_constant import AirDataRate, UARTParity, UARTBaudRate, TransmissionPower, \
RssiAmbientNoiseEnable, SubPacketSetting, FixedTransmission, WorPeriod, LbtEnableByte, RssiEnableByte
# Инициализация UART (GP0 - TX, GP1 - RX, baudrate=9600 по умолчанию для E220)
uart = busio.UART(board.GP0, board.GP1, baudrate=9600)
# Инициализация LoRa E220 (модель '400T22D' для 433 МГц, 22 dBm; укажите вашу модель)
lora = LoRaE220('400T22D', uart, aux_pin=board.GP2, m0_pin=board.GP3, m1_pin=board.GP4)
# Запуск модуля
code = lora.begin()
print("Инициализация: {}".format(ResponseStatusCode.get_description(code)))
# Получение текущей конфигурации
code, config = lora.get_configuration()
print("Текущая конфигурация: {}".format(ResponseStatusCode.get_description(code)))
print(config.to_string()) # Печать конфигурации в читаемом виде
# Настройка новой конфигурации (пример: адрес 0x0001, канал 23 для 433 МГц, мощность 22 dBm, air rate 9.6 kbps)
config_to_set = Configuration('400T22D')
config_to_set.ADDH = 0x00 # Старший байт адреса
config_to_set.ADDL = 0x01 # Младший байт адреса
config_to_set.CHAN = 23 # Канал (433 МГц + CHAN, от 0 до 83)
config_to_set.SPED.airDataRate = AirDataRate.AIR_DATA_RATE_100_96 # 9.6 kbps для надежности
config_to_set.SPED.uartParity = UARTParity.MODE_00_8N1 # 8N1 (по умолчанию)
config_to_set.SPED.uartBaudRate = UARTBaudRate.BPS_9600 # 9600 бод
config_to_set.OPTION.transmissionPower = TransmissionPower('400T22D').get_transmission_power().POWER_22 # 22 dBm
config_to_set.OPTION.RSSIAmbientNoise = RssiAmbientNoiseEnable.RSSI_AMBIENT_NOISE_DISABLED
config_to_set.OPTION.subPacketSetting = SubPacketSetting.SPS_200_00 # 200 байт пакеты
config_to_set.TRANSMISSION_MODE.fixedTransmission = FixedTransmission.FIXED_TRANSMISSION # Фиксированная передача (по адресу)
config_to_set.TRANSMISSION_MODE.WORPeriod = WorPeriod.WOR_2000_011 # 2000 мс для WOR
config_to_set.TRANSMISSION_MODE.enableLBT = LbtEnableByte.LBT_DISABLED # LBT выкл
config_to_set.TRANSMISSION_MODE.enableRSSI = RssiEnableByte.RSSI_ENABLED # Вкл RSSI
config_to_set.CRYPT.CRYPT_H = 0x00 # Шифрование (ключ, если нужно)
config_to_set.CRYPT.CRYPT_L = 0x00
# Применение конфигурации (временно, сохраняется после power-off)
code, set_config = lora.set_configuration(config_to_set, permanent_configuration=False)
print("Установка конфигурации: {}".format(ResponseStatusCode.get_description(code)))
print(set_config.to_string())
# Пример отправки (как отправитель; закомментируйте для получателя)
# lora.send_fixed_message(0x00, 0x02, 23, "Состояние: ON, Temp: 25.5") # Отправка строки на адрес 0x0002, канал 23
# lora.send_fixed_dict(0x00, 0x02, 23, {"status": "ON", "temp": 25.5}) # Отправка словаря
# print("Сообщение отправлено")
# Цикл приема (как получатель)
while True:
if lora.available() > 0: # Проверка буфера
# Прием строки с RSSI
code, message, rssi = lora.receive_message(rssi=True)
if code == ResponseStatusCode.E220_SUCCESS:
print("Получено: {} (RSSI: {})".format(message, rssi))
else:
print("Ошибка приема: {}".format(ResponseStatusCode.get_description(code)))
# Альтернатива: прием словаря
# code, dict_message, rssi = lora.receive_dict(rssi=True)
# if code == ResponseStatusCode.E220_SUCCESS:
# print("Получено dict: {} (RSSI: {})".format(dict_message, rssi))
time.sleep(0.5) # Пауза для экономии ресурсов
Объяснение
- Инициализация: Создает объект LoRaE220 с UART и пинами управления.
- Конфигурация: Получает текущую, настраивает новую (адрес, частота, мощность, скорость). Параметры сохраняются в модуле.
- Отправка:
send_fixed_messageдля строк по адресу/каналу;send_fixed_dictдля словарей. Для прозрачной передачи (broadcast) используйтеsend_transparent_message. - Прием: Проверяет
available(), получает сообщение с/без RSSI. Для WOR-режима настройтеWORPeriod. - Ошибки: Все операции возвращают код статуса (E220_SUCCESS и т.д.).
Тестирование
- Запустите на двух RP2040: один с отправкой (раскомментируйте), другой с приемом.
- Мониторьте в REPL (Thonny/Mu): увидите конфигурацию и сообщения.
- Для состояний: замените "Состояние: ON, Temp: 25.5" на вашу структуру данных.
- Если RSSI не нужен, уберите
rssi=TrueиenableRSSI.
Если ошибки (например, UART), проверьте пины/baudrate. Для WOR или sleep добавьте lora.set_mode(Mode.WOR_TRANSMITTER) перед отправкой. Библиотека полная, документация на GitHub.
---------- Simple (very) --------
import time
import board
import busio
from lora_e220 import LoRaE220, ResponseStatusCode
Настройка UART (пины GP0 и GP1 для TX/RX)
uart = busio.UART(board.GP0, board.GP1, baudrate=9600)
Инициализация LoRa E220 (модель 400T22D, 433 МГц, 22 dBm)
lora = LoRaE220('400T22D', uart, aux_pin=board.GP2, m0_pin=board.GP3, m1_pin=board.GP4)
Запуск модуля
print("Запуск LoRa...")
code = lora.begin()
if code == ResponseStatusCode.E220_SUCCESS:
print("LoRa готова!")
else:
print("Ошибка запуска:", ResponseStatusCode.get_description(code))
Установка базовых настроек (433 МГц, канал 23, прозрачная передача)
lora.set_configuration_to_default() # Сброс на настройки по умолчанию
print("Настройки установлены")
Основной цикл: отправка и прием сообщений
while True:
Отправка сообщения (раскомментируйте для отправителя)
message = "Состояние: ON"
lora.send_transparent_message(message)
print("Отправлено:", message)
Проверка и прием сообщений
if lora.available() > 0:
code, message = lora.receive_message()
if code == ResponseStatusCode.E220_SUCCESS:
print("Получено:", message)
else:
print("Ошибка приема:", ResponseStatusCode.get_description(code))
time.sleep(1) # Пауза 1 секунда
-------- for EBYTE E220 900M22S ----------------
Да, всё, о чём мы говорили (RP2040-Zero, передача состояний между модулями, CircuitPython с библиотекой ebyte-lora-e220-circuitpython, подключение по UART, примеры кода для отправки/приёма строк или словарей), полностью подойдёт для EBYTE E220-900M22S. Это тот же базовый модуль из серии E220, что и E220-400T22D (на чипе LLCC68 от Semtech, аналог SX1262), но с ключевым отличием: диапазон частот 850–930 МГц (868/915 МГц) вместо 410–493 МГц (433 МГц). Остальные характеристики идентичны: UART-интерфейс, 22 dBm мощность, дальность до 5–7 км в прямой видимости, поддержка WOR/sleep, шифрование и т.д.
Почему всё совместимо
- Аппаратная часть:
- Подключение к RP2040-Zero такое же: VCC/GND на 3.3V, RX/TX к GP0/GP1, AUX к GP2, M0 к GP3, M1 к GP4. Нет нужды в level-shifter'ах или изменениях схемы.
- Антенна: У E220-900M22S обычно IPEX-разъём (SMD-версия, компактная 14x20 мм), так что используйте подходящую антенну для 900 МГц (лучше проникает через стены, чем 433 МГц).
- Программная часть:
- Библиотека
ebyte-lora-e220-circuitpythonработает с любой моделью E220 — просто укажите'900M22S'вместо'400T22D'при инициализации:lora = LoRaE220('900M22S', uart, aux_pin=board.GP2, m0_pin=board.GP3, m1_pin=board.GP4). - Код из предыдущих примеров (упрощённый или полный) копируется 1:1. Единственное изменение: в настройках конфигурации укажите канал (CHAN) для 868/915 МГц. Например:
- Для 868 МГц: CHAN = 0–36 (начальная частота 850 МГц + CHAN).
- Для 915 МГц: CHAN = 65–83 (850 + 65 = 915 МГц).
- Пример:
config_to_set.CHAN = 65для 915 МГц (в полном коде). - В упрощённом коде
set_configuration_to_default()автоматически подхватит диапазон модуля, так что даже не нужно трогать. - Передача состояний: Всё то же — строки ("Состояние: ON"), словари
{"status": "ON", "temp": 25.5}, фиксированная/прозрачная передача, RSSI. Пакеты до 200–240 байт, низкое потребление (<10 мкА в sleep).
Что нужно учесть (маленькие нюансы)
- Частота и регуляции:
- 868 МГц — для Европы/России (лучше для городской среды с препятствиями, но проверьте локальные правила: ISM-диапазон, мощность до 25 mW EIRP).
- 915 МГц — для США/Азии (больше помех от Wi-Fi, но дальность похожая).
- В коде настройте air rate на 2.4–9.6 kbps для надёжности (как в примерах).
- Дальность: Такая же, как у 400T22D (3–5 км реально в помещении/лесу, до 7 км LOS), но на 900 МГц чуть лучше проникаемость через стены.
- SMD-формат: Это SMD-версия (поверхностный монтаж), так что если вы новичок, купите с тестовой платой (E220-900MBL-01, ~$10 на AliExpress) для удобства пайки/прототипа. Она добавляет USB-TTL и STM8 MCU для отладки.
- Цена/покупка: 6–10$ на AliExpress/LCSC. Ищите "EBYTE E220-900M22S" с отзывами (FCC-сертифицирован, надёжный). Datasheet: [скачайте здесь](https://www.lcsc.com/datasheet/lcsc_datasheet_2201210930_Chengdu-Ebyte-Elec-Tech-E220-900M22S_C2971736.pdf) — там все регистры и команды UART.
Пример скорректированного кода (для 915 МГц)
В упрощённом коде добавьте только это после lora.set_configuration_to_default():
# Настройка канала для 915 МГц (CHAN=65)
from lora_e220 import Configuration
config = Configuration('900M22S')
config.CHAN = 65 # 850 + 65 = 915 МГц
lora.set_configuration(config)
print("Канал установлен на 915 МГц")
Для 868 МГц: config.CHAN = 18 (850 + 18 = 868 МГц). Остальное без изменений.
[file-name 000253_2025-10-08_20-42-00.txt]