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]