В первом уроке мы заставили светодиод мигать и таким образом научились отправлять единички и нули (логические) на пины GPIO. Во втором уроке по изучению Pi4J, мы узнаем как считывать цифровые данные с GPIO, а для тестирования мы будем подключить кнопку и инфракрасный датчик движения HC-SR501.
Как подключить кнопку
Самый простой способ изменения состояния пина из «1» в «0» и наоборот — это подключить и нажать обычную кнопку.
Схема подключения кнопки
Схема, как мы видим, очень простая и состоит из: Orange Pi, макетной платы, кнопки и двух проводов. Нарисована в fritzing, очень удобная штука, да и красиво выглядит.
Код программы
Если для подачи и снятия рабочего напряжения на пины GPIO используется интерфейс GpioPinDigitalOutput
, то для чтения используется GpioPinDigitalInput
.
import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalInput; import com.pi4j.io.gpio.OrangePiPin; import com.pi4j.io.gpio.PinMode; import com.pi4j.io.gpio.PinPullResistance; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent; import com.pi4j.io.gpio.event.GpioPinListenerDigital; import com.pi4j.platform.Platform; import com.pi4j.platform.PlatformManager; import com.pi4j.util.Console; public class PushButton { public static void main(String[] args) { try { /* * Поскольку мы не используем платформу Raspberry Pi, мы должны явно * указывать платформу, в нашем случае - это Orange Pi. */ PlatformManager.setPlatform(Platform.ORANGEPI); /* * Создаём экземпляр консоли */ Console console = new Console(); /* * Позволяем пользователю выйти из программы с помощью CTRL-C */ console.promptForExit(); /* * Создаём экземпляр контроллера GPIO */ GpioController gpio = GpioFactory.getInstance(); /* * настройка вывода GPIO.23, задаём режим входа и включаем подтягивающий * резистор в "1" */ GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin( OrangePiPin.GPIO_23, // Номер пина по WiringPi "Кнопка", // Имя пина (необязательный) PinPullResistance.PULL_UP); // включаем подтягивающий (необязательный) /* * настроика поведения выключения */ myButton.setShutdownOptions( true, // освобождаем пин PinState.LOW, // задаём состояние 0 PinPullResistance.OFF, // отключаем подтягивающий резистор PinMode.DIGITAL_INPUT);// установливаем режим входа /* * Это объект, который "слушает" и исполняет код в зависимости от события. */ myButton.addListener(new GpioPinListenerDigital() { @Override public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { if (event.getState() == PinState.LOW) { System.out.println(" --> Кнопка нажата: " + event.getPin() + " = " + event.getState()); } else { System.out.println(" --> Кнопка не нажата: " + event.getPin() + " = " + event.getState()); } } }); /* * ждёт, пока пользователь нажмёт CTRL-C */ console.waitForExit(); gpio.shutdown(); } catch (Exception e) { e.printStackTrace(); } } }
Чтобы проверить данный код нужно:
- создать java файл, вставить код (в PuTTY это делается правой кнопкой мыши) и сохранить файл (CTRL+X, Y, ENTER);
nano PushButton.java
- скомпилировать этот файл;
javac -classpath .:classes:/opt/pi4j/lib/'*' -d . PushButton.java
- запустить программу.
sudo java -classpath .:classes:/opt/pi4j/lib/'*' PushButton
Результат
Как подключить HC-SR501
Подключить кнопку и нажать её — это хорошо, но давайте попробуем что-то поинтереснее, к примеру, датчик движения и присутствия — HC-SR501. Более того мы подключим светодиод и включим его, когда датчик обнаружит играющегося кота. Всё это можно сделать и без этих одноплатных компьютеров, но мы-то не ищем лёгких путей.
Схема подключения HC-SR501
Код программы
import com.pi4j.io.gpio.GpioController; import com.pi4j.io.gpio.GpioFactory; import com.pi4j.io.gpio.GpioPinDigitalInput; import com.pi4j.io.gpio.GpioPinDigitalOutput; import com.pi4j.io.gpio.GpioPinShutdown; import com.pi4j.io.gpio.OrangePiPin; import com.pi4j.io.gpio.PinMode; import com.pi4j.io.gpio.PinPullResistance; import com.pi4j.io.gpio.PinState; import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent; import com.pi4j.io.gpio.event.GpioPinListenerDigital; import com.pi4j.io.gpio.impl.GpioPinShutdownImpl; import com.pi4j.platform.Platform; import com.pi4j.platform.PlatformManager; import com.pi4j.util.Console; public class PushButtonHcSr501 { /** * @param args */ public static void main(String[] args) { try { /* * Поскольку мы не используем платформу Raspberry Pi, мы должны явно * указывать платформу, в нашем случае - это Orange Pi. */ PlatformManager.setPlatform(Platform.ORANGEPI); /* * Создаём экземпляр консоли */ Console console = new Console(); /* * Позволяем пользователю выйти из программы с помощью CTRL-C */ console.promptForExit(); /* * Создаём экземпляр контроллера GPIO */ GpioController gpio = GpioFactory.getInstance(); /* * настройка вывода GPIO.23, задаём режим входа и включаем подтягивающий * резистор в "1" */ GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin( OrangePiPin.GPIO_23, // Номер пина по WiringPi "HC-SR501", // Имя пина (необязательный параметр) PinPullResistance.PULL_UP); // включаем подтягивающий (необязательный // параметр) /* * настройка вывода GPIO.24, задаём режим выхода и установливаем значение * LOW при запуске */ GpioPinDigitalOutput myLed = gpio.provisionDigitalOutputPin( OrangePiPin.GPIO_24, // Номер пина по WiringPi "Светодиод", // Имя пина (необязательный параметр) PinState.LOW); // Состояние пина при запуске (необязательный параметр) GpioPinShutdown pinShutdown = new GpioPinShutdownImpl(); /* * установливаем режим входа */ pinShutdown.setMode(PinMode.DIGITAL_INPUT); /* * отключаем подтягивающий резистор */ pinShutdown.setPullResistor(PinPullResistance.OFF); /* * задаём состояние "0" */ pinShutdown.setState(PinState.LOW); /* * освобождаем пин */ pinShutdown.setUnexport(true); /* * настроика поведения выключения */ myLed.setShutdownOptions(pinShutdown); myButton.setShutdownOptions(pinShutdown); /* * Это объект, который "слушает" и исполняет код в зависимости от события. */ myButton.addListener(new GpioPinListenerDigital() { @Override public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) { System.out.println(" --> Состояние пина: " + event.getPin() + " = " + event.getState()); /* * Включаем/выключаем светодиод */ myLed.setState(event.getState()); } }); /* * ждёт, пока пользователь нажмёт CTRL-C */ console.waitForExit(); gpio.shutdown(); } catch (Exception e) { e.printStackTrace(); } } }
Проверяем код:
- создаём java файл и вставляем код;
nano PushButtonHcSr501.java
- компилируем файл;
javac -classpath .:classes:/opt/pi4j/lib/'*' -d . PushButtonHcSr501.java
- запускаем программу.
sudo java -classpath .:classes:/opt/pi4j/lib/'*' PushButtonHcSr501
Результат
Удачи! Если у вас возникнут какие-то вопросы, пишите, буду рад вам помочь.
При подключении к Orange Pi Zero к пину OrangePiPin.GPIO_01 и на некоторых других пинах (10, 4, 1, 5) в коде с кнопкой выдает ошибку «Unable to open GPIO edge interface for pin 1: Permission denied» (Даже если запускать от sudo), но на некоторых пинах работает. Подскажите пожалуйста, как заставить работать код?
Я думаю тут несколько вариантов:
1. На Orange pi Zero нужно установить правильный WiringPi, пробуйте этот вариант:
2. Также может выть, что пины (10, 4, 1, 5) имеют другое назначение, допустим настроены как I2C, SPI или UART, но слабо верится, потому что они общего назначения и должны работать как обычные цифровые пины.
3. Возможно Pi4J не настроили для работы с Orange Pi Zero, работают только некоторые пины.
Можете сделать цикл и проверить все пины, при использовании которых не выдаётся эта ошибка.
Нашёл у одного индуса вот такой пример:
он использует пины
OrangePiPin.GPIO_00
иOrangePiPin.GPIO_07
и вроде работает.https://www.weargenius.in/orange-pi-zero-gpio-programming-using-java/
К сожалению у меня нету Orange Pi Zero и не могу проверять работоспособность Pi4J, на Orange Pi PC всё работает нормально.
Главные новости мира https://ua-vestnik.com и страны: политика, экономика, спорт, культура, технологии. Оперативная информация, аналитика и эксклюзивные материалы для тех, кто следит за событиями в реальном времени.