[Teensy 4.1] I/O Pin Internal Capacitor and Resistor Values

I am making a capacitance meter with a teensy 4.1. I have two circuits, one for higher values and one for lower values.

I am working with the lower capacitance circuit currently, which is simply the capacitor connected to analog A0 and A2. I am looking for the ARM Cortex-M7 internal equivalent schematic of the digital pins, so that I can have the actual pull up resistor value and pin capacitor value so I can do the math and find my actual exact capacitances.

For reference, I am following this video tutorial which is Arduino Uno based (skip to 8:30 for the small capacitor circuit info). :

I looked in the ARM reference and user manual to no avail. I am wondering if anyone knows where I can find these specs, I have tried and tried. Thanks in advance!
 
Internal pullups aren't resistors, they are FETs, they are non-linear and the value varies a lot between different chips - basically no use for measurements like this. On a CMOS chip a FET is perhaps 1000's of times smaller than a resistor....
 
Internal pullups aren't resistors, they are FETs, they are non-linear and the value varies a lot between different chips - basically no use for measurements like this. On a CMOS chip a FET is perhaps 1000's of times smaller than a resistor....
I see. Thanks for the input ~ so this method of measurement is pretty much impossible to setup on the teensy I take it? In the video, the measurements are at 9:36. Thanks again. :)
 
Just use an external resistor driven from a different pin...
Ive been looking into how I would do this, and it is a little unclear to me. As an example, I could get a 1k ohm resistor and put it in another analog pin, set that to charge with R_PULLUP in my code set to 1k, and then keep the discharge pin as is?

Wouldn't the 1k resistor just add to the internal pullup resistance? For clarity, below is my code so it is more clear what I am working with

Code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ADC.h>

// Pin definitions for Teensy 4.1
const int OUT_PIN = 16; // Analog pin A2 on Teensy 4.1
const int IN_PIN = 14;  // Analog pin A0 on Teensy 4.1

LiquidCrystal_I2C lcd(0x27, 20, 4); // LCD address and dimensions

const float IN_STRAY_CAP_TO_GND = 14.59; // Adjusted value for your setup
const float IN_CAP_TO_GND = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 22000.0; // Pull-up resistor value in Ohms
const int MAX_ADC_VALUE = 4095; // Teensy 4.1 ADC max value for 12-bit resolution

ADC *adc = new ADC(); // Create an ADC object

void setup() {
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
  lcd.init();
  lcd.backlight();

  // Set up ADC
  adc->adc0->setAveraging(16); // Set number of averages
  adc->adc0->setResolution(12); // Set resolution to 12 bits
  adc->adc0->setConversionSpeed(ADC_CONVERSION_SPEED::HIGH_SPEED); // Set conversion speed
  adc->adc0->setSamplingSpeed(ADC_SAMPLING_SPEED::HIGH_SPEED); // Set sampling speed
}

void loop() {
  pinMode(IN_PIN, INPUT);
  digitalWrite(OUT_PIN, HIGH);
  int val = adc->adc0->analogRead(IN_PIN);
  digitalWrite(OUT_PIN, LOW);

  lcd.setCursor(0, 0);
  lcd.print("ADC Value: ");
  lcd.print(val);

  if (val < (MAX_ADC_VALUE * 0.9)) { // Adjust threshold if needed
    pinMode(IN_PIN, OUTPUT);

    float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);

    lcd.setCursor(0, 1);
    if (capacitance > 1000.0) {
      lcd.print(capacitance / 1000.0, 3);
      lcd.print(" nF");
    } else {
      lcd.print(capacitance, 3);
      lcd.print(" pF");
    }
  } else {
    pinMode(IN_PIN, OUTPUT);
    delay(1);
    pinMode(OUT_PIN, INPUT_PULLUP);
    unsigned long u1 = micros();
    unsigned long t;
    int digVal;

    do {
      digVal = digitalRead(OUT_PIN);
      unsigned long u2 = micros();
      t = u2 > u1 ? u2 - u1 : u1 - u2;
    } while ((digVal < 1) && (t < 400000UL)); // Ensure correct type for UL

    pinMode(OUT_PIN, INPUT);
    val = adc->adc0->analogRead(OUT_PIN);
    digitalWrite(IN_PIN, HIGH);
    int dischargeTime = (int)(t / 1000UL) * 5; // Ensure correct type for UL
    delay(dischargeTime);
    pinMode(OUT_PIN, OUTPUT);
    digitalWrite(OUT_PIN, LOW);
    digitalWrite(IN_PIN, LOW);

    float capacitance = -(float)t / R_PULLUP / log(1.0 - (float)val / (float)MAX_ADC_VALUE);

    lcd.setCursor(0, 1);
    if (capacitance > 1e6) {
      lcd.print(capacitance / 1e6, 3);
      lcd.print(" uF");
    } else if (capacitance > 1000.0) {
      lcd.print(capacitance / 1000.0, 3);
      lcd.print(" nF");
    } else {
      lcd.print(capacitance, 3);
      lcd.print(" pF");
    }
  }

  while (micros() % 1000 != 0);
}
 
Back
Top