Disclaimer

Я не верстальщик, а бэкендер - поэтому страницу лучше открывать с компьютера, извините.
Вся документация является собственностью ее авторов и распространяется исключительно в ознакомительных целях.
Данный материал является дополнением к вступительной лекции по АСВТ и не претендует на полноту или научную новизну.
Автор статьи не несет никакой ответственности за поврежденные вами устройства - все что вы делаете - вы делаете на свой страх и риск.

0. Установка библиотек

				apt-get install python3-pip
				apt-get install git
				pip3 install python-periphery
				git clone http://github.com/anaym/hmmio
			

1. Пример: работа с RTC

Попробуем изменить текущее время через отмаппленную память.
Откроем официальную документацию (для H2+) (пароль - MatMeh).
В четвертом разделе System приведено описание "API" доступных устройств.
Нас интересует восьмой подраздел - RTC (страница 171).
Во-первых, нам нужен базовый адрес в памяти: 0x01F00000, а так же длина: 1024 байта.
Во-вторых - оффсет регистра, отвечающий за время (RTC_HH_MM_SS_REG): 0x14.
В-третьих - диапазон бит, отвечающий за HH(HOUR): 20:16.
В-четвертых - Управляющий регистр, бит которого нужно выставить после записи времени.
    LOSC_CTRL_REG RTC_HHMMSS_ACCE: Оффсет - 0x00, Бит - 8:8.
Теперь все готово, чтобы написать нашу первую демонстрационную программу:
				from hmmio import MMIO
				from time import sleep
				
				rtc_mmio = MMIO(0x01F00000, 1024)
									
				print('SSMMHH ' + str(rtc_mmio[0x14:0x20].bytes_array()))
				sleep(1)
				rtc_mmio[0x14][20:16] = 15
				rtc_mmio.writeB(0x00, 8, 8, 1)
				print('SSMMHH ' + str(rtc_mmio.readI(0x14, 12)))
				
				rtc_mmio.close()
			
Так же можно проверить, что время изменилось, выполнив команду timedatectl.

2. Пример: работа с GPIO

У нас в распоряжении есть 20 пинов ввода/вывода общего назначения (GPIO):
UART MODEGPIO MODEP#P#GPIO MODEUART MODE
3.3V01025V
GPIO 1203045V
GPIO 110506GNDUART1 GND
GPIO 60708GPIO 198UART1 TX
UART2 GNDGND0910GPIO 199UART1 RX
UART2 RXGPIO 11112GPIO 7
UART2 TXGPIO 01314GND
GPIO 31516GPIO 19
3.3V1718GPIO 18
GPIO 151920GND
GPIO 162122GPIO 2
GPIO 142324GPIO 13
GND2526GPIO 10
Направление на ETHERNET
Для примера будем переключать состояние светодиода нажатием на аналоговую кнопку.
Соберем следующую схему: GPIO12--[КНОПКА]--GND и GPIO14--[С.ДИОД]--GND.
К сожалению, библиотека используемая в прошлом примере не позволяет "читать" из GPIO.
Поэтому установим еще одну:
				git clone https://github.com/duxingkei33/orangepi_PC_gpio_pyH3
				cd orangepi_PC_gpio_pyH3
				python3 setup.py install
				cd pyA20
			
В папке pyA20 создадим программу и запустим ее как sudo:
		
				from time import sleep
				from pyA20.gpio import gpio
				from pyA20.gpio import port

				d = port.PA14
				i = port.PA12

				gpio.init()
				gpio.setcfg(d, gpio.OUTPUT)
				gpio.setcfg(i, gpio.INPUT)

				d_state = True
				i_state = False

				def read(pin):
				    return gpio.input(pin) == 0

				def write(pin, state):
				    gpio.output(pin, state)

				while True:
				    i_cur = read(i)
				    if not i_state and i_cur:
				        d_state = not d_state
				        write(d, d_state)
				    i_state = i_cur
				    sleep(0.1)
			
Хочется обратить внимание, что возвращаемы уровень сигнала при нажатой кнопке - 0.
Это происходит потому, что мы, нажав кнопку, соединяем pin с землей. Результат (43 Мб).

3. Пример: работа с UART

UART - Универсальный асинхронный приёмопередатчик - узел вычислительных устройств,
    предназначенный для организации связи с другими цифровыми устройствами.
    Самый распространенный пример - RS-232, он же COM-port.
Для того чтобы передать данные по COM-порту нам необходимо понять, как устроено это соединение.
Минимум, у каждого COM-порта есть три пина: RX - вход, TX - выход, GND - земля.
У OPI есть еще три пина для COM порта: они расположены между Ethernet-разъемом и GPIO пинами:
    Ближайший к "краю" платы пин - GND, затем RX и TX. Назовем их UART0.
Для обмена данными, RX одного устройства должен быть подключен к TX другого (и наоборот)
Пожалуйста, отключите ваш OrangePi перед тем как соединять пины!
Соедините UART0.GND с UART1.GND; UART0.TX с UART0.RX; UART0.RX с UART1.TX
После запуска OrangePi введите в консоль команду ls /dev/ | grep tty
На экране отобразится список доступны COM-портов. Скорее всего, среди них будут:
    ttyS0 - UART0, ttyS1 - UART1 и ttyS2 - UART2.
Если этих устройств нет, или повторить пример не получается - изучите лог загрузки системы: например, для lubuntu: cat /var/log/dmesg.0 | grep tty
Теперь можно написать программу, которая будет писать в один COM-порт, а читать - из другого:
			from periphery import Serial
			from time import sleep

			serial = Serial("/dev/ttyS0", 115200)
			serial1 = Serial("/dev/ttyS1", 115200)

			while True:
			    c = input()
			    if c == 'e':
			        break
			    serial.write(bytes(c, 'ASCII'))
			    serial.flush()
			    print('sended ' , c)
			    sleep(1)
			    buf = serial1.read(128, 0.5)
			    print("read %d bytes: _%s_" % (len(buf), buf))
			
Обратите внимание, что несмотря на то, что перед чтением есть задержка - данные читаются без потерь

См. также:

Библиотека на C для OPi