inital commit working

This commit is contained in:
IMback
2018-11-26 22:30:39 +01:00
commit 63ff73a066
13 changed files with 644 additions and 0 deletions

90
BMP280.cpp Normal file
View File

@ -0,0 +1,90 @@
#include "BMP280.h"
#include "writepin.h"
#include <util/delay.h>
BMP280::BMP280(SpiMaster* spi, volatile uint8_t *port, const uint8_t pin): _port(port), _pin(pin), _spi(spi)
{
writePin(_port, _pin, true);
}
void BMP280::write(const uint8_t address, const uint8_t data)
{
writePin(_port, _pin, false);
_spi->write(address & ~(1<<7));
_spi->write(data);
writePin(_port, _pin, true);
}
uint16_t BMP280::read16b(const uint8_t address)
{
writePin(_port, _pin, false);
_spi->write(address);
uint16_t out = static_cast<uint16_t>(_spi->read()) << 8;
out |= _spi->read();
writePin(_port, _pin, false);
return out;
}
uint8_t BMP280::read8b(const uint8_t address)
{
writePin(_port, _pin, false);
_spi->write(address);
return _spi->read();
}
uint16_t BMP280::getPressure()
{
write(CTRL_REG, 0b11100101);
_delay_ms(10);
uint16_t out = read16b(PRESS_REG_HIGH);
_delay_ms(10);
write(CTRL_REG, 0b11100100);
return compensatePressure(out);
}
#ifndef PRECOMP_COMPENSATION
uint32_t BMP280::compensatePressure(const int32_t adc_P)
{
int32_t var1, var2;
uint32_t p;
var1 = (((int32_t)t_fine)>>1) - (int32_t)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)read16b(DIG_P6));
var2 = var2 + ((var1*((int32_t)read16b(DIG_P5)))<<1);
var2 = (var2>>2)+(((int32_t)read16b(DIG_P4))<<16);
var1 = ((((read16b(DIG_P3) * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)read16b(DIG_P2)) * var1)>>1))>>18);
var1 =((((32768+var1))*((int32_t)read16b(DIG_P1)))>>15);
if (var1 == 0) return 0;
p = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;
if (p < 0x80000000)
{
p = (p << 1) / ((uint32_t)var1);
}
else
{
p = (p / (uint32_t)var1) * 2;
}
var1 = (((int32_t)read16b(DIG_P9)) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;
var2 = (((int32_t)(p>>2)) * ((int32_t)read16b(DIG_P8)))>>13;
p = (uint32_t)((int32_t)p + ((var1 + var2 + (int16_t)read16b(DIG_P7)) >> 4));
return p;
}
#else
uint32_t BMP280::compensatePressure(const int32_t adc_P)
{
if constexpr(var1StepB == 0) return 0;
uint32_t p = (((uint32_t)(((int32_t)1048576)-adc_P)-var2StepB))*3125;
if (p < 0x80000000)
{
p = (p << 1) / var1StepB;
}
else
{
p = (p / var1StepB) * 2;
}
int16_t var1 = (((int32_t)digP9value) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;
int16_t var2 = (((int32_t)(p>>2)) * ((int32_t)digP8value))>>13;
p = (uint32_t)((int32_t)p + ((var1 + var2 + (int16_t)digP7value) >> 4));
return p;
}
#endif

68
BMP280.h Normal file
View File

@ -0,0 +1,68 @@
#pragma once
#include <stdint.h>
#include "softspim.h"
#define PRECOMP_COMPENSATION
class BMP280
{
private:
static constexpr uint8_t TEMP_REG_LOW = 0xFB;
static constexpr uint8_t TEMP_REG_HIGH = 0xFA;
static constexpr uint8_t PRESS_REG_LOW = 0xF8;
static constexpr uint8_t PRESS_REG_HIGH = 0xF7;
static constexpr uint8_t CONFIG_REG = 0xF5;
static constexpr uint8_t CTRL_REG = 0xF4;
static constexpr uint8_t ID_REG = 0xD0;
static constexpr uint8_t DIG_T1 = 0x88;
static constexpr uint8_t DIG_T2 = 0x8A;
static constexpr uint8_t DIG_T3 = 0x8C;
static constexpr uint8_t DIG_P1 = 0x8E;
static constexpr uint8_t DIG_P2 = 0x90;
static constexpr uint8_t DIG_P3 = 0x92;
static constexpr uint8_t DIG_P4 = 0x94;
static constexpr uint8_t DIG_P5 = 0x96;
static constexpr uint8_t DIG_P6 = 0x98;
static constexpr uint8_t DIG_P7 = 0x9A;
static constexpr uint8_t DIG_P8 = 0x9C;
static constexpr uint8_t DIG_P9 = 0x9E;
static constexpr int32_t t_fine = 102400;
#ifdef PRECOMP_COMPENSATION
static constexpr uint16_t digP1value = 42;
static constexpr int16_t digP2value = 48;
static constexpr int16_t digP3value = 49;
static constexpr int16_t digP4value = 30;
static constexpr int16_t digP5value = -32;
static constexpr int16_t digP6value = 58;
static constexpr int16_t digP7value = 7;
static constexpr int16_t digP8value = 3;
static constexpr int16_t digP9value = 58;
static constexpr int32_t var1StepA = ((((int32_t)t_fine)>>1) - (int32_t)64000);
static constexpr int32_t var1StepB = ((((32768+((((digP3value *
(((var1StepA>>2) * (var1StepA>>2)) >> 13 )) >> 3) + ((((int32_t)digP2value) * var1StepA)>>1))>>18)))*
((int32_t)digP1value))>>15);
static constexpr int32_t var2StepA = ((((var1StepA>>2) * (var1StepA>>2)) >> 11 ) * ((int32_t)digP6value)) + ((var1StepA*((int32_t)digP5value))<<1);
static constexpr int16_t var2StepB = ((var2StepA>>2)+(((int32_t)digP4value)<<16))>>12;
static constexpr int32_t var3 = 52;
#endif
volatile uint8_t *_port;
const uint8_t _pin;
SpiMaster *_spi;
void write(const uint8_t address, const uint8_t data);
uint16_t read16b(const uint8_t address);
uint8_t read8b(const uint8_t address);
uint32_t compensatePressure(const int32_t adc_P);
public:
BMP280(SpiMaster* spi, volatile uint8_t *port, const uint8_t pin);
uint16_t getPressure();
};

97
W433DataTransmitter.cpp Normal file
View File

@ -0,0 +1,97 @@
#include "W433DataTransmitter.h"
#include "writepin.h"
W433DataTransmitter::W433DataTransmitter(volatile unsigned char *port, unsigned char pin): _port(port), _pin(pin)
{
}
void W433DataTransmitter::sendBit(const bool bit)
{
switch(bit)
{
case true:
writePin(_port,_pin,true);
_delay_us(SMALL_TIME);
writePin(_port,_pin,false);
_delay_us(LARGE_TIME);
writePin(_port,_pin,true);
_delay_us(SMALL_TIME);
writePin(_port,_pin,false);
_delay_us(LARGE_TIME);
break;
case false:
writePin(_port,_pin,true);
_delay_us(LARGE_TIME);
writePin(_port,_pin,false);
_delay_us(SMALL_TIME);
writePin(_port,_pin,true);
_delay_us(SMALL_TIME);
writePin(_port,_pin,false);
_delay_us(LARGE_TIME);
break;
}
}
void W433DataTransmitter::sendSyncpulse()
{
for(uint8_t i = 0; i < 25; ++i)
{
writePin(_port,_pin,true);
_delay_us(SYNC_TIME);
writePin(_port,_pin,false);
_delay_us(SYNC_TIME);
}
}
void W433DataTransmitter::sendEndPulse()
{
writePin(_port,_pin,false);
_delay_us(LARGE_TIME);
writePin(_port,_pin,true);
_delay_us(LARGE_TIME);
writePin(_port,_pin,false);
_delay_us(LARGE_TIME*10);
}
void W433DataTransmitter::sendRawData(const uint8_t data)
{
for(uint8_t i = 0; i < 8; i++) sendBit(data & ( 1 << (7 - i)));
}
void W433DataTransmitter::sendPacket(const uint32_t data)
{
sendSyncpulse();
_delay_us(LARGE_TIME);
sendRawData(signature);
uint8_t checksum = 0;
for(uint8_t i = 0; i < 4; ++i)
{
uint8_t dataOctet = (data & (0xFF000000 >> i*8 )) >> (24 - 8*i);
for(uint8_t i = 0; i < 8; i++) checksum = checksum + (dataOctet & ( 1 << (8 - i)));
sendRawData( dataOctet );
}
sendRawData( checksum );
sendEndPulse();
}
void W433DataTransmitter::send(const uint8_t* const data, uint16_t length)
{
uint16_t packets = length/4;
if(length % 4 != 0) ++packets;
for(uint8_t j = 0; j < packets; j++)
{
uint32_t paketData = 0;
uint8_t* paketDataPointer = reinterpret_cast<uint8_t*>(&paketData);
for(uint8_t i = 0; i < 4 && j*4+i < length; i++) paketDataPointer[3-i] = data[j*4+i];
sendPacket(paketData);
}
}
void W433DataTransmitter::send(const uint8_t data)
{
sendPacket(data);
}

31
W433DataTransmitter.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <stdint.h>
#include <util/delay.h>
class W433DataTransmitter
{
private:
static constexpr uint16_t SYNC_TIME = 800;
static constexpr uint16_t LARGE_TIME = 2000;
static constexpr uint16_t SMALL_TIME = 500;
static constexpr uint8_t signature = 0xA5;
volatile unsigned char * const _port;
unsigned char _pin;
void sendBit(const bool bit);
void sendSyncpulse();
void sendRawData(const uint8_t data);
void sendEndPulse();
public:
W433DataTransmitter(volatile unsigned char * const port, unsigned char pin);
void send(const uint8_t* const data, uint16_t length);
void send(const uint8_t data);
void sendPacket(const uint32_t data);
};

79
dht11.cpp Normal file
View File

@ -0,0 +1,79 @@
#include "dht11.h"
Dht11::Dht11(volatile unsigned char *port, volatile unsigned char *inPort, volatile unsigned char *port_ctl, const unsigned char pin): _port(port), _inPort(inPort), _port_ctl(port_ctl), _pin(pin)
{}
uint8_t Dht11::read()
{
// BUFFER TO RECEIVE
uint8_t bits[5];
uint8_t cnt = 7;
uint8_t idx = 0;
// EMPTY BUFFER
for (uint8_t i=0; i< 5; i++) bits[i] = 0;
// REQUEST SAMPLE
setDirection(_port_ctl, _pin, true);
writePin(_port, _pin, false);
_delay_ms(2);
writePin(_port, _pin, true);
setDirection(_port_ctl, _pin, false);
_delay_us(42);
// ACKNOWLEDGE or TIMEOUT
unsigned int loopCnt = LOOP_TIMEOUT_COUNT;
while(!readPin(_inPort, _pin))
if (loopCnt-- == 0) return 1;
loopCnt = LOOP_TIMEOUT_COUNT;
while(readPin(_inPort, _pin) )
if (loopCnt-- == 0) return 2;
// READ OUTPUT - 40 BITS => 5 BYTES or TIMEOUT
for (uint8_t i=0; i<40; i++)
{
loopCnt = LOOP_TIMEOUT_COUNT;
while(!readPin(_inPort, _pin))
if (loopCnt-- == 0) return 3;
loopCnt = 0;
while(readPin(_inPort, _pin))
{
_delay_us(10);
if (loopCnt++ > LOOP_TIMEOUT_SMALL_COUNT) return 4;
}
if( loopCnt > BIT_COUNT )bits[idx] |= (1 << cnt);
if (cnt == 0) // next byte?
{
cnt = 7; // restart at MSB
idx++; // next byte!
}
else cnt--;
}
// WRITE TO RIGHT VARS
// as bits[1] and bits[3] are allways zero they are omitted in formulas.
uint8_t sum;
if constexpr(DHT22) sum= bits[0] + bits[1] + bits[2] + bits[3];
else sum = bits[1] + bits[3];
if(bits[4] == sum && sum != 0)
{
if constexpr(DHT22)
{
humidity = (static_cast<uint16_t>(bits[0]) << 8) + bits[1];
temperature = (static_cast<uint16_t>((bits[2] & 0b01111111) << 8) + bits[3]);
if(bits[2] & 0b10000000) temperature=temperature*-1;
}
else
{
humidity = bits[1];
temperature = bits[3]*10;
}
return 0;
}
else return 5;
}

23
dht11.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
#include<util/delay.h>
#include "writepin.h"
class Dht11
{
static constexpr uint16_t LOOP_TIMEOUT_COUNT = (10000.0 / 16000000.0)*F_CPU;
static constexpr uint8_t LOOP_TIMEOUT_SMALL_COUNT = (100.0 / 16000000.0)*F_CPU;
static constexpr uint8_t BIT_COUNT = 6;//(8.0 / 16000000.0)*F_CPU;
static constexpr bool DHT22 = true;
volatile unsigned char * const _port;
volatile unsigned char * const _port_ctl;
volatile unsigned char * const _inPort;
const unsigned char _pin;
public:
Dht11(volatile unsigned char *port, volatile unsigned char *inPort, volatile unsigned char *port_ctl, const unsigned char pin);
uint8_t read();
int16_t humidity = 0;
uint16_t temperature = 0;
};

104
main.cpp Normal file
View File

@ -0,0 +1,104 @@
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "dht11.h"
#include "W433DataTransmitter.h"
#include "watchdog.h"
#include "softspim.h"
#include "BMP280.h"
#define TEMP_SENSOR_DATA PB4
#define TRANSMITTER_DATA PD0
#define DOOR_PIN PD2
#define POWER_PIN PD5
#define LED_PIN PD1
EMPTY_INTERRUPT( WDT_OVERFLOW_vect);
static constexpr uint8_t id = 1;
static constexpr bool WATCH_DOOR = false;
static void power(const bool power)
{
if(power)
{
PORTD |= 1 << POWER_PIN | 1 << LED_PIN;
DDRD = 1 << POWER_PIN | 1 << LED_PIN | 1 << TRANSMITTER_DATA;
DDRB = 1 << PB0 | 1 << PB1 | 1 << PB3;
}
else
{
PORTD &= ~(1 << POWER_PIN | 1 << LED_PIN | 1 << TRANSMITTER_DATA);
//DDRD &= ~(1 << TRANSMITTER_DATA);
DDRB = 0;
}
}
int main()
{
Dht11 tempSensor(&PORTB, &PINB, &DDRB, TEMP_SENSOR_DATA);
//pressure sensor
SpiMaster spi;
BMP280 pressSensor(&spi, &PORTB, PB1);
//Transmitter and transmiter power
W433DataTransmitter transmiter(&PORTD, TRANSMITTER_DATA);
sei();
wdt_set(WDTO_8S);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
uint8_t couter = 50;
while(true)
{
if(++couter > 1)
{
couter = 0;
power(true);
_delay_ms(2000);
//temperature sensor
tempSensor.read();
uint8_t paket[4];
paket[0] = 1;
paket[1] = id;
paket[2] = tempSensor.temperature >> 8;
paket[3] = tempSensor.temperature;
transmiter.send(paket, 4);
//humidity sensor
paket[0] = 2;
paket[2] = tempSensor.humidity >> 8;
paket[3] = tempSensor.humidity;
transmiter.send(paket, 4);
//presure sensor
uint16_t pressure = pressSensor.getPressure();
paket[0] = 3;
paket[2] = pressure >> 8;
paket[3] = pressure;
transmiter.send(paket, 4);
//door
if constexpr(WATCH_DOOR)
{
paket[0] = 0;
paket[1] = 2;
paket[2] = 0;
paket[3] = readPin(&PIND, DOOR_PIN);
transmiter.send(paket, 4);
}
power(false);
}
sleep_mode();
}
}

0
power.h Normal file
View File

56
softspim.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "softspim.h"
#include "writepin.h"
#include <util/delay.h>
SpiMaster::SpiMaster()
{
}
uint8_t SpiMaster::readWrite(uint8_t in)
{
_delay_us(DELAY_TIME_US);
uint8_t recByte = 0;
for(uint8_t i = 0; i < 8; ++i)
{
if constexpr (BIT_ORDER == 0) writePin(_port, _pinOut, in & (1 << i));
else writePin(_port, _pinOut, in & (1 << (7-i)));
if constexpr (CLOCK_PHASE == 0) _delay_us(DELAY_TIME_US);
writePin(_port, _pinClock, !CLOCK_POLARITY);
if constexpr (CLOCK_PHASE == 1) _delay_us(DELAY_TIME_US);
if constexpr (BIT_ORDER == 0) recByte |= readPin(_pinReg, _pinIn) << i;
else recByte |= readPin(_pinReg, _pinIn) << (7-i);
if constexpr (CLOCK_PHASE == 0) _delay_us(DELAY_TIME_US);
writePin(_port, _pinClock, CLOCK_POLARITY);
if constexpr (CLOCK_PHASE == 1) _delay_us(DELAY_TIME_US);
}
return recByte;
}
void SpiMaster::readWrite(uint8_t length, uint8_t* bufferIn, uint8_t* bufferOut)
{
for(uint8_t i = 0; i < length; ++i)
{
uint8_t outByte = 0;
if(bufferOut) outByte = bufferOut[i];
uint8_t inByte = readWrite(outByte);
if(bufferIn) bufferIn[i] = inByte;
}
}
void SpiMaster::prepare()
{
writePin(_port, _pinClock, CLOCK_POLARITY);
}
void SpiMaster::write(uint8_t in)
{
readWrite(in);
}
uint8_t SpiMaster::read()
{
return readWrite();
}

30
softspim.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <avr/io.h>
#include <stdint.h>
class SpiMaster
{
private:
static constexpr uint8_t CLOCK_POLARITY = 1;
static constexpr uint8_t CLOCK_PHASE = 1;
static constexpr uint8_t BIT_ORDER = 1;
volatile uint8_t *_port = &PORTB;
volatile uint8_t *_pinReg = &PINB;
static constexpr uint8_t _pinIn = PB2;
static constexpr uint8_t _pinOut = PB0;
static constexpr uint8_t _pinClock = PB3;
static constexpr uint8_t DELAY_TIME_US = 10;
public:
SpiMaster();
void readWrite(uint8_t length, uint8_t* bufferIn, uint8_t* bufferOut);
uint8_t readWrite(uint8_t in = 0);
void prepare();
uint8_t read();
void write(uint8_t in);
};

33
watchdog.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <avr/wdt.h>
#define wdt_set(value) \
__asm__ __volatile__ ( \
"in __tmp_reg__,__SREG__" "\n\t" \
"cli" "\n\t" \
"wdr" "\n\t" \
"sts %0,%1" "\n\t" \
"out __SREG__,__tmp_reg__" "\n\t" \
"sts %0,%2" \
: /* no outputs */ \
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
_BV(WDIE) | (value & 0x07)) ) \
: "r0" \
)
#define wdt_off(x) \
__asm__ __volatile__ ( \
"in __tmp_reg__,__SREG__" "\n\t" \
"cli" "\n\t" \
"wdr" "\n\t" \
"sts %0,%1" "\n\t" \
"sts %0,%2" \
: /* no outputs */ \
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
"r" ((uint8_t) (0x00)) \
: "r0" \
)

19
writepin.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "writepin.h"
void writePin(volatile unsigned char *port, const unsigned char pin, const bool state) //waste 2 cycles
{
if(!state) *port &= ~(1 << pin);
else *port |= (1 << pin);
}
void setBit( volatile unsigned char *reg, const unsigned char bit, bool value )
{
writePin(reg, bit, value);
}
void setDirection( volatile unsigned char *portDirReg, const unsigned char pin, bool makeOutput )
{
writePin(portDirReg, pin, makeOutput);
}
bool readPin( volatile unsigned char *inPort, const unsigned char pin){ return (bool) (*inPort & (1 << pin));}

14
writepin.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef WRITEPIN_H
#define WRITEPIN_H
#include <avr/io.h>
void writePin(volatile unsigned char *port, const unsigned char pin, const bool state);
void setBit( volatile unsigned char *reg, const unsigned char bit, bool value );
void setDirection( volatile unsigned char *portDirReg, const unsigned char pin, bool makeOutput );
bool readPin( volatile unsigned char *inPort, const unsigned char pin);
#endif