Since I don’t know the specs for your sensor, I don’t know how it’s supposed to be wired up. If it has three leads (as I’m guessing it does), I imagine one would be connected to Vcc (5 V), one would be connected to ground, and the third would connect to your Orangutan’s I/O line. A small resistor on the signal line probably won’t hurt you too much, but it shouldn’t be necessary.
Pretty much any question you have about using the mega8’s hardware can be answered by looking at the mega8 datasheet, although it can be a bit difficult to follow if you’re new to AVRs. I suggest you take a quick look at the ADC section to see if its explanation of the mega8’s ADC hardware makes sense to you.
To answer your specific question: the low five bits of the ADMUX register determine the adc channel. In the code you posted you can see this here (especially since it’s well commented):
// 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;
...
PC0 is channel 0, PC1 is channel 1, …, PC5 is channel 5, ADC6 is channel 6, and ADC7 is channel 7. I suggest you connect your humidity sensor to a ADC6 and then call analog10(6) or analog8(6), depending on whether you want a 10-bit or 8-bit result.
Vbat is the voltage of your power supply (often this is a battery). Vcc is the regulated voltage used for digital logic. On the Orangutan Vcc is 5 V, but some devices use a Vcc of 3.3 V. Many sensors that use integrated circuits will expect a regulated 5 V as an input from which they will draw the power they need to operate. If you supply Vbat to them instead of Vcc, you could easily destroy them (since Vbat can often be much higher than 5 V).
[quote]Does:
DDRC |=(0 << PC5);
PORTC |=(0 << PC5);
set PC5 as input and then read from it?[/quote]
I understand the temptation to replace a 1 with a 0 when your goal is to set a bit to zero, but unfortunately this isn’t right. The << operator performs a “bit shift”. That is to say, it takes all the bits in a byte and shifts them left by the number of specified spaces. For example, imagine the byte 01101001:
01101001 << 1 = 11010010 (bit shift this number left by one bit)
01101001 << 3 = 01001000 (bit shift this number left by three bits)
01101001 >> 3 = 00001101 (bit shift this number right by three bits)
Because of the nature of binary numbers, bit shifting left is the same as multiplying by a power of two and bit shifting right is the same as dividing by a power of two. For example, take an arbitrary byte referred to as x that we will bit shift by n bits:
x << n can also be written as x * 2^n
x >> n can also be written as (int)(x / 2^n)
Now, in this light, if we look at 0 << PC5, we see that’s the same as 0 * 2^PC5, which is always zero. It doesn’t even matter what the value of PC5 is. Bit shifting zero will always just get us zero, so we’re going to need a different approach. It turns out that the correct way to clear (set to zero) a single bit in a byte while leaving all the other bits unchanged is the following:
DDRC &= ~(1 << PC5);
The ~ operator is “bitwise not” and will turn all 1 bits to 0 and all 0 bits to 1. If (1 << PC5) = (1 << 5) = 00100000, then ~(1 << PC5) = 11011111. When we AND this with DDRC, only bit 5 gets set to zero since 1 & x = x and 0 & x = 0. For a more detailed explanation of this, please see nexisnet’s fantastic post in this thread:
Something else I should note here is that the effect of the PORT register differs depending on whether the pin in question is an output or an input. If the DDR bit for the pin is 1, the pin is an output and the PORT bit for the pin determines if the pin is driven high (PORT bit = 1) or driven low (PORT bit = 0). If the DDR bit for the pin is 0, the pin is an input and the PORT bit for the pin determines if the pin weakly pulled high (PORT bit = 1) or floating (PORT bit = 0). Do you understand what I mean by “pulled high” and “floating”?
Note that when you are working with an AVR digital I/O pin, you set its output behavior with the PORT register and you read its input value with its PIN register. So, putting it all together, if I want to know what the value is of pin PC5, I would do the following:
DDRC &= ~(1 << PC5); // set PC5 as a digital input
unsigned char value = PINC & (1 << PC5); // use (1 << PC5) to mask away all of PINC except for bit PC5
If value = 0, I know that the input value on pin PC5 was low. If value = 1 << PC5, I know that the input value on pin PC5 was high.
- Ben
