Управление на хардуер от Raspberry Pi Невероятно забавно и полезно е, след като овладеете комуникационните му шини. В ежедневната употреба ключовите играчи са UART и I2C: едната е традиционната асинхронна серийна шина; другата е двупроводна синхронна шина, която позволява едновременното свързване на множество устройства. Ето ясно и лесно ръководство за използването им в Raspberry Pi.
В допълнение към обяснението какво представляват и как да ги активирате, Ще видите реални конфигурации на Raspberry Pi. (серийна конзола, пинове, инструменти), практически примери в Python, фини подробности за Bluetooth и mini-UART в определени модели и диагностичен раздел За често срещани грешки, като например ужасяващата грешка при отдалечен вход/изход при смесване на I2C и UART, сме включили и подхода на Windows 10/IoT с RhProxy и ACPI, в случай че работите в тази област.
Какво представляват UART и I2C и защо трябва да ви е грижа?

UART (универсален асинхронен приемник-предавател) Това е асинхронен сериен интерфейс, който предава и приема данни без споделен тактов генератор. Той използва две специални линии: Тексас (доставка) y RX (приемане)Тъй като няма часовник, двата края трябва да се споразумеят за една и съща скорост, т.е. скорост на бод (например, 9600, 115200 bps). В сравнение със SPI или I2C, свързването е по-лесно, въпреки че обикновено е по-бавно и е от точка до точка.
От другата страна имаме I2C (интегрирана схема), синхронен сериен протокол, който работи само с два проводника: S.D.A. (данни) и SCL (часовник). Всяко устройство на шината има 7 или 10-битов уникален адресТова позволява свързването на множество сензори, дисплеи или устройства с памет към едни и същи линии. Поддържа различни скорости (100 kHz стандартна, 400 kHz бърза и по-високи варианти, като например 3.4 Mbps) и мултимастър при определени условия.
На практика, UART е идеален за конзоли, GPS, Bluetooth или микроконтролери които говорят класически сериен сигнал; I2C блести за четене на множество сензори с минимално окабеляване и добра интеграция в проекти Интернет на нещата, роботика и автоматизацияИ двете работят чудесно заедно на Raspberry Pi, стига да конфигурирате правилно техните пинове и да избягвате припокривания.
UART на Raspberry Pi: Настройки на пинове, конзола и ключове

На Raspberry Pi, Основният UART е изложен на GPIO14 (TXD) и GPIO15 (RXD). на 40-пиновия конектор. По подразбиране много системни изображения активирайте серия конзоли Тези пинове са много полезни за дебъгване без монитор или мрежа. В миналото, Broadcom SoC включва два UART-а: UART0 (PL011, завършен) y UART1 (мини-UART, съкратен).
В модели като Raspberry Pi 3, „Добрият“ UART (PL011) е запазен за Bluetooth и конзолата преминава към mini-UART. Това има последствия: mini-UART зависи от честотата на ядрото и за да бъде тя стабилна, обикновено е задайте core_freq=250В противен случай може да се сблъскате с вариации в скоростта на предаване с честотния регулатор и да загубите символи като луди.
Ако искате да използвате UART за вашия проект вместо конзолата, обичайното нещо, което трябва да направите, е деактивирайте серийната конзолаИмате няколко опции: чрез raspi-config в Interfaces > Serial, деактивиране на серийния вход (но запазване на хардуера активиран) или ръчно чрез редактиране /boot/cmdline.txt да изтрия конзола=сериален0,115200 y рестартиранеС това, GPIO пинове 14/15 са свободни за вашето приложение.
Друга много полезна опция е да използвате USB-UART адаптерМного кабели имат четири проводника: червен (5V), черен (GND), бял и зелен (TX/RX). При типична употреба с Raspberry Pi, Не свързвайте червения проводник. (Pi вече е със самостоятелно захранване.) Свържете GND към GND и кръстосайте TX към RX (TX на адаптера към RX на Pi и обратно). Свържете USB края към Pi, за да комуникирате с друга платка или друг Pi чрез... /dev/ttyUSB0 o / dev / ttyACM0.
За да тествате серийната конзола от самия Raspberry Pi, използвайки адаптера, Можете да използвате miniterm.py или друг сериен терминал: miniterm.py /dev/ttyUSB0 115200Ще видите подкана за вход (потребителско име) pi, парола малина (в класическите системи). За да излезете от miniterm в примера с работилницата, използвайте Ctrl + AltGr + ]Ако предпочитате екран: екран /dev/ttyUSB0 115200 и излизаш с Ctrl-A последвано от \.
I2C на Raspberry Pi: активиране, окабеляване и основни инструменти
I2C на Raspberry Pi Той е изложен на физически пинове 3 и 5 на конектора (SDA1 и SCL1, които съответстват на GPIO2 и GPIO3). Първата стъпка е да го активирате. В Raspberry OS отидете на sudo raspi-config и в „Разширени опции“ или „Опции на интерфейса“ активирайте I2CСъветникът предлага да зареди модула при стартиране.
В класическите конфигурации те бяха добавени към / и т.н. / модули линиите i2c-bcm2708 e i2c-devДнешните последни изображения вече обработват наслагвания, но i2c-dev Това остава ключово за потребителското пространство. Инсталирайте помощните програми с: sudo apt актуализация y sudo apt инсталира i2c-tools python-smbus (o python3-smbus (според твоята версия).
За да проверите дали всичко работи, изпълнете lsmod | grep i2c и ще видите заредените модули. След това идентифицирайте шината и я разгледайте с i2cdetect -y 1 (в много стари модели беше -и 0Ако има правилно свързани устройства и с набирания подходящо за SDA и SCL, сканирането ще покаже адреси като 0x48, 0x20И др
Не забравяйте, че I2C шината изисква pull-up резистори в SDA и SCL (при 3.3 V на Pi) и че всички маси трябва да бъдат обединени (обща земя). Липсата на pull-up конектори или дълги/шумни кабели може да причини периодични проблеми или NACK, особено при 400 kHz и нагоре.
Говорейки за I2C от Python (smbus/smbus2)
За да взаимодействате с I2C устройства от Python, можете да използвате смус o smbus2Инсталирайте го, ако е необходимо с pip инсталира smus2Основен пример за писане и четене на адрес 0x48 ще бъде следното:
from smbus2 import SMBus
DEVICE_ADDRESS = 0x48 # Dirección I2C del dispositivo
bus = SMBus(1) # Bus I2C 1 en Raspberry Pi
# Escribir un byte (por ejemplo, 0x01) al dispositivo
bus.write_byte(DEVICE_ADDRESS, 0x01)
# Leer un byte del dispositivo
data = bus.read_byte(DEVICE_ADDRESS)
print(f"Dato leído: {data}")
bus.close()
Този модел на писане/четене Това ви помага да проверите дали устройството реагира. Ако срещнете Грешка в отдалечен вход/изход, обикновено робът Не разпознава адреса или изпратеният запис/транзакция, или Линиите SDA/SCL не са в добро състояние (издърпвания, окабеляване, заземяване или захранване).
UART комуникация с Arduino: USB или GPIO, вие избирате
За да комуникират Raspberry Pi и Arduino серийно, най-директният метод е да USB кабелСвързвате Arduino към Pi и ще се появи порт като този. / dev / ttyACM0 o /dev/ttyUSB0Удобно е и избягва проблеми с нивата и конзолата. Като алтернатива можете да използвате GPIO пинове (хардуерен UART) ако деактивирате серийното влизане с raspi-конфигурация и оставяте хардуера активен.
Инсталирайте серийната библиотека на Python с sudo apt инсталира python3-serial и намерете наличния порт с ls /dev/tty*В Arduino качете проста скица, която изпраща текст:
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("Hello from Arduino!");
delay(1000);
}
На Raspberry Pi, минимален четец с писериален Би изглеждало горе-долу така:
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)
# Espera breve para que Arduino reinicie al abrir el puerto
time.sleep(2)
try:
while True:
if ser.in_waiting > 0:
data = ser.readline().decode('utf-8', errors='ignore').strip()
print(f"Received: {data}")
except KeyboardInterrupt:
ser.close()
За да изпратите данни от Pi към Arduino, просто... ser.write(b"Здравей от Raspberry Pi!\n") и в скицата, прочетена с Serial.readStringUntil('\n')Жизненоважно е, че и двете използват една и съща скорост (бодова скорост) и е препоръчително да изчакате няколко секунди, когато отваряте порта, за да може ATmega да се рестартира и да избегне първоначалния "боклук".
Подходът на Windows 10/IoT: Потребителски API за GPIO, I2C, SPI и UART с RhProxy и ACPI
Ако работите с Windows 10/IoT Core или Windows Enterprise, има механизъм за Отворете GPIO, I2C, SPI и UART в потребителски режим чрез контролер, наречен RhProxyИдеята е да се декларират в таблиците ACPI (ASL/AML) SPB/GPIO ресурсите, които са разрешени за потребителя, а RhProxy ги прави достъпни чрез Windows.Devices.* API. Това е подходът, използван от платки като Raspberry Pi 2/3 в тази екосистема.
Началната точка е да се създаде ACPI възел като Устройство (RHPX) с _HID/_CID «MSFT8000» и _UIDи в рамките на дефинирането на ресурси от тип SPISerialBus, I2C Серийна шина, UARTСерийна шина и GPIO позволено на потребителя. В _DSD свойствата са свързани с такива като bus-SPI-SPI0, SPI0-MinClockInHz, SPI0-MaxClockInHz, SPI0-Поддържани дължини на битовете данни o шина-I2C-I2C1така че API да може да върне „контролер по подразбиране“ за всяка шина.
За I2C, пример за дескриптор би бил нещо подобно I2CSerialBus(… «\_SB.I2C1» …), докато за UART имате UARTСерийна шина с полета на начален бод, паритет, буфери и Източник на ресурс на контролера. В SPI, всеки CE (избор на чип) Той се декларира като отделен ресурс и след това се групира по шина в DSD с индекси на ресурси.
Мощна концепция в тази среда е мултиплексиране на пинове по време на изпълнениеЧрез специални ресурси на ACPI MsftFunctionConfig(), рамките GpioClx, SpbCx y SerCx Те инструктират GPIO контролера да превключи функцията на пиновете, когато клиент отключи устройството (напр. FromIdAsync() (в UWP). Ако пиновете вече са били използвани от друга функция, отварянето се проваля; при затваряне на дескриптора, той връща мултиплексиране.
От гледна точка на разработчика на платформата, валидирането Това включва проверка с devcon че драйверите на SpbCx/GpioClx/SerCx зареждат, че rhproxy съществува в системата (ключ за регистрация на услуга), компилирайте ASL в ACPITABL.dat с asl.exe (начин /MsftInternal за MsftFunctionConfig) и активирайте подписване на тестовеСлед това можете да изброите потребителските устройства с инструменти като I2cTestTool.exe -списък, SpiTestTool.exe -списък, GpioTestTool.exe -списък o MinComm.exe -списъки ги упражнявайте с примерни упражнения за четене/писане. За сертифициране, изпълнете тестовете на HLK (I2C WinRT, GPIO WinRT, SPI WinRT).
Смесване на I2C и UART без грешки: Дистанционна диагностика на входно/изходни връзки и други изненади
Типичен случай: изпълнявате програма, която говори през I2C с IMU сензор (ITG/MPU) и друг, който използва UART с контролер (напр. SSC-32) и изведнъж I2C процесът експлодира с Грешка в отдалечен вход/изходТази грешка показва, че учителят не получава ACK На шината: устройството не отговаря или линиите не са в правилно състояние.
За да излезете от задръстването, проверете следното: 1) Серийната конзола е деактивирана Ако използвате GPIO пинове 14/15 за вашия собствен UART; 2) На Pi 3/деривативи, помислете Деактивиране на Bluetooth Ако имате нужда PL011 UART да е стабилен или поне фиксиран. core_freq=250 ако издърпате mini-UART; 3) Проверете обща маса сред цялото оборудване (Pi, IMU, контролер) и a чисто хранене (IMU са чувствителни към спадове на захранването).
4) Проверете I2C адресиранесканиране с i2cdetect -y 1 и се уверете, че адресът (напр. 0x68/0x69 на много IMU) се появява. Ако не се появи, може да се наложи да използвате грешен автобус, има повреден кабел или набирания5) Проверете скорост на автобуса (Ако използвате 400 kHz и настройката е на платка с дълги кабели, намалете честотата до 100 kHz и тествайте.) 6) Избягвайте колизии при достъп: въпреки че Linux позволява множество процеси на /dev/i2c-1Ако две нишки осъществяват достъп паралелно, без да се координират, можете да предизвикате странни условия; използвайте брави или сериализира операциите.
7) Ако грешката се появи точно когато UART програмата се зареди или увеличи натоварването на процесора, подозирайте мини-UART не е синхронизиран поради мащабиране на честотата (симптом в Pi 3). Фиксирано core_freq=250 en /boot/config.txt или освобождава PL011 за вашия UART 8) Проверете дали Не споделяш пинове Освен други неща: в Windows/IoT, отварянето би се провалило поради мултиплексиране; в Raspberry OS, наслагване или услуга може да държи определени GPIO пинове заети. 9) Накрая, валидирайте физическо окабеляванеSDA с SDA, SCL с SCL, без кръстосване и TX–RX кръстосани последователно.
Бързи тестове и помощни програми, които спасяват положението
За I2C основният тризъбец е: i2cdetect -y 1 за преглед на устройства, i2cget/i2cset за прости четения и записи в регистри и скрипт на smbus2 за валидиране на действителния поток. Ако i2cdetect Не вижда IMU, не си губете времето с кода: Има физически проблем или проблем с наслагването..
За UART използвайте miniterm.py o екран като сериен терминал и проверете дали можете да изпращате/получавате с избраната скорост без никакви странни символи. В Python, писериален с таймаут и кратка начална пауза Обикновено избягва празни показания. И ако работите с Windows IoT, devcon, ACPITABL.dat с asl.exe и примерните инструменти I2cTestTool/SpiTestTool/GpioTestTool/MinComm Те ви дават пълна видимост.
Вече имате пълната карта за работа с I2C и UART. на Raspberry OS (и също на Windows/IoT, ако е приложимо): от това какво представляват и как да ги активирате, до използването им в Python, работа с конзола, UART функции на Pi 3 и мултиплексиране на пинове, до разделителната способност на Грешка 121 Когато комбинирате двете шини, правилно конфигурирани и с чисто окабеляване, те са надеждни инструменти за всеки проект, свързан със сензори, роботика или управление.