Added DHT and improved OneWire
This commit is contained in:
@@ -23,7 +23,7 @@ void adc_disable()
|
|||||||
/** Sample analog pin with 8-bit precision */
|
/** Sample analog pin with 8-bit precision */
|
||||||
uint8_t adc_read_byte(uint8_t channel)
|
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(ADMUX, ADLAR); // Align result to left
|
||||||
sbi(ADCSRA, ADSC); // Start conversion
|
sbi(ADCSRA, ADSC); // Start conversion
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ uint8_t adc_read_byte(uint8_t channel)
|
|||||||
/** Sample analog pin with 10-bit precision */
|
/** Sample analog pin with 10-bit precision */
|
||||||
uint16_t adc_read_word(uint8_t channel)
|
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
|
cbi(ADMUX, ADLAR); // Align result to right
|
||||||
sbi(ADCSRA, ADSC); // Start conversion
|
sbi(ADCSRA, ADSC); // Start conversion
|
||||||
|
|
||||||
|
|||||||
+88
@@ -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;
|
||||||
|
}
|
||||||
+16
@@ -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);
|
||||||
+21
-4
@@ -26,7 +26,7 @@ bool ow_reset(const uint8_t pin)
|
|||||||
|
|
||||||
|
|
||||||
/** Send a single bit */
|
/** 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);
|
as_output_n(pin);
|
||||||
pin_low_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++)
|
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 */
|
/** Read a single bit */
|
||||||
bool ow_rx_bit(const uint8_t pin)
|
bool _ow_rx_bit(const uint8_t pin)
|
||||||
{
|
{
|
||||||
as_output_n(pin);
|
as_output_n(pin);
|
||||||
pin_low_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++)
|
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;
|
return byte;
|
||||||
@@ -186,6 +186,7 @@ uint8_t crc8(uint8_t *addr, uint8_t len)
|
|||||||
|
|
||||||
// --- utils for DS1820 ---
|
// --- utils for DS1820 ---
|
||||||
|
|
||||||
|
|
||||||
/** Read temperature in 0.0625°C, or TEMP_ERROR on error */
|
/** Read temperature in 0.0625°C, or TEMP_ERROR on error */
|
||||||
int16_t ds1820_read_temp(uint8_t pin)
|
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;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
+19
-17
@@ -1,5 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
//
|
||||||
|
// Utils for Dallas OneWire bus (DS1820 etc)
|
||||||
|
//
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
@@ -10,47 +14,45 @@
|
|||||||
/** Perform bus reset. Returns true if any device is connected */
|
/** Perform bus reset. Returns true if any device is connected */
|
||||||
bool ow_reset(const uint8_t pin);
|
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 */
|
/** Send a single byte */
|
||||||
void ow_send(const uint8_t pin, const uint8_t 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 */
|
/** Read a single byte */
|
||||||
uint8_t ow_read(const uint8_t pin);
|
uint8_t ow_read(const uint8_t pin);
|
||||||
|
|
||||||
|
|
||||||
/** Wait until the device is ready. Returns false on timeout */
|
/** Wait until the device is ready. Returns false on timeout */
|
||||||
bool ow_wait_ready(const uint8_t pin);
|
bool ow_wait_ready(const uint8_t pin);
|
||||||
|
|
||||||
|
|
||||||
/** Read bytes into an array */
|
/** Read bytes into an array */
|
||||||
void ow_read_arr(const uint8_t pin, uint8_t* array, const uint8_t count);
|
void ow_read_arr(const uint8_t pin, uint8_t* array, const uint8_t count);
|
||||||
|
|
||||||
|
|
||||||
/** Compute a CRC16 checksum */
|
/** Compute a CRC16 checksum */
|
||||||
uint16_t crc16( uint8_t *data, uint8_t len);
|
uint16_t crc16( uint8_t *data, uint8_t len);
|
||||||
|
|
||||||
|
|
||||||
/** Compute a CRC8 checksum */
|
/** Compute a CRC8 checksum */
|
||||||
uint8_t crc8(uint8_t *addr, uint8_t len);
|
uint8_t crc8(uint8_t *addr, uint8_t len);
|
||||||
|
|
||||||
|
|
||||||
// --- utils for DS1820 ---
|
// --- utils for DS1820 ---
|
||||||
|
|
||||||
#define TEMP_ERROR -32768
|
#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);
|
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);
|
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);
|
||||||
|
|||||||
Reference in New Issue
Block a user