It seem to take > 1000 microseconds to read one analog value. I want to continuously read 3 analog inputs in 1 milliseconds, is it possible with this hat (e.g. change ADC clock etc.)?
Code:
import datetime
import math
import sys
import time
from grove.adc import ADC
class GroveGSRSensor:
def __init__(self, channel):
self.channel = channel
self.adc = ADC()
@property
def GSR(self):
a = datetime.datetime.now()
value = self.adc.read(self.channel)
b = datetime.datetime.now()
print("time: ",(b-a).microseconds)
return value
Grove = GroveGSRSensor
def main():
if len(sys.argv) < 2:
print('Usage: {} adc_channel'.format(sys.argv[0]))
sys.exit(1)
Now I created a C version, but still it took ~300 microseconds to read a value. Sometimes there is a spike to 1000ms, probably has to do with the OS. Maybe I should use arduino? But Arduino Nano 33 IOT has a firmware bug at this point… Any suggestions?
C code:
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
#include <sys/time.h>
int main()
{
int file_i2c;
int value;
char reg = 0x30;
char read_buffer[3];
struct timeval st, et;
char *filename = (char*)"/dev/i2c-1";
if ((file_i2c = open(filename, O_RDONLY)) < 0)
{
printf("Failed to open the i2c bus");
return 0;
}
int addr = 0x8; // Grove Hat ADC address
if (ioctl(file_i2c, I2C_SLAVE_FORCE, addr) < 0)
{
printf("Failed to acquire bus access and/or talk to slave.\n");
return 0;
}
while (1) {
gettimeofday(&st,NULL);
i2c_smbus_write_byte(file_i2c, reg);
gettimeofday(&et,NULL);
value = i2c_smbus_read_word_data(file_i2c, reg);
printf("%d\n", value);
printf("time: %ld\n", et.tv_usec - st.tv_usec);
}
return 0;
}
Thanks for the reply! Yes, it was a mistake, that I should timed both write and read together instead of just the write operation. Follow your suggestion, I found indeed I can do more read following one write instructions. So here is the measurement results: i2c_smbus_write_byte(file_i2c, reg); // ~270 μs i2c_smbus_read_word_data(file_i2c, reg); // ~820 μs
Since write_byte transmitted 1 byte while read_word transmitted 3 bytes, it makes sense that read_word costs roughly three times more time.
I contacted SeeedStudio customer service, they told me the firmware limits adc read rate and it’s better not to change that…
Note I tested on both raspberry pi 3b and zero w which have different processors but the same results. So it is likely just a firmware limitation.