I used an ads1115 tied to the Pi i2c bus and running at 3.3
volts
I experimented with the Python software but the latest
Raspberry Pi OS needs the complexity of a virtual environment
for python.
There are several solutions using C code . The simplest I found was
https://github.com/giobauermeister/ads1115-linux-rpi/
I modified ads1115_example.c to save the measured voltages in
the ramdisk created in my Pi
#!/bin/bash # /home/pi/MakeRAMdisk/setup-ramfs.sh RAM_DISK="/var/www/html/ramdisk" RAM_DISK_SIZE=6M # Create RAM Disk ########################## if [ ! -z "$RAM_DISK" ]; then echo "Creating RAM Disk... $RAM_DISK" mkdir -p $RAM_DISK chmod 777 $RAM_DISK mount -t tmpfs -o size=$RAM_DISK_SIZE tmpts $RAM_DISK/ echo "RAM Disk created at $RAM_DISK" fi ############################################ #http://cubik-tech.blogspot.co.uk/2016/03/preserve-your-raspberry-pi-sd-card-with.html |
/* https://github.com/giobauermeister/ads1115-linux-rpi/blob/master/ads1115_example.c modifeid with thanks by Sunspot to save data to ramdisk Instructions for compiling and running ads1115_example.c 1 - Clone this repository to your Raspberry Pi $ git clone https://github.com/giobauermeister/ads1115-linux-rpi.git 2 - Go into the cloned folder $ cd /home/pi/ads1115-linux-rpi 3 - Run gcc to compile the example $ sudo gcc ads1115_example.c ads1115_rpi.c -o ads1115_example 4 - Run the example $ ./ads1115_example sudo gcc /home/pi/ads1115-linux-rpi/ads1115_example.c /home/pi/ads1115-linux-rpi/ads1115_rpi.c -o /home/pi/ads1115-linux-rpi/ads1115_example /home/pi/ads1115-linux-rpi/ads1115_example ============================================================================ Name : ads1115_example.c Author : Giovanni Bauermeister Description : Read analog values from potentiometer using ADS1115 and prints to terminal ============================================================================ */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/i2c-dev.h> #include <sys/ioctl.h> #include <fcntl.h> #include "ads1115_rpi.h" int main(void) { if(openI2CBus("/dev/i2c-1") == -1) { return EXIT_FAILURE; } setI2CSlave(0x48); // while(1) // { printf("CH_0 = %.2f V | ", readVoltage(0)); printf("CH_1 = %.2f V | ", readVoltage(1)); printf("CH_2 = %.2f V | ", readVoltage(2)); printf("CH_3 = %.2f V \n", readVoltage(3)); // ChatGPT gave me the save to file code below!! FILE *file; // Open the file in write mode ("w") file = fopen("/var/www/html/ramdisk/Volts0.txt", "w"); if (file == NULL) { // Error handling if file cannot be opened printf("Could not open file for writing\n"); return 1; } // Write the float to the file with desired formatting fprintf(file, "%f\n", readVoltage(0)); // Close the file fclose(file); // Open the file in write mode ("w") file = fopen("/var/www/html/ramdisk/Volts1.txt", "w"); if (file == NULL) { // Error handling if file cannot be opened printf("Could not open file for writing\n"); return 1; } // Write the float to the file with desired formatting fprintf(file, "%f\n", readVoltage(1)); // Close the file fclose(file); // Open the file in write mode ("w") file = fopen("/var/www/html/ramdisk/Volts2.txt", "w"); if (file == NULL) { // Error handling if file cannot be opened printf("Could not open file for writing\n"); return 1; } // Write the float to the file with desired formatting fprintf(file, "%f\n", readVoltage(2)); // Close the file fclose(file); // Open the file in write mode ("w") file = fopen("/var/www/html/ramdisk/Volts3.txt", "w"); if (file == NULL) { // Error handling if file cannot be opened printf("Could not open file for writing\n"); return 1; } // Write the float to the file with desired formatting fprintf(file, "%f\n", readVoltage(3)); // Close the file fclose(file); printf("Float written to file successfully\n"); // } return EXIT_SUCCESS; } |
#ifndef ADS1115_RPI #define ADS1115_RPI /*========================================================================= CONFIG REGISTER -----------------------------------------------------------------------*/ #define CONFIG_REG_OS_SINGLE (0x8000) #define CONFIG_REG_OS_BUSY (0x0000) #define CONFIG_REG_OS_NOTBUSY (0x8000) #define CONFIG_REG_MUX_MASK (0x7000) #define CONFIG_REG_MUX_DIFF_0_1 (0x0000) // default #define CONFIG_REG_MUX_DIFF_0_3 (0x1000) #define CONFIG_REG_MUX_DIFF_1_3 (0x2000) #define CONFIG_REG_MUX_DIFF_2_3 (0x3000) #define CONFIG_REG_MUX_CHAN_0 (0x4000) #define CONFIG_REG_MUX_CHAN_1 (0x5000) #define CONFIG_REG_MUX_CHAN_2 (0x6000) #define CONFIG_REG_MUX_CHAN_3 (0x7000) #define CONFIG_REG_PGA_6_144V (0x0000) // +/-6.144V range #define CONFIG_REG_PGA_4_096V (0x0200) // +/-4.096V range #define CONFIG_REG_PGA_2_048V (0x0400) // +/-2.048V range // default #define CONFIG_REG_PGA_1_024V (0x0600) // +/-1.024V range #define CONFIG_REG_PGA_0_512V (0x0800) // +/-0.512V range #define CONFIG_REG_PGA_0_256V (0x0A00) // +/-0.256V range #define CONFIG_REG_MODE_CONTIN (0x0000) #define CONFIG_REG_MODE_SINGLE (0x0100) // default #define CONFIG_REG_DR_8SPS (0x0000) #define CONFIG_REG_DR_16SPS (0x0020) #define CONFIG_REG_DR_32SPS (0x0040) #define CONFIG_REG_DR_64SPS (0x0060) #define CONFIG_REG_DR_128SPS (0x0080) // default #define CONFIG_REG_DR_250SPS (0x00A0) #define CONFIG_REG_DR_475SPS (0x00C0) #define CONFIG_REG_DR_860SPS (0x00E0) #define CONFIG_REG_CMODE_TRAD (0x0000) // default #define CONFIG_REG_CMODE_WINDOW (0x0010) #define CONFIG_REG_CPOL_ACTIV_LOW (0x0000) // default #define CONFIG_REG_CPOL_ACTIV_HIGH (0x0080) #define CONFIG_REG_CLATCH_NONLATCH (0x0000) // default #define CONFIG_REG_CLATCH_LATCH (0x0040) #define CONFIG_REG_CQUE_1CONV (0x0000) #define CONFIG_REG_CQUE_2CONV (0x0001) #define CONFIG_REG_CQUE_4CONV (0x0002) #define CONFIG_REG_CQUE_NONE (0x0003) // default int openI2CBus(char *bus); int setI2CSlave(unsigned char deviceAddr); float readVoltage(int channel); #endif |
/* * ads1115_rpi.c * * Created on: 14 de fev de 2019 * Author: giobauermeister */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <linux/i2c-dev.h> #include <sys/ioctl.h> #include <fcntl.h> #include "ads1115_rpi.h" //char *bus = "/dev/i2c-1"; int i2cFile; //int deviceAddr = 0x48; unsigned char writeBuf[3] = {0}; int openI2CBus(char *bus) { if ((i2cFile = open(bus, O_RDWR)) < 0) { printf("Failed to open the bus. \n"); return -1; } else { printf("Bus open \n"); return 1; } } int setI2CSlave(unsigned char deviceAddr) { if(ioctl(i2cFile, I2C_SLAVE, deviceAddr) < 0) { printf("Failed to set I2C_SLAVE at address: 0x%x. \n", deviceAddr); return -1; } else { printf("I2C_SLAVE set at address: 0x%x \n", deviceAddr); return 1; } } float readVoltage(int channel) { unsigned char readBuf[2] = {0}; unsigned int analogVal; float voltage; float adnumber; unsigned int config = 0; config = CONFIG_REG_OS_SINGLE | CONFIG_REG_PGA_4_096V | CONFIG_REG_MODE_SINGLE | CONFIG_REG_DR_128SPS | CONFIG_REG_CMODE_TRAD | CONFIG_REG_CPOL_ACTIV_LOW | CONFIG_REG_CLATCH_NONLATCH | CONFIG_REG_CQUE_NONE; void configDevice(unsigned int config) { writeBuf[0] = 0x01; writeBuf[1] = config >> 8; writeBuf[2] = config & 0xFF; write(i2cFile, writeBuf, 3); } switch (channel) { case 0: config |= CONFIG_REG_MUX_CHAN_0; break; case 1: config |= CONFIG_REG_MUX_CHAN_1; break; case 2: config |= CONFIG_REG_MUX_CHAN_2; break; case 3: config |= CONFIG_REG_MUX_CHAN_3; break; default: printf("Give a channel between 0-3\n"); } configDevice(config); while (readBuf[0] >> 7 != 1) { read(i2cFile, readBuf, 2); } writeBuf[0] = 0x00; write(i2cFile, writeBuf, 1); if(read(i2cFile, readBuf, 2) != 2) // read data and check error { printf("Error : Input/Output Error \n"); } else { analogVal = readBuf[0] << 8 | readBuf[1]; voltage = (float)analogVal*4.096/32767.0; } return voltage; } |