#include #include #include #include #include #include #include #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; }