cbeagleboneblackbeagleboardadciio

Reading an input (4096) from a directory to use in C


I'm trying to read an ADC (12 bit which is 0 - 4095) input from my AIN0 channel, and using that as an "int" so I could use it in a math function. Is this possible?

The directory I'm referring to is "sys/bus/iio/devices/iio:device0/in_voltage0_raw" on the Beaglebone Black Debian Wheezy.

Currently, I have a C file that reads the user's input (through terminal) and does the math function I need it to do, but I'm having a hard time wrapping my head around this active/constantly changing ADC value. I've looked into using "fopen" functions as well. Using the code below, I'm able to get the ADC value on the terminal, and it'll change based on how much volts go in. Is there a way to "grab" the input from the ADC and use it in a math function, even if the ADC value constantly changes?

#define SYSFS_ADC_DIR "/sys/bus/iio/devices/iio:device0/in_voltage0_raw"
#define MAX_BUFF 64
int main(){
  int fd;
  char buf[MAX_BUFF];
  char ch[5];   //Update
  ch[4] = 0;    //Update

  int i;
  for(i = 0; i < 30; i++)
      {
      snprintf(buf, sizeof(buf), SYSFS_ADC_DIR);
      fd = open(buf, O_RDONLY);
      read(fd,ch,4);
      printf("%s\n", ch);
      close(fd);

      usleep(1000);
    }
  }

Updated Code

I've made the changes to char ch[5], I've also gotten a little farther in the code putting the math functions I wanted.

int AIN0_low = 0;    //lowest input of adc
int AIN0_high = 4095;   //highest input of adc
int motor_low = 0;      //lowest speed value for motor
int motor_high = 3200;  //highest speed value for motor
double output = 0;

int  main(){
  double fd;
  char buf[MAX_BUF];
  char ch[4] = 0;

  int i;
  for(i = 0; i < 30; i++)
  {
    snprintf(buf, sizeof(buf), SYSFS_ADC_DIR);

    fd = open(buf, O_RDONLY);
    read(fd, ch, 4);

    double slope = 1.0 * (motor_high - motor_low) / (AIN0_high - AIN0_low);
    output = motor_low + slope * (ch - AIN0_low);

    printf("%f\n", output);

    close(fd);
    usleep(1000);
  }
}

Solution

  • In your second function you are using the filehandle in your calculations. I think you meant the value you read (ch). Just convert the value to float before putting into the calculation.

    Also add another byte to the buffer you read with to accommodate an ending \0

    Something like this

    int  main(){
      double fd = 0.0;
      char buf[MAX_BUF] = {0};
      char ch[5] = {0,0,0,0,0};
    
      // move slope here since it is constant
      double slope = 1.0 * (motor_high - motor_low) / (AIN0_high - AIN0_low);
    
      int i;
      for(i = 0; i < 30; i++)
      {
        snprintf(buf, sizeof(buf), SYSFS_ADC_DIR);
    
        fd = open(buf, O_RDONLY);
        read(fd, ch, 4);
        output = motor_low + slope * (atof(ch) - AIN0_low);
    
        printf("%f\n", output);
    
        close(fd);
        usleep(1000);
      }
      return 0; // add this
    }
    

    disclaimer: i don't know about the hardware you are using, just fixed your code if the device behaves like a file.