アナログ値を測定する(C言語)
準備
初めて使用する場合は、セットアップ(ボードの取り付け)をおこないます。
AIO-32/0RA-IRCのセットアップ(ラズベリーパイ)
AIO-32/0RA-IRCのセットアップ(NVIDIA Jetson Nano 開発者キット)
プログラムの作成
「test_aio320ra.cpp」というファイル名で以下のファイルを保存します。
(または test_aio320ra.cpp からダウンロードします)
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#define I2C_DEVICE "/dev/i2c-1"
#define AIO320RA_ADS1115_ADDRESS 0x49
#define AIO320RA_PCA9554_ADDRESS 0x3e
enum PCA9554_Register {
PCA9554_Reg_InputPort,
PCA9554_Reg_OutputPort,
PCA9554_Reg_PolarityInversion,
PCA9554_Reg_Configuration
};
enum ADS1115_Register {
ADS1115_Reg_Conversion,
ADS1115_Reg_Config,
ADS1115_Reg_LoThresh,
ADS1115_Reg_HiThresh
};
enum ADS1115_SingleShotCoversion {
ADS1115_SingleShotCoversion_NoEffect,
ADS1115_SingleShotCoversion_Begin
};
enum ADS1115_Mux {
ADS1115_Mux_Ain0_Ain1,
ADS1115_Mux_Ain0_Ain3,
ADS1115_Mux_Ain1_Ain3,
ADS1115_Mux_Ain2_Ain3,
ADS1115_Mux_Ain0_Gnd,
ADS1115_Mux_Ain1_Gnd,
ADS1115_Mux_Ain2_Gnd,
ADS1115_Mux_Ain3_Gnd
};
enum ADS1115_PGA {
ADS1115_PGA_6_144V,
ADS1115_PGA_4_096V,
ADS1115_PGA_2_048V,
ADS1115_PGA_1_024V,
ADS1115_PGA_0_512V,
ADS1115_PGA_0_256V
};
enum ADS1115_Mode {
ADS1115_Mode_Continuous,
ADS1115_Mode_PowerDownSingleShot
};
enum ADS1115_DataRate {
ADS1115_DataRate_8SPS,
ADS1115_DataRate_16SPS,
ADS1115_DataRate_32SPS,
ADS1115_DataRate_64SPS,
ADS1115_DataRate_128SPS, // Default
ADS1115_DataRate_250SPS,
ADS1115_DataRate_475SPS,
ADS1115_DataRate_860SPS,
};
enum ADS1115_ComparatorQueue {
ADS1115_ComparatorQueue_Disable = 0x03
};
enum AIO320RA_PGA {
AIO320RA_PGA_10_0352V = ADS1115_PGA_2_048V,
AIO320RA_PGA_5_0176V = ADS1115_PGA_1_024V,
AIO320RA_PGA_2_5088V = ADS1115_PGA_0_512V,
AIO320RA_PGA_1_2544V = ADS1115_PGA_0_256V
};
enum AIO320RA_DataRate {
AIO320RA_DataRate_8SPS = ADS1115_DataRate_8SPS,
AIO320RA_DataRate_16SPS = ADS1115_DataRate_16SPS,
AIO320RA_DataRate_32SPS = ADS1115_DataRate_32SPS,
AIO320RA_DataRate_64SPS = ADS1115_DataRate_64SPS,
AIO320RA_DataRate_128SPS = ADS1115_DataRate_128SPS,
AIO320RA_DataRate_250SPS = ADS1115_DataRate_250SPS,
AIO320RA_DataRate_475SPS = ADS1115_DataRate_475SPS,
AIO320RA_DataRate_860SPS = ADS1115_DataRate_860SPS,
};
uint8_t multiplexerSettings;
int PCA9554_SetDirectionByte(int fd, uint8_t value) {
uint8_t reg[] = { PCA9554_Reg_Configuration , value };
if ((write(fd, reg, 2)) != 2) {
perror("PCA9554_SetDirectionByte(write)");
return 1;
}
return 0;
}
int PCA9554_WriteByte(int fd, uint8_t value) {
uint8_t reg[] = { PCA9554_Reg_OutputPort, value };
if ((write(fd, reg, 2)) != 2) {
perror("PCA9554_WriteByte(write)");
return 1;
}
return 0;
}
int16_t ADS1115_AnalogRead(int fd, ADS1115_Mux mux, ADS1115_DataRate dataRate = ADS1115_DataRate_128SPS, ADS1115_PGA pga = ADS1115_PGA_2_048V) {
uint8_t reg[] = {
ADS1115_Reg_Config,
(uint8_t)(ADS1115_SingleShotCoversion_Begin << 7 | mux << 4 | pga << 1 | ADS1115_Mode_PowerDownSingleShot),
(uint8_t)(dataRate << 5 | ADS1115_ComparatorQueue_Disable) };
if ((write(fd, reg, 3)) != 3) {
perror("ADS1115_AnalogRead(write)");
return 1;
}
reg[0] = 0;
while ((reg[0] & 0x80) == 0) {
if (read(fd, reg, 1) != 1) {
perror("ADS1115_AnalogRead(read)");
return 1;
}
}
reg[0] = ADS1115_Reg_Conversion;
if ((write(fd, reg, 1)) != 1) {
perror("ADS1115_AnalogRead(write)");
return 1;
}
if (read(fd, reg, 2) != 2) {
perror("ADS1115_AnalogRead(read)");
return 1;
}
return (int16_t)reg[0] << 8 | reg[1];
}
int AIO320RA_Init(int fdMux) {
multiplexerSettings = 0xff;
if (PCA9554_WriteByte(fdMux, multiplexerSettings) != 0)
return 1;
if (PCA9554_SetDirectionByte(fdMux, 0) != 0)
return 1;
return 0;
}
int16_t AIO320RA_AnalogRead(int fdAdc, int fdMux, int channel, AIO320RA_DataRate dataRate = AIO320RA_DataRate_128SPS, AIO320RA_PGA pga = AIO320RA_PGA_10_0352V) {
uint8_t extMux;
ADS1115_Mux adcMux;
if (channel < 16) {
extMux = (uint8_t)((multiplexerSettings & 0xf0) | channel);
adcMux = ADS1115_Mux_Ain0_Gnd;
}
else if (channel < 32) {
extMux = (uint8_t)((multiplexerSettings & 0x0f) | (channel & 0x0f) << 4);
adcMux = ADS1115_Mux_Ain1_Gnd;
}
else if (channel < 48) {
extMux = (uint8_t)((multiplexerSettings & 0xf0) | channel);
adcMux = ADS1115_Mux_Ain0_Ain3;
}
else if (channel < 64) {
extMux = (uint8_t)((multiplexerSettings & 0x0f) | (channel & 0x0f) << 4);
adcMux = ADS1115_Mux_Ain1_Ain3;
}
else if (channel < 256) {
return 0;
}
else {
extMux = (uint8_t)(channel & 0xff);
adcMux = ADS1115_Mux_Ain0_Ain1;
}
if (multiplexerSettings != extMux) {
PCA9554_WriteByte(fdMux, extMux);
multiplexerSettings = extMux;
}
return ADS1115_AnalogRead(fdAdc, adcMux, (ADS1115_DataRate)dataRate, (ADS1115_PGA)pga);
}
float AIO320RA_AnalogReadVolt(int fdAdc, int fdMux, int channel, AIO320RA_DataRate dataRate = AIO320RA_DataRate_128SPS, AIO320RA_PGA pga = AIO320RA_PGA_10_0352V) {
switch (pga) {
case AIO320RA_PGA_1_2544V:
return (float)(0.256 * 49 / 10 / 32767 * AIO320RA_AnalogRead(fdAdc, fdMux, channel, dataRate, pga));
case AIO320RA_PGA_2_5088V:
return (float)(0.512 * 49 / 10 / 32767 * AIO320RA_AnalogRead(fdAdc, fdMux, channel, dataRate, pga));
case AIO320RA_PGA_5_0176V:
return (float)(1.024 * 49 / 10 / 32767 * AIO320RA_AnalogRead(fdAdc, fdMux, channel, dataRate, pga));
default:
return (float)(2.048 * 49 / 10 / 32767 * AIO320RA_AnalogRead(fdAdc, fdMux, channel, dataRate, pga));
}
}
int main(int argc, char **argv)
{
int fdAdc, fdMux;
if ((fdAdc = open(I2C_DEVICE, O_RDWR)) < 0) {
perror("adc open");
exit(1);
}
if (ioctl(fdAdc, I2C_SLAVE, AIO320RA_ADS1115_ADDRESS) < 0) {
perror("adc ioctl");
exit(1);
}
if ((fdMux = open(I2C_DEVICE, O_RDWR)) < 0) {
perror("mux open");
exit(1);
}
if (ioctl(fdMux, I2C_SLAVE, AIO320RA_PCA9554_ADDRESS) < 0) {
perror("mux ioctl");
exit(1);
}
if (AIO320RA_Init(fdMux) != 0)
exit(1);
// アナログ入力値の読み出し(電圧値)(860SPS)
float volt[32];
for (int channel = 0; channel < 32; channel++) {
volt[channel] = AIO320RA_AnalogReadVolt(fdAdc, fdMux, channel, AIO320RA_DataRate_860SPS);
printf("CH%d: %2.3fV\n", channel, volt[channel]);
}
close(fdAdc);
close(fdMux);
return 0;
}
動作確認
プログラムをコンパイルします。
$ g++ -o test_aio320ra test_aio320ra.cpp
プログラムを実行します。
$ ./test_aio320ra
アナログ入力電圧が表示されます。
CH0: 5.205V
CH1: 0.000V
CH2: 0.000V
...
使用方法について
差動入力で使用する場合
AIO320RA_AnalogReadVolt関数 または AIO320RA_AnalogRead関数 で引数(channel)を以下の値にすることで、各差動入力チャネルの電圧を読み出すことが可能です。
channelの値 = 差動入力チャネル * 17 + 256
channel | 差動入力チャネル | 接続先 |
---|---|---|
256 | 差動入力チャネル0 | P1-1pinとP1-2pin |
273 | 差動入力チャネル1 | P1-3pinとP1-4pin |
290 | 差動入力チャネル2 | P1-5pinとP1-6pin |
・・・ |
必ず入力信号の基準電位(0V)を、AG(P1-33pin・P1-34pinどちらかのピン)に接続してください。