BASIC4MCU | 질문게시판 | 답변 : 아두이노 millis ->atmega128에서 사용하고 싶습니다.
페이지 정보
작성자 master 작성일2022-05-19 17:27 조회563회 댓글2건본문
#define TdsSensorPin A1
#define VREF 5.0 // analog reference voltage(Volt)of the ADC
#define SCOUNT 30 // sum of sample point
//
int analogBuffer[SCOUNT]; // store the analog value in the array,read from ADC
int analogBufferTemp[SCOUNT];
int analogBufferIndex=0,copyIndex=0;
float averageVoltage=0,tdsValue=0,temperature=25;
//
volatile char flag40=0,flag800=0;
//
ISR(TIMER1_COMPA_vect){ // 40ms
static char c=0;
flag40=1;
if(++c>=20){ c=0; flag800=1; } // 800ms
}
//
int main(){
Serial.begin(115200);
pinMode(TdsSensorPin,INPUT);
TCCR1B=0x0B; OCR1A=9999; TIMSK=0x10; SREG=0x80; //40ms
while(1){
if(flag40){ flag40=0; // 40ms
analogBuffer[analogBufferIndex]=analogRead(TdsSensorPin); // read ADC
analogBufferIndex++;
if(analogBufferIndex==SCOUNT)analogBufferIndex=0;
}
//
if(flag800){ flag800=0; // 800ms
for(copyIndex=0;copyIndex<SCOUNT;copyIndex++)analogBufferTemp[copyIndex]=analogBuffer[copyIndex];
averageVoltage=getMedianNum(analogBufferTemp,SCOUNT)*(float)VREF/1024.0; // read the analog value more stable by the median filtering algorithm,and convert to voltage value
float compensationCoefficient=1.0+0.02*(temperature-25.0); // temperature compensation formula: fFinalResult(25^C)=fFinalResult(current)/(1.0+0.02*(fTP-25.0));
float compensationVolatge=averageVoltage/compensationCoefficient; // temperature compensation
tdsValue=(133.42*compensationVolatge*compensationVolatge*compensationVolatge-255.86*compensationVolatge*compensationVolatge+857.39*compensationVolatge)*0.5; //convert voltage value to tds value
//Serial.print("voltage:"); Serial.print(averageVoltage,2); Serial.print("V ");
Serial.print("TDS Value:"); Serial.print(tdsValue,0); Serial.println("ppm");
}
}
}
int getMedianNum(int bArray[],int iFilterLen){
int bTab[iFilterLen];
for(byte i=0;i<iFilterLen;i++)bTab[i]=bArray[i];
int i,j,bTemp;
for(j=0;j<iFilterLen-1;j++){
for(i=0;i<iFilterLen-j-1;i++){
if(bTab[i]>bTab[i+1]){ bTemp=bTab[i]; bTab[i]=bTab[i+1]; bTab[i+1]=bTemp; }
}
}
if((iFilterLen&1)>0)bTemp=bTab[(iFilterLen-1)/2];
else bTemp=(bTab[iFilterLen/2]+bTab[iFilterLen/2-1])/2;
return bTemp;
}
댓글 2
조회수 563akmong413님의 댓글
akmong413 작성일8MHz에서 사용하려면 timer0 쓰면 될까요?
master님의 댓글
master
타이머0의 최대는 16MHz에서 16,384ms, 8MHz에서 32,768ms 밖에 안되므로 40ms를 만들기 위해서는 변수를 하나 더 사용해야 하는 번거로움이 있습니다.
번거로워도 상관없고 구지 8비트를 사용하고 싶다면
TCCR0=0x0E; OCR0=249; TIMSK=2; //16000000/256/(1+249),4ms
이 설정은 16mHz에서 4ms이므로 8MHz에서 8ms가 됩니다.
변수로 카운트 해서 5일 때가 40ms가 되겠죠
//
16Mhz에서 20ms는 8MHz에서 40ms가 됩니다.
타이머1에서 20ms 설정을 찾으면 몇가지 종류가 나옵니다.
TCCR1B=0x0A; OCR1A=39999; TIMSK=0x10; //20ms
TCCR1B=0x0B; OCR1A=4999; TIMSK=0x10; //20ms
TCCR1B=0x0C; OCR1A=1249; TIMSK=0x10; //20ms
이 중 맘에드는 것으로 아무 것이나 골라서 사용하세요