diff --git a/am2302.c b/am2302.c index 57b248d..d1b4d6c 100644 --- a/am2302.c +++ b/am2302.c @@ -58,6 +58,15 @@ #define SENSOR_is_low !(PIN_SENSOR & (1 << SENSOR)) +/** + * @brief init avr for am2302 sda + */ +inline void am2302_init(void); +{ + DDR_SENSOR &= ~(1 << SENSOR); // define as input + PORT_SENSOR &= ~(1 << SENSOR); // disable pullup +} + uint8_t am2302(uint16_t *humidity, uint16_t *temp) { if (SENSOR_is_low) @@ -73,13 +82,35 @@ // Bus master has released time min: 20us, typ: 30us, max: 200us uint8_t timeout = 200; - while(SENSOR_is_hi) {_delay_us(1); if (!timeout--) {return 2;}} + while(SENSOR_is_hi) + { + _delay_us(1); + if (!timeout--) + { + return 2; + } + } // AM2302 response signal min: 75us typ:80us max:85us timeout = 85; - while(SENSOR_is_low) {_delay_us(1); if (!timeout--) {return 3;}} // response to low time + while(SENSOR_is_low) + { + _delay_us(1); + if (!timeout--) + { + return 3; + } + } // response to low time + timeout = 85; - while(SENSOR_is_hi) {_delay_us(1); if (!timeout--) {return 4;}} // response to high time + while(SENSOR_is_hi) + { + _delay_us(1); + if (!timeout--) + { + return 4; + } + } // response to high time /* @@ -90,35 +121,63 @@ */ uint8_t sensor_data[5]={0}; + for(uint8_t i = 0; i < 5; i++) { uint8_t sensor_byte = 0; - for(uint8_t j = 1; j <= 8; j++) // get 8 bits from sensor + + // get 8 bits from sensor + for(uint8_t j = 1; j <= 8; j++) { + // wait for sensor response timeout = 55; - while(SENSOR_is_low) {_delay_us(1); if (!timeout--) {return 5;}} // signal "0", "1" low time - _delay_us(30); - sensor_byte <<= 1; // add new lower byte - if (SENSOR_is_hi) // if sda high after 30us => bit=1 else bit=0 + while(SENSOR_is_low) { - sensor_byte |= 1; + _delay_us(1); + + // if timeout == 0 => sensor do not response + if (!timeout--) + { + return 5; + } + } + + // wait 30 us to check if bit is logical "1" or "0" + _delay_us(30); + sensor_byte <<= 1; // add new lower bit + + // If sda ist high after 30 us then bit is logical "1" else it was a logical "0" + // For a logical "1" sda have to be low after 75 us. + if (SENSOR_is_hi) + { + sensor_byte |= 1; // add logical "1" timeout = 45; // 30us - 75us = 45us - while(SENSOR_is_hi) {_delay_us(1); if (!timeout--) {return 6;}} + + while(SENSOR_is_hi) + { + _delay_us(1); + + if (!timeout--) + { + return 6; + } + } } } + sensor_data[i] = sensor_byte; } // checksum - if ( ((sensor_data[0]+sensor_data[1]+sensor_data[2]+sensor_data[3]) & 0xff ) != sensor_data[4]) + if ( ((sensor_data[0] + sensor_data[1] + sensor_data[2] + sensor_data[3]) & 0xff ) != sensor_data[4]) { // debug output //printf("%b %b %b %b %b %b" CR, sensor_data[0], sensor_data[1], sensor_data[2], sensor_data[3], sensor_data[4], ((sensor_data[0]+sensor_data[1]+sensor_data[2]+sensor_data[3]) & 0xff )); return 7; } - *humidity = (sensor_data[0]<<8) + sensor_data[1]; - *temp = (sensor_data[2]<<8) + sensor_data[3]; + *humidity = (sensor_data[0] << 8) + sensor_data[1]; + *temp = (sensor_data[2] << 8) + sensor_data[3]; return 0; } diff --git a/am2302.h b/am2302.h index 59c731b..03c1b18 100644 --- a/am2302.h +++ b/am2302.h @@ -26,7 +26,7 @@ uint8_t am2302(uint16_t *humidity, uint16_t *temp); - +inline void am2302_init(void); #endif /* AM2302_H_ */ diff --git a/main.c b/main.c index 84ead68..a018805 100644 --- a/main.c +++ b/main.c @@ -34,11 +34,9 @@ int main(void) { - DDR_SENSOR &= ~(1 << SENSOR); // define as input + am2302_init(); DDR_LED |= (1 << LED); // define as output - PORT_SENSOR &= ~(1 << SENSOR); // disable pullup - led_off; uart_init(BAUDRATE); @@ -51,9 +49,10 @@ uint16_t humidity = 0; uint16_t temp = 0; + // turn led on at measurement led_on; - uint8_t error = am2302(&humidity, &temp); + uint8_t error = am2302(&humidity, &temp); // get data from am2302 if (!error) { printf("%i,%i%% %i,%iC" CR, humidity/10, humidity%10, temp/10, temp%10); @@ -63,8 +62,10 @@ printf("Error %i" CR, error); } + // turn led off; led_off; + // wait one second _delay_ms(1000); }