29. ADC

目前硬件上引出ADC的有以下板卡:

  • LubanCat-3金手指/BTB底板(含有ADC*4)

警告

ADC只支持0~1.8V电压采集,不能超压!

LubanCat-3金手指/BTB底板接口定义如下:

../../_images/adc_0.jpg

29.1. 接口说明

ADC属于IIO子系统,IIO提供了一个统一的接口来管理不同类型的传感器和数据采集设备,从而方便了数据的获取和处理。

ADC相应接口在/sys/bus/iio/devices/目录下,以鲁班猫3IO为例,系统中只有ADC一个IIO设备,注册为iio:device0,如果存在多个IIO设备那么ADC对应的设备号可能不一样,以实际为准。

1
2
3
4
5
6
7
8
9
#查看iio:device0目录
ls /sys/bus/iio/devices/iio:device0

#信息输出如下
buffer           in_voltage2_raw  in_voltage7_raw   scan_elements
buffer0          in_voltage3_raw  in_voltage_scale  subsystem
dev              in_voltage4_raw  name              trigger
in_voltage0_raw  in_voltage5_raw  of_node           uevent
in_voltage1_raw  in_voltage6_raw  power             waiting_for_supplier

该目录下文件数目很多,但我们主要关注in_voltagex_raw、in_voltage_scale这两个文件即可, 其中in_voltageX_raw为对应adc通道的adc数据的原始数值,in_voltage_scale为adc数据与电压值换算比例, 将从这两个读取到的数据相乘即可得到我们想要的板载电位器上的电压值。

29.2. 使用shell脚本读取

由于读取电压值相对简单,以下将编写简单的shell脚本获取 iio:device0 的 IN5通道 的电压值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#!/bin/bash

echo "Press Ctrl+C to quit"

while true
do
    vol_raw=$(cat /sys/bus/iio/devices/iio:device0/in_voltage5_raw)
    vol_scale=$(cat /sys/bus/iio/devices/iio:device0/in_voltage_scale)
    vol=$(echo "scale=4; $vol_raw * $vol_scale / 1000" | bc)
    formatted_vol=$(printf "%.4f" $vol)
    echo "vol_raw:$vol_raw, vol_scale:$vol_scale, vol:$formatted_vol V"
    sleep 1s
done

执行shell脚本后,每秒将输出in_voltage5_raw的原始值、in_voltage_scale数据与电压值换算比例以及转换后的电压值。

29.3. 使用C程序读取

由于读取电压值相对简单,以下将编写C程序获取 IN5通道 的电压值。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define RAW_PATH "/sys/bus/iio/devices/iio:device0/in_voltage5_raw"
#define SCALE_PATH "/sys/bus/iio/devices/iio:device0/in_voltage_scale"

int main(void)
{
    FILE *raw_file, *scale_file;
    int raw_value;
    float scale_value, voltage;

    while (1) {
        // 打开文件
        raw_file = fopen(RAW_PATH, "r");
        if (raw_file == NULL) {
            perror("Error opening raw file");
            return EXIT_FAILURE;
        }

        scale_file = fopen(SCALE_PATH, "r");
        if (scale_file == NULL) {
            perror("Error opening scale file");
            fclose(raw_file);
            return EXIT_FAILURE;
        }

        // 读取原始值
        if (fscanf(raw_file, "%d", &raw_value) != 1) {
            perror("Error reading raw value");
            fclose(raw_file);
            fclose(scale_file);
            return EXIT_FAILURE;
        }

        // 读取比例因子
        if (fscanf(scale_file, "%f", &scale_value) != 1) {
            perror("Error reading scale value");
            fclose(raw_file);
            fclose(scale_file);
            return EXIT_FAILURE;
        }

        // 计算电压
        voltage = raw_value * scale_value;

        // 输出电压值
        printf("Voltage: %.3f mV\n", voltage);

        // 关闭文件
        fclose(raw_file);
        fclose(scale_file);

        // 延时1秒
        sleep(1);
    }

    return EXIT_SUCCESS;
}

编译并执行以上C程序后,每秒将输出转换后的电压值,单位mV。