Sensors

Hi, I have a orangutan mega8, and am tryin got configure a humidity sensor which is described by manufacturer as a 2-terminal variable resistance humidity sensor. just a little box to two metal contact prongs sticking out the bottom.
I have one of those going into the signal i/o and one going to ground. My program flashes an led based on the value of the humidity sensor.
But i cant get it to change and therefore wonder if the sensor is actually sensing? I held a boiling kettle under it and nothing… I am also wondering whether my code is refreshing the value once it has been set - does my infinte for loop work? It is on ADC6.
Here is the code

// F_CPU tells util/delay.h our clock frequency
#define F_CPU 8000000UL // Orangutan frequency (8MHz)
//#define F_CPU 20000000UL // Baby Orangutan frequency (20MHz)
#include <avr/io.h>
#include <util/delay.h>

void delayms( uint16_t millis ) {
while ( millis ) {
_delay_ms( 1 );
millis--;
}
}

void analog_init(void)
{
// The Orangutans have an external reference voltage on the AREF
// pin tied to our +5V regulated Vcc. We want to set our ADC to
// use this as our reference. The ADMUX register needs REFS0
// set to 1, and REFS1 set to zero for this mode.
ADMUX = (1 << REFS0);

// The ADC Control and Status Register A sets up the rest of
// what we need. Three bits ADPS0, 1, and 2, set the prescale
// for how fast our conversions are done. In this example
// we use CPU/64, or mode 6:

ADCSRA = (6 << ADPS0);

// Conversions take 13 ADC cycles to complete the sample and hold.
// Dividing our CPU by 64 gives us the following samples/sec for
// our devices:
//
// Orangutan 9615
// Baby-O 24038
// X2 24038

// Finally, we enable the ADC subsystem:

ADCSRA |= (1 << ADEN);
}


// Read out the specified analog channel to 10 bits
unsigned int analog10(unsigned char channel)
{
// Begin by setting up the MUX so it knows which channel
// to connect to the ADC:

// Clear the channel selection (low 5 bits in ADMUX)
ADMUX &= ~0x1F;
// Select the specified channel
ADMUX |= channel;

// Now we initiate a conversion by telling the ADC's
// control register to start conversion (ADSC):

// ADC stert conversion
ADCSRA |= (1 << ADSC);

// We wait for conversion to complete by watching the
// ADSC bit on the ADCSRA register. When it goes away,
// the conversion is done:
while (bit_is_set(ADCSRA, ADSC));

// Since we're reading out ten bits, we have to read
// the results out of two different registers: ADCL for
// the low byte, and ADCH for the high byte. Caution
// here: We have to read ADCL before we read ADCH.
// Since they're both just bytes, we have to shift the
// high byte over by 8-bits and or the two together
// to make the full 10-bit value:

return (ADCL | ADCH << 8); // read ADC (full 10 bits);
}


// And now for the maximum in cheesiness: How do you do an
// 8-bit conversion if you're in 10-bit mode? Simple! Do a
// 10-bit conversion and ditch the two least significant bits.
// Laugh all you want, that's how AVRLIB does it, too.

// Read out the specified analog channel to 8 bits
unsigned int analog8(unsigned char channel)
{
return(analog10(channel) >> 2);
}


// That's it for the ADC stuff. Remember, there are lots of other
// ways the ADC subsystem can be used. This is just ONE way. If it
// doesn't meet your needs, read the data sheet and experiment.


// And now for our main routine:


int main( void )
{
while(1)
{

// A variable to store our converted analog value in:
int pot;

// Initialize the ADC:
analog_init();

DDRB |= (1 << PB0); // set buzzer pin PB0 to output
DDRC |= (1<< PC5);// led breadboard
// DDRB &= ~(1 << PB3); // make PB3 (button SW3 pin) an input
DDRD |= (1<<PD1); //Led output

// The endless loop
for(;;)
{
// Store the value of our analog input:
pot = analog10(6);
if (pot > 50)
{

//PORTB &= ~( 1 << PB0 ); // buzzer off
PORTD |= (1 << PD1);//LED ON
//PORTC &=~ (1<< PC5);// turn off breadboard
delayms( pot/5 ); // delay 50 ms
//PORTB |= (1 << PB0); //BUZZER ON
//PORTC |= (1 << PC5);//turn on bread boar
PORTD &= ~(1 << PD1); // LED OFF
delayms( pot/5 ); // delay 50 ms
}

else
PORTB &= ~(1 << PB0);
PORTD &= ~(1 << PD1);

}
}
return 1;


}

Thanks guys. Any ideas?

Alex

Hello.

I suggest you change your ADC channel from 6 (your sensor) to 7 (the trimpot) and display the conversion result on the LCD. If your code is working right, you’ll see the number on the LCD updating as you turn the trimpot. I think using the LCD would be very helpful to you right now as debugging with flashing LEDs is quite limiting.

As far as the sensor goes, you really should take a look at its datasheet. If it’s a variable resistor with only two leads, you probably have to use it as part of a voltage divider circuit. Do you know the model number of your sensor or have any other information that could help you locate its datasheet?

- Ben

Cool yeah. Someone else told me that the lcd would be better. But I was also told they are quite complicated. Is there a hello world for using lcds…

I have put the sensor into the power and ground and a 47k resistor from signal to gound. i think the led was flashing at different speeds, but hard to tell so the lcd thingy would be good… if i put a lower resistor, will it make the sensor any more sensitive to change?

If you use Orangutan-lib’s LCD routines, using the LCD should be simple. Just call the functions that Orangutan-lib defines to display strings on the LCD:

orangutan-lib.sourceforge.net/docs.shtml#lcd

As for how to wire up your humidity sensor, you should not be wiring its leads to power and ground because your signal will then always be 5 V. You want to create a voltage divider:

5 V — known resistor —o--- humidity sensor (variable resistor) — GND

You would connect the node between the resistor and the sensor (marked by an o above) to your ADC input. The voltage at this node can be expressed as:

Vsignal = 5 V * R2 / (R1 + R2)

where R1 is the fixed/known resistor (e.g. 47k) and R2 is the resistance of your humidity sensor, which should correspond fairly closely to the actual humidity. The value you choose for R1 should depend on the typical resistance of your humidity sensor (e.g. does it range from 0 to 1k, 0 to 10k, or 0 to 100k?)

An alternative to using a voltage divider would be to use a capacitor with your sensor to create an RC circuit and time how long it takes for the capacitor to discharge below a certain voltage. The discharge time would relate to the resistance of your sensor. Ultimately, your problem, as I understand it, is that you have a resistor whose resistance you want to discover, but the only thing you can measure is voltage.

Without seeing the datasheet, my advice is only blind suggestion, though. You really should see if you can locate the sensor’s datasheet as it might have a suggested technique for measuring the sensor’s output. At the very least it should tell you how resistance varies as a function of humidity.

- Ben

thanks ben, you little diagrams are the best!