Raspberry Pi и Pi4J. Урок 1. Мигающий светодиод

В этой статье показано как с помощью одноплатного компьютера и Pi4J сделать мигающий светодиод. Можно сказать, что это первый «урок для начинающих» из этой серии.

Проект Pi4J — это мост между оборудованием Raspberry Pi и Java с объектно-ориентированным подходом. Pi4J — проект с открытым исходным кодом. В дополнение к базовым функциональным возможностям доступа к аппаратным средствам, этот проект также пытается предоставить набор расширенных функций, которые делают работу с Raspberry Pi простой в использовании и более удобной для Java-разработчиков.

И так, для начала нужно установить библиотеки Pi4J на ваш компьютер. Pi4J поддерживает следующие платы: Raspberry Pi, Banana Pi, Banana Pro, Synovoip BPI, Odroid, Orange Pi и NanoPi. По умолчанию Pi4J настроен под Raspberry Pi.

Необходимые компоненты

Чтобы зажечь светодиод понадобится:

  1. одноплатный компьютер (в моём случае — это Orange Pi PC);
  2. светодиод;
  3. резистор 220 Ом.

Подключение светодиода

Raspberry Pi и Pi4J. Урок 1. Мигающий светодиод (Fritzing - Orange Pi One + LED)

Мы подключаем резистор сопротивлением 220 Ом к выходу номер 24 (GPIO.24), к резистору в свою очередь подключаем анод (обычно длинная ножка) светодиода. Катод подсоединяем к земле (GND или 0v).Orange Pi (H3 Soc) GPIO - pinout (Raspberry Pi и Pi4J. Урок 1. Мигающий светодиод)
определить какой пин 24-й, так это колонка wpi после выполнения gpio readall.
Orange Pi PC (H3 Soc) GPIO - gpio readall (Raspberry Pi и Pi4J. Урок 1. Мигающий светодиод)

Инициализация компонентов

Если у вас есть Raspberry Pi, тогда вам не надо выбирать платформу. У меня Orange Pi PC, по этому я должны явно указывать платформу — Orange Pi.

PlatformManager.setPlatform(Platform.ORANGEPI);

Перед взаимодействием с Pi4J мы должны сначала создать экземпляр контроллера GPIO. GpioFactory включает метод getInstance для создания контроллера GPIO. Проект будет содержать только один экземпляр контроллера GPIO, так как паттерн Singleton гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.

final GpioController gpio = GpioFactory.getInstance();

Чтобы получить доступ к пинам GPIO, мы должны сначала обеспечить нужный пин. С помощью методов provisionDigitalOutputPin мы можем настроить пин в режиме выхода, задать имя и состояние пина при запуске (0 или 1).

GpioPinDigitalOutput myLed = gpio.provisionDigitalOutputPin(
		OrangePiPin.GPIO_24, // Номер пина по WiringPi
		"Светодиод", // Имя пина (необязательный)
		PinState.LOW); // Состояние пина при запуске (необязательный)

Pi4J обеспечивает реализацию для автоматического задания состояний выводов GPIO, когда приложение завершает работу. К примеру, нам нужно освободить пин, установить в режим входа, отключить подтягивающий резистор и задать состояние LOW (0), чтобы вернуть пин в исходное состояние.

myLed.setShutdownOptions(
		true, // освобождаем пин
		PinState.LOW, // задаём состояние 0
		PinPullResistance.OFF, // отключаем подтягивающий резистор
		PinMode.DIGITAL_INPUT);// установливаем режим входа

Если необходимо исполнять какой-то код во время изменения состояния пина (из 0 в 1 или наоборот), тогда нужно создать «слушатель». Обычно они нужны в случае подключения, к примеру, кнопки или датчика движения. В этом примере мы просто будем выводить в консоль имя и состояние пина.

myLed.addListener(new GpioPinListenerDigital() {
	@Override
	public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
		System.out.println(" --> Состояние пина: " + event.getPin() + " = " + event.getState());
	}
});

Интерфейс GpioPinDigitalOutput

Интерфейс GpioPinDigitalOutput содержит методы для подачи (логический «1«) или снятия (логический «0«) рабочего напряжения на пины GPIO. Все методы этого интерфейса описаны ниже.

void high();

отправляет на цифровой вывод значение HIGH.

void low();

отправляет на цифровой вывод значение LOW.

void toggle();

отправляет на цифровой вывод значение HIGH, если текущее значение LOW или LOW — если HIGH.

Future<?> blink(long delay);

непрерывно отправляет на цифровой вывод значение HIGH и LOW.
Параметры:

  • long delay — интервал в миллисекундах;
Future<?> blink(long delay, PinState blinkState);

непрерывно отправляет на цифровой вывод значение HIGH и LOW.
Параметры:

  • long delay — интервал в миллисекундах;
  • PinState blinkState — начальное значение: PinState.LOW или PinState.HIGH.
Future<?> blink(long delay, long duration);

отправляет на цифровой вывод значение HIGH и LOW.
Параметры:

  • long delay — это интервал в миллисекундах;
  • long duration — продолжительность в миллисекундах.
Future<?> blink(long delay, long duration, PinState blinkState);

отправляет на цифровой вывод значение HIGH и LOW.
Параметры:

  • long delay — это интервал в миллисекундах;
  • long duration — продолжительность в миллисекундах;
  • PinState blinkState — начальное значение: PinState.LOW или PinState.HIGH.
Future<?> pulse(long duration);

отправляет на цифровой вывод значение HIGH.
Параметры:

  • long duration — продолжительность в миллисекундах.
Future<?> pulse(long duration, Callable<Void> callback);

отправляет на цифровой вывод значение HIGH.
Параметры:

  • long duration — продолжительность в миллисекундах;
  • Callable<Void> callback — задача, которая будет выполняться по истечению времени duration.
Future<?> pulse(long duration, boolean blocking);

отправляет на цифровой вывод значение HIGH.
Параметры:

  • long duration — продолжительность в миллисекундах;
  • boolean blockingtrue блокирует текущий поток на время выполнения импульса и false — запуск импульса в отдельный поток (в фоновом режиме).
Future<?> pulse(long duration, boolean blocking, Callable<Void> callback);

отправляет на цифровой вывод значение HIGH.
Параметры:

  • long duration — продолжительность в миллисекундах;
  • boolean blockingtrue блокирует текущий поток на время выполнения импульса и false — запуск импульса в отдельный поток (в фоновом режиме);
  • Callable<Void> callback — задача, которая будет выполняться по истечению времени duration.
Future<?> pulse(long duration, PinState pulseState);

отправляет на цифровой вывод значение.
Параметры:

  • long duration — это продолжительность в миллисекундах;
  • PinState pulseState — это, непосредственно, значение PinState.LOW или PinState.HIGH.
Future<?> pulse(long duration, PinState pulseState, Callable<Void> callback);

отправляет на цифровой вывод значение.
Параметры:

  • long duration — продолжительность в миллисекундах;
  • PinState pulseState — значение PinState.LOW или PinState.HIGH;
  • Callable<Void> callback — задача которая будет выполняться по истечению времени duration.
Future<?> pulse(long duration, PinState pulseState, boolean blocking);

отправляет на цифровой вывод значение.
Параметры:

  • long duration — продолжительность в миллисекундах;
  • PinState pulseState — значение PinState.LOW или PinState.HIGH;
  • boolean blockingtrue блокирует текущий поток на время выполнения импульса и false — запуск импульса в отдельный поток (в фоновом режиме).
Future<?> pulse(long duration, PinState pulseState, boolean blocking, Callable<Void> callback);

отправляет на цифровой вывод значение.
Параметры:

  • long duration — продолжительность в миллисекундах;
  • PinState pulseState — значение PinState.LOW или PinState.HIGH;
  • boolean blockingtrue блокирует текущий поток на время выполнения импульса и false — запуск импульса в отдельный поток (в фоновом режиме);
  • Callable<Void> callback — задача которая будет выполняться по истечению времени duration.
void setState(PinState state);

отправляет на цифровой вывод значение HIGH и LOW.
Параметры:

  • PinState pulseState — значение PinState.LOW или PinState.HIGH;
void setState(boolean state);

отправляет на цифровой вывод значение HIGH и LOW.
Параметры:

  • boolean state — значение true или false.

Future — это интерфейс для получения результатов работы асинхронной операции. Ключевым методом здесь является метод get, который блокирует текущий поток (с таймаутом или без) до завершения работы асинхронной операции в другом потоке. Также, дополнительно существуют методы для отмены операции и проверки текущего статуса.

Мигающий светодиод — примеры

Мигать светодиодом можно несколькими способами. Первый способ — используя методы void high(); и void low(); — зажигаем и выключаем светодиод соответственно.

for (int i = 0; i < 10; i++) {
	myLed.high();
	Thread.sleep(500);
	myLed.low();
	Thread.sleep(500);
}

Второй способ — используя методы void setState(PinState state); и void setState(boolean state); — задаёт состояние пина в зависимости от значения параметра arg0: true и false или PinState.LOW и PinState.HIGH.

for (int i = 0; i < 10; i++) {
	myLed.setState(true);
	Thread.sleep(500);
	myLed.setState(PinState.LOW);
	Thread.sleep(500);
}

Третий способ — используя метод void toggle();. Этот метод работает как переключатель, если пин в состоянии «1», тогда меняет её в «0» и наоборот.

for (int i = 0; i < 20; i++) {
	myLed.toggle();
	Thread.sleep(500);
}

Четвёртый способ — используя методы Future<?> blink(long delay);. Как по мне, так это самый интересный способ мигать светодиодом. К примеру, нам нужно мигать непрерывно светодиодом пока программа запущена.

Future<?> future = myLed.blink(500);

Или непрерывно мигать в течении некоторого времени.

// непрерывно мигает светодиод каждые 1/2 секунды в течение 15 секунд
Future<?> future = myLed.blink(500, 15000);
// Ждём окончания мигания
while (!future.isDone()) {
	Thread.sleep(50);
}

Завершение программы

Метод shutdown() остановливает все действия/потоки GPIO, выключив контроллер GPIO, другими словами, этот метод будет принудительно отключать все потоки мониторинга GPIO и задачи.

gpio.shutdown();

Пример Java программы

Ниже привёл пример программы «мигающий светодиод» с использованием функции Future<?> blink(long arg0, long arg1);. Программа непрерывно мигает светодиод каждые 1/4 секунды в течение 3 секунд.

import java.util.concurrent.Future;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
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;

public class LedBlinking {
  public static void main(String[] args) {
    try {
      /*
       * Поскольку мы не используем платформу Raspberry Pi, мы должны явно
       * указывать платформу, в нашем случае - это Orange Pi.
       */
      PlatformManager.setPlatform(Platform.ORANGEPI);

      /*
       * Создаём экземпляр контроллера GPIO
       */
      final GpioController gpio = GpioFactory.getInstance();

      /*
       * настройка вывода GPIO.24, задаём режим выхода и установливаем значение
       * LOW при запуске
       */
      GpioPinDigitalOutput myLed = gpio.provisionDigitalOutputPin(
          OrangePiPin.GPIO_24, // Номер пина по WiringPi
          "Светодиод", // Имя пина (необязательный)
          PinState.LOW); // Состояние пина при запуске (необязательный)

      /*
       * настроика поведения выключения
       */
      myLed.setShutdownOptions(
          true, // освобождаем пин
          PinState.LOW, // задаём состояние 0
          PinPullResistance.OFF, // отключаем подтягивающий резистор
          PinMode.DIGITAL_INPUT);// установливаем режим входа

      /*
       * Это объект, который "слушает" и исполняет код в зависимости от события.
       */
      myLed.addListener(new GpioPinListenerDigital() {
        @Override
        public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
          System.out.println(" --> Состояние пина: " + event.getPin() + " = " + event.getState());
        }
      });

      // непрерывно мигает светодиод каждые 1/4 секунды в течение 3 секунд
      Future<?> future = myLed.blink(250, 3000);
      // ждёт окончания мигания
      while (!future.isDone()) {
        Thread.sleep(50);
      }
      gpio.shutdown();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Как скомпилировать Java файла

Для компиляции этой программы используйте следующую команду:

javac -classpath .:classes:/opt/pi4j/lib/'*' -d . LedBlinking.java

Как запуск class файла

Следующая команда запустит этот пример программы:

sudo java -classpath .:classes:/opt/pi4j/lib/'*' LedBlinking

Результат

Raspberry Pi и Pi4J. Урок 1. Мигающий светодиод - результат

Похожие записи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *