0

I have successfully run the code provided here on an Arduino Nano. If nothing is connected, it will output a very small capacitance (~ 1 pF).

Then I tried to migrate the code to the ATtiny85 (using a Digispark USB Development Board), but I fail to get anything reasonable out of the code. The first analogRead will always give 1023, whereas on the Nano it gives a very small value (again for nothing connected to the input pins).

It's a bit trickier on the ATtiny85 because the pin numbers are different for digital and analog, but I thought I got that right, so what went wrong in the migration?

const int OUT_PIN = 2; // digital pin PB2 is 2, positive pin of C
const int IN_PIN  = 5; // digital pin PB5 is 5, negative pin of C
const int OUT_ANA = 1; // analog read PB2 is 1
const int IN_ANA  = 0; // analog read PB5 is 0

const float IN_STRAY_CAP_TO_GND = 24.48;
const float IN_CAP_TO_GND  = IN_STRAY_CAP_TO_GND;
const float R_PULLUP = 34.8;  
const int MAX_ADC_VALUE = 1023;

#include "DigiKeyboard.h"

void setup() {
  pinMode(1, OUTPUT);
  pinMode(OUT_PIN, OUTPUT);
  pinMode(IN_PIN, OUTPUT);
  digitalWrite(OUT_PIN, LOW);
  digitalWrite(IN_PIN, LOW);  
  DigiKeyboard.update();
}

void loop() {

    pinMode(IN_PIN, INPUT);
    digitalWrite(OUT_PIN, HIGH);
    int val = analogRead(IN_ANA); // IN_PIN in Nano version
    digitalWrite(OUT_PIN, LOW);

    DigiKeyboard.println(val);
    if (val < 1000) {
      pinMode(IN_PIN, OUTPUT);
      float capacitance = (float)val * IN_CAP_TO_GND / (float)(MAX_ADC_VALUE - val);
      DigiKeyboard.print(capacitance);
      DigiKeyboard.println(" 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 < 400000L));

      pinMode(OUT_PIN, INPUT);  
      val = analogRead(OUT_ANA); // OUT_PIN in Nano version
      digitalWrite(IN_PIN, HIGH);
      int dischargeTime = (int)(t / 1000L) * 5;
      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);

      if (capacitance > 1000.0) {
        DigiKeyboard.print(capacitance / 1000.0);
        DigiKeyboard.println(" uF");
      } else {
        DigiKeyboard.print(capacitance);
        DigiKeyboard.println(" nF");
      }
      DigiKeyboard.println(val); // usually ~ 520 (because we wait until digVal == 1?)
      DigiKeyboard.println(t); // depends on C: ~ 26000 for 1 µF, ~ 2600 for 100 nF, ~ 250000 for 10 µF
  }

  digitalWrite(1, 1);
  delay(10);
  while (micros() % 1000 != 0);
  digitalWrite(1, 0);

}
1

The reason this doesn't work is that PB5 is pulled high (as it's used as -RESET pin on the board). The code can be rewritten to use only one ADC pin though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.