Hello
i got a "CES191" humidity sensor made by Cimel, and i have found the attached documentation which illustrate how to use this sensor (GND - 1st wire ; digital in 1 - 2nd wire ; out 5v- 3rd wire) , but i couldn't manage to read from it i hope that you can help.
Please post the circuit and program that you tried.
UKHeliBob:
Please post the circuit and program that you tried.
Arduino GND -> 1st wire
digital in 1 -> 2nd wire
out 5v of arduino -> 3rd wire
I've used the simple 'digital read' example in Arduino, but i don't know how to read it as a frequency
You need to determine how many times the Arduino input goes HIGH (or LOW) in a period of time. In interrupt is one way to do this. All it needs to do is increment a variable.
Use millis() for the timing so that the Arduino code is not blocked.
Once you know the total pulse count over a period you can derive the frequency and from that the humidity.
is this right?
int sensor = 1;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
const byte ledPin = 13; //using the built in LED
int lowstate = 0;
int hightstate = 0;
long ratio = 0;
void setup() {
Serial.begin(9600);
pinMode(sensor, INPUT);
startMillis = millis(); //initial start time
}
void loop() {
currentMillis = millis();
int state = digitalRead(sensor);
if(state == 1) hightstate = hightstate +1;
if(state == 0) lowstate = lowstate +1;
ratio = hightstate / (lowstate+hightstate);
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
Serial.println(state);
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
is this right?
It would have been better if you Auto Formatted it and posted it in code tags like this
int sensor = 1;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
const byte ledPin = 13; //using the built in LED
int lowstate = 0;
int hightstate = 0;
long ratio = 0;
void setup()
{
Serial.begin(9600);
pinMode(sensor, INPUT);
startMillis = millis(); //initial start time
}
void loop()
{
currentMillis = millis();
int state = digitalRead(sensor);
if (state == 1) hightstate = hightstate + 1;
if (state == 0) lowstate = lowstate + 1;
ratio = hightstate / (lowstate + hightstate);
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
Serial.println(state);
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
}
}
The idea looks OK but
1 - you don't need to count both the HIGH and LOW states
2 - do any calculations at the end of the period
3 - you should really count when the input becomes HIGH rather than when it is HIGH
4 - why are you printing state ?
UKHeliBob:
The idea looks OK but1 - you don't need to count both the HIGH and LOW states
2 - do any calculations at the end of the period
3 - you should really count when the input becomes HIGH rather than when it is HIGH
4 - why are you printing state ?
1- if i just count the HIGH states, the code should be:
ratio = hightstate / (total)
the total should be the frequency of the arduino processor?
2- I've put the ration calculation in the if clause.
3- i hope that you tell me how to do that.
4- i should print the ration and note the state, it was a mistake, thanks.
when i print the lowstate+highstate i get strange numbers (screenshot attached)
1 - you have named the variable ratio but from the small detail that you posted it looks like you should be calculating the frequency of the received signal. Whilst variables can have any name it would probably be better to give this one a name indicating what it is.
As to the calculation, the frequency of the Arduino has nothing to do with it as long as you count each change of state of the input (see 3 below). Suppose that you counted transitions between LOW and HIGH for 1 second and the total was 12,345 then the frequency would be 12,345 Hz
2 - If you mean in the portion of the program that is executed only when the period ends, then that is the right place
3 - Look at the StateChangeDetection example in the IDE. If you just poll the input each time through loop() then if it remains HIGH for more than one iteration of loop() you will get the wrong answer.
4 - do as little as possible in loop() when counting the changes of input state
You could do all of the above using an interrupt to detect and count the input changes of state but start by trying the polling method as you are now.
that's my new code
int sensor = 1;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
long freq = 0;
int state = 0;
int lstate = 0;
void setup() {
Serial.begin(9600);
pinMode(sensor, INPUT);
startMillis = millis(); //initial start time
}
void loop() {
currentMillis = millis();
state = digitalRead(sensor);
if (state != lstate) {
freq = freq +1;
lstate = state;
}
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
Serial.println(freq);
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
freq = 0;
}
}
but in the serial monitor, i always get 25?
You need to save the current state to last state each time through loop() before you read it again so that your program can detect when it has changed.
UKHeliBob:
You need to save the current state to last state each time through loop() before you read it again so that your program can detect when it has changed.
since the state is not changed i think i can just put: (lstate = state;) in the : ( if (state != lstate)) loop.
i tried changing the laststate to just before the end of loop() and i got the same result
since the state is not changed i think i can just put: (lstate = state;) in the : ( if (state != lstate)) loop.
You are right, but I have always thought that it was more explicit to save the current state before reading it again. At the moment you are incrementing freq at every change of state, which is not strictly neccessary. You could add a test to see whether the state is HIGH (or LOW) when it changes. This will halve the number of times that freq is updated.
Depending on the frequencies involved you may need to use an interrupt to increment the counter.
Hold on a minute !
I have just noticed that you are using pin 1 as your sensor input and that is used by the Serial interface. Try using another digital pin (not pin 0) for the input. While you are at it, change the data type of state and lstate to byte, freq to unsigned int and the input pin to const byte.
Thank you very much! i really forget about that at all
now i get: 33553, and when removing the pin i get 0, that means it's working
thanks!
now i should try to know how much humidity is.
i will post any tries i make.
From the section of the data sheet that you attached to the first post it appears that the humidity is inversely proportional to the output frequency
UKHeliBob:
From the section of the data sheet that you attached to the first post it appears that the humidity is inversely proportional to the output frequency
that means if i have 33k the humidity should be a value minus that frequency? sorry, i didn't understand it well.
Today at 17:59:41
Quote from: UKHeliBob on Today at 16:00:24
From the section of the data sheet that you attached to the first post it appears that the humidity is inversely proportional to the output frequency
that means if i have 33k the humidity should be a value minus that frequency?
No.
If the frequency were directly proportional to the humidity then doubling the humidity would double the frequency. However, it seems that the frequency is inversely proportional to the frequency which means that if the humidity doubles the frequency halves.
The partial data sheet that you posted seems to indicate that at a frequency of 16 KHz the humidity is 76% and that a variation of 25 Hz indicates a humidity variation of 1%
So, if you are getting a frequency of 33 KHz whilst counting every state change the actual frequency is about 16.5 KHz which means that the humidity is about 76 - ((16,500 - 16,000) / 25) which gives a result of about 56% If I am right then you should be able to write a formula based on the one above into which you can put your frequency measurement and derive the humidity.
Bear in mind that I am going on very little information in a foreign language so could be way off beam.
Thank you.
that's my new code
int sensor = 2;
unsigned long startMillis; //some global variables available anywhere in the program
unsigned long currentMillis;
const unsigned long period = 1000; //the value is a number of milliseconds
long freq = 0;
float hum = 0;
int state = 0;
int lstate = 0;
void setup() {
Serial.begin(9600);
pinMode(sensor, INPUT);
startMillis = millis(); //initial start time
}
void loop() {
currentMillis = millis();
state = digitalRead(sensor);
if (state != lstate) {
freq = freq +1;
}
if (currentMillis - startMillis >= period) //test whether the period has elapsed
{
freq = freq/2;
hum = 76 - ((freq - 16000)/25);
Serial.println(hum);
startMillis = currentMillis; //IMPORTANT to save the start time of the current LED state.
freq = 0;
}
lstate = state;
}
i'm getting now 43
i will test with another sensor and see if i get the same results.
if (state != lstate)
Personally I would change this to
if (state != lstate && state == HIGH)
to avoid the need to divide the frequency by 2 later.
Does the reading go in the correct direction if you change the humidity ?
UKHeliBob:
if (state != lstate)Personally I would change this to
if (state != lstate && state == HIGH)to avoid the need to divide the frequency by 2 later.
Does the reading go in the correct direction if you change the humidity ?
i think it's going on the right direction, when i blow on the sensor the humidity increase, but the results are very far, i get the results shown in the attached files (the float is the humidity, it is very high?)
the float is the humidity, it is very high?
Very high ?
Well, the maximum relative humidity is 100% so, yes, the numbers in your output are high.
Incidentally, you can copy from the Serial monitor and paste directly into a post here.


