NodeMCU 보드를 사용하여 커패시터의 방전 시간을 측정하려고합니다. 아래의 전체 스케치를 참조하십시오. 이 코드는 잘 동작하지만, 타이밍을 위해 ESP.getCycleCount()
함수와 인터럽트를 사용하여 더 나은 시간 스케일을 얻으려면이 코드를 개선하고 싶습니다.Arduino/ESP8266 샘플을 얻기 위해 인터럽트 사용하기
startTime = micros();
while (digitalRead(capPos) == HIGH) {
delayMicroseconds (1);
}
endTime = micros();
while
루프 나는이 같은 뭔가 위의 함수를 대체 capPos 핀의 하강 에지를 듣고, 인터럽트 기반 기능의 형태로 재 작성하려면 :
startTime = micros();
attachInterrupt(digitalPinToInterrupt(capPos), dischargeInterrupt, FALLING);
}
void dischargeInterrupt() {
endTime = micros();
detachInterrupt(digitalPinToInterrupt(capPos));
그 후 원래 코드가 계속됩니다.
테 문제 저는 100 개의 샘플을 채취하는 방법을 알고 있습니다. startTime
이 수행 된 후에 인터럽트를 설정하면이 루틴은 100 개의 반복 작업 중 다음 작업을 완료하고 수행합니다. 대신 인터럽트가 오기를 기다려야하며 원래 스케치에 따라 나머지 루틴을 완료해야합니다. 오히려 새로운 인터럽트이기 때문에, 나는 그 부분으로 어디에서 시작해야할지 전혀 모른다.
그래서해야할 것에 : - loop()
전화 getEC()
getEC()
100 개 샘플을 취 방전 핀을 설정충전 캡을 설정 인터럽트는 방전을 측정 시각.
인터럽트가 오면 시간이 경과합니다. 네거티브 캡주기가 수행되고 한 번의 샘플링이 완료됩니다. LOW에 핀 낙하에 즉시 반응 시간이 훨씬 더 높은 해상도를 사용 :
이 변화의 주요 목적은 타이밍이 더 정확한 확인하는 것입니다. 현재 마이크로 초 해상도가 작업을 수행하지만 심각한 한계가 있습니다.
다음내 완료, 작업, 스케치 :
// capacitor based TDS measurement
// pin D5 C+ - 330 ohm resistor----------|------------|
// | |
// cap EC probe or
// | resistor (for simulation)
// pin D6 C- ----------------------------| |
// |
// pin A0 EC -----------------------------------------|
#include <Average.h>
int capPos = D5; //C+
int capNeg = D6; //C-
int EC = D7; //EC
float CAP = 47; // capacity in nF
#define calibration 150 // a calibration factor to link time with EC.
void setup() {
Serial.begin(9600);
}
void loop() {
float EC = getEC(); // get the EC as mS/cm.
Serial.println (", EC: " + String(EC) + " mS/cm");
delay(100);
}
float getEC() {
int samples = 100; // number of EC samples to take and average.
unsigned long startTime; // the time stamp (in microseconds) the measurement starts.
unsigned long endTime; // the time stamp (in microseconds) the measurement is finished.
unsigned int dischargeTime; // the time it took for the capacitor to discharge.
Average<unsigned int> discharge(samples); // Take measurements on both the positive and negative cycles.
unsigned int chargeDelay = 500; // The time (in microseconds) given to the cap to fully charge/discharge - about 10x RC is a good value.
int startLevel; // analog level of the pin.
int endLevel;
pinMode(A0, INPUT);
for(int i=0; i<samples; i++) { // take <samples> measurements of the EC.
// Stage 1: fully charge capacitor for positive cycle.
// C+ high, C- low, EC disconnected.
pinMode (EC, INPUT);
pinMode (capPos,OUTPUT);
digitalWrite (capPos, HIGH);
pinMode (capNeg, OUTPUT);
digitalWrite (capNeg, LOW);
delayMicroseconds(chargeDelay);
// Stage 2: positive side discharge; measure time it takes.
// C+ disconnected, C- low, EC low.
pinMode (capPos,INPUT); //set C+ to input to keep voltage from grounding a discharging thru this output pin
pinMode (EC, OUTPUT);
digitalWrite (EC, LOW);
// Measure time until capPos goes LOW. Can't use pulseIn() here as the pin will be high already.
startTime = micros();
while (digitalRead(capPos) == HIGH) {
delayMicroseconds (1);
}
endTime = micros();
// handle potential overflow of micros() just as we measure, this happens every 70 minutes.
if (endTime < startTime) dischargeTime = 4294967295 - startTime + endTime;
else dischargeTime = endTime - startTime;
discharge.push(dischargeTime);
// Stage 3: fully charge capacitor for negative cycle. C+ low, C- high, EC disconnected.
pinMode (EC, INPUT);
pinMode (capPos,OUTPUT);
digitalWrite (capPos, LOW);
pinMode (capNeg, OUTPUT);
digitalWrite (capNeg, HIGH);
delayMicroseconds(chargeDelay);
// Stage 4: negative side charge; don't measure as we just want to balance it the directions.
// C+ disconnected, C- low, EC low.
pinMode (capPos,INPUT); //set C+ to input to keep voltage from grounding a discharging thru this output pin
pinMode (EC, OUTPUT);
digitalWrite (EC, HIGH);
delayMicroseconds(dischargeTime);
}
float dischargeAverage = discharge.mean();
Serial.print("Discharge time: ");
Serial.print(dischargeAverage);
// Calculate EC from the discharge time.
return dischargeAverage;
}
이의 당신에게 마이크로보다 더 정확한 타이밍 정보를 제공하는 방법이 표시되지 않습니다 ... – dandavis