Added DHT and improved OneWire

pull/1/head
Ondřej Hruška 9 years ago
parent c51eacf06c
commit 49c95d1b6d
  1. 4
      lib/adc.c
  2. 88
      lib/dht11.c
  3. 16
      lib/dht11.h
  4. 25
      lib/onewire.c
  5. 36
      lib/onewire.h

@ -23,7 +23,7 @@ void adc_disable()
/** Sample analog pin with 8-bit precision */
uint8_t adc_read_byte(uint8_t channel)
{
write_low_nibble(ADMUX, channel); // Select channel to sample
set_low_nibble(ADMUX, channel); // Select channel to sample
sbi(ADMUX, ADLAR); // Align result to left
sbi(ADCSRA, ADSC); // Start conversion
@ -36,7 +36,7 @@ uint8_t adc_read_byte(uint8_t channel)
/** Sample analog pin with 10-bit precision */
uint16_t adc_read_word(uint8_t channel)
{
write_low_nibble(ADMUX, channel); // Select channel to sample
set_low_nibble(ADMUX, channel); // Select channel to sample
cbi(ADMUX, ADLAR); // Align result to right
sbi(ADCSRA, ADSC); // Start conversion

@ -0,0 +1,88 @@
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdbool.h>
#include "iopins.h"
#include "dht11.h"
/** Read one bit */
bool _dht11_rxbit(const uint8_t pin)
{
// Wait until start of pulse
while (is_low_n(pin));
uint8_t cnt = 0;
while (is_high_n(pin))
{
cnt++;
_delay_us(5);
}
return (cnt > 8);
}
/** Read one byte */
uint8_t _dht11_rxbyte(const uint8_t pin)
{
uint8_t byte = 0;
for (uint8_t i = 0; i < 8; i++)
{
if (_dht11_rxbit(pin))
byte |= (1 << (7 - i));
}
return byte;
}
/** Read tehmperature and humidity from the DHT11, returns false on failure */
bool dht11_read(const uint8_t pin, dht11_result_t* result)
{
// bus down for > 18 ms
as_output_n(pin);
pin_low_n(pin);
_delay_ms(20);
// bus up for 20-40us
pin_high_n(pin);
_delay_us(20);
// release
as_input_pu_n(pin);
// DHT should send 80us LOW & 80us HIGH
_delay_us(40);
if (!is_low_n(pin))
return false; // init error
_delay_us(80);
if (!is_high_n(pin))
return false; // init error
// skip to start of first bit
_delay_us(50);
// Receive 5 data bytes (Rh int, Rh dec, Temp int, Temp dec, Checksum)
// Decimal bytes are zero for DHT11 -> we can ignore them.
uint8_t bytes[5];
uint8_t sum = 0;
for (uint8_t i = 0; i < 5; i++)
{
uint8_t b = _dht11_rxbyte(pin);
bytes[i] = b;
if (i < 4) sum += b;
}
// Verify checksum
if (sum != bytes[4]) return false;
result->rh = bytes[0];
result->temp = bytes[2];
return true;
}

@ -0,0 +1,16 @@
#pragma once
//
// Reading temperature and relative humidity from DHT11
//
#include <stdint.h>
#include <stdbool.h>
typedef struct {
int8_t temp;
int8_t rh;
} dht11_result_t;
/** Read tehmperature and humidity from the DHT11, returns false on failure */
bool dht11_read(const uint8_t pin, dht11_result_t* result);

@ -26,7 +26,7 @@ bool ow_reset(const uint8_t pin)
/** Send a single bit */
void ow_tx_bit(const uint8_t pin, const bool bit)
void _ow_tx_bit(const uint8_t pin, const bool bit)
{
as_output_n(pin);
pin_low_n(pin);
@ -48,13 +48,13 @@ void ow_send(const uint8_t pin, const uint8_t byte)
{
for (uint8_t i = 0; i < 8; i++)
{
ow_tx_bit(pin, (byte >> i) & 0x01);
_ow_tx_bit(pin, (byte >> i) & 0x01);
}
}
/** Read a single bit */
bool ow_rx_bit(const uint8_t pin)
bool _ow_rx_bit(const uint8_t pin)
{
as_output_n(pin);
pin_low_n(pin);
@ -78,7 +78,7 @@ uint8_t ow_read(const uint8_t pin)
for (uint8_t i = 0; i < 8; i++)
{
byte = (byte >> 1) | (ow_rx_bit(pin) << 7);
byte = (byte >> 1) | (_ow_rx_bit(pin) << 7);
}
return byte;
@ -186,6 +186,7 @@ uint8_t crc8(uint8_t *addr, uint8_t len)
// --- utils for DS1820 ---
/** Read temperature in 0.0625°C, or TEMP_ERROR on error */
int16_t ds1820_read_temp(uint8_t pin)
{
@ -222,3 +223,19 @@ int16_t ds1820_read_temp_c(uint8_t pin)
return (int16_t) temp;
}
bool ds1820_single_measure(uint8_t pin)
{
ow_reset(pin);
ow_send(pin, SKIP_ROM);
ow_send(pin, CONVERT_T);
if(!ow_wait_ready(pin)) {
return false;
}
ow_reset(pin);
ow_send(pin, SKIP_ROM);
return true;
}

@ -1,5 +1,9 @@
#pragma once
//
// Utils for Dallas OneWire bus (DS1820 etc)
//
#include <stdint.h>
#include <stdbool.h>
@ -10,47 +14,45 @@
/** Perform bus reset. Returns true if any device is connected */
bool ow_reset(const uint8_t pin);
/** Send a single bit */
void ow_tx_bit(const uint8_t pin, const bool bit);
/** Send a single byte */
void ow_send(const uint8_t pin, const uint8_t byte);
/** Read a single bit */
bool ow_rx_bit(const uint8_t pin);
/** Read a single byte */
uint8_t ow_read(const uint8_t pin);
/** Wait until the device is ready. Returns false on timeout */
bool ow_wait_ready(const uint8_t pin);
/** Read bytes into an array */
void ow_read_arr(const uint8_t pin, uint8_t* array, const uint8_t count);
/** Compute a CRC16 checksum */
uint16_t crc16( uint8_t *data, uint8_t len);
/** Compute a CRC8 checksum */
uint8_t crc8(uint8_t *addr, uint8_t len);
// --- utils for DS1820 ---
#define TEMP_ERROR -32768
/** Read temperature in 0.0625°C, or TEMP_ERROR on error */
/**
* Read temperature in 0.0625°C, or TEMP_ERROR on error
* Use this where you'd normally use READ_SCRATCHPAD
*/
int16_t ds1820_read_temp(uint8_t pin);
/** Read temperature in 0.1°C, or TEMP_ERROR on error */
/**
* Read temperature in 0.1°C, or TEMP_ERROR on error
* Use this where you'd normally use READ_SCRATCHPAD
*/
int16_t ds1820_read_temp_c(uint8_t pin);
/**
* Perform a temperature measurement with single DS1820 device on the line
* Can be followed by a call to read temperature (READ_SCRATCHPAD).
*
* Returns false on failure (device not connected)
*/
bool ds1820_single_measure(uint8_t pin);

Loading…
Cancel
Save