LuckFox ADC Печать
Добавил(а) microsin   

В этой статье (перевод документации [1]) приведен пример чтения напряжения двух каналов АЦП платы LuckFox Pico, с использованием доступа к IIO через файлы устройства в user space. Архив с кодом можно скачать с Google-диска (см. ссылку на Code.zip в оригинальной документации [1]).

[1. Подсистема IIO]

IIO (Industrial I/O) это интегральная часть Linux kernel, специально разработанная для обработки аналоговых входов и выходов устройств в индустриальных и встраиваемых приложениях. Такими устройствами могут быть датчики, ADC (Analog-to-Digital Converter, аналого-цифровые преобразователи, АЦП), DAC (Digital-to-Analog Converter, цифро-аналоговые преобразователи, ЦАП), и другие устройства, работающие с аналоговыми сигналами. Основная цель подсистемы IIO - предоставить универсальный и унифицированный фреймворк для поддержки различных типов аналоговых устройств в Linux.

Подсистема IIO предоставляет унифицированный интерфейс через файловую систему sysfs и user space, позволяя пользователям получить доступ и конфигурировать аналоговые устройства. Это означает, что приложения могут коммуницировать с датчиками и аналоговыми устройствами, используя стандартные файловые I/O операции Linux.

[2. Чтение ADC в скрипте shell]

2.1. Входы АЦП. Платы разработчика LuckFox обычно поставляются с разрешенными интерфейсами ADC, которые могут измерять уровни напряжения в диапазоне от 0V до 1.8V. Ниже приведена цоколевка шести моделей плат LickFox Pico. У четырех из них есть входы ADC, соответствующие номерам выводов 144 (SARADC_IN0) и 145 (SARADC_IN1).

Цоколевка LuckFox Pico:

Pico pinout

Цоколевка LuckFox Pico Mini A/B:

Pico Mini AB pinout

Цоколевка LuckFox Pico Plus:

Pico Plus pinout

Цоколевка LuckFox Pico Pro/Max:

Pico Pro Max pinout

Цоколевка LuckFox Pico Ultra/Ultra W:

Pico Ultra Ultra W pinout

2.2. Device Directory. Директория /sys/bus/iio/devices содержит подкаталоги, относящиеся к IIO-устройствам, которые определила система Linux. Каждый подкаталог обычно соответствует определенному устройству IIO, и его имя может включать тип устройства и его номер в системе. Вы можете просмотреть устройства IIO в системе следующей командой:

[root@luckfox ]# ls -1 /sys/bus/iio/devices/iio:device0

Примечание: iio:device0 это директория устройств, символическая ссылка на каталог наподобие /sys/devices/platform/ff3c0000.saradc/iio:device0.

2.3. Свойства устройств. Каждый подкаталог устройства содержит набор файлов свойств, используемых для получения и конфигурирования различных параметров и состояний устройства IIO. Например, вы можете прочитать эти файлы, чтобы получить данные датчика, сконфигурировать частоту оцифровки (sampling frequency), или установить пороги уровней для прерываний (interrupt thresholds).

Список файлов устройства можно просмотреть командой:

[root@luckfox ]# ls -1 /sys/bus/iio/devices/iio:device0buffer
dev
in_voltage0_raw
in_voltage1_raw
in_voltage_scale
name
of_node
power
scan_elements
subsystem
trigger
uevent

В этой директории основные файлы свойств это in_voltage0_raw, in_voltage1_raw и in_voltage_scale.

• Файл in_voltage0_raw содержит сырое значение напряжения, прочитанное из входа канала 0 ADC (вывод 144 SARADC_IN0), обычно представленное как целое число. Вы можете прочитать это значение командой cat, например:

[root@luckfox ]# cat /sys/bus/iio/devices/iio\:device0/in_voltage0_raw
1023

Аналогично in_voltage1_raw это файл, который соответствует значению канала 1 ADC (вывод 145 SARADC_IN1).

• Файл in_voltage_scale содержит коэффициент масштабирования, который можно использовать для преобразования сырых значений АЦП в реальное напряжение. Вы также можете прочитать его командой cat, например:

[root@luckfox ]# cat /sys/bus/iio/devices/iio\:device0/in_voltage_scale
1.757812500

2.4. Shell-скрипт для чтения значений напряжения. Чтобы получить реальные значение напряжений для каналов 0 и 1 ADC, вы можете написать shell-скрипт, чтобы прочитать сырые значения из файлов in_voltage0_raw, in_voltage1_raw, и затем умножить их на коэффициент из файла in_voltage_scale. Пример создания такого скрипта:

1. С помощью редактора текста (vi или nano) создайте shell-скрипт:

# nano adc.sh

2. Вставьте в него следующий текст и сохраните файл:

#!/bin/sh

echo "Press Ctrl+C to quit"
ADC_DIR="/sys/bus/iio/devices/iio:device0"

while true
do scale_value=$(cat "$ADC_DIR/in_voltage_scale")
IN0_raw_value=$(cat "$ADC_DIR/in_voltage0_raw")
IN1_raw_value=$(cat "$ADC_DIR/in_voltage1_raw")
IN0_voltage=$(awk -v raw="$IN0_raw_value" -v scale="$scale_value" \
'BEGIN { printf "%.6f\n", raw * scale / 1000 }')
IN1_voltage=$(awk -v raw="$IN1_raw_value" -v scale="$scale_value" \
'BEGIN { printf "%.6f\n", raw * scale / 1000 }')
echo "IN0_Voltage: $IN0_voltage V,IN1_Voltage: $IN1_voltage V"
sleep 1
done

3. Запустите скрипт:

# chmod +x adc.sh
# ./adc.sh
Press Ctrl+C to quit
IN0_Voltage: 1.796484 V,IN1_Voltage: 1.798242 V
IN0_Voltage: 1.798242 V,IN1_Voltage: 1.798242 V
...

[3. Чтение ADC в программе Python]

Следующая программа читает уровни напряжений каналов ADC 0 и 1.

import time
ADC_DIR = "/sys/bus/iio/devices/iio:device0"

def read_value(file_path): with open(file_path, "r") as file: return file.read().strip()

def main(): print("Press Ctrl+C to quit") while True: scale_value = float(read_value(f"{ADC_DIR}/in_voltage_scale")) IN0_raw_value = float(read_value(f"{ADC_DIR}/in_voltage0_raw")) IN1_raw_value = float(read_value(f"{ADC_DIR}/in_voltage1_raw"))
IN0_voltage = f"{IN0_raw_value * scale_value / 1000:.2f}" IN1_voltage = f"{IN1_raw_value * scale_value / 1000:.2f}"
print(f"IN0_Voltage: {IN0_voltage} V, IN1_Voltage: {IN1_voltage} V") time.sleep(1)

if __name__ == "__main__": try: main() except KeyboardInterrupt: pass

Создайте файл adc.py, вставьте в него текст этой программы и сохраните. Запустить эту программу можно командой:

[root@luckfox adctest]# python3 adc.py
Press Ctrl+C to quit
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
IN0_Voltage: 1.80 V, IN1_Voltage: 1.80 V
...

[4. Чтение ADC в программе C]

Мы также можем считывать значения напряжений с помощью функций библиотеки языка C, или с помощью системных вызовов для чтения файлов. Имейте в виду, что для компиляции программ на определенных встраиваемых системах необходим специальный тулчейн, для LuckFox Pico это тулчейн для чипа Rockchip RV1103, который можно установить вместе с LuckFox SDK [2].

С помощью следующей программы мы можем получить значения каналов 0 и 1 ADC.

#include < stdio.h>
#include < stdlib.h>
#include < unistd.h>
#include < fcntl.h>

int main() {
printf("Press Ctrl+C to quit\n");
const char *adc_dir = "/sys/bus/iio/devices/iio:device0";
char in_voltage0_raw_path[256];
char in_voltage1_raw_path[256];
char in_voltage_scale_path[256];

sprintf(in_voltage0_raw_path, "%s/in_voltage0_raw", adc_dir);
sprintf(in_voltage1_raw_path, "%s/in_voltage1_raw", adc_dir);
sprintf(in_voltage_scale_path, "%s/in_voltage_scale", adc_dir);

FILE *scale_file = fopen(in_voltage_scale_path, "r");
FILE *in0_raw_file = fopen(in_voltage0_raw_path, "r");
FILE *in1_raw_file = fopen(in_voltage1_raw_path, "r");

while (1) {
char buffer[32];

fseek(scale_file, 0, SEEK_SET);
fseek(in0_raw_file, 0, SEEK_SET);
fseek(in1_raw_file, 0, SEEK_SET);

if (scale_file && in0_raw_file && in1_raw_file) {
fgets(buffer, sizeof(buffer), scale_file);
float scale = strtof(buffer, NULL);

fgets(buffer, sizeof(buffer), in0_raw_file);
int in0_raw_value = atoi(buffer);

fgets(buffer, sizeof(buffer), in1_raw_file);
int in1_raw_value = atoi(buffer);

float in0_voltage = (in0_raw_value * scale) / 1000.0;
float in1_voltage = (in1_raw_value * scale) / 1000.0;

printf("IN0 Voltage: %.6f V, IN1 Voltage: %.6f V\n", in0_voltage, in1_voltage);
}
sleep(1);
}

fclose(scale_file);
fclose(in0_raw_file);
fclose(in1_raw_file);
return 0; }

Скомпилировать эту программу вы можете на хосте с помощью SDK LuckFox, процесс компиляции и запуска программы описан в статье [3] (см. секции "4.7. Кросс-компиляция" и "4.8. Запуск программы на плате LuckFox").

[Ссылки]

1. LuckFox ADC site:wiki.luckfox.com.
2. LuckFox FAQ: установка SDK.
3. LuckFox SPI: обмен данными с внешним устройством.