I am working on a project which sampling a measurement frequently - at the slowest we need to sample every 5us. I've tested the ADC using analogread() on the Teensy 3.0 and have found it takes 20 - 23us to read an analog signal, which is just a bit too slow for our application. I've read through previous posts and it seems that Paul recently updated analogread to make it faster, which is why it's as fast as it is now (thanks for that, btw!) - but it's still too slow for what we're trying to do. I also know (or think I know) that the ADC itself is quite fast - it's 818Ksps in 16 bit or 461Ksps in <13 bit (~1 - 2 microseconds) based on reading page 36 and 37 of the K20 manual (http://cache.freescale.com/files/32bit/doc/data_sheet/K20P64M50SF0.pdf).
So far, I've tried a few things:
I tried to comment out some not completely necessary parts of the analogread() command in the analog.c library in the teensy core (commented out the calibration and the "if pin X then Y" part):
int analogRead(uint8_t pin)
{
int result;
/*
if (pin >= 14) {
if (pin <= 23) {
pin -= 14; // 14-23 are A0-A9
} else if (pin >= 34 && pin <= 39) {
pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
} else {
return 0; // all others are invalid
}
}
//serial_print("analogRead");
//return 0;
if (calibrating) wait_for_cal();
//pin = 5; // PTD1/SE5b, pin 14, analog 0
*/
ADC0_SC1A = channel2sc1a[pin];
while ((ADC0_SC1A & ADC_SC1_COCO) == 0) {
yield();
// wait
//serial_print(".");
}
//serial_print("\n");
result = ADC0_RA >> analog_right_shift;
//serial_phex16(result >> 3);
//serial_print("\n");
return result;
};
These changes didn't help much (saved about 1us).
I'm currently trying to use the port register directly (as per this http://forum.pjrc.com/threads/17532...PORT-DDR-D-B-registers-vs-ARM-GPIO_PDIR-_PDOR thread), but it's a bit confusing a slow going.
So I have 2 basic questions:
1) What exactly is it that's taking that 20us? The ADC itself is only taking part of it so I know that something else is taking up the rest, but I can't figure out what it is. If someone understands the breakdown of that 20us I'd love to hear it.
2) How can I reduce that time? I found a lot of posts for the ATMega using a prescaler to increase the response of the ADC while decreasing the accuracy, but I haven't been able to figure out how to do this on the Teensy's ADC. Is the port register shifting the way to go, or something else?
Sorry if this is a noob question, I'm fairly new at this but learning fast. Thanks,
Greg
So far, I've tried a few things:
I tried to comment out some not completely necessary parts of the analogread() command in the analog.c library in the teensy core (commented out the calibration and the "if pin X then Y" part):
int analogRead(uint8_t pin)
{
int result;
/*
if (pin >= 14) {
if (pin <= 23) {
pin -= 14; // 14-23 are A0-A9
} else if (pin >= 34 && pin <= 39) {
pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
} else {
return 0; // all others are invalid
}
}
//serial_print("analogRead");
//return 0;
if (calibrating) wait_for_cal();
//pin = 5; // PTD1/SE5b, pin 14, analog 0
*/
ADC0_SC1A = channel2sc1a[pin];
while ((ADC0_SC1A & ADC_SC1_COCO) == 0) {
yield();
// wait
//serial_print(".");
}
//serial_print("\n");
result = ADC0_RA >> analog_right_shift;
//serial_phex16(result >> 3);
//serial_print("\n");
return result;
};
These changes didn't help much (saved about 1us).
I'm currently trying to use the port register directly (as per this http://forum.pjrc.com/threads/17532...PORT-DDR-D-B-registers-vs-ARM-GPIO_PDIR-_PDOR thread), but it's a bit confusing a slow going.
So I have 2 basic questions:
1) What exactly is it that's taking that 20us? The ADC itself is only taking part of it so I know that something else is taking up the rest, but I can't figure out what it is. If someone understands the breakdown of that 20us I'd love to hear it.
2) How can I reduce that time? I found a lot of posts for the ATMega using a prescaler to increase the response of the ADC while decreasing the accuracy, but I haven't been able to figure out how to do this on the Teensy's ADC. Is the port register shifting the way to go, or something else?
Sorry if this is a noob question, I'm fairly new at this but learning fast. Thanks,
Greg