SHT-11 temp&RH sensor readings Needs stabilizer
Igor_Rast
Posts: 357
Hi there fellow form members ,
i am using the sensiron sht-11 demo object found in the OBEX .
modified it a Little so I only get the hi resolution readings,
but I still have a problem , The readings jumps up and down allittle . by say 1 degree .
0.1 is acceptable but not more , back and forth a couple of times.
I am using these readings to display a graph in a webpage served by a wiznet w5200 . ( almost fininshed project)
and here the result is that i have spikes showing up in my graph .
anybody get an idea on how to improve the readings stability , buffer of some kind , but dont realy know how
this s the code im using now
i am using the sensiron sht-11 demo object found in the OBEX .
modified it a Little so I only get the hi resolution readings,
but I still have a problem , The readings jumps up and down allittle . by say 1 degree .
0.1 is acceptable but not more , back and forth a couple of times.
I am using these readings to display a graph in a webpage served by a wiznet w5200 . ( almost fininshed project)
and here the result is that i have spikes showing up in my graph .
anybody get an idea on how to improve the readings stability , buffer of some kind , but dont realy know how
this s the code im using now
var byte status OBJ term : "fullduplexserial" sht : "Sensirion_full" fp : "FloatString" f : "Float32" PUB main | count,tmp,rawTemp, rawHumidity, tempC, rh, dewC, TF_fp, RH_fp term.start(31, 30, 0, 115200) f.start ' start floating point object sht.start(SHT_DATA, SHT_CLOCK) ' start sensirion object waitcnt(clkfreq*3+cnt) sht.config(33,sht#off,sht#yes,sht#hires) 'configure SHT-11 term.tx(CLS) ' read SHT-11 sensor and update (note: need to set baud to 57K if want output data to PLX-DAQ) term.Str(String("MSG,Sensirion SHT-11 Demo",13)) term.Str(String("Temp_raw, RH_raw, TC_float, TF_float, RH_float, DewPtC_float, DewPtF_float, TF_fixpt, RH_fixpt, status_byte",13)) term.Str(String("CLEARDATA",13)) repeat term.Str(String("DATA,")) rawTemp := f.FFloat(sht.readTemperature) term.str(fp.FloatToFormat(rawTemp, 5, 0)) term.str(string(",")) rawHumidity := f.FFloat(sht.readHumidity) term.str(fp.FloatToFormat(rawHumidity, 5, 0)) term.str(string(",")) tempC := celsius(rawTemp) term.str(fp.FloatToFormat(tempC, 5, 1)) term.str(string(",")) term.str(fp.FloatToFormat(fahrenheit(tempC), 5, 1)) term.str(string(",")) rh := humidity(tempC, rawHumidity) term.str(fp.FloatToFormat(rh, 5, 1)) term.str(string("%, ")) dewC := dewpoint(tempC, rh) term.str(fp.FloatToFormat(dewC, 5, 1)) term.str(string(", ")) term.str(fp.FloatToFormat(fahrenheit(dewC), 5, 1)) term.str(string(", ")) TF_fp:=sht.getTemperatureF term.dec(TF_fp) term.str(string(", ")) RH_fp:=sht.getHumidity term.dec(RH_fp) term.str(string(", ")) status:=sht.readStatus term.bin(status,8) term.str(string(", ")) ' status:=sht.checkLowBat ' term.bin(status,8) term.str(string(13)) {if count//4} 'toggle every 4 cycles {sht.config(33,sht#off,sht#no,sht#lores)} '3 fast, loRes measurements {else} sht.config(33,sht#off,sht#yes,sht#hires) '1 slow, hiRes measurement count++ ' waitcnt (clkfreq*2+cnt) 'display every 2 seconds PUB celsius(t) ' from SHT1x/SHT7x datasheet using value for 3.5V supply ' celsius = -39.7 + (0.01 * t) return f.FAdd(-39.7, f.FMul(0.01, t)) PUB fahrenheit(t) ' fahrenheit = (celsius * 1.8) + 32 return f.FAdd(f.FMul(t, 1.8), 32.0) PUB humidity(t, rh) | rhLinear ' rhLinear = -2.0468 + (0.0367 * rh) + (-1.5955E-6 * rh * rh) ' simplifies to: rhLinear = ((-1.5955E-6 * rh) + 0.0367) * rh -2.0468 rhLinear := f.FAdd(f.FMul(f.FAdd(0.0367, f.FMul(-1.5955E-6, rh)), rh), -2.0468) ' rhTrue = (t - 25.0) * (0.01 + 0.00008 * rawRH) + rhLinear return f.FAdd(f.FMul(f.FSub(t, 25.0), f.FAdd(0.01, f.FMul(0.00008, rh))), rhLinear) PUB dewpoint(t, rh) | h ' h = (log10(rh) - 2.0) / 0.4343 + (17.62 * t) / (243.12 + t) h := f.FAdd(f.FDiv(f.FSub(f.log10(rh), 2.0), 0.4343), f.FDiv(f.FMul(17.62, t), f.FAdd(243.12, t))) ' dewpoint = 243.12 * h / (17.62 - h) return f.FDiv(f.FMul(243.12, h), f.FSub(17.62, h))
Comments
The simple way is to sum up ten readings, then divide by ten, and use that result.
A more complicated way is averaging over a sliding window of the last 10 results.
but you have any examples. Only one cog runs to update the reading , othe cog just use the reading , but it has to be available all the time
Your example works ,
when it takes the average of 10 readings the awnser is pretty stable, But its taking a bit long
If i let it take less readings say 5 , then I get a bigger differeance every time .
So I was tinking about the roling window you were mentioning that the cog continuesly updates the raw reading , and the program calculates the average over the last 10 raw readings every time the reading is asked
So it knows the last 10 readings , but keeps giving average with every reading added to it .
but not sure how to make that array
I figured out something like this , It looks to be working , But maybe im doing something wrong ,. any advice
1. Pick a "new value factor." F Start with 0.1, but make it selectable; higher values (0.2) will make the display more responsive, lower (0.05) more stable.
2. Seed your display value D with the first reading.
3. On each new reading R, D = D * (1 - F) + (R * F)
This makes readings contribute less and less to the final total as they get older.
I do understand de idea so it rotates tru the values that need to be written to , But its not working out completly .
The i value seems to trick me here orso .
is the aproch also available to do it like this
. let a newcog run getting the raw values into the array. repeatetly .
incorporate a lock , so it doesnt write when we are going to read from the array,.
and then in the main cog , run only the set of the rutine and get the average over the last 10 readings , ( the other cog has to stop and wait for the main cog to read the value )
this is what i did but its not realy working
@localroger .
I do understand a little the theorie behind that approche. I think .bare with me, Im not that a good with the prop starting from scratch , hope you can give a example
ill definitly work my way around managing once i get something to read/test/ figure out . thanks
UPDATE
I put the i in the variabels to be a global variable. and all works out now . nice .
im still intrested in your theorie roger as to how to implement it with this code
the tempcontrol method gets lached in a newcog , another cog displays it on the lcd , and the other one serves it at the webpage
Looks like it did the job pretty good , resulting in a lean graph
I also ended up removing the locks as this didnt seem to affect the reading/displaying , only slowing the server from responding with the xml