TucoRamirez
Senior Member
Offline
Posts: 307
Thank You
-Given: 257
-Receive: 115
Tuco ... dead or Alive
|
|
« on: July 06, 2015, 10:15:51 10:15 » |
|
Hi, I bought a HCZ-H8 sensor, quite cheap , anyway the accuracy needed in my application is not that high, so it's ok. So we need this sensor and any temperature sensor, in order to associate the measured impedance (by applying 'backwards' a voltage divider). The datasheet indicates te following LUT (i multiplied it x2 but i think i'll trim it to x3 to avoid some identical values)... uint16_t temptables[]={50,100,150,200,250,300,350,400,450,500,550,600,600};//last just to avoid a limit test
uint16_t RHtableX2[]= {40000, 20000, 9600, 4200, 1960, 960, 500, 260, 146, 82, 46, 26, 14 , 8, 4, //T=5*( 0+1) 30000, 14800, 6800, 3000, 1400, 700, 380, 200, 114, 64, 38, 22, 13 , 7, 4, //T=5*( 1+1) 22000, 10600, 4800, 2200, 1040, 520, 280, 160, 92, 54, 32, 19, 11 , 7, 4, //T=5*( 2+1) 16400, 7800, 3600, 1640, 800, 400, 220, 128, 74, 44, 28, 17, 10 , 6, 4, //T=5*( 3+1) 12600, 6000, 2800, 1260, 620, 320, 174, 98, 62, 38, 23, 15, 10 , 6, 4, //T=5*( 4+1) 9800, 4600, 2200, 980, 480, 240, 148, 86, 52, 32, 20, 13, 9 , 6, 4, //T=5*( 5+1) 8000, 3600, 1740, 780, 380, 200, 122, 72, 44, 28, 18, 12, 8 , 6, 3, //T=5*( 6+1) 6600, 3000, 1420, 640, 320, 172, 102, 60, 38, 24, 16, 11, 8 , 5, 3, //T=5*( 7+1) 5600, 2600, 1200, 540, 260, 146, 88, 52, 34, 22, 15, 10, 7 , 5, 3, //T=5*( 8+1) 5000, 2200, 1020, 460, 220, 126, 76, 46, 30, 20, 14, 9, 7 , 5, 3, //T=5*( 9+1) 4400, 2000, 900, 400, 200, 110, 68, 42, 28, 18, 13, 9, 7 , 5, 3, //T=5*(10+1) 4200, 1840, 820, 360, 182, 100, 60, 38, 26, 17, 12, 8, 6 , 5, 3 }; //T=5*(11+1) // 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90-----RH
uint16_t getpeaks[16],threshold,min,max,amp; uint16_t gettemps[16],temperature;
Now on each measurement, pick 16 or more points and do the calculation of the min, max, midpoint, in order to have an average amplitude then to obtain the impedance ... i.e. i'm using TIM4 to generate the 1Khz pwm signal, then i can hang on the tim4 flag to have a start point, then i put a delay to begin to sample... while(1) { // first, read temperature: while((TIM4->SR & TIM_SR_UIF)==0x00){}; dummy=400; do{dummy--;} while (dummy>0); getpeaks[i]=ReadChannel(10); gettemps[i]=ReadChannel(11); i++; if (i==16) { // store temperature and voltage on 16 measurements threshold=0; temperature=0; for (i=0;i<16;i++) { temperature +=gettemps[i]; threshold +=getpeaks[i]; } // average by /16 threshold >>=4; temperature >>=4; min=0;max=0; // sort min max and calculate average min and average max: uint8_t ci,cj; ci=0; cj=0; for (i=0;i<16;i++) { if (getpeaks[i]>threshold) {max+=getpeaks[i];ci++;} else {min+=getpeaks[i];cj++;} } min /=cj; max /=ci; amp = 0; amp = max; amp -= min; i=0; // Now Amplitude is known, now apply the voltage divider relation Rcal= 47 (k) Rmes = (409500 / amp)-100; Rmes *= Rcal; Rmes /=100; //for the X2 table
// and here do whatever you want to get your temperature ... 1 degree= 10 50 degrees= 500 /* skip if temperature < 5 degrees and > 60 in order to fit in the lut from the datasheet.... */ if (Tmes > 600) { //here comes the error condition High }
if (Tmes < 50) { //here comes the error condition Low } else { // round/ fix temperature in order to approach it to the LUT RHtemp=Tmes; RHDelta= temptables[2]-temptables[1]; RHDelta>>=1; for (j=0;j<12;j++) { if (temptables[j+1]-RHDelta>RHtemp) { (RHTTemp = temptables[j]); break; } } // j contains the position to fetch ... Now do a fetch using the resistor... for (k=1;k<15;k++) { if (RHtableX2[j*15+k]<Rmes) { (RHVal = RHtableX2[j*15+k]);//-1 break; } } RH=20 + (5*(k+1)); } TmpVal=RH; // And here RH contains the value of the relative humidity... ( +/-3 RH% ) StopPwm; GPIOB->MODER &= ~(2<<(HCpwm*2));// change to HiZ GPIOB->ODR &= ~(1<<8);
DelayLoop(50); GPIOB->MODER |= (af<<(HCpwm*2));
StartPwm; DelayLoop(4); } } }
I'll put online the final mess later ... i'm working on the wind speed, battery charging and menu stuff now... best regards...
|