Arduino:Основы/Измерение емкости и константы времени RC

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Версия для печати больше не поддерживается и может содержать ошибки обработки. Обновите закладки браузера и используйте вместо этого функцию печати браузера по умолчанию.

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Измерение емкости и константы времени RC[1]

Краткое описание: резистор будет заряжать конденсатор в течение TC секунд.

  • TC – R x C; это константа времени (исчисляется в секундах)
  • R – сопротивление в омах
  • C – емкость в фарадах; 1 микрофарад (мкФ) = 0,0000001 фарад

Напряжение за одну TC равно 63,2% от напряжения заряда.

  • Пример 1: 1 мегаом х 1 микрофарад = 1 секунда
  • Пример 2: 10 килоом х 100 микрофарад = 1 секунда

Этот скетч работает, потому что контакты Arduino могут быть в одном из 2 состояний, которые электрически очень сильно отличаются друг от друга.

Состояние «input» (режим ввода данных)

Задается при помощи pinMode(pin, INPUT).

  • Высокий импеданс (сопротивление); благодаря этому требования к питанию от цепи, с которой считываются данные, значительно снижаются
  • Хорошо подходит для считывания данных с датчиков, но не для управления светодиодами

Состояние «output» (режим вывода данных)

Задается при помощи pinMode(pin; OUTPUT).

  • Низкий импеданс; можно отдавать ток в 40 мА (положительное напряжение) или тянуть его
  • Хорошо подходит для управления светодиодами или другими цепями; бесполезно для считывания данных с датчиков

Кроме того, контактам можно задать состояние HIGH (+ 5 вольт), для зарядки конденсатора, или LOW («земля»), для разрядки конденсатора.

Схема построения скетча для измерителя емкости:

  • Выставляем разрядный контакт в режим INPUT (чтобы он не мог разрядить конденсатор)
  • Записываем начальное время при помощи millis()
  • Выставляем зарядный контакт в режим OUTPUT и задаем ему значение HIGH
  • Начинаем циклически проверять напряжение, пока оно не достигнет отметки 63,2%
  • Когда конденсатор будет заряжен, вычитаем текущее время из стартового времени, чтобы узнать, сколько времени заняла зарядка конденсатора
  • Находим емкость; для этого делим время (в секундах) на сопротивление (в омах)
  • Печатаем значение при помощи Serial.print()
  • Разряжаем конденсатор; для этого, во-первых, выставляем зарядный контакт в режим INPUT, во-вторых, выставляем разрядный контакт в режим OUTPUT и задаем ему значение LOW, и в-третьих, считываем напряжение, чтобы убедиться, что конденсатор заряжен полностью
  • Запускаем цикл снова

Сам скетч представлен ниже:

/*  Измеритель емкости
 *  Пол Бэджер (Paul Badger), 2008 год
 *  Демонстрирует использование константы времени TC 
 *  для измерения заряда конденсатора
 *
 *  Теория
 * 
 *  Конденсатор заряжается через резистор в течение 
 *  одной константы времени, именуемой здесь TC
 * 
 *  TC = R x C; константа времени (в секундах)
 *  R = сопротивление (в омах)
 *  C = емкость (в фарадах); 1 микрофарад (мкФ) = 0,0000001 фарад 
 *
 *  Напряжение конденсатора за одну константу времени 
 *  определяется как 63,2% от зарядного напряжения.
 *
 *  Построение цепи:
 *  
 *  Тестовый конденсатор между узловой точкой и «землей»;
 *  положительная сторона электролитического конденсатора 
 *  должна быть подключена к узловой точке.
 *  Тестовый резистор между chargePin и узловой точкой.
 *  Резистор на 220 ом между dischargePin и узловой точкой.
 *  Провод между общей точкой и analogPin 
 *  (это входной контакт для аналогово-цифровых данных).
 */

#define analogPin      0         // аналоговый контакт для измерения 
                                 // напряжения в конденсаторе
#define chargePin      13        // контакт для зарядки конденсатора 
                                 // (нужно подключить к одному концу 
                                 // зарядного резистора) 
#define dischargePin   11        // контакт для разрядки конденсатора
#define resistorValue  10000.0F  // поставьте здесь емкость 
                                 // своего конденсатора;      
                                 // буква «F» говорит компилятору, 
                                 // что это число с плавающей точкой 

unsigned long startTime;
unsigned long elapsedTime;
float microFarads;              // переменная типа «число 
                                // с плавающей точкой», чтобы 
                                // сохранить точность при вычислениях
float nanoFarads;

void setup(){
  pinMode(chargePin, OUTPUT);   // делаем chargePin 
                                // выходным контактом
  digitalWrite(chargePin, LOW);  

  Serial.begin(9600);           // инициализируем последовательную 
                                // коммуникацию (для отладки)
}

void loop(){
  digitalWrite(chargePin, HIGH);  // задаем контакту chargePin
                                  // значение HIGH, и конденсатор
                                  // начинает заряжаться
  startTime = millis();

  while(analogRead(analogPin) < 648){   // 647 это 63.2% от 1023,
                                        // и это заряд, полученный
                                        // в течение одной TC
  }

  elapsedTime= millis() - startTime;
 // конвертируем миллисекунды в секунды ( 10^-3 ), 
 // а фарады – в микрофарады ( 10^6 )  
 // (10^3 – это 1000):
  microFarads = ((float)elapsedTime / resistorValue) * 1000;   
  Serial.print(elapsedTime);       // печатаем значение 
                                   // в мониторе порта
  Serial.print(" mS    ");         // печатаем единицы измерения 
                                   // и ставим символ 
                                   // возврата каретки

  if (microFarads > 1){
    Serial.print((long)microFarads);    // печатаем значение 
                                        // в мониторе порта

    Serial.println(" microFarads");     // печатаем единицы измерения 
                                        // и ставим символ 
                                        // возврата каретки

  }
  else
  {
    // если значение меньше одного микрофарада, 
    // конвертируем в нанофарады (0,0000000001 фарада);
    // это потребует обходного маневра, потому что Serial.print()
    // не печатает символы с плавающей точкой:

    nanoFarads = microFarads * 1000.0;  // умножаем на 1000, 
                                        // чтобы преобразовать
                                        // в нанофарады
    Serial.print((long)nanoFarads);     // печатаем значение 
                                        // в мониторе порта
    Serial.println(" nanoFarads");      // печатаем единицы измерения
                                        // и символ возврата каретки
  }

  /* разрядка конденсатора  */
  digitalWrite(chargePin, LOW);         // задаем зарядному контакту 
                                        // значение LOW 
  pinMode(dischargePin, OUTPUT);        // задаем разрядному контакту 
                                        // режим OUTPUT 
  digitalWrite(dischargePin, LOW);      // задаем разрядному контакту 
                                        // значение LOW 
  while(analogRead(analogPin) > 0){     // ждем, пока конденсатор 
                                        // не разрядится полностью
  }

  pinMode(dischargePin, INPUT);         // снова задаем разрядному 
                                        // контакту режим INTPUT 
}

Что еще можно попробовать

  • Если зарядка выполняется слишком быстро, поставьте резисторы побольше, а если слишком долго – поменьше
  • Измерьте значения конденсаторов, подключив их и параллельно, и последовательно. Сверьте полученный результат с теоретическими расчетами
  • Для большей точности рассчитайте среднее число на основе нескольких считанных данных
  • Чтобы добавить функцию автовыбора диапазона измеряемых данных, подключите к разным контактам разные зарядные резисторы
  • Модифицируйте скетч, чтобы зарядный резистор также разряжал конденсатор. Обратите внимание, что новое значение, сообщающее процент заряда, не будет в два раза превышать прошлое значение. Почему – объясняется в графике выше (на том, где изображена кривая).

См.также

Внешние ссылки