diff --git a/CL56.cpp b/CL56.cpp index f477201..3e8ff8e 100644 --- a/CL56.cpp +++ b/CL56.cpp @@ -159,6 +159,12 @@ void DualCl56::setString(const char string[], const uint8_t dp) break; } if( (1 << i) & dp ) _segments[i] |= 1; + else _segments[i] &= ~1; } if(string[i] == '\0') for(; i < 8; i++) _segments[i]&=SEG_DP; } + +void DualCl56::setSegments(const uint8_t segments, const uint8_t place) +{ + _segments[place] = segments; +} diff --git a/CL56.h b/CL56.h index 6fe05d9..2a46660 100644 --- a/CL56.h +++ b/CL56.h @@ -3,18 +3,18 @@ #include #include "shiftreg.h" -#define SEG_A 0b10000000 -#define SEG_B 0b01000000 -#define SEG_C 0b00100000 -#define SEG_D 0b00010000 -#define SEG_E 0b00001000 -#define SEG_F 0b00000100 -#define SEG_G 0b00000010 -#define SEG_DP 0b00000001 - class DualCl56 { public: + + static constexpr uint8_t SEG_A = 0b10000000; + static constexpr uint8_t SEG_B = 0b01000000; + static constexpr uint8_t SEG_C = 0b00100000; + static constexpr uint8_t SEG_D = 0b00010000; + static constexpr uint8_t SEG_E = 0b00001000; + static constexpr uint8_t SEG_F = 0b00000100; + static constexpr uint8_t SEG_G = 0b00000010; + static constexpr uint8_t SEG_DP= 0b00000001; static constexpr uint8_t COLEN_A = 0b00000010; static constexpr uint8_t COLEN_B = 0b00100000; @@ -79,5 +79,6 @@ class DualCl56 void tick(); void setString(const char* string, const uint8_t dp = 0); + void setSegments(const uint8_t segments, const uint8_t place); }; diff --git a/CMakeLists.txt b/CMakeLists.txt index 7039ef4..16863ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags") # Set own source files # Simply list all your C / C++ source (not header!) files here -set(SRC_FILES main.cpp serial.cpp W433DataReciver.cpp CL56.cpp ds1302.cpp) +set(SRC_FILES main.cpp serial.cpp W433DataReciver.cpp CL56.cpp ds1302.cpp dht11.cpp WirelessRelay.cpp item.cpp) # Compiler suite specification set(CMAKE_C_COMPILER /usr/bin/avr-gcc) diff --git a/W433DataReciver.cpp b/W433DataReciver.cpp index 6f6e4a5..4d4c590 100644 --- a/W433DataReciver.cpp +++ b/W433DataReciver.cpp @@ -1,231 +1,144 @@ #include "W433DataReciver.h" +#include #include "writepin.h" -#include -#include -#include -#include -#include "serial.h" W433DataReciver* W433DataReciver::instance = nullptr; -W433DataReciver::W433DataReciver(volatile unsigned char* const port , const unsigned char pin, volatile uint16_t * timerRegister, volatile uint8_t* const timerOverflowRegister, void (* const packetCallback)(uint32_t, void*), void* const userData, void (*errorCodeHandler)(uint8_t, void*) ): -_port(port), _pin(pin), _timerRegister(timerRegister), _timerOverflowRegister(timerOverflowRegister), _packetCallback(packetCallback), _errorCodeHandler(errorCodeHandler), _userData(userData) +W433DataReciver::W433DataReciver(volatile unsigned char* const portIn, const unsigned char pinIn, + void (*packetCallbackIn)(uint32_t, void*), void* userDataIn, + void (*errorCodeHandlerIn)(uint8_t, void*)): + port(portIn), pin(pinIn), + packetCallback(packetCallbackIn), errorCodeHandler(errorCodeHandlerIn), userData(userDataIn) { - instance = this; - for(uint8_t i = 0; i < 33; i++) timesBuffer[i] = 0; + instance = this; } W433DataReciver::~W433DataReciver() { - instance = nullptr; + instance = nullptr; } void W433DataReciver::staticInterrupt() { - if(instance != nullptr) instance->interrupt(); + if(instance != nullptr) + instance->interrupt(); } -int8_t W433DataReciver::reciveBit(uint8_t index) +uint16_t W433DataReciver::calcCrc(uint32_t data) { - if( - timesBuffer[index] < 0 && - isTime(timesBuffer[index+1], SMALL_TIME, true, SMALL_TIME_TOLERANCE) && - isTime(timesBuffer[index+2], LARGE_TIME, false, LARGE_TIME_TOLERANCE) //&& - //isTime(timesBuffer[index+3], SMALL_TIME, true, SMALL_TIME_TOLERANCE) - ) - { - return 1; - } - else if( - timesBuffer[index] < 0 && - isTime(timesBuffer[index+1], LARGE_TIME, true, LARGE_TIME_TOLERANCE) && - isTime(timesBuffer[index+2], SMALL_TIME, false, SMALL_TIME_TOLERANCE) //&& - //isTime(timesBuffer[index+3], SMALL_TIME, true, SMALL_TIME_TOLERANCE) - ) - { - return 0; - } - else return -1; + uint16_t crc = 0xffff; + uint8_t* ptr = reinterpret_cast(&data); + for(size_t i = 0; i < sizeof(data); ++i) + crc = _crc_ccitt_update(crc, ptr[i]); + return crc; } -void W433DataReciver::waitForReciveIdle(const uint16_t timeoutMs) +uint8_t W433DataReciver::symbolDecode(uint8_t symbol) { - uint16_t counter = 0; - while(true) - { - while(counter < timeoutMs && state != LOOKING_FOR_SYNC) - { - _delay_ms(1); - ++counter; - } - _delay_ms(500); - counter+=500; - if(state == LOOKING_FOR_SYNC || counter >= timeoutMs) break; - } -} - - -bool W433DataReciver::isTime(int16_t input, const uint16_t time, const bool state, const uint16_t tollerance) -{ - if((state && input < 0) || (!state && input > 0)) return false; - input = abs(input); - return input < (int16_t)(time+tollerance) && input > (int16_t)(time-tollerance); -} - -bool W433DataReciver::reciveSync(const uint16_t elapsedTime) -{ - if(elapsedTime < SYNC_TIME+SYNC_TIME_TOLERANCE && elapsedTime > SYNC_TIME-SYNC_TIME_TOLERANCE) - { - ++syncCount; - } - else + switch(symbol) { - if(syncCount > 4 && syncFailCount < 3) ++syncFailCount; - else + case 0xe: + return 1; + case 0x13: + return 2; + case 0x15: + return 3; + case 0x16: + return 4; + case 0x19: + return 5; + case 0x1a: + return 6; + case 0x1c: + return 7; + case 0x23: + return 8; + case 0x25: + return 9; + case 0x26: + return 10; + case 0x29: + return 11; + case 0x2a: + return 12; + case 0x2c: + return 13; + case 0x32: + return 14; + case 0x34: + return 15; + case 0xd: + default: + return 0; + } +} + +void W433DataReciver::pll(bool sample) +{ + // Integrate each sample + if(sample) + rxIntegrator++; + + if (sample != prevSample) + { + pllRamp += pllRamp < PLL_RAMP_TRANSITION ? PLL_RAMP_INC_RETARD : PLL_RAMP_INC_ADVANCE; + prevSample = sample; + } + else + { + pllRamp += PLL_RAMP_INC_STEP; + } + if (pllRamp >= PLL_RAMP_LEN) + { + rxBits >>= 1; + + if (rxIntegrator >= 5) + rxBits |= 0x800; + + pllRamp -= PLL_RAMP_LEN; + rxIntegrator = 0; + + if(mode == MODE_RECEIVING) { - //if(syncCount > 7) error(ERR_SYNC_FAIL); - setState(LOOKING_FOR_SYNC); + if (++rxCount >= 12) + { + uint8_t currentByte = (symbolDecode(rxBits & 0x3f)) | symbolDecode(rxBits >> 6) << 4; + rxBuf[PACKET_LENGTH-1-(rxLen++)] = currentByte; + + if (rxLen >= PACKET_LENGTH) + { + mode = MODE_SEARCHING; + uint32_t* packet = reinterpret_cast(rxBuf+2); + uint16_t crc = rxBuf[0] << 8 | rxBuf[1]; + uint16_t crcC = calcCrc(*packet); + if(crc != crcC) + { + if(errorCodeHandler) + errorCodeHandler(ERROR_CRC, userData); + } + else + { + packetCallback(*packet, userData); + } + } + rxCount = 0; + } + } + else if (rxBits == 0xb38) + { + mode = MODE_RECEIVING; + rxCount = 0; + rxLen = 0; } } - if(syncCount > 10) return true; - else return false; -} - -bool W433DataReciver::recivedByte(const uint16_t elapsedTime) -{ - timesBuffer[timesBufferIndex] = readPin(_port, _pin) ? 0-elapsedTime : elapsedTime; - ++timesBufferIndex; - return timesBufferIndex == 32; -} - -uint8_t W433DataReciver::assmbleByte() -{ - uint8_t byte = 0; - for(uint8_t i = 0; i < 8; ++i) - { - int8_t bit = reciveBit(i*4); - if(bit >= 0) byte = byte | (bit << (7-i)); - else - { - setState(LOOKING_FOR_SYNC); - error(ERR_BYTE_ASM); - } - } - timesBufferIndex = 0; - return byte; -} - -void W433DataReciver::error(const uint8_t errorCode) -{ - if(_errorCodeHandler != nullptr) (*_errorCodeHandler)(errorCode, _userData); -} - -void W433DataReciver::setState(const uint8_t stateIn) -{ - TIMSK2 = stateIn == LOOKING_FOR_SYNC; - state = stateIn; - timesBufferIndex = 0; - packetIndex = 0; - syncCount = 0; - syncFailCount = 0; } void W433DataReciver::interrupt() { - uint16_t elapsedTime = polarity*(((*_timerOverflowRegister & 0x01) ? *_timerRegister+(UINT16_MAX - previousTime) : *_timerRegister - previousTime)/TICKS_PER_US); - - if(elapsedTime < DISCARD_TIME) - { - if(timesBufferIndex > 0 && elapsedTime + abs(timesBuffer[timesBufferIndex-1]) < LARGE_TIME+LARGE_TIME_TOLERANCE) - { - previousTime = *_timerRegister - elapsedTime - abs(timesBuffer[timesBufferIndex-1]); - timesBufferIndex-=1; - } - return; - } - previousTime = *_timerRegister; - *_timerOverflowRegister = *_timerOverflowRegister | 0x01; - - if(state == LOOKING_FOR_SYNC && reciveSync(elapsedTime)) - { - setState(LOOKING_FOR_SYNC_END); - } - else if(state == LOOKING_FOR_SYNC_END) - { - if(elapsedTime > SYNC_TIME + SYNC_END_TIME_TOLERANCE) - { - if(elapsedTime < LARGE_TIME - LARGE_TIME_TOLERANCE) - { - setState(LOOKING_FOR_SYNC); - error(ERR_NO_SYNC_END); - } - else - { - timesBuffer[0] = -LARGE_TIME; - setState(LOOKING_FOR_SIGNATURE); - ++timesBufferIndex; - } - } - } - else if(state == LOOKING_FOR_SIGNATURE) - { - if(recivedByte(elapsedTime)) - { - uint8_t recivedSignature = assmbleByte(); - if( recivedSignature == signature) setState(RECVING_PACKET); - else - { - error(ERR_WRONG_SIG); - setState(LOOKING_FOR_SYNC); - } - } - } - else if( state == RECVING_PACKET ) - { - - if(recivedByte(elapsedTime)) - { - uint8_t packetByte = assmbleByte(); - - packet = packet | ((uint32_t)packetByte) << ((3-packetIndex)*8); - ++packetIndex; - if(packetIndex > 3) - { - packetIndex = 0; - timesBufferIndex = 0; - setState(RECVING_PACKET_CHECKSUM); - } - } - } - else if(state == RECVING_PACKET_CHECKSUM) - { - if(recivedByte(elapsedTime)) - { - uint8_t recivedChecksum = assmbleByte(); - - volatile uint8_t* buffer = reinterpret_cast(&packet); - - uint8_t computedChecksum = 0; - for(uint8_t j = 0; j < sizeof(packet); j++) for(uint8_t i = 0; i < 8; i++) computedChecksum = computedChecksum + ((buffer[j] & ( 1 << (8 - i))) >> (8 - i)); - //for(uint8_t j = 0; j < sizeof(packet); j++) for(uint8_t i = 0; i < 8; i++) computedChecksum = computedChecksum + (buffer[j] & ( 1 << (8 - i))); - - if(computedChecksum == recivedChecksum) - { - #ifdef USE_RINGBUFFER - _ringBuffer.write(const_cast(buffer), sizeof(packet)); - #endif - if(_packetCallback != nullptr)(*_packetCallback)(packet, _userData); - } - else error(ERR_CHECKSUM); - packet = 0; - setState(LOOKING_FOR_SYNC); - } - } + pll(readPin(port, pin)); } -#ifdef USE_RINGBUFFER -RingBuffer* W433DataReciver::getRingBuffer() +uint16_t W433DataReciver::calculateOverflowRegister(uint16_t bitRate, uint16_t devisor) { - return &_ringBuffer; + return (F_CPU /(8UL*devisor))/bitRate; } -#endif diff --git a/W433DataReciver.h b/W433DataReciver.h index fb8f5b1..5279cf5 100644 --- a/W433DataReciver.h +++ b/W433DataReciver.h @@ -1,94 +1,63 @@ #pragma once -#include -#include "ringbuffer.h" -//#define USE_RINGBUFFER +#include +#include class W433DataReciver { public: - - static constexpr uint8_t RINGBUFFER_LENGTH = 32; - - //errors - static constexpr uint8_t ERR_SYNC_FAIL = 1; - static constexpr uint8_t ERR_NO_SYNC_END = 2; - static constexpr uint8_t ERR_BYTE_ASM = 3; - static constexpr uint8_t ERR_WRONG_SIG = 4; - static constexpr uint8_t ERR_CHECKSUM = 5; - + static constexpr int ERROR_CRC = 1; + + static constexpr int SAMPLES_PER_BIT = 8; + static constexpr int PLL_RAMP_LEN = 160; + static constexpr int PLL_RAMP_INC_STEP = PLL_RAMP_LEN/SAMPLES_PER_BIT; + static constexpr int PLL_RAMP_TRANSITION = PLL_RAMP_LEN/2; + static constexpr int PLL_RAMP_INC_RETARD = PLL_RAMP_INC_STEP-9; + static constexpr int PLL_RAMP_INC_ADVANCE = PLL_RAMP_INC_STEP+9; + static constexpr int PLL_HEADER_LEN_BITS = 8; + static constexpr int PACKET_LENGTH = sizeof(uint32_t)+2; + private: - - static W433DataReciver* instance; - - //constants - static constexpr uint8_t CLOCK_DEVIDER = 1; - static constexpr uint16_t LARGE_TIME = 2000; - static constexpr uint16_t SMALL_TIME = 500; - static constexpr uint16_t SYNC_TIME = 800; - static constexpr uint8_t SYNC_TIME_TOLERANCE = SYNC_TIME*0.20; - static constexpr uint16_t SYNC_END_TIME_TOLERANCE = SYNC_TIME*0.50; - static constexpr uint16_t LARGE_TIME_TOLERANCE = LARGE_TIME*0.30; - static constexpr uint8_t SMALL_TIME_TOLERANCE = SMALL_TIME*0.30; - static constexpr uint16_t DISCARD_TIME = SMALL_TIME*0.6; - static constexpr uint16_t TICKS_PER_US = (F_CPU) / (1000000*CLOCK_DEVIDER) ; - static constexpr uint8_t signature = 0xA5; - - static constexpr int8_t polarity = 1; - - static constexpr uint8_t LOOKING_FOR_SYNC = 0; - static constexpr uint8_t LOOKING_FOR_SYNC_END = 1; - static constexpr uint8_t LOOKING_FOR_SIGNATURE = 2; - static constexpr uint8_t RECVING_PACKET = 3; - static constexpr uint8_t RECVING_PACKET_CHECKSUM = 4; - - //variables - volatile unsigned char *_port; - unsigned char _pin; - - volatile uint16_t *_timerRegister; - volatile uint8_t *_timerOverflowRegister; - -#ifdef USE_RINGBUFFER - RingBuffer _ringBuffer; -#endif - - volatile uint16_t previousTime = 0; - volatile uint8_t timesBufferIndex = 0; - volatile int16_t timesBuffer[33]; - - volatile uint8_t packetIndex = 0; - volatile uint32_t packet = 0; - - void (* const _packetCallback)(uint32_t, void*); - void (* const _errorCodeHandler)(uint8_t, void*); - void* const _userData; - - volatile uint8_t syncCount = 0; - volatile uint8_t syncFailCount = 0; - volatile uint8_t state = 0; - - //private functions - int8_t reciveBit(uint8_t index); - - inline uint8_t assmbleByte(); - inline void setState(const uint8_t stateIn); - inline bool recivedByte(const uint16_t elapsedTime); - inline bool reciveSync(const uint16_t elapsedTime); - - inline void error(const uint8_t errorCode); - - static inline bool isTime(int16_t input, const uint16_t time, const bool state = true, const uint16_t tollerance = 100); - + + static constexpr int MODE_SEARCHING = 0; + static constexpr int MODE_RECEIVING = 1; + + static W433DataReciver* instance; + + volatile unsigned char *port; + unsigned char pin; + + bool prevSample = 0; + uint8_t pllRamp = 0; + uint8_t rxIntegrator = 0; + + uint16_t rxBits = 0; + + uint8_t mode = MODE_SEARCHING; + + uint8_t rxBuf[PACKET_LENGTH]; + uint8_t rxCount = 0; + volatile uint8_t rxLen = 0; + + void (* const packetCallback)(uint32_t, void*); + void (* const errorCodeHandler)(uint8_t, void*); + void* const userData; + +private: + + static uint16_t calcCrc(uint32_t data); + static uint8_t symbolDecode(uint8_t symbol); + void pll(bool sample); + public: - - W433DataReciver(volatile unsigned char* const port , const unsigned char pin, volatile uint16_t * timerRegister, volatile uint8_t* const timerOverflowRegister, void (*packetCallback)(uint32_t, void*) = nullptr, void* userData = nullptr, void (*errorCodeHandler)(uint8_t, void*) = nullptr ); - ~W433DataReciver(); - static void initTimer(); - static void staticInterrupt(); - void waitForReciveIdle(const uint16_t timeoutMs = 10000); - void interrupt(); -#ifdef USE_RINGBUFFER - RingBuffer* getRingBuffer(); -#endif + + W433DataReciver(volatile unsigned char* const portIn, const unsigned char pinIn, void (*packetCallbackIn)(uint32_t, + void*), + void* userDataIn = nullptr, void (*errorCodeHandlerIn)(uint8_t, void*) = nullptr ); + ~W433DataReciver(); + + static void staticInterrupt(); + void interrupt(); + + static uint16_t calculateOverflowRegister(uint16_t bitRate, uint16_t devisor); }; diff --git a/main.cpp b/main.cpp index c91b0fd..9374be7 100644 --- a/main.cpp +++ b/main.cpp @@ -15,11 +15,20 @@ #include "ds1302.h" #include "sensor.h" #include "pwm.h" +#include "dht11.h" +#include "WirelessRelay.h" + +//#define HAS_DHT +#define HAS_TRANSMITTER +//#define HAS_RECIVER #define MAX_SENSORS 32 #define COMMAND_BUFFER_SIZE 64 #define SNPRINTF_BUFFER_SIZE 96 +#define welcomeString "HELO " +static constexpr bool bdayMsg = false; + void buttonHandler(uint8_t index, uint8_t type, void* data); SVector sensors; ShiftReg<16> shiftReg(&PORTB, PB3, PB2, PB1); @@ -27,11 +36,30 @@ DS1302 clock(&PORTC, &PINC, &DDRC, PC0, PC2, PC1); DualCl56 display(&shiftReg); Buttons buttons(&buttonHandler); +#ifdef HAS_DHT +#define DPY_FIXED_ITEMS 4 +#else +#define DPY_FIXED_ITEMS 2 +#endif + +static constexpr uint8_t almA = 0b01; +static constexpr uint8_t almB = 0b10; + uint8_t displaying = 0; +uint8_t alm = 0; + +volatile bool setting = false; +volatile int8_t settingOffset = 0; + +volatile bool ringging = false; char buffer[SNPRINTF_BUFFER_SIZE]; -volatile bool sensorsPaused=true; +volatile bool sensorsPaused = true; + +volatile bool relaySetting = false; + +volatile uint8_t timer = 0; ISR(INT1_vect) { @@ -42,15 +70,40 @@ ISR(TIMER2_OVF_vect) { display.tick(); buttons.tick(); + if(ringging && ((timer % 4 == 0 && timer < 128) || (timer > 128 && timer % 16 == 0)) ) writePin(&PORTD, PD4, true); + else writePin(&PORTD, PD4, false); + ++timer; } void buttonHandler(uint8_t index, uint8_t type, void* data) { - if(index == 0 && type == Buttons::RELEASED) - { - if(++displaying < sensors.count()+2); - else displaying = 0; - } + if(!setting) + { + if(index == 0 && type == Buttons::RELEASED) + { + if(++displaying < sensors.count()+DPY_FIXED_ITEMS); + else displaying = 0; + } + else if(index == 0 && type == Buttons::LONG_PRESSED) + { + relaySetting = !relaySetting; + } + else if(index == 1 && type == Buttons::RELEASED ) + { + if(!ringging) if(++alm > 3) alm = 0; + else ringging = false; + } + else if(index == 1 && type == Buttons::LONG_PRESSED ) + { + setting = true; + } + } + else + { + if(index == 1 && type == Buttons::LONG_PRESSED ) setting = false; + else if(index == 0 && type == Buttons::RELEASED ) settingOffset += 10; + else if(index == 1 && type == Buttons::RELEASED ) settingOffset -= 1; + } } void printSensor(const Sensor& sensor, Serial* serial) @@ -152,7 +205,7 @@ void serialDispatch(Serial* serial, SVector* sensors) DS1302::Timeval time = {atoi(sec),atoi(min),atoi(hour),atoi(day),atoi(mon),atoi(year)}; clock.setTime(time); serial->write_p(PSTR("date and time set\n")); - display.setString("SET"); + display.setString("SET "); _delay_ms(1000); } else serial->write_p(PSTR("usage: set [yyyy] [mm] [dd] [hh] [mm] [ss]\n")); @@ -195,13 +248,11 @@ void serialDispatch(Serial* serial, SVector* sensors) } else if(strcmp(token, "beep") == 0) { - for(uint16_t i = 0; i < 250; ++i) - { - writePin(&PORTD, PD4, true); - _delay_us(500); - writePin(&PORTD, PD4, false); - _delay_us(1000); - } + serial->write_p(PSTR("Beeping\n")); + ringging = true; + _delay_ms(1000); + serial->write_p(PSTR("Done\n")); + ringging = false; } else if(strcmp(token, "help") == 0) { @@ -212,7 +263,7 @@ void serialDispatch(Serial* serial, SVector* sensors) } } -void displayItems(const DS1302::Timeval& time) +void displayItems(const DS1302::Timeval& time, int16_t temp, int16_t humid) { switch(displaying) { @@ -220,27 +271,64 @@ void displayItems(const DS1302::Timeval& time) writePin(&PORTB, PB4, time.sec % 2); snprintf(buffer, 9, " %02u%02u", time.hour, time.min); display.setString(buffer); + display.setSegments((alm & almA ? DualCl56::SEG_A : 0) | (alm & almB ? DualCl56::SEG_D : 0), 0); break; case 1: writePin(&PORTB, PB4, false); snprintf(buffer, 9, "%02u%02u%04u", time.day, time.month, time.year); display.setString(buffer, DualCl56::DP_B | DualCl56::DP_D); break; +#ifdef HAS_DHT + case 2: + writePin(&PORTB, PB4, false); + snprintf(buffer, 9, "0 1%4u", temp); + display.setString(buffer, DualCl56::DP_G); + break; + case 3: + writePin(&PORTB, PB4, false); + snprintf(buffer, 9, "0 2%4u", humid); + display.setString(buffer, DualCl56::DP_G); + break; +#endif default: - if(displaying == 2 && sensors.count() == 0) display.setString("0 SENSOR"); - else - { - writePin(&PORTB, PB4, false); - snprintf(buffer, 9, "%u%3u%4u", sensors[displaying-2].id, sensors[displaying-2].type, sensors[displaying-2].field); - display.setString(buffer, sensors[displaying-2].type == 1 || sensors[displaying-2].type == 2 ? DualCl56::DP_G : 0); - } + writePin(&PORTB, PB4, false); + snprintf(buffer, 9, "%u%3u%4u", + sensors[displaying-DPY_FIXED_ITEMS].id, + sensors[displaying-DPY_FIXED_ITEMS].type, + sensors[displaying-DPY_FIXED_ITEMS].field); + display.setString(buffer, sensors[displaying-DPY_FIXED_ITEMS].type == 1 || sensors[displaying-2].type == 2 ? DualCl56::DP_G : 0); } } +void setAlarm(DS1302::Timeval* alarm, uint8_t leadingSegment = 0) +{ + writePin(&PORTB, PB4, true); + while(setting) + { + if(settingOffset+alarm->min > 59) + { + if(++alarm->hour > 23) alarm->hour = 0; + alarm->min = settingOffset+alarm->min-60; + } + else if(settingOffset+alarm->min < 0) + { + if(alarm->hour-1 < 0) alarm->hour = 24; + --alarm->hour; + alarm->min = settingOffset+alarm->min+60; + } + else alarm->min += settingOffset; + settingOffset = 0; + snprintf(buffer, 9, "S %02u%02u", alarm->hour, alarm->min); + display.setString(buffer); + display.setSegments(leadingSegment, 1); + } + writePin(&PORTB, PB4, false); +} + int main() { DDRB = (1 << PB1) | ( 1 << PB2) | ( 1 << PB3) | ( 1 << PB4) | ( 1 << PB5); - DDRD = 1<(128); + DS1302::Timeval alarmB = EEPROM_read_class(128+64); DS1302::Timeval time = clock.getTime(); - + alm = EEPROM_read_char(0); + uint8_t oldAlm = alm; + + +#ifdef HAS_TRANSMITTER + char name[] = "relay"; + WirelessRelay relay(0b1011010001000000, name); +#endif + +#ifdef HAS_DHT + Dht11 sensor(&PORTD, &PIND, &DDRD, PD2); +#endif if(time.day == 28 && time.month == 5) { - display.setString("HAPPY"); - _delay_ms(1000); - display.setString("b-DAY"); - _delay_ms(1000); - display.setString("SASA"); - _delay_ms(1000); + if constexpr(bdayMsg) + { + display.setString("HAPPY "); + _delay_ms(1000); + display.setString("b-DAY "); + _delay_ms(1000); + display.setString("SASA "); + _delay_ms(1000); + } } else { - display.setString("HELOJANA"); + display.setString(welcomeString); _delay_ms(1000); } +#ifdef HAS_DHT + sensor.read(); + _delay_ms(1000); + sensor.read(); +#endif + W433DataReciver reciver(&PIND, PD3, &TCNT1, &TIFR1, &packetHandler, reinterpret_cast(&serial), &reciverError); uint8_t deleteDate = 0; serial.write_p(PSTR("Ready\n")); - + + uint16_t i = 0; + + bool oldRelaySetting = false; + while(true) { - time = clock.getTime(); - displayItems(time); +#ifdef HAS_DHT + if((displaying == 2 || displaying == 3) && i%2048 == 0) + { + cli(); + sensor.read(); + sei(); + } +#endif + + if(alm != oldAlm) + { + oldAlm = alm; + EEPROM_write_char(0, alm); + } + +#ifdef HAS_TRANSMITTER + if(oldRelaySetting != relaySetting) + { + writePin(&PORTB, PB4, false); + oldRelaySetting = relaySetting; + relay.setValue(relaySetting); + display.setString( relaySetting ? "RLY ON " : "RLY OFF "); + _delay_ms(1000); + } +#endif + + if(setting) + { + setAlarm(&alarmA, DualCl56::SEG_A); + setting = true; + setAlarm(&alarmB, DualCl56::SEG_D); + EEPROM_write_class(128, alarmA); + EEPROM_write_class(128+64, alarmB); + } + + time = clock.getTime(); + +#ifdef HAS_DHT + displayItems(time, sensor.temperature, sensor.humidity); +#else + displayItems(time, 0, 0); +#endif + if(time.hour == alarmA.hour && time.min == alarmA.min && time.sec == 0) + { + ringging = true; + } + + if(time.hour == alarmB.hour && time.min == alarmB.min && time.sec == 0) + { +#ifdef HAS_TRANSMITTER + relay.setValue(true); +#else + ringging = true; +#endif + } + +#ifdef HAS_RECIVER serialDispatch(&serial, &sensors); if(deleteDate != time.day) { displaying = 0; sensors.clear(); deleteDate = time.day; + display.setString("CLEAR "); + _delay_ms(1000); } +#endif + ++i; } return 0;