From 5dac2e5ff9ca5970a335836f25d97b5c30a3222e Mon Sep 17 00:00:00 2001 From: IMback Date: Mon, 29 Oct 2018 18:21:42 +0100 Subject: [PATCH] Changed Sensor Output formating --- CMakeCache.txt | 2 +- CMakeLists.txt | 2 +- W433DataReciver.cpp | 174 ++++++++++++++++++++++++++++++++++++++++++++ W433DataReciver.h | 72 ++++++++++++++++++ main.cpp | 63 ++++++++++++++-- serial.cpp | 4 +- writepin.h | 13 ++++ 7 files changed, 318 insertions(+), 12 deletions(-) create mode 100644 W433DataReciver.cpp create mode 100644 W433DataReciver.h diff --git a/CMakeCache.txt b/CMakeCache.txt index dcb30c4..678dcf0 100644 --- a/CMakeCache.txt +++ b/CMakeCache.txt @@ -238,7 +238,7 @@ CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3 //Minor version of cmake used to create the current loaded cache CMAKE_CACHE_MINOR_VERSION:INTERNAL=12 //Patch version of cmake used to create the current loaded cache -CMAKE_CACHE_PATCH_VERSION:INTERNAL=2 +CMAKE_CACHE_PATCH_VERSION:INTERNAL=3 //ADVANCED property for variable: CMAKE_COLOR_MAKEFILE CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1 //Path to CMake executable. diff --git a/CMakeLists.txt b/CMakeLists.txt index 8d49cea..0d0cd2a 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 WirelessRelay.cpp pwm.cpp rgbled.cpp) +set(SRC_FILES main.cpp serial.cpp WirelessRelay.cpp pwm.cpp rgbled.cpp W433DataReciver.cpp) # Compiler suite specification set(CMAKE_C_COMPILER /usr/bin/avr-gcc) diff --git a/W433DataReciver.cpp b/W433DataReciver.cpp new file mode 100644 index 0000000..af9babf --- /dev/null +++ b/W433DataReciver.cpp @@ -0,0 +1,174 @@ +#include "W433DataReciver.h" +#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 ): +_port(port), _pin(pin), _timerRegister(timerRegister), _timerOverflowRegister(timerOverflowRegister), _packetCallback(packetCallback), _userData(userData) +{ + instance = this; + for(uint8_t i = 0; i < 33; i++) timesBuffer[i] = 0; +} + +W433DataReciver::~W433DataReciver() +{ + instance = nullptr; +} + +void W433DataReciver::staticInterrupt() +{ + if(instance != nullptr) instance->interrupt(); +} + +int8_t W433DataReciver::reciveBit(uint8_t index) +{ + if( + timesBuffer[index] < 0 && + isTime(timesBuffer[index+1], SMALL_TIME, true) && + isTime(timesBuffer[index+2], LARGE_TIME, false) && + isTime(timesBuffer[index+3], SMALL_TIME, true) + ) + { + return 1; + } + else if( + timesBuffer[index] < 0 && + isTime(timesBuffer[index+1], LARGE_TIME, true) && + isTime(timesBuffer[index+2], SMALL_TIME, false) && + isTime(timesBuffer[index+3], SMALL_TIME, true) + ) + { + return 0; + } + else return -1; +} + + +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+50 && elapsedTime > SYNC_TIME-50) + { + ++syncCount; + } + else syncCount = 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); + } + timesBufferIndex = 0; + return byte; +} + +void W433DataReciver::setState(const uint8_t stateIn) +{ + state = stateIn; + timesBufferIndex = 0; + packetIndex = 0; +} + +void W433DataReciver::interrupt() +{ + uint16_t elapsedTime = polarity*(((*_timerOverflowRegister & 0x01) ? *_timerRegister+(UINT16_MAX - previousTime) : *_timerRegister - previousTime)/TICKS_PER_US); + + if(elapsedTime < SMALL_TIME/4) 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 + 50) + { + if(elapsedTime < LARGE_TIME + 50) setState(LOOKING_FOR_SYNC); + 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 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))); + + if(computedChecksum == recivedChecksum) + { + _ringBuffer.write(const_cast(buffer), sizeof(packet)); + if(_packetCallback != nullptr)(*_packetCallback)(packet, _userData); + } + packet = 0; + setState(LOOKING_FOR_SYNC); + } + } +} + +RingBuffer* W433DataReciver::getRingBuffer() +{ + return &_ringBuffer; +} diff --git a/W433DataReciver.h b/W433DataReciver.h new file mode 100644 index 0000000..6c6e36e --- /dev/null +++ b/W433DataReciver.h @@ -0,0 +1,72 @@ +#pragma once +#include +#include "ringbuffer.h" + +class W433DataReciver +{ +public: + + static constexpr uint8_t RINGBUFFER_LENGTH = 32; + +private: + + static W433DataReciver* instance; + + //constants + static constexpr uint8_t CLOCK_DEVIDER = 1; + static constexpr uint16_t SYNC_TIME = 800; + static constexpr uint16_t LARGE_TIME = 2000; + static constexpr uint16_t SMALL_TIME = 500; + 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; + + RingBuffer _ringBuffer; + + 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*) = nullptr; + void* const _userData; + + volatile uint8_t syncCount = 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); + + static inline bool isTime(int16_t input, const uint16_t time, const bool state = true, const uint16_t tollerance = 50); + +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 ); + ~W433DataReciver(); + static void initTimer(); + static void staticInterrupt(); + void interrupt(); + RingBuffer* getRingBuffer(); +}; diff --git a/main.cpp b/main.cpp index 977a829..9331a83 100644 --- a/main.cpp +++ b/main.cpp @@ -10,6 +10,7 @@ #include "eeprom.h" #include "bitrep.h" #include "staticvector.h" +#include "W433DataReciver.h" #define COMMAND_BUFFER_SIZE 64 #define SNPRINTF_BUFFER_SIZE 64 @@ -21,6 +22,13 @@ char buffer[SNPRINTF_BUFFER_SIZE]; SVector relays; +bool flag = false; + +ISR(PCINT1_vect) +{ + W433DataReciver::staticInterrupt(); +} + inline static void printHelp(Serial* serial) { @@ -270,6 +278,7 @@ void serialDispatch(Serial* serial, SVector* relays, unsigned int length = serial->getString(buffer, COMMAND_BUFFER_SIZE); if(length > 2) { + cli(); char* token = strtok(buffer, " \n"); if(strcmp(token, "relay") == 0) { @@ -311,10 +320,28 @@ void serialDispatch(Serial* serial, SVector* relays, { serial->write_p(PSTR("Not a valid command\n")); } + sei(); } } } +void temperaturePacketRecived(uint32_t data, void* userData) +{ + Serial* serial = reinterpret_cast(userData); + if(data >> 24 == 1) + { + serial->write_p(PSTR("SENSOR TYPE: ")); + serial->write(data >> 24); + serial->write_p(PSTR(" ID: ")); + serial->write((data & 0x00FF0000) >> 16); + serial->write_p(PSTR(" TEMPERATURE: ")); + serial->write((data & 0x0000FF00) >> 8); + serial->write_p(PSTR(" HUMIDITY: ")); + serial->write(data & 0x000000FF); + serial->putChar('\n'); + } +} + int main() { @@ -340,8 +367,12 @@ int main() RgbLed rgbled( &pwmTc0, &pwmTc2 ); Pwm16b pwmTc1 ( &TCCR1A, &TCCR1B, &OCR1A, &OCR1B, &ICR1, 0b00000001, true, false); - - serial.write_p(PSTR("RGBController v0.7 starting\n")); + + setBit(&PCICR, PCIE1, true); + setBit(&PCMSK1, PCINT8, true); + W433DataReciver reciver(&PINC, PC0, &TCNT1, &TIFR1, &temperaturePacketRecived, reinterpret_cast(&serial)); + + serial.write_p(PSTR("RGBController v0.8 starting\n")); load(); @@ -355,9 +386,14 @@ int main() _delay_ms(10); if(doorOne != readPin(&PINB, PB3)) { - doorOne = readPin(&PINB, PB3); - serial.write("D1"); - doorOne ? serial.write("O\n") : serial.write("C\n"); + doorOne = readPin(&PINB, PB3); + serial->write_p(PSTR("SENSOR TYPE: ")); + serial->putChar('0'); + serial->write_p(PSTR(" ID: ")); + serial->putChar('0'); + serial->write_p(PSTR(" STATE: ")); + serial->write(doorOne); + serial->putChar('\n'); } } @@ -366,9 +402,14 @@ int main() _delay_ms(10); if(doorTow != readPin(&PINB, PB4)) { - doorTow = readPin(&PINB, PB4); - serial.write("D2"); - doorTow ? serial.write("O\n") : serial.write("C\n"); + doorTow = readPin(&PINB, PB3); + serial->write_p(PSTR("SENSOR TYPE: ")); + serial->putChar('0'); + serial->write_p(PSTR(" ID: ")); + serial->putChar('1'); + serial->write_p(PSTR(" STATE: ")); + serial->write(doorTow); + serial->putChar('\n'); } } if(doorTow) openCount++; @@ -378,6 +419,12 @@ int main() openCount = 0; } + if(flag) + { + flag = false; + serial.write("flag\n"); + } + _delay_ms(2); } diff --git a/serial.cpp b/serial.cpp index 6e95273..b4366a3 100644 --- a/serial.cpp +++ b/serial.cpp @@ -1,7 +1,7 @@ #include "serial.h" #include "ringbuffer.h" -RingBuffer rxBuffer; +RingBuffer rxBuffer; bool stopped = false; @@ -111,7 +111,7 @@ char Serial::getChar() unsigned int Serial::getString(char* buffer, const int bufferLength) { - return rxBuffer.getString(_terminator, buffer, bufferLength); + return rxBuffer.getString(_terminator, (uint8_t*)buffer, bufferLength); } unsigned int Serial::read(char* buffer, const unsigned int length ) diff --git a/writepin.h b/writepin.h index 4ef214f..78db970 100644 --- a/writepin.h +++ b/writepin.h @@ -2,12 +2,25 @@ #define WRITEPIN_H #include + inline void writePin(volatile unsigned char *port, const unsigned char pin, const bool state) //waste 2 cycles { *port &= ~(1 << pin); if(state) *port |= (1 << pin); } +inline void setBit( volatile unsigned char *reg, const unsigned char bit, bool value ) +{ + writePin(reg, bit, value); +} + + +inline void setDirection( volatile unsigned char *portDirReg, const unsigned char pin, bool makeOutput ) +{ + writePin(portDirReg, pin, makeOutput); +} + inline bool readPin( volatile unsigned char *inPort, const unsigned char pin){ return (bool) (*inPort & (1 << pin));} + #endif