Raspberry Pi и Pi4J. Урок 9. Работа с Аналого-Цифровым Преобразователем/АЦП ADS1115

Чтобы считать напряжение и преобразовать его к осязаемому цифровому значению используется аналого-цифровой преобразователь (AЦП). В мини-компьютерах Raspberry Pi, Banana Pi, Orange Pi, Nano Pi и др. отсутствуют встроенные АЦП, поэтому для чтения аналоговых сигналов потребуется внешний АЦП. Один из них — это Аналого-Цифровой Преобразователь/АЦП ADS1115.

ADS1115 — это 4-х канальный 16-битный аналого-цифровой преобразователь (АЦП). Преобразователь разработан для обеспечения точности, энергоэффективности, простоты в реализации, выполняет преобразование с программируемыми скоростями обработки данных. Встроенный усилитель с программируемым коэффициентом усиления (PGA), что позволяет проводить точные измерения больших и малых напряжений. ADS1115 имеет входной мультиплексор (MUX), который позволяет выполнять два дифференциальных или четыре несимметричных входных измерения.

В Pi4J есть библиотека для работы с АЦП ADS1115 по I2C/TWI из Java на Raspberry Pi, Banana Pi, Orange Pi, Nano Pi и Odroid. Все классы и интерфейсы находятся в пакете com.pi4j.gpio.extension.ads.*;.

Пока не все возможности АЦП модулей ADS1x15 реализованы, например, нельзя дифференциально измерять напряжение между входами модуля, доступно только измерение относительно земли (GND). Также не реализована возможность использования пина ALERT/READY, используя GPIO для уведомления о событиях. Это было бы более эффективно, чем постоянный опрос доступности данных.

Класс ADS1x15GpioProvider

Это абстрактный класс, что реализует общие методы аналого-цифровых преобразователей серии ADS1x15, ADS1015 и ADS1113/ADS1114/ADS1115.

ADS1x15GpioProvider(int, int)

Конструктор класса.

public ADS1x15GpioProvider(int busNumber, int address) throws UnsupportedBusNumberException, IOException

Параметры
busNumber — номер шины.
address — I2C адрес устройства.
Возвращает
новый экземпляр ADS1x15GpioProvider
Бросает
UnsupportedBusNumberException — если данный номер шины не поддерживается базовой системой.
IOException — если сообщение с шиной I2C не работает.

ADS1x15GpioProvider(I2CBus, int)

Конструктор класса.

public ADS1x15GpioProvider(I2CBus bus, int address) throws IOException

Параметры
bus — I2C шина.
address — I2C адрес устройства.
Возвращает
новый экземпляр ADS1x15GpioProvider
Бросает
IOException — если сообщение с шиной I2C не работает.

getProgrammableGainAmplifier(Pin)

Возвращает коэффициент усиления внутреннего усилителя (PGA).

public ProgrammableGainAmplifierValue getProgrammableGainAmplifier(Pin pin)

Параметры
pin — номер пина АЦП.
Возвращает
экземпляр ProgrammableGainAmplifierValue — Коэффициент усиления внутреннего усилителя (PGA).

setProgrammableGainAmplifier(ProgrammableGainAmplifierValue, Pin…)

Настройка коэффициента усиления внутреннего усилителя (PGA).

public void setProgrammableGainAmplifier(ProgrammableGainAmplifierValue pga, Pin...pin)

Параметры
pga — коэффициент усиления внутреннего усилителя (PGA).
pin — номер пина/пинов АЦП.

getEventThreshold(Pin)

Возвращает заданный пину порог события.

public double getEventThreshold(Pin pin)

Параметры
pin — номер пина АЦП.
Возвращает
порог события

setEventThreshold(double, Pin…)

Задаёт минимальное значение порога срабатывания события/й. Другими словами, событие срабатывает, если разница между предыдущим и текущим измерением больше заданного значения.

public void setEventThreshold(double threshold, Pin...pin)

Параметры
threshold — минимальное значение порога срабатывания события/й.
pin — пин АЦП.

getMonitorInterval()

Метод возвращает интервал обновления потока мониторинга (в миллисекундах).

public int getMonitorInterval()

setMonitorInterval(int)

Метод задаёт интервал обновления потока мониторинга (в миллисекундах). Это определяет скорость, с которой контрольный поток будет считывать входные значения из чипа АЦП (значение менее 50 мс не разрешено, по умолчанию — 100 мс).

public void setMonitorInterval(int monitorInterval)

Параметры
monitorInterval — интервал обновления потока мониторинга (в миллисекундах).

getImmediateValue(Pin)

Метод используется «монитором» (ADCMonitor), чтобы получить текущее напряжение с указанного пина АЦП. Напряжение измеряется между одним из входов и общим проводом (GND), а дифференциальное измерение библиотека не поддерживает.

public double getImmediateValue(Pin pin) throws IOException

Параметры
pin — пин АЦП.
Возвращает
текущее значение от АЦП.
Бросает
IOException — если сообщение с шиной I2C не работает.

ADCMonitor

Этот класс/поток используется для активного мониторинга прерываний GPIO. Монитор запускается при создании экземпляра класса ADS1x15GpioProvider.

private class ADCMonitor extends Thread {}

Класс ADS1115GpioProvider

Этот GPIO провайдер расширяет абстрактный класс ADS1x15GpioProvider и реализует интерфейс GpioProvider, для работы с пинами АЦП ADS1115, как с родными пинами Pi4J.

ADS1115GpioProvider(int, int)

Конструктор класса.

public ADS1115GpioProvider(int busNumber, int address) throws UnsupportedBusNumberException, IOException

Параметры
busNumber — номер шины.
address — I2C адрес устройства.
Возвращает
новый экземпляр ADS1115GpioProvider
Бросает
UnsupportedBusNumberException — если данный номер шины не поддерживается базовой системой.
IOException — если сообщение с шиной I2C не работает.

ADS1115GpioProvider(I2CBus, int)

Конструктор класса.

public ADS1115GpioProvider(I2CBus bus, int address) throws IOException

Параметры
bus — I2C шина.
address — I2C адрес устройства.
Возвращает
новый экземпляр ADS1115GpioProvider
Бросает
IOException — если сообщение с шиной I2C не работает.

Класс ADS1115Pin

Класс ADS1115Pin содержит 4 экземпляра пинов АЦП ADS1115: INPUT_A0, INPUT_A1, INPUT_A2 и INPUT_A3.

createAnalogInputPin(int, String)

С помощью этого метода можно создать собственный аналоговый пин. Различие между пином по умолчанию и собственным лишь в том, что второму можно задать имя.

private static Pin createAnalogInputPin(int address, String name)

Параметры
address — номер пина (0-3).
name — имя пина.
Возвращает
новый экземпляр Pin

Подключение АЦП ADS1115 к Orange Pi PC

Поскольку эта библиотека не поддерживает дифференциальное измерение, я привёл только один пример, напряжение измеряется между одним из входов и общим проводом (GND).

Схема подключения ADS1115 к Orange Pi

Можно подключить по одному переменному резистору на каждый вход датчика, если хотите проверить все входы. АЦП ADS1115 подключён к порту номер 1, так как адрес 0x48 на порту 0 резервирован. Но можно менять адрес АЦП с помощью пина ADDR и подключить устройство на порт 0.

Схема подключения АЦП ADS1115 к Orange Pi

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

Приведённая ниже программа считывает данные с датчика и выводит результаты в терминал. Обратите внимание на следующую строку:

gpioProvider.setEventThreshold(500, ADS1115Pin.ALL);

я установил порог в 500 (макс.: ‭32767‬). Если вам нужно, чтобы событие сработало при любом изменении значений с датчика, тогда установите 0 вместо 500:

gpioProvider.setEventThreshold(0, ADS1115Pin.ALL);

Пример кода:

import java.io.IOException;
import java.text.DecimalFormat;

import com.pi4j.gpio.extension.ads.ADS1115GpioProvider;
import com.pi4j.gpio.extension.ads.ADS1115Pin;
import com.pi4j.gpio.extension.ads.ADS1x15GpioProvider.ProgrammableGainAmplifierValue;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinAnalogInput;
import com.pi4j.io.gpio.event.GpioPinAnalogValueChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerAnalog;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CFactory.UnsupportedBusNumberException;

public class ADS1115Example {

  /**
   * @param args
   */
  public static void main(String[] args) {
    try {
      System.out.println("<--Pi4J--> ADS1115 GPIO Example ... started.");

      /*
       * формат чисел для вывода данных
       */
      final DecimalFormat df = new DecimalFormat("#.##");
      final DecimalFormat pdf = new DecimalFormat("###.#");
      /*
       * создаем gpio контроллер
       */
      GpioController gpio = GpioFactory.getInstance();
      /*
       * создаем пользовательский provider GPIO ADS1115
       */
      final ADS1115GpioProvider gpioProvider = new ADS1115GpioProvider(I2CBus.BUS_1, ADS1115GpioProvider.ADS1115_ADDRESS_0x48);
      /*
       * создаём аналоговые входные пины от ADS1115
       */
      GpioPinAnalogInput analogInputPin0 = gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A0, "MyAnalogInput-A0");
      GpioPinAnalogInput analogInputPin1 = gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A1, "MyAnalogInput-A1");
      GpioPinAnalogInput analogInputPin2 = gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A2, "MyAnalogInput-A2");
      GpioPinAnalogInput analogInputPin3 = gpio.provisionAnalogInputPin(gpioProvider, ADS1115Pin.INPUT_A3, "MyAnalogInput-A3");
      /*
       * ВНИМАНИЕ !! Для всех аналоговых входных контактов важно установить PGA
       * (программируемый коэффициент усиления внутреннего усилителя). (Вы
       * можете опционально установить каждый вход на другое значение).
       * Измеренное входное напряжение никогда не должно превышать это значение!
       */
      gpioProvider.setProgrammableGainAmplifier(ProgrammableGainAmplifierValue.PGA_4_096V, ADS1115Pin.ALL);
      /*
       * Определяем пороговое значение для каждого вывода для событий изменения
       * аналогового значения. Важно установить этот порог достаточно высоким,
       * чтобы программа не захлебнулась событиями изменения для незначительных
       * изменений
       */
      gpioProvider.setEventThreshold(500, ADS1115Pin.ALL);
      /*
       * Определите интервал обновления потока мониторинга (в миллисекундах).
       * Это определяет скорость, с которой контрольный поток будет считывать
       * входные значения из чипа АЦП (значение менее 50 мс не разрешено)
       */
      gpioProvider.setMonitorInterval(300);
      /*
       * создаем слушатель изменения значения входного напряжения
       */
      GpioPinListenerAnalog listener = new GpioPinListenerAnalog() {
        @Override
        public void handleGpioPinAnalogValueChangeEvent(GpioPinAnalogValueChangeEvent event) {
          /* необработанное значение */
          double value = event.getValue();

          /* в процентах */
          double percent = ((value * 100) / ADS1115GpioProvider.ADS1115_RANGE_MAX_VALUE);

          /*
           * приблизительное напряжение (* масштабируется на основе настройки
           * PGA)
           */
          double voltage = gpioProvider.getProgrammableGainAmplifier(event.getPin()).getVoltage() * (percent / 100);

          /* выводим данные */
          System.out.println(" (" + event.getPin().getName() + ") : VOLTS=" + df.format(voltage) + "  | PERCENT=" + pdf.format(percent) + "% | RAW=" + value + "       ");
        }
      };
      analogInputPin0.addListener(listener);
      analogInputPin1.addListener(listener);
      analogInputPin2.addListener(listener);
      analogInputPin3.addListener(listener);
      /*
       * Оставляем программу работать 5 минут
       */
      Thread.sleep(5 * 60 * 1000);

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

      System.out.println("Exiting ADS1115GpioExample");
    } catch (UnsupportedBusNumberException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Проверяем код:

  1. создаём java файл и вставляем код:
    nano ADS1115Example.java
  2. компилируем файл:
    javac -classpath .:classes:/opt/pi4j/lib/'*' ADS1115Example.java
  3. запускаем программу:
    sudo java -classpath .:classes:/opt/pi4j/lib/'*' ADS1115Example

Результат

Подключение АЦП ADS1115 к Orange Pi PC - Результат

Материалы

ADS1115 — 16-битный Аналого-Цифровой Преобразователь с I2C интерфейсом. Модуль RI038
Pi4J/pi4j · GitHub
Скачать документацию Datasheet ADS1115.pdf

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

Комментарии 1

  • Bet Zula, en populer bahis platformu konusunda benzersiz secenekler sunar. derbi heyecan? icin betzula guncel giris baglant?s? ile favori tak?mlar?n?za destek olabilirsiniz.

    Betzula’n?n guvenilir altyap?s?, kullan?c?lar?na her zaman kolayl?k saglar. Betzula Twitter hesab?n? takip ederek bonus f?rsatlar?ndan haberdar olabilirsiniz.

    Turkiye Super Lig derbilerinin heyecan?n? Betzula ile yasayabilirsiniz.

    Ayr?ca, platformun en yeni versiyonu, mobil cihazlar uzerinden kolay erisim sunar. Ozel olarak, https://decodeistanbul.com/ — betzula guncel giris, tum bahis severler icin en iyi cozum.

    Betzula, mobil uyumlu ve h?zl? erisim f?rsatlar?na kadar tum kullan?c?lar?n ihtiyaclar?n? kars?lar. favori tak?m?n?z?n galibiyetini kutlamak icin Betzula ile kazanmaya baslay?n!
    371212+

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

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