added tone request gateway before actually swithcing the pin
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
.pio
|
||||||
|
.vscode/.browse.c_cpp.db*
|
||||||
|
.vscode/c_cpp_properties.json
|
||||||
|
.vscode/launch.json
|
||||||
|
.vscode/ipch
|
||||||
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||||
|
// for the documentation about the extensions.json format
|
||||||
|
"recommendations": [
|
||||||
|
"platformio.platformio-ide"
|
||||||
|
],
|
||||||
|
"unwantedRecommendations": [
|
||||||
|
"ms-vscode.cpptools-extension-pack"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
This directory is intended for project header files.
|
||||||
|
|
||||||
|
A header file is a file containing C declarations and macro definitions
|
||||||
|
to be shared between several project source files. You request the use of a
|
||||||
|
header file in your project source file (C, C++, etc) located in `src` folder
|
||||||
|
by including it, with the C preprocessing directive `#include'.
|
||||||
|
|
||||||
|
```src/main.c
|
||||||
|
|
||||||
|
#include "header.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Including a header file produces the same results as copying the header file
|
||||||
|
into each source file that needs it. Such copying would be time-consuming
|
||||||
|
and error-prone. With a header file, the related declarations appear
|
||||||
|
in only one place. If they need to be changed, they can be changed in one
|
||||||
|
place, and programs that include the header file will automatically use the
|
||||||
|
new version when next recompiled. The header file eliminates the labor of
|
||||||
|
finding and changing all the copies as well as the risk that a failure to
|
||||||
|
find one copy will result in inconsistencies within a program.
|
||||||
|
|
||||||
|
In C, the convention is to give header files names that end with `.h'.
|
||||||
|
|
||||||
|
Read more about using header files in official GCC documentation:
|
||||||
|
|
||||||
|
* Include Syntax
|
||||||
|
* Include Operation
|
||||||
|
* Once-Only Headers
|
||||||
|
* Computed Includes
|
||||||
|
|
||||||
|
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
This directory is intended for project specific (private) libraries.
|
||||||
|
PlatformIO will compile them to static libraries and link into the executable file.
|
||||||
|
|
||||||
|
The source code of each library should be placed in a separate directory
|
||||||
|
("lib/your_library_name/[Code]").
|
||||||
|
|
||||||
|
For example, see the structure of the following example libraries `Foo` and `Bar`:
|
||||||
|
|
||||||
|
|--lib
|
||||||
|
| |
|
||||||
|
| |--Bar
|
||||||
|
| | |--docs
|
||||||
|
| | |--examples
|
||||||
|
| | |--src
|
||||||
|
| | |- Bar.c
|
||||||
|
| | |- Bar.h
|
||||||
|
| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||||
|
| |
|
||||||
|
| |--Foo
|
||||||
|
| | |- Foo.c
|
||||||
|
| | |- Foo.h
|
||||||
|
| |
|
||||||
|
| |- README --> THIS FILE
|
||||||
|
|
|
||||||
|
|- platformio.ini
|
||||||
|
|--src
|
||||||
|
|- main.c
|
||||||
|
|
||||||
|
Example contents of `src/main.c` using Foo and Bar:
|
||||||
|
```
|
||||||
|
#include <Foo.h>
|
||||||
|
#include <Bar.h>
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
The PlatformIO Library Dependency Finder will find automatically dependent
|
||||||
|
libraries by scanning project source files.
|
||||||
|
|
||||||
|
More information about PlatformIO Library Dependency Finder
|
||||||
|
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
; PlatformIO Project Configuration File
|
||||||
|
;
|
||||||
|
; Build options: build flags, source filter
|
||||||
|
; Upload options: custom upload port, speed and extra flags
|
||||||
|
; Library options: dependencies, extra library storages
|
||||||
|
; Advanced options: extra scripting
|
||||||
|
;
|
||||||
|
; Please visit documentation for the other options and examples
|
||||||
|
; https://docs.platformio.org/page/projectconf.html
|
||||||
|
|
||||||
|
[env:nodemcu-32s]
|
||||||
|
platform = espressif32
|
||||||
|
board = nodemcu-32s
|
||||||
|
framework = arduino
|
||||||
|
upload_port = COM9
|
||||||
|
upload_speed = 921600
|
||||||
|
monitor_speed = 115200
|
||||||
|
build_flags =
|
||||||
|
-I ./src/xcp
|
||||||
|
-I ./src/Receivers433
|
||||||
|
-I ./src/Receivers433/Receivers3ByteKeys
|
||||||
|
lib_deps =
|
||||||
|
adafruit/Adafruit GFX Library@^1.12.4
|
||||||
|
thingpulse/ESP8266 and ESP32 OLED driver for SSD1306 displays@^4.6.1
|
||||||
+126
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
Base32.cpp - Library for encoding to/decoding from Base32.
|
||||||
|
Compatible with RFC 4648 ( http://tools.ietf.org/html/rfc4648 )
|
||||||
|
Created by Vladimir Tarasow, December 18, 2012.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "Base32.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
Base32::Base32()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* appends 0 to the base32 string */
|
||||||
|
int Base32::toBase32(byte* in, long length, char * out, boolean usePadding)
|
||||||
|
{
|
||||||
|
char base32StandardAlphabet[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"};
|
||||||
|
char standardPaddingChar = '=';
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
int count = 0;
|
||||||
|
int bufSize = 8;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
if (length < 0 || length > 268435456LL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
int buffer = in[0];
|
||||||
|
int next = 1;
|
||||||
|
int bitsLeft = 8;
|
||||||
|
|
||||||
|
while (count < bufSize && (bitsLeft > 0 || next < length))
|
||||||
|
{
|
||||||
|
if (bitsLeft < 5)
|
||||||
|
{
|
||||||
|
if (next < length)
|
||||||
|
{
|
||||||
|
buffer <<= 8;
|
||||||
|
buffer |= in[next] & 0xFF;
|
||||||
|
next++;
|
||||||
|
bitsLeft += 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int pad = 5 - bitsLeft;
|
||||||
|
buffer <<= pad;
|
||||||
|
bitsLeft += pad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index = 0x1F & (buffer >> (bitsLeft -5));
|
||||||
|
|
||||||
|
bitsLeft -= 5;
|
||||||
|
out[result] = (byte)base32StandardAlphabet[index];
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usePadding)
|
||||||
|
{
|
||||||
|
int pads = (result % 8);
|
||||||
|
if (pads > 0)
|
||||||
|
{
|
||||||
|
pads = (8 - pads);
|
||||||
|
for (int i = 0; i < pads; i++)
|
||||||
|
{
|
||||||
|
out[result] = standardPaddingChar;
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out[result] = '\0';
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Base32::fromBase32(byte* in, long length, byte*& out)
|
||||||
|
{
|
||||||
|
int result = 0; // Length of the array of decoded values.
|
||||||
|
int buffer = 0;
|
||||||
|
int bitsLeft = 0;
|
||||||
|
byte* temp = NULL;
|
||||||
|
|
||||||
|
temp = (byte*)malloc(length); // Allocating temporary array.
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
byte ch = in[i];
|
||||||
|
|
||||||
|
// ignoring some characters: ' ', '\t', '\r', '\n', '='
|
||||||
|
if (ch == 0xA0 || ch == 0x09 || ch == 0x0A || ch == 0x0D || ch == 0x3D) continue;
|
||||||
|
|
||||||
|
// recovering mistyped: '0' -> 'O', '1' -> 'L', '8' -> 'B'
|
||||||
|
if (ch == 0x30) { ch = 0x4F; } else if (ch == 0x31) { ch = 0x4C; } else if (ch == 0x38) { ch = 0x42; }
|
||||||
|
|
||||||
|
|
||||||
|
// look up one base32 symbols: from 'A' to 'Z' or from 'a' to 'z' or from '2' to '7'
|
||||||
|
if ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A)) { ch = ((ch & 0x1F) - 1); }
|
||||||
|
else if (ch >= 0x32 && ch <= 0x37) { ch -= (0x32 - 26); }
|
||||||
|
else { free(temp); return 0; }
|
||||||
|
|
||||||
|
buffer <<= 5;
|
||||||
|
buffer |= ch;
|
||||||
|
bitsLeft += 5;
|
||||||
|
if (bitsLeft >= 8)
|
||||||
|
{
|
||||||
|
temp[result] = (unsigned char)((unsigned int)(buffer >> (bitsLeft - 8)) & 0xFF);
|
||||||
|
result++;
|
||||||
|
bitsLeft -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out = (byte*)malloc(result);
|
||||||
|
memcpy(out, temp, result);
|
||||||
|
free(temp);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
Base32.h - Library for encoding to/decoding from Base32.
|
||||||
|
Compatible with RFC 4648 ( http://tools.ietf.org/html/rfc4648 )
|
||||||
|
Created by Vladimir Tarasow, December 18, 2012.
|
||||||
|
Released into the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef Base32_h
|
||||||
|
#define Base32_h
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
class Base32
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Base32();
|
||||||
|
int toBase32(byte*, long, char*, boolean);
|
||||||
|
int fromBase32(byte*, long, byte*&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* DataSender.cpp
|
||||||
|
*
|
||||||
|
* Created on: 08.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "MyWifiClient.h"
|
||||||
|
#include "Seconds.h"
|
||||||
|
|
||||||
|
#include "DataSender.h"
|
||||||
|
|
||||||
|
DataSender dataSender;
|
||||||
|
|
||||||
|
#define SEND_INTERVAL_SECONDS 120
|
||||||
|
#define DATA_SIZE_PER_FENSTER 11
|
||||||
|
|
||||||
|
static uint8_t buf[DATA_SIZE_PER_FENSTER * NUM_FENSTER];
|
||||||
|
|
||||||
|
|
||||||
|
DataSender::DataSender()
|
||||||
|
{
|
||||||
|
bRequestSendWifi = true;
|
||||||
|
tNextSend = SEND_INTERVAL_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSender::~DataSender()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated destructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void DataSender::onSetup(void)
|
||||||
|
{
|
||||||
|
myWifiClient.onSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void DataSender::onLoop(void)
|
||||||
|
{
|
||||||
|
if (Seconds::Get() >= tNextSend )
|
||||||
|
{
|
||||||
|
bRequestSendWifi = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bRequestSendWifi && myWifiClient.canSend())
|
||||||
|
{
|
||||||
|
bRequestSendWifi = false;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
uint8_t offset = DATA_SIZE_PER_FENSTER * i;
|
||||||
|
memcpy( &buf[offset], alleFenster[i]->name, 8 );
|
||||||
|
|
||||||
|
uint16_t remainingTime = (uint16_t) alleFenster[i]->GetRemainingTime();
|
||||||
|
memcpy( &buf[offset+8], &remainingTime , 2);
|
||||||
|
|
||||||
|
uint8_t state = alleFenster[i]->IsOpen() ? 1 : 0;
|
||||||
|
state |= alleFenster[i]->ShallPiep() ? 2 : 0;
|
||||||
|
memcpy( &buf[offset+10], &state , 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
myWifiClient.send(buf, sizeof(buf));
|
||||||
|
tNextSend = Seconds::Get() + SEND_INTERVAL_SECONDS;
|
||||||
|
}
|
||||||
|
|
||||||
|
myWifiClient.onLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void DataSender::requestSend(void)
|
||||||
|
{
|
||||||
|
bRequestSendWifi = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* DataSender.h
|
||||||
|
*
|
||||||
|
* Created on: 08.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DATASENDER_H_
|
||||||
|
#define DATASENDER_H_
|
||||||
|
|
||||||
|
class DataSender
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DataSender();
|
||||||
|
virtual ~DataSender();
|
||||||
|
void onSetup(void);
|
||||||
|
void onLoop(void);
|
||||||
|
void requestSend(void);
|
||||||
|
private:
|
||||||
|
bool bRequestSendWifi;
|
||||||
|
uint32_t tNextSend;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DataSender dataSender;
|
||||||
|
|
||||||
|
#endif /* DATASENDER_H_ */
|
||||||
+178
@@ -0,0 +1,178 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#if VERSION_BIG_DISPLAY
|
||||||
|
/*
|
||||||
|
* Display.cpp
|
||||||
|
*
|
||||||
|
* Created on: 15.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <Adafruit_GFX.h> // needs Adafruit_GFX_Library + Adafruit_BusIO
|
||||||
|
#include <Adafruit_ST7735.h> // needs Adafruit_ST7735_and_ST7789_Library
|
||||||
|
|
||||||
|
#include <Fonts/FreeSans9pt7b.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "Display.h"
|
||||||
|
|
||||||
|
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_PIN_CS, TFT_PIN_DC, TFT_PIN_MOSI, TFT_PIN_CLK, TFT_PIN_RST); // ST7735-Bibliothek Setup
|
||||||
|
|
||||||
|
Display display;
|
||||||
|
|
||||||
|
static int wWindow = 38;
|
||||||
|
static int hWindow = 18;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Display::Init(void)
|
||||||
|
{
|
||||||
|
tft.initR(INITR_BLACKTAB);
|
||||||
|
tft.setRotation(1);
|
||||||
|
tft.fillScreen(ST7735_BLACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void drawWindow(int x, int y, Fenster *fenster)
|
||||||
|
{
|
||||||
|
uint16_t col = fenster->ShallPiep() ? ST7735_ORANGE : fenster->IsOpen() ? ST77XX_WHITE : 0x0010;
|
||||||
|
|
||||||
|
if (col != fenster->color)
|
||||||
|
{
|
||||||
|
tft.fillRect(x,y,wWindow, hWindow, ST7735_BLACK);
|
||||||
|
tft.drawRect(x,y,wWindow, hWindow, col);
|
||||||
|
tft.setCursor( x+2, y + hWindow/2 - 3);
|
||||||
|
|
||||||
|
tft.setTextSize(1);
|
||||||
|
tft.setTextColor(col);
|
||||||
|
tft.print(fenster->name);
|
||||||
|
|
||||||
|
fenster->color = col;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DeciSeconds_t calcRemainingTime()
|
||||||
|
{
|
||||||
|
|
||||||
|
DeciSeconds_t remainingTime = 99999;
|
||||||
|
for (uint8_t i = 0; i < NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
if (alleFenster[i]->IsOpen()) remainingTime = min(remainingTime, alleFenster[i]->GetRemainingTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Display::Update(void)
|
||||||
|
{
|
||||||
|
// drawRect(pos_links,pos_oben,breite,hoehe,farbe);
|
||||||
|
|
||||||
|
// setTextSize(groesse);
|
||||||
|
|
||||||
|
//tft.fillScreen(ST7735_BLACK);
|
||||||
|
tft.drawRect(0, 0, 160, 128, ST7735_BLUE);
|
||||||
|
|
||||||
|
tft.setFont(NULL);
|
||||||
|
int x = 0;
|
||||||
|
int xs = 1;
|
||||||
|
int y = 1;
|
||||||
|
#if 0
|
||||||
|
drawWindow(xs + 0 * (wWindow + 2), y, &fensterBadOben);
|
||||||
|
drawWindow(xs + 1 * (wWindow + 2), y, &fensterFlo);
|
||||||
|
drawWindow(xs + 2 * (wWindow + 2), y, &fensterHanna);
|
||||||
|
drawWindow(xs + 3 * (wWindow + 2), y, &fensterFloBuero);
|
||||||
|
|
||||||
|
y += hWindow + 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
drawWindow(xs , y, &fensterBadUnten);
|
||||||
|
drawWindow(xs + 1 * (wWindow + 2), y, &fensterKueche);
|
||||||
|
drawWindow(xs + 2 * (wWindow + 2), y, &fensterWz);
|
||||||
|
drawWindow(xs + 3 * (wWindow + 2), y, &fensterWz2);
|
||||||
|
//drawWindow(xs+3*(wWindow+2), y, "Bad", true);
|
||||||
|
|
||||||
|
y += hWindow + 2;
|
||||||
|
drawWindow(xs + 0 * (wWindow + 2), y, &fensterToniNeu);
|
||||||
|
drawWindow(xs + 1 * (wWindow + 2), y, &fensterGefrier);
|
||||||
|
|
||||||
|
y += hWindow + 2;
|
||||||
|
drawWindow(xs + 0 * (wWindow + 2), y, &fensterKeller);
|
||||||
|
drawWindow(xs + 1 * (wWindow + 2), y, &fensterGaeste);
|
||||||
|
// drawWindow(xs+1*(wWindow+2), y, "Vorrat", getRandBool(), getRandBool());
|
||||||
|
//drawWindow(xs+2*(wWindow+2), y, "Wohnz", true);
|
||||||
|
//drawWindow(xs+3*(wWindow+2), y, "Bad", true);
|
||||||
|
|
||||||
|
//tft.setFont(&FreeSans9pt7b);
|
||||||
|
tft.setTextSize(2);
|
||||||
|
tft.setTextColor( ST77XX_CYAN);
|
||||||
|
x = 90;
|
||||||
|
y = 70;
|
||||||
|
tft.setCursor(x, y);
|
||||||
|
tft.fillRect(x, y-1, 159-90, 20, ST7735_BLACK );
|
||||||
|
//thermoData.rh = 50; thermoData.temp =7.3;
|
||||||
|
if (thermoData.rhPercent > 0)
|
||||||
|
{
|
||||||
|
sprintf(strBuf, "% 3d C", (int) thermoData.tempC );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(strBuf, " --");
|
||||||
|
}
|
||||||
|
tft.print(strBuf);
|
||||||
|
|
||||||
|
x = 10;
|
||||||
|
y = 97;
|
||||||
|
|
||||||
|
tft.setTextSize(3);
|
||||||
|
|
||||||
|
int yrect = 90;
|
||||||
|
int xrect = 1;
|
||||||
|
uint16_t wrect = 158;
|
||||||
|
uint16_t hrect = 127-yrect;
|
||||||
|
|
||||||
|
strcpy(strBuf, "");
|
||||||
|
for (uint8_t i = 0; i < NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
if (alleFenster[i]->ShallPiep())
|
||||||
|
{
|
||||||
|
strcpy(strBuf, alleFenster[i]->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(strBuf)==0)
|
||||||
|
{
|
||||||
|
DeciSeconds_t remainingTime = calcRemainingTime();
|
||||||
|
uint8_t mins = (remainingTime / 10) / 60;
|
||||||
|
uint8_t secs = (remainingTime / 10) % 60;
|
||||||
|
if (mins < 60)
|
||||||
|
{
|
||||||
|
sprintf(strBuf, "%d:%02d", (int) (mins), (int) (secs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strlen(strBuf)==0)
|
||||||
|
{
|
||||||
|
tft.fillRect(xrect, yrect, wrect, hrect, ST7735_BLACK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tft.fillRect(xrect, yrect, wrect, hrect, ST7735_WHITE);
|
||||||
|
tft.setTextColor( ST77XX_BLACK);
|
||||||
|
uint16_t w, h;
|
||||||
|
int16_t x1, y1;
|
||||||
|
tft.getTextBounds(strBuf, x, y, &x1, &y1, &w, &h);
|
||||||
|
tft.setCursor(xrect + (wrect - w) / 2, yrect + (hrect - h) / 2);
|
||||||
|
tft.print(strBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Display.h
|
||||||
|
*
|
||||||
|
* Created on: 15.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#if VERSION_BIG_DISPLAY
|
||||||
|
|
||||||
|
#ifndef DISPLAY_H_
|
||||||
|
#define DISPLAY_H_
|
||||||
|
|
||||||
|
class Display
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Init(void);
|
||||||
|
void Update(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
char strBuf[50];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Display display;
|
||||||
|
|
||||||
|
#endif /* DISPLAY_H_ */
|
||||||
|
|
||||||
|
#endif /* #if VERSION_EG_ONLY */
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#if VERSION_SMALL_DISPLAY
|
||||||
|
/*
|
||||||
|
* Display.cpp
|
||||||
|
*
|
||||||
|
* Created on: 15.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "Display_SSD1306.h"
|
||||||
|
#include "SSD1306Wire.h" /* LIBRARY : ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays */
|
||||||
|
|
||||||
|
// for 128x64 displays:
|
||||||
|
SSD1306Wire ssd1306(0x3c, SDA, SCL); // ADDRESS, SDA, SCL
|
||||||
|
|
||||||
|
Display display;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Display::Init(void)
|
||||||
|
{
|
||||||
|
ssd1306.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DeciSeconds_t calcRemainingTime()
|
||||||
|
{
|
||||||
|
|
||||||
|
DeciSeconds_t remainingTime = 99999;
|
||||||
|
for (uint8_t i = 0; i < NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
if (alleFenster[i]->IsOpen()) remainingTime = min(remainingTime, alleFenster[i]->GetRemainingTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
return remainingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void Display::Update(void)
|
||||||
|
{
|
||||||
|
ssd1306.clear();
|
||||||
|
ssd1306.setFont(ArialMT_Plain_16); /* https://github.com/ThingPulse/esp8266-oled-ssd1306/blob/master/README.md */
|
||||||
|
ssd1306.setBrightness(100u);
|
||||||
|
|
||||||
|
int x = 2;
|
||||||
|
int y = 0;
|
||||||
|
int yrect = 0;
|
||||||
|
int xrect = 0;
|
||||||
|
uint16_t wrect = 64;
|
||||||
|
uint16_t hrect = 18;
|
||||||
|
|
||||||
|
/* print Windows */
|
||||||
|
uint8_t i;
|
||||||
|
for (i=0; i<NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
if (alleFenster[i]->IsOpen())
|
||||||
|
{
|
||||||
|
ssd1306.setColor(WHITE);
|
||||||
|
ssd1306.fillRect(xrect, yrect, wrect, hrect);
|
||||||
|
|
||||||
|
ssd1306.setColor(BLACK);
|
||||||
|
ssd1306.drawString(x, y, alleFenster[i]->name);
|
||||||
|
ssd1306.drawString(x+1, y, alleFenster[i]->name);
|
||||||
|
ssd1306.drawString(x+1, y+1, alleFenster[i]->name);
|
||||||
|
ssd1306.drawString(x, y+1, alleFenster[i]->name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ssd1306.setColor(WHITE);
|
||||||
|
ssd1306.drawString(x, y, alleFenster[i]->name);
|
||||||
|
}
|
||||||
|
if (i&1)
|
||||||
|
{
|
||||||
|
xrect = 0u;
|
||||||
|
x = 2u;
|
||||||
|
yrect += 20;
|
||||||
|
y+= 20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xrect = 64;
|
||||||
|
x = 66;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* print Temperature */
|
||||||
|
x=0;
|
||||||
|
y=64-16;
|
||||||
|
if (thermoData.rhPercent > 0)
|
||||||
|
{
|
||||||
|
sprintf(strBuf, "% 3d C", (int) thermoData.tempC);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(strBuf, " --");
|
||||||
|
}
|
||||||
|
//tft.print(strBuf);
|
||||||
|
ssd1306.setColor(WHITE);
|
||||||
|
ssd1306.drawString(x, y, strBuf);
|
||||||
|
|
||||||
|
/* print Remaining time */
|
||||||
|
yrect = 64-16;
|
||||||
|
xrect = 64;
|
||||||
|
wrect = 32;
|
||||||
|
hrect = 16;
|
||||||
|
strcpy(strBuf, "");
|
||||||
|
for (uint8_t i = 0; i < NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
if (alleFenster[i]->ShallPiep())
|
||||||
|
{
|
||||||
|
strcpy(strBuf, alleFenster[i]->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(strBuf)==0)
|
||||||
|
{
|
||||||
|
DeciSeconds_t remainingTime = calcRemainingTime();
|
||||||
|
uint8_t mins = (remainingTime / 10) / 60;
|
||||||
|
uint8_t secs = (remainingTime / 10) % 60;
|
||||||
|
if (mins < 60)
|
||||||
|
{
|
||||||
|
sprintf(strBuf, "%d:%02d", (int) (mins), (int) (secs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strlen(strBuf)==0)
|
||||||
|
{
|
||||||
|
//ssd1306.setColor(BLACK);
|
||||||
|
//ssd1306.fillRect(xrect, yrect, wrect, hrect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ssd1306.setColor(WHITE);
|
||||||
|
//ssd1306.fillRect(xrect, yrect, wrect, hrect);
|
||||||
|
//ssd1306.setColor(BLACK);
|
||||||
|
|
||||||
|
ssd1306.drawString(xrect,yrect, strBuf);
|
||||||
|
ssd1306.drawString(xrect+1,yrect, strBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssd1306.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #if VERSION_DG_ONLY
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Display.h
|
||||||
|
*
|
||||||
|
* Created on: 15.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#if VERSION_SMALL_DISPLAY
|
||||||
|
|
||||||
|
#ifndef DISPLAY_SSD1306_H_
|
||||||
|
#define DISPLAY_SSD1306_H_
|
||||||
|
|
||||||
|
class Display
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void Init(void);
|
||||||
|
void Update(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
char strBuf[50];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Display display;
|
||||||
|
|
||||||
|
#endif /* DISPLAY_SSD1306_H_ */
|
||||||
|
#endif
|
||||||
+107
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Fenster.cpp
|
||||||
|
*
|
||||||
|
* Created on: 29.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "Fenster.h"
|
||||||
|
#include "ReceiverFunkThermometer.h"
|
||||||
|
|
||||||
|
#define SERIAL_PRINT(x) //Serial.print(" "); Serial.print(x)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Fenster::Fenster(const char *_name, uint8_t myKeyNumber)
|
||||||
|
{
|
||||||
|
strcpy(this->name , _name);
|
||||||
|
this->myKeyNumber = myKeyNumber;
|
||||||
|
openingTime = 0;
|
||||||
|
shallPiep = false;
|
||||||
|
color = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* keyNum : key number with offset
|
||||||
|
*/
|
||||||
|
bool Fenster::HandleKey(int8_t keyNum, bool direction)
|
||||||
|
{
|
||||||
|
bool bThisWindowChanged = false;
|
||||||
|
if (keyNum == myKeyNumber)
|
||||||
|
{
|
||||||
|
if (direction == DIRECTION_OPEN)
|
||||||
|
{
|
||||||
|
if (openingTime == 0u)
|
||||||
|
{
|
||||||
|
bThisWindowChanged = true;
|
||||||
|
openingTime = tDecis;
|
||||||
|
SERIAL_PRINT("open ");
|
||||||
|
SERIAL_PRINT(myKeyNumber);
|
||||||
|
SERIAL_PRINT(waitTimeDs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (openingTime != 0u)
|
||||||
|
{
|
||||||
|
bThisWindowChanged = true;
|
||||||
|
shallPiep = false;
|
||||||
|
openingTime = 0;
|
||||||
|
SERIAL_PRINT("close ");
|
||||||
|
SERIAL_PRINT(myKeyNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bThisWindowChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool Fenster::ShallPiep()
|
||||||
|
{
|
||||||
|
DeciSeconds_t tWaitDs = waitTimeDs;
|
||||||
|
if (this == &fensterGefrier)
|
||||||
|
{
|
||||||
|
tWaitDs = 300u;
|
||||||
|
}
|
||||||
|
if ((tDecis > openingTime + tWaitDs) && (openingTime > 0))
|
||||||
|
{
|
||||||
|
shallPiep = true;
|
||||||
|
}
|
||||||
|
return shallPiep;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DeciSeconds_t Fenster::GetRemainingTime()
|
||||||
|
{
|
||||||
|
DeciSeconds_t tWaitDs = waitTimeDs;
|
||||||
|
if (this == &fensterGefrier)
|
||||||
|
{
|
||||||
|
tWaitDs = 300u;
|
||||||
|
}
|
||||||
|
if (openingTime > 0)
|
||||||
|
{
|
||||||
|
DeciSeconds_t remainingTime = openingTime + tWaitDs - tDecis;
|
||||||
|
return remainingTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Fenster::IsOpen()
|
||||||
|
{
|
||||||
|
return (openingTime > 0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Fenster.h
|
||||||
|
*
|
||||||
|
* Created on: 29.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FENSTER_H_
|
||||||
|
#define FENSTER_H_
|
||||||
|
|
||||||
|
#include "typedefs.h"
|
||||||
|
|
||||||
|
class Fenster
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
char name[8];
|
||||||
|
uint16_t color;
|
||||||
|
Fenster(const char *_name, uint8_t myKeyNumber);
|
||||||
|
|
||||||
|
bool HandleKey(int8_t keyNum, bool direction);
|
||||||
|
|
||||||
|
bool ShallPiep();
|
||||||
|
DeciSeconds_t GetRemainingTime();
|
||||||
|
bool IsOpen();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t myKeyNumber;
|
||||||
|
DeciSeconds_t openingTime;
|
||||||
|
bool shallPiep;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FENSTER_H_ */
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Hamming.cpp
|
||||||
|
*
|
||||||
|
* Created on: 10.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Hamming.h"
|
||||||
|
|
||||||
|
Hamming::Hamming()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Hamming::~Hamming()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated destructor stub
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Hamming.h
|
||||||
|
*
|
||||||
|
* Created on: 10.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAMMING_H_
|
||||||
|
#define HAMMING_H_
|
||||||
|
|
||||||
|
class Hamming
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Hamming();
|
||||||
|
virtual ~Hamming();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* HAMMING_H_ */
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "PiepPattern.h"
|
||||||
|
#include "ReceiverSmartWares.h"
|
||||||
|
#include "ReceiverAiggend.h"
|
||||||
|
#include "ReceiverOval.h"
|
||||||
|
#include "ReceiverKerui.h"
|
||||||
|
#include "ReceiverFunkThermometer.h"
|
||||||
|
|
||||||
|
#include "InterruptHandler.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define LOOP_COUNTS_FOR_PAUSE (2u)
|
||||||
|
/*****************************************************/
|
||||||
|
|
||||||
|
IRAM_ATTR void timerIsr();
|
||||||
|
IRAM_ATTR void pinLevelChangeIsr(void);
|
||||||
|
|
||||||
|
/*****************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void InterruptHandler_Init(void)
|
||||||
|
{
|
||||||
|
/* setup interrupt */
|
||||||
|
attachInterrupt(digitalPinToInterrupt(DIN_FUNK), pinLevelChangeIsr, CHANGE);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
hw_timer_t * timer = timerBegin(0, 80, true); /* 80 -> 1 Mhz */
|
||||||
|
timerAttachInterrupt(timer, &timerIsr, true);
|
||||||
|
timerAlarmWrite(timer, ISR_TIME_US, true);
|
||||||
|
timerAlarmEnable(timer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* called every 10 ms
|
||||||
|
*
|
||||||
|
* used to update tDecis, and for beeping
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void timerIsr()
|
||||||
|
{
|
||||||
|
static uint32_t tshortPiepStartedMs = 0;
|
||||||
|
static uint8_t count = 0;
|
||||||
|
static boolean toneOn = false;
|
||||||
|
uint32_t tMillis = millis();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static bool on = true;
|
||||||
|
if (on) digitalWrite(DOUT_TEST_TIMER, HIGH);
|
||||||
|
else digitalWrite(DOUT_TEST_TIMER, LOW);
|
||||||
|
on = !on;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (++count == MS_TO_ISR_COUNT(100uL) )
|
||||||
|
{
|
||||||
|
/* increment tDecis every 100ms */
|
||||||
|
count = 0;
|
||||||
|
tDecis++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bRequestShortBeep)
|
||||||
|
{
|
||||||
|
bRequestShortBeep = false;
|
||||||
|
tshortPiepStartedMs = tMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tshortPiepStartedMs > 0u)
|
||||||
|
{
|
||||||
|
if (tMillis < (tshortPiepStartedMs + 30uL))
|
||||||
|
{
|
||||||
|
if (false == toneOn)
|
||||||
|
{
|
||||||
|
TONE_REQUEST_ON(TONE_REQUEST_SOURCE_SHORTPIEP);
|
||||||
|
toneOn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TONE_REQUEST_OFF(TONE_REQUEST_SOURCE_SHORTPIEP);
|
||||||
|
tshortPiepStartedMs = 0;
|
||||||
|
toneOn = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
piepPattern->TaskCyclic();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toneRequest != 0u)
|
||||||
|
{
|
||||||
|
digitalWrite(DOUT_PIEP_VCC, HIGH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
digitalWrite(DOUT_PIEP_VCC, LOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IRAM_ATTR void InterruptHandler_PauseReceive()
|
||||||
|
{
|
||||||
|
loopCountSincePause = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void pinLevelChangeIsr(void)
|
||||||
|
{
|
||||||
|
static bool lastVal = LOW;
|
||||||
|
static uint32_t lastMics = 0;
|
||||||
|
static uint32_t MINIMAL_DT_MICROS_FOR_RECEIVERS = 100u;
|
||||||
|
|
||||||
|
uint32_t dtMicros = micros() - lastMics;
|
||||||
|
bool pinFunkVal = digitalRead(DIN_FUNK);
|
||||||
|
|
||||||
|
if (lastVal == pinFunkVal)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastMics = micros();
|
||||||
|
|
||||||
|
lastVal = pinFunkVal;
|
||||||
|
if (loopCountSincePause < LOOP_COUNTS_FOR_PAUSE)
|
||||||
|
{
|
||||||
|
/* after receiving a key, wait for the main loop to run x times before activating receiving again */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (dtMicros > MINIMAL_DT_MICROS_FOR_RECEIVERS)
|
||||||
|
{
|
||||||
|
receiverSw.Isr(dtMicros, pinFunkVal);
|
||||||
|
receiverAiggend.Isr(dtMicros, pinFunkVal);
|
||||||
|
receiverOval.Isr(dtMicros, pinFunkVal);
|
||||||
|
receiverKerui.Isr(dtMicros, pinFunkVal);
|
||||||
|
receiverThermo.Isr(dtMicros, pinFunkVal);
|
||||||
|
|
||||||
|
//digitalWrite(LED_BUILTIN, pinFunkVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* interruptHandler.h
|
||||||
|
*
|
||||||
|
* Created on: 11.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef INTERRUPTHANDLER_H_
|
||||||
|
#define INTERRUPTHANDLER_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define ISR_TIME_US (10000uL)
|
||||||
|
|
||||||
|
#define MS_TO_ISR_COUNT(ms) ( ((ms)*1000uL) / ISR_TIME_US )
|
||||||
|
|
||||||
|
|
||||||
|
void InterruptHandler_Init(void);
|
||||||
|
void InterruptHandler_PauseReceive();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* INTERRUPTHANDLER_H_ */
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* LedBlinker.cpp
|
||||||
|
*
|
||||||
|
* Created on: 29.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "LedBlinker.h"
|
||||||
|
#include "ReceiverFunkThermometer.h"
|
||||||
|
|
||||||
|
#define BLINK_TIME ((DeciSeconds_t)2)
|
||||||
|
|
||||||
|
LedBlinker ledBlinker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void LedBlinker::OnLoop()
|
||||||
|
{
|
||||||
|
|
||||||
|
static DeciSeconds_t tOn;
|
||||||
|
static DeciSeconds_t tOff;
|
||||||
|
static uint32_t numBlinkFast = 0;
|
||||||
|
|
||||||
|
if (numberWindowsOpen > 0)
|
||||||
|
{
|
||||||
|
if (tDecis > tOn)
|
||||||
|
{
|
||||||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||||||
|
tOff = tDecis + BLINK_TIME;
|
||||||
|
tOn = tOff + BLINK_TIME;
|
||||||
|
}
|
||||||
|
if (tDecis > tOff)
|
||||||
|
{
|
||||||
|
digitalWrite(LED_BUILTIN, LOW);
|
||||||
|
tOn = tDecis + BLINK_TIME;
|
||||||
|
tOff = tOn + BLINK_TIME;
|
||||||
|
if (numBlinkFast>0)
|
||||||
|
{
|
||||||
|
numBlinkFast--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numBlinkFast = numberWindowsOpen-1;
|
||||||
|
tOn += BLINK_TIME*3;
|
||||||
|
tOff += BLINK_TIME*3;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* LedBlinker.h
|
||||||
|
*
|
||||||
|
* Created on: 29.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LEDBLINKER_H_
|
||||||
|
#define LEDBLINKER_H_
|
||||||
|
|
||||||
|
class LedBlinker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void OnLoop();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern LedBlinker ledBlinker;
|
||||||
|
|
||||||
|
#endif /* LEDBLINKER_H_ */
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* MyWifiClient.cpp
|
||||||
|
*
|
||||||
|
* Created on: 24.09.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "Base32.h"
|
||||||
|
#include "Seconds.h"
|
||||||
|
#include "Version.h"
|
||||||
|
|
||||||
|
#include "MyWifiClient.h"
|
||||||
|
|
||||||
|
Base32 base32;
|
||||||
|
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define MonitorPrint(...) Serial.print(__VA_ARGS__)
|
||||||
|
#define MonitorPrintln(...) Serial.println(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define MonitorPrint(...)
|
||||||
|
#define MonitorPrintln(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
MyWifiClient myWifiClient;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MyWifiClient::MyWifiClient()
|
||||||
|
{
|
||||||
|
state = IDLE;
|
||||||
|
bSend = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MyWifiClient::~MyWifiClient()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool MyWifiClient::canSend(void)
|
||||||
|
{
|
||||||
|
return state == IDLE && bSend == false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* converts dat to base32 and triggers GET request */
|
||||||
|
void MyWifiClient::send(uint8_t *dat, uint16_t len)
|
||||||
|
{
|
||||||
|
strcpy( wifibufMsg , "GET /genericData.php?project=fensterpiepser&dataname=fenster&data=");
|
||||||
|
size_t pos = strlen(wifibufMsg);
|
||||||
|
(void) base32.toBase32(dat, len, &wifibufMsg[pos], true);
|
||||||
|
strcat( wifibufMsg, " HTTP/1.1\r\nHost: fly-with-cats.com\r\nAccept: */*\r\n\r\n");
|
||||||
|
|
||||||
|
bSend = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void MyWifiClient::onSetup(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void MyWifiClient::onLoop(void)
|
||||||
|
{
|
||||||
|
static substate_t substate = ENTRY;
|
||||||
|
static state_t prevState = IDLE;
|
||||||
|
|
||||||
|
if (prevState != state)
|
||||||
|
{
|
||||||
|
substate = ENTRY;
|
||||||
|
prevState = state;
|
||||||
|
switch(state)
|
||||||
|
{
|
||||||
|
case IDLE:
|
||||||
|
MonitorPrintln("IDLE");
|
||||||
|
break;
|
||||||
|
case WAIT_CONNECT:
|
||||||
|
MonitorPrintln("WAIT_CONNECT");
|
||||||
|
break;
|
||||||
|
case WAIT_RECEIVE:
|
||||||
|
MonitorPrintln("WAIT_RECEIVE");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case IDLE:
|
||||||
|
switch (substate)
|
||||||
|
{
|
||||||
|
static uint32_t tConnectWifiEndSeconds;
|
||||||
|
case ENTRY:
|
||||||
|
tConnectWifiEndSeconds = Seconds::Get() + 60;
|
||||||
|
substate = CYCLIC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CYCLIC:
|
||||||
|
if (WiFi.isConnected())
|
||||||
|
{
|
||||||
|
tConnectWifiEndSeconds = Seconds::Get() + 60;
|
||||||
|
if (bSend)
|
||||||
|
{
|
||||||
|
bSend = false;
|
||||||
|
state = WAIT_CONNECT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Seconds::Get() > tConnectWifiEndSeconds)
|
||||||
|
{
|
||||||
|
Serial.println("RESET (Wifi)");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_CONNECT:
|
||||||
|
switch (substate)
|
||||||
|
{
|
||||||
|
static uint32_t tConnectEndSeconds;
|
||||||
|
case ENTRY:
|
||||||
|
/* Connect to Server */
|
||||||
|
this->connect("fly-with-cats.com", 8887, 100);
|
||||||
|
tConnectEndSeconds = Seconds::Get() + 5;
|
||||||
|
substate = CYCLIC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CYCLIC:
|
||||||
|
if (this->connected())
|
||||||
|
{
|
||||||
|
/* send HTTP request */
|
||||||
|
this->print(wifibufMsg);
|
||||||
|
MonitorPrint(wifibufMsg);
|
||||||
|
state = WAIT_RECEIVE;
|
||||||
|
}
|
||||||
|
else if (Seconds::Get() > tConnectEndSeconds)
|
||||||
|
{
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WAIT_RECEIVE:
|
||||||
|
switch (substate)
|
||||||
|
{
|
||||||
|
static uint32_t tReceiveEndSeconds;
|
||||||
|
|
||||||
|
case ENTRY:
|
||||||
|
tReceiveEndSeconds = Seconds::Get() + 5;
|
||||||
|
substate = CYCLIC;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CYCLIC:
|
||||||
|
if (this->available())
|
||||||
|
{
|
||||||
|
int sizeRec = this->read(wifibufRx, WIFI_BUF_SIZE_RX);
|
||||||
|
wifibufRx[sizeRec] = 0;
|
||||||
|
//MonitorPrintln((char*)wifibufRx);
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
else if (Seconds::Get() >= tReceiveEndSeconds)
|
||||||
|
{
|
||||||
|
this->stop();
|
||||||
|
state = IDLE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* MyWifiClient.h
|
||||||
|
*
|
||||||
|
* Created on: 24.09.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MYWIFICLIENT_H_
|
||||||
|
#define MYWIFICLIENT_H_
|
||||||
|
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include "Base32.h"
|
||||||
|
#include <WiFiClient.h>
|
||||||
|
|
||||||
|
#define WIFI_BUF_SIZE_RX 1024
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum { IDLE, WAIT_CONNECT, WAIT_RECEIVE } state_t;
|
||||||
|
typedef enum { ENTRY, CYCLIC } substate_t;
|
||||||
|
class MyWifiClient: public WiFiClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyWifiClient();
|
||||||
|
virtual ~MyWifiClient();
|
||||||
|
void send(uint8_t *dat, uint16_t len);
|
||||||
|
void onSetup(void);
|
||||||
|
void onLoop(void);
|
||||||
|
bool canSend(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool bSend;
|
||||||
|
state_t state;
|
||||||
|
char wifibufMsg[WIFI_BUF_SIZE_RX];
|
||||||
|
|
||||||
|
uint8_t wifibufRx[WIFI_BUF_SIZE_RX];
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MyWifiClient myWifiClient;
|
||||||
|
extern Base32 base32;
|
||||||
|
|
||||||
|
#endif /* MYWIFICLIENT_H_ */
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* PiepMode.cpp
|
||||||
|
*
|
||||||
|
* Created on: 25.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "PiepMode.h"
|
||||||
|
|
||||||
|
#define SERIAL_PRINT(x) //Serial.print(" "); Serial.print(x)
|
||||||
|
|
||||||
|
|
||||||
|
#define STANDBY 0
|
||||||
|
#define ON 1
|
||||||
|
#define OFF 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
PiepMode::PiepMode()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated constructor stub
|
||||||
|
state = STANDBY;
|
||||||
|
startRequest = false;
|
||||||
|
stopRequest = false;
|
||||||
|
requestCount = 255;
|
||||||
|
timer = 0;
|
||||||
|
onTime = 100;
|
||||||
|
offTime = 100;
|
||||||
|
counter = 0;
|
||||||
|
outPin = 13;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void PiepMode::Start(uint8_t outPin)
|
||||||
|
{
|
||||||
|
startRequest = true;
|
||||||
|
this->outPin = outPin;
|
||||||
|
//pinMode(outPin, OUTPUT);
|
||||||
|
state = STANDBY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void PiepMode::Stop()
|
||||||
|
{
|
||||||
|
stopRequest = true;
|
||||||
|
TONE_REQUEST_OFF(TONE_REQUEST_SOURCE_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR bool PiepMode::HasCompleted(void)
|
||||||
|
{
|
||||||
|
return (state == STANDBY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void PiepMode::TaskCyclic()
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case STANDBY:
|
||||||
|
SERIAL_PRINT("S");
|
||||||
|
stopRequest = false;
|
||||||
|
if (startRequest)
|
||||||
|
{
|
||||||
|
startRequest = false;
|
||||||
|
state = ON;
|
||||||
|
counter = 0;
|
||||||
|
timer = onTime;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ON:
|
||||||
|
SERIAL_PRINT(timer);
|
||||||
|
SERIAL_PRINT(onTime);
|
||||||
|
/* switch on */
|
||||||
|
startRequest = false;
|
||||||
|
if (stopRequest)
|
||||||
|
{
|
||||||
|
state = STANDBY;
|
||||||
|
}
|
||||||
|
else if (timer > 0)
|
||||||
|
{
|
||||||
|
TONE_REQUEST_ON(TONE_REQUEST_SOURCE_MODE);
|
||||||
|
timer--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
timer = offTime;
|
||||||
|
state = OFF;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFF:
|
||||||
|
SERIAL_PRINT("F");
|
||||||
|
/* switch off */
|
||||||
|
startRequest = false;
|
||||||
|
if (stopRequest)
|
||||||
|
{
|
||||||
|
state = STANDBY;
|
||||||
|
}
|
||||||
|
else if (timer > 0)
|
||||||
|
{
|
||||||
|
TONE_REQUEST_OFF(TONE_REQUEST_SOURCE_MODE);
|
||||||
|
timer--;
|
||||||
|
}
|
||||||
|
else if (requestCount == 0)
|
||||||
|
{
|
||||||
|
timer = onTime;
|
||||||
|
state = ON;
|
||||||
|
}
|
||||||
|
else if (++counter < requestCount)
|
||||||
|
{
|
||||||
|
timer = onTime;
|
||||||
|
state = ON;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
state = STANDBY;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Serial.print(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* PiepMode.h
|
||||||
|
*
|
||||||
|
* Created on: 25.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIEPMODE_H_
|
||||||
|
#define PIEPMODE_H_
|
||||||
|
|
||||||
|
class PiepMode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PiepMode();
|
||||||
|
|
||||||
|
void TaskCyclic();
|
||||||
|
void Start(uint8_t outPin);
|
||||||
|
void Stop();
|
||||||
|
bool HasCompleted(void);
|
||||||
|
|
||||||
|
uint32_t onTime, offTime;
|
||||||
|
uint32_t requestCount;
|
||||||
|
|
||||||
|
private :
|
||||||
|
uint32_t counter, timer, outPin;
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t startRequest, stopRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PIEPMODE_H_ */
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* PiepPattern.cpp
|
||||||
|
*
|
||||||
|
* Created on: 25.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "PiepPattern.h"
|
||||||
|
#include "PiepMode.h"
|
||||||
|
|
||||||
|
#define SERIAL_PRINT(x) // Serial.print(" "); Serial.print(x)
|
||||||
|
|
||||||
|
#define STANDBY 0
|
||||||
|
#define ON 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
PiepPattern::PiepPattern()
|
||||||
|
{
|
||||||
|
requestCount = 0;
|
||||||
|
numberModes = 0;
|
||||||
|
counter = 0;
|
||||||
|
modeIndex = 0;
|
||||||
|
startRequest = false;
|
||||||
|
stopRequest = false;
|
||||||
|
state = STANDBY;
|
||||||
|
outPin = 13;
|
||||||
|
piepModes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void PiepPattern::Start(uint8_t outPin)
|
||||||
|
{
|
||||||
|
startRequest = true;
|
||||||
|
this->outPin = outPin;
|
||||||
|
state = STANDBY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void PiepPattern::Stop()
|
||||||
|
{
|
||||||
|
stopRequest = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void PiepPattern::TaskCyclic()
|
||||||
|
{
|
||||||
|
switch (state)
|
||||||
|
{
|
||||||
|
case STANDBY:
|
||||||
|
SERIAL_PRINT("STDBY");
|
||||||
|
stopRequest = false;
|
||||||
|
if (startRequest)
|
||||||
|
{
|
||||||
|
startRequest = false;
|
||||||
|
counter = 0;
|
||||||
|
modeIndex = 0;
|
||||||
|
if (numberModes > 0)
|
||||||
|
{
|
||||||
|
state = ON;
|
||||||
|
piepModes[modeIndex]->Start(outPin);
|
||||||
|
piepModes[modeIndex]->TaskCyclic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ON:
|
||||||
|
SERIAL_PRINT(modeIndex);
|
||||||
|
SERIAL_PRINT(piepModes[modeIndex]->onTime);
|
||||||
|
startRequest = false;
|
||||||
|
piepModes[modeIndex]->TaskCyclic();
|
||||||
|
|
||||||
|
if (stopRequest)
|
||||||
|
{
|
||||||
|
piepModes[modeIndex]->Stop();
|
||||||
|
state = STANDBY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (piepModes[modeIndex]->HasCompleted())
|
||||||
|
{
|
||||||
|
if (++modeIndex < numberModes)
|
||||||
|
{
|
||||||
|
piepModes[modeIndex]->Start(outPin);
|
||||||
|
}
|
||||||
|
else if ( requestCount == 0)
|
||||||
|
{
|
||||||
|
modeIndex = 0;
|
||||||
|
piepModes[modeIndex]->Start(outPin);
|
||||||
|
}
|
||||||
|
else if ( ++counter < requestCount )
|
||||||
|
{
|
||||||
|
modeIndex = 0;
|
||||||
|
piepModes[modeIndex]->Start(outPin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Serial.print(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* PiepPattern.h
|
||||||
|
*
|
||||||
|
* Created on: 25.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PIEPPATTERN_H_
|
||||||
|
#define PIEPPATTERN_H_
|
||||||
|
|
||||||
|
#include "PiepMode.h"
|
||||||
|
|
||||||
|
class PiepPattern
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PiepPattern();
|
||||||
|
void TaskCyclic();
|
||||||
|
void Start(uint8_t outPin);
|
||||||
|
void Stop(void);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t requestCount;
|
||||||
|
uint8_t numberModes;
|
||||||
|
class PiepMode **piepModes;
|
||||||
|
|
||||||
|
|
||||||
|
private :
|
||||||
|
uint8_t counter;
|
||||||
|
uint8_t modeIndex;
|
||||||
|
uint8_t outPin;
|
||||||
|
uint8_t startRequest, stopRequest;
|
||||||
|
uint8_t state;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* PIEPPATTERN_H_ */
|
||||||
@@ -0,0 +1,326 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverFunkThermometer.cpp
|
||||||
|
*
|
||||||
|
* Created on: 10.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "DataSender.h"
|
||||||
|
#include "ReceiverFunkThermometer.h"
|
||||||
|
|
||||||
|
#define DEBUG_LEVEL 0
|
||||||
|
|
||||||
|
#define MonitorPrint(x) // Serial.print(x)
|
||||||
|
|
||||||
|
ReceiverFunkThermometer receiverThermo;
|
||||||
|
|
||||||
|
/* ca. alle 50s wird temp + rh gesendet */
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ReceiverFunkThermometer::ReceiverFunkThermometer()
|
||||||
|
{
|
||||||
|
ResetBuffer();
|
||||||
|
data.tempC = 10;
|
||||||
|
data.rhPercent = 50;
|
||||||
|
bNewData = false;
|
||||||
|
dataLast.tempC = 99;
|
||||||
|
dataLast.rhPercent = 0u;
|
||||||
|
rBitNumber = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool ReceiverFunkThermometer::HasNewData(void)
|
||||||
|
{
|
||||||
|
return bNewData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ReceiverFunkThermometerData_t ReceiverFunkThermometer::GetData(void)
|
||||||
|
{
|
||||||
|
ReceiverFunkThermometerData_t datTemp = data;
|
||||||
|
return datTemp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverFunkThermometer::Isr(uint32_t dtMicros, bool pinValue)
|
||||||
|
{
|
||||||
|
static SignalDurationThermometer_t lastDuration = FUNK_THERMO_INVALID;
|
||||||
|
SignalDurationThermometer_t thisDuration = FUNK_THERMO_INVALID;
|
||||||
|
|
||||||
|
|
||||||
|
if (dtMicros > 350 && dtMicros < 600)
|
||||||
|
{
|
||||||
|
thisDuration = MS_0_5;
|
||||||
|
}
|
||||||
|
else if (dtMicros > 800 && dtMicros < 1200)
|
||||||
|
{
|
||||||
|
thisDuration = MS_1_0;
|
||||||
|
}
|
||||||
|
else if (dtMicros > 1800 && dtMicros < 2200)
|
||||||
|
{
|
||||||
|
thisDuration = MS_2_0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisDuration = FUNK_THERMO_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (thisDuration == FUNK_THERMO_INVALID )
|
||||||
|
{
|
||||||
|
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
if (lastDuration == FUNK_THERMO_INVALID)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (pinValue == HIGH )
|
||||||
|
{
|
||||||
|
#if DEBUG_LEVEL > 1
|
||||||
|
bool bprint = (rByteIndex > 0 || rBitIndex<7);
|
||||||
|
#else
|
||||||
|
bool bprint = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (bprint)
|
||||||
|
{
|
||||||
|
sprintf(textBuf, "\n%d %d : ", rByteIndex, rBitIndex );
|
||||||
|
MonitorPrint(textBuf);
|
||||||
|
}
|
||||||
|
if (thisDuration==MS_2_0 && lastDuration == MS_0_5)
|
||||||
|
{
|
||||||
|
if (bprint)
|
||||||
|
{
|
||||||
|
MonitorPrint(F("1"));
|
||||||
|
}
|
||||||
|
/* bit 1 received */
|
||||||
|
rBytes[rByteIndex] |= (1 << rBitIndex);
|
||||||
|
if (rBitIndex == 0)
|
||||||
|
{
|
||||||
|
NextByte();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBitIndex--;
|
||||||
|
}
|
||||||
|
rBitNumber++;
|
||||||
|
if (THERMO_NUM_BITS_IGNORED == rBitNumber)
|
||||||
|
{
|
||||||
|
rByteIndex = 0;
|
||||||
|
rBitIndex = 7;
|
||||||
|
rBytes[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (thisDuration==MS_1_0 &&lastDuration == MS_0_5)
|
||||||
|
{
|
||||||
|
if (bprint)
|
||||||
|
{
|
||||||
|
MonitorPrint(F("0"));
|
||||||
|
}
|
||||||
|
/* bit 0 received */
|
||||||
|
if (rBitIndex == 0)
|
||||||
|
{
|
||||||
|
NextByte();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBitIndex--;
|
||||||
|
}
|
||||||
|
rBitNumber++;
|
||||||
|
if (THERMO_NUM_BITS_IGNORED == rBitNumber)
|
||||||
|
{
|
||||||
|
rByteIndex = 0;
|
||||||
|
rBitIndex = 7;
|
||||||
|
rBytes[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
lastDuration = thisDuration;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverFunkThermometer::ResetBuffer(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
rByteIndex = 0;
|
||||||
|
rBitIndex = 7;
|
||||||
|
rBytes[0] = 0;
|
||||||
|
rBitNumber = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverFunkThermometer::NextByte(void)
|
||||||
|
{
|
||||||
|
rByteIndex++;
|
||||||
|
rBitIndex = 7;
|
||||||
|
|
||||||
|
if (rByteIndex == THERMO_KEY_NUMBYTES_PER_KEY)
|
||||||
|
{
|
||||||
|
OnTempReceived();
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* init the next byte */
|
||||||
|
rBytes[rByteIndex] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
bytes received from woolworth temp
|
||||||
|
-0,9C 89%
|
||||||
|
112
|
||||||
|
255
|
||||||
|
127
|
||||||
|
89
|
||||||
|
------------
|
||||||
|
-0,8 89
|
||||||
|
112
|
||||||
|
255
|
||||||
|
143
|
||||||
|
89
|
||||||
|
------------
|
||||||
|
-0,7 89
|
||||||
|
112
|
||||||
|
255
|
||||||
|
159
|
||||||
|
89
|
||||||
|
------------
|
||||||
|
-0,6 89
|
||||||
|
112
|
||||||
|
255
|
||||||
|
175
|
||||||
|
89
|
||||||
|
------------
|
||||||
|
-0,5 89
|
||||||
|
112
|
||||||
|
255
|
||||||
|
191
|
||||||
|
89
|
||||||
|
------------
|
||||||
|
0,0 90
|
||||||
|
112
|
||||||
|
0
|
||||||
|
15
|
||||||
|
90 rh
|
||||||
|
------------
|
||||||
|
0.1 90
|
||||||
|
112
|
||||||
|
0
|
||||||
|
31
|
||||||
|
90
|
||||||
|
|
||||||
|
|
||||||
|
112
|
||||||
|
0
|
||||||
|
95
|
||||||
|
90
|
||||||
|
|
||||||
|
6.4
|
||||||
|
112
|
||||||
|
4
|
||||||
|
15
|
||||||
|
69
|
||||||
|
|
||||||
|
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverFunkThermometer::OnTempReceived(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* first 4 bits of 36 bits are thrown away.. Rest :
|
||||||
|
bytes 0 1 2 3
|
||||||
|
nibbles : 0 1 2 3 4 5 6 7
|
||||||
|
value : id id t t t 0xf h h
|
||||||
|
*/
|
||||||
|
#define PRINT_ON_TEMP_RECEIVED 0
|
||||||
|
#if 0
|
||||||
|
/* testdaten */
|
||||||
|
rBytes[0] = 112u;
|
||||||
|
rBytes[1] = 255u;
|
||||||
|
rBytes[2] = 191u;
|
||||||
|
rBytes[3] = 89u;
|
||||||
|
#endif
|
||||||
|
#if PRINT_ON_TEMP_RECEIVED
|
||||||
|
Serial.println(rBytes[0]);
|
||||||
|
Serial.println(rBytes[1]);
|
||||||
|
Serial.println(rBytes[2]);
|
||||||
|
Serial.println(rBytes[3]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((rBytes[2]&0xF) == 0xF) /* these 4 bits must be 1 */
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
int16_t tempInt = 0;
|
||||||
|
int16_t tempNow = 0;
|
||||||
|
uint8_t rhNow = rBytes[3];
|
||||||
|
bool isNegative;
|
||||||
|
|
||||||
|
tempInt = rBytes[1] << 4;
|
||||||
|
tempInt |= (int16_t)(rBytes[2] >> 4);
|
||||||
|
isNegative = (rBytes[1]&0x80) != 0u;
|
||||||
|
|
||||||
|
if ( isNegative) // the first bit of nibble 1 shows if the value is negative
|
||||||
|
{
|
||||||
|
/* 2's complement */
|
||||||
|
tempInt = (~tempInt) & 0xFFFu;
|
||||||
|
tempInt += 1;
|
||||||
|
}
|
||||||
|
#if PRINT_ON_TEMP_RECEIVED
|
||||||
|
Serial.println(tempInt);
|
||||||
|
#endif
|
||||||
|
/* do the rounding with positive number */
|
||||||
|
tempNow = (tempInt + 5) / 10;
|
||||||
|
|
||||||
|
if (isNegative)
|
||||||
|
{
|
||||||
|
/* set to negative */
|
||||||
|
tempNow = -tempNow;
|
||||||
|
}
|
||||||
|
#if PRINT_ON_TEMP_RECEIVED
|
||||||
|
Serial.println(tempNow);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int16_t dTempAbs = (tempNow >= dataLast.tempC) ? (tempNow - dataLast.tempC) : (dataLast.tempC - tempNow);
|
||||||
|
uint8_t dRHAbs = (rhNow >= dataLast.rhPercent) ? (rhNow - dataLast.rhPercent) : (dataLast.rhPercent - rhNow);
|
||||||
|
|
||||||
|
dataLast.tempC = tempNow;
|
||||||
|
dataLast.rhPercent = rhNow;
|
||||||
|
#if 1
|
||||||
|
/* plausibility check: Temp and RH cannot have changed more than 2 units , if a similar value was received two times, it should be ok*/
|
||||||
|
if ( (dTempAbs <= 2) &&
|
||||||
|
(dRHAbs <= 2u) )
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
bNewData = true;
|
||||||
|
data = dataLast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverFunkThermometer.h
|
||||||
|
*
|
||||||
|
* Created on: 10.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVERFUNKTHERMOMETER_H_
|
||||||
|
#define RECEIVERFUNKTHERMOMETER_H_
|
||||||
|
|
||||||
|
#define THERMO_NUM_BITS_IGNORED 4
|
||||||
|
#define THERMO_NUM_BITS_PER_KEY 36
|
||||||
|
#define THERMO_KEY_NUMBYTES_PER_KEY 4/* 36 bits, but first 4 bits are ignored -> 32 bits */
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
FUNK_THERMO_INVALID,
|
||||||
|
MS_0_5,
|
||||||
|
MS_1_0,
|
||||||
|
MS_2_0
|
||||||
|
} SignalDurationThermometer_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int16_t tempC;
|
||||||
|
uint8_t rhPercent;
|
||||||
|
} ReceiverFunkThermometerData_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiverFunkThermometer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReceiverFunkThermometer();
|
||||||
|
|
||||||
|
void Isr(uint32_t dtMicros, bool pinValue);
|
||||||
|
bool HasNewData(void);
|
||||||
|
ReceiverFunkThermometerData_t GetData(void);
|
||||||
|
void ResetNewData(void){ bNewData = false; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnTempReceived(void);
|
||||||
|
void ResetBuffer(void);
|
||||||
|
void NextByte(void);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t rBytes[THERMO_KEY_NUMBYTES_PER_KEY];
|
||||||
|
uint8_t rByteIndex = 0;
|
||||||
|
uint8_t rBitIndex = 7;
|
||||||
|
uint8_t rBitNumber = 0;
|
||||||
|
ReceiverFunkThermometerData_t data;
|
||||||
|
ReceiverFunkThermometerData_t dataLast;
|
||||||
|
bool bNewData = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern ReceiverFunkThermometer receiverThermo;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* RECEIVERFUNKTHERMOMETER_H_ */
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverSmartWares.cpp
|
||||||
|
*
|
||||||
|
* Created on: 22.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
#include "ReceiverSmartWares.h"
|
||||||
|
|
||||||
|
#define MonitorPrint(x) //Serial.print(x)
|
||||||
|
#define MonitorPrintln(x) //Serial.println(x)
|
||||||
|
|
||||||
|
#define KEY_BYTE_OPEN 0x56
|
||||||
|
#define KEY_BYTE_CLOSE 0x55
|
||||||
|
|
||||||
|
ReceiverSmartWares receiverSw;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static const char* keyNames[] = {
|
||||||
|
"DAEMM","FB1","FB2","FB3","FB4",
|
||||||
|
"HAUSTUERE","KLO EG","BAD","WIN 4","KELLERTREPPE",
|
||||||
|
"GEFRIER","ABSTELL","WIN TONI","Doppel_L","DOPPEL_R",
|
||||||
|
"LICHT S","LICHT W","LICHT O","LICHT GARAGE","BEW GARAGE",
|
||||||
|
"STECK 1","STECK 2"};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* bytes 4 + 5 sind immer 0x55, byte 6 sagt ON oder oFF, daher hier nur als 0 aufgefuehrt */
|
||||||
|
const uint8_t ReceiverSmartWares::keys[SMW_KEY_NUMKEYS][SMW_KEY_NUMBYTES_PER_KEY] =
|
||||||
|
{
|
||||||
|
/* ausgelesene Keys */
|
||||||
|
{ 0b01010101, 0b01100101, 0b10010110, 0b10011001, 0, 0, 0, 0b01010110 }, //0 DAEMMERUNG
|
||||||
|
{ 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01010110 }, //1 FB1
|
||||||
|
{ 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01011001 }, //2 FB2
|
||||||
|
{ 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01011010 }, //3 FB3
|
||||||
|
{ 0b01011010, 0b01100101, 0b10101001, 0b10010101, 0, 0, 0, 0b01100101 }, //4 FB4
|
||||||
|
{ 0b01010110, 0b01010101, 0b10101001, 0b01100110, 0, 0, 0, 0b01010110 }, //5 BEW HAUSTUERE
|
||||||
|
{ 0b01010101, 0b01101001, 0b10010110, 0b10010101, 0, 0, 0, 0b01010110 }, //6 WINDOW KLO unten
|
||||||
|
{ 0b01010101, 0b10011010, 0b10010110, 0b10100110, 0, 0, 0, 0b01010110 }, //7 WINDOW BAD oben
|
||||||
|
{ 0b01010101, 0b10100110, 0b01011010, 0b01011010, 0, 0, 0, 0b01010110 }, //8 WINDOW FLO
|
||||||
|
{ 0b01010101, 0b01011001, 0b01010101, 0b01100110, 0, 0, 0, 0b01010110 }, //9 BEW KELLERTREPPE
|
||||||
|
{ 0b01010101, 0b10011010, 0b01101001, 0b01100110, 0, 0, 0, 0b01010110 }, //10 GEFRIER
|
||||||
|
{ 0b01010101, 0b10100110, 0b01011010, 0b01011010, 0, 0, 0, 0b01010110 }, //11 ABSTELLRAUM
|
||||||
|
{ 0b01010101, 0b10101001, 0b01100110, 0b01011010, 0, 0, 0, 0b01010110 }, //12 WINDOW TONI
|
||||||
|
{ 0b01011001, 0b01101001, 0b01100101, 0b01011001, 0, 0, 0, 0b01010110 }, //13 DOPPELSCHALTER_L
|
||||||
|
{ 0b01011001, 0b01101001, 0b01100101, 0b01011001, 0, 0, 0, 0b01011001 }, //14 DOPPELSCHALTER_R
|
||||||
|
|
||||||
|
/* selbst erfundene Keys */
|
||||||
|
/* nur 5,6,9,a : immer genausoviele 1en wie 0en -> immer gleich lange sendedauer */
|
||||||
|
{ 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x55}, //15 LICHT TERASSE_SUED
|
||||||
|
{ 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x56}, //16 LICHT TERASSE_WEST
|
||||||
|
{ 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x59}, //17 LICHT HAUSTÜRE_OST
|
||||||
|
{ 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x5a}, //18 LICHT GARAGE
|
||||||
|
{ 0x56, 0x55, 0x56, 0x55, 0, 0, 0, 0x65}, //19 BEW GARAGE (weitergeleitet von ReceiverBew)
|
||||||
|
{ 0x6A, 0x95, 0x55, 0x99, 0, 0, 0, 0x56} , // Smartwares Ferbedienung Steckdose Au�en A
|
||||||
|
{ 0x6A, 0x95, 0x55, 0x99, 0, 0, 0, 0x59} , // Smartwares Ferbedienung Steckdose Au�en B
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_SW_WINDOW_KEYS 5u
|
||||||
|
const uint8_t smWindowKeys[NUM_SW_WINDOW_KEYS] = {6u, 7u, 8u, 10u, 12u };
|
||||||
|
|
||||||
|
/* NUR FENSTER KEYS WERDEN WEITERGELEITET , SIEHE UNTEN*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
ReceiverSmartWares::ReceiverSmartWares()
|
||||||
|
{
|
||||||
|
lastReceivedKeyNum = -1;
|
||||||
|
lastKeyOpenDirection = 0;
|
||||||
|
ResetBuffer();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverSmartWares::Isr(uint32_t dtMicros, bool pinValue)
|
||||||
|
{
|
||||||
|
static SignalDuration_t lastDuration = INVALID;
|
||||||
|
SignalDuration_t thisDuration = INVALID;
|
||||||
|
|
||||||
|
if (dtMicros > 150 && dtMicros < 350)
|
||||||
|
{
|
||||||
|
thisDuration = SHORT;
|
||||||
|
}
|
||||||
|
else if (dtMicros > 1000 && dtMicros < 1350)
|
||||||
|
{
|
||||||
|
thisDuration = LONG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisDuration = INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisDuration == INVALID)
|
||||||
|
{
|
||||||
|
if (numBits == 64)
|
||||||
|
{
|
||||||
|
compareKeys();
|
||||||
|
}
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lastDuration == INVALID)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (pinValue == HIGH)
|
||||||
|
{
|
||||||
|
numBits++;
|
||||||
|
|
||||||
|
if (thisDuration == LONG && lastDuration == SHORT)
|
||||||
|
{
|
||||||
|
rBytes[rByteIndex] |= (1 << rBitIndex); /* set a 1 */
|
||||||
|
|
||||||
|
if (rBitIndex == 0)
|
||||||
|
{
|
||||||
|
NextByte();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBitIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (thisDuration == SHORT && lastDuration == SHORT)
|
||||||
|
{
|
||||||
|
/* leave the 0 that was the init value of every bit */
|
||||||
|
if (rBitIndex == 0)
|
||||||
|
{
|
||||||
|
NextByte();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBitIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
lastDuration = thisDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverSmartWares::ResetBuffer()
|
||||||
|
{
|
||||||
|
rByteIndex = 0;
|
||||||
|
rBitIndex = 7;
|
||||||
|
numBits = 0;
|
||||||
|
rBytes[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverSmartWares::NextByte()
|
||||||
|
{
|
||||||
|
rByteIndex++;
|
||||||
|
rBitIndex = 7;
|
||||||
|
if (rByteIndex == SMW_KEY_NUMBYTES_PER_KEY)
|
||||||
|
{
|
||||||
|
compareKeys();
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBytes[rByteIndex] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void ReceiverSmartWares::compareKeys()
|
||||||
|
{
|
||||||
|
int8_t keyFound = -1;
|
||||||
|
uint8_t i,j;
|
||||||
|
for (i=0; i<NUM_SW_WINDOW_KEYS; i++)
|
||||||
|
{
|
||||||
|
keyFound = smWindowKeys[i];
|
||||||
|
if (rBytes[0] != keys[keyFound][0] ) { keyFound = -1; }
|
||||||
|
else if (rBytes[1] != keys[keyFound][1] ) { keyFound = -1; }
|
||||||
|
else if (rBytes[2] != keys[keyFound][2] ) { keyFound = -1; }
|
||||||
|
else if (rBytes[3] != keys[keyFound][3] ) { keyFound = -1; }
|
||||||
|
else if (rBytes[4] != 0x55 ) { keyFound = -1; }
|
||||||
|
else if (rBytes[5] != 0x55 ) { keyFound = -1; }
|
||||||
|
else if ((rBytes[6] != KEY_BYTE_OPEN) && (rBytes[6] != KEY_BYTE_CLOSE)) { keyFound = -1; }
|
||||||
|
else if (rBytes[7] != keys[keyFound][7] ) { keyFound = -1; }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MonitorPrint("\nSM ");
|
||||||
|
MonitorPrint(keyFound);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool direction = (rBytes[6] == KEY_BYTE_OPEN);
|
||||||
|
if ((keyFound>=6 && keyFound<=8) || keyFound==12 || keyFound==10) /* NUR FENSTER KEYS WERDEN WEITERGELEITET */
|
||||||
|
{
|
||||||
|
if ((keyFound != lastReceivedKeyNum) || (direction != lastKeyOpenDirection))
|
||||||
|
{
|
||||||
|
newKeyReceived = true;
|
||||||
|
lastReceivedKeyNum = keyFound;
|
||||||
|
lastKeyOpenDirection = direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(textBuf, "SM %x %x %x %X %x %x %x %x", rBytes[0], rBytes[1],
|
||||||
|
rBytes[2], rBytes[3], rBytes[4], rBytes[5], rBytes[6],
|
||||||
|
rBytes[7]);
|
||||||
|
MonitorPrintln(textBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverSmartWares.h
|
||||||
|
*
|
||||||
|
* Created on: 22.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVERSMARTWARES_H_
|
||||||
|
#define RECEIVERSMARTWARES_H_
|
||||||
|
|
||||||
|
#include "ReceiverWinSensor433.h"
|
||||||
|
|
||||||
|
#define SMW_KEY_NUMKEYS 22
|
||||||
|
#define SMW_KEY_NUMBYTES_PER_KEY 8
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiverSmartWares : public Receiver433
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReceiverSmartWares();
|
||||||
|
|
||||||
|
virtual void Isr(uint32_t dtMicros, bool pinValue);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const uint8_t keys[SMW_KEY_NUMKEYS][SMW_KEY_NUMBYTES_PER_KEY];
|
||||||
|
uint8_t rBytes[SMW_KEY_NUMBYTES_PER_KEY];
|
||||||
|
uint8_t rByteIndex = 0;
|
||||||
|
uint8_t rBitIndex = 7;
|
||||||
|
uint8_t numBits = 0;
|
||||||
|
char textBuf[32];
|
||||||
|
|
||||||
|
//void printByteBits(byte by);
|
||||||
|
//void printBuffer();
|
||||||
|
void compareKeys();
|
||||||
|
//uint8_t correlationFunction(uint8_t buf1[], uint8_t buf2[], uint8_t sizeBufs, int8_t shift);
|
||||||
|
void ResetBuffer();
|
||||||
|
void NextByte();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern ReceiverSmartWares receiverSw;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* RECEIVERSMARTWARES_H_ */
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Receiver433.cpp
|
||||||
|
*
|
||||||
|
* Created on: 17.10.2021
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ReceiverWinSensor433.h"
|
||||||
|
|
||||||
|
Receiver433::Receiver433()
|
||||||
|
{
|
||||||
|
doBuffer = true;
|
||||||
|
newKeyReceived = false;
|
||||||
|
lastReceivedKeyNum = -1;
|
||||||
|
lastKeyOpenDirection = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Receiver433::~Receiver433()
|
||||||
|
{
|
||||||
|
// TODO Auto-generated destructor stub
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int8_t Receiver433::GetLastReceivedKeyNum()
|
||||||
|
{
|
||||||
|
if (newKeyReceived) return lastReceivedKeyNum;
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
void Receiver433::ResetReceivedKeyNum()
|
||||||
|
{
|
||||||
|
newKeyReceived = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Receiver433::GetLastReceivedDirection()
|
||||||
|
{
|
||||||
|
return lastKeyOpenDirection;
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Receiver433.h
|
||||||
|
*
|
||||||
|
* Created on: 17.10.2021
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVERWINSENSOR433_H_
|
||||||
|
#define RECEIVERWINSENSOR433_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
INVALID,
|
||||||
|
SHORT,
|
||||||
|
LONG
|
||||||
|
} SignalDuration_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* VIRTUAL BASE CLASS FOR RECEIVERS */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Receiver433
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Receiver433();
|
||||||
|
virtual ~Receiver433();
|
||||||
|
|
||||||
|
virtual void Isr(uint32_t dtMicros, bool pinValue) = 0;
|
||||||
|
|
||||||
|
virtual int8_t GetLastReceivedKeyNum();
|
||||||
|
virtual void ResetReceivedKeyNum();
|
||||||
|
virtual bool GetLastReceivedDirection();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool lastKeyOpenDirection; // TRUE -> OPEN, FALSE -> CLOSE
|
||||||
|
bool doBuffer;
|
||||||
|
bool newKeyReceived;
|
||||||
|
int8_t lastReceivedKeyNum;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* RECEIVERWINSENSOR433_H_ */
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
/*
|
||||||
|
* Receiver3ByteKey.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Receiver3ByteKey.h"
|
||||||
|
#include "InterruptHandler.h"
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
#define DEBUG_LEVEL_NO_PRINT 0
|
||||||
|
#define DEBUG_LEVEL_PRINT_NEW_KEYS_ONLY 1
|
||||||
|
#define DEBUG_LEVEL_PRINT_ALL_RECEIVED_KEYS 2
|
||||||
|
|
||||||
|
|
||||||
|
#define DEBUG_LEVEL DEBUG_LEVEL_NO_PRINT
|
||||||
|
#define SERIAL_PRINT(x) Serial.print(x)
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Receiver3ByteKey::Receiver3ByteKey()
|
||||||
|
{
|
||||||
|
lastDuration = INVALID;
|
||||||
|
lastReceivedKeyNum = -1;
|
||||||
|
lastKeyOpenDirection = 0;
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void Receiver3ByteKey::Isr(uint32_t dtMicros, bool pinValue)
|
||||||
|
{
|
||||||
|
|
||||||
|
SignalDuration_t thisDuration = INVALID;
|
||||||
|
|
||||||
|
if (dtMicros > config.tShortMin && dtMicros < config.tShortMax)
|
||||||
|
{
|
||||||
|
thisDuration = SHORT;
|
||||||
|
//if (doBuffer) buft[ibuf++] = dtMicros;
|
||||||
|
}
|
||||||
|
else if (dtMicros > config.tLongMin && dtMicros < config.tLongMax)
|
||||||
|
{
|
||||||
|
thisDuration = LONG;
|
||||||
|
//if (doBuffer) buft[ibuf++] = dtMicros;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisDuration = INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisDuration == INVALID)
|
||||||
|
{
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lastDuration == INVALID)
|
||||||
|
{
|
||||||
|
/* ResetBuffer was already called last time */
|
||||||
|
}
|
||||||
|
else if (pinValue == HIGH)
|
||||||
|
{
|
||||||
|
// a valid bit is always terminated with a rising edge (the last bit is always 0 so this is the termination for the last bit to read )
|
||||||
|
|
||||||
|
if (thisDuration == LONG && lastDuration == SHORT) // short high, long low -> bit 0
|
||||||
|
{
|
||||||
|
/* bytes are initialized as 0, so for bit 0, nothing to change */
|
||||||
|
NextBit();
|
||||||
|
}
|
||||||
|
else if (thisDuration == SHORT && lastDuration == LONG) // long high, short low -> bit 1
|
||||||
|
{
|
||||||
|
rBytes[rByteIndex] |= (1 << rBitIndex); // bit 1
|
||||||
|
|
||||||
|
NextBit();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// long -> long or short->short is invalid
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* falling edge -> wait for next rising edge */
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
lastDuration = thisDuration;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void Receiver3ByteKey::ResetBuffer()
|
||||||
|
{
|
||||||
|
rByteIndex = 0;
|
||||||
|
rBitIndex = 7;
|
||||||
|
rBytes[0] = 0; /* all other bytes are set to 0 in NextByte() */
|
||||||
|
ibuf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void Receiver3ByteKey::NextBit()
|
||||||
|
{
|
||||||
|
if (rBitIndex == 0)
|
||||||
|
{
|
||||||
|
NextByte();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBitIndex--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void Receiver3ByteKey::NextByte()
|
||||||
|
{
|
||||||
|
rByteIndex++;
|
||||||
|
rBitIndex = 7;
|
||||||
|
if (rByteIndex == NUM_BYTES_PER_KEY)
|
||||||
|
{
|
||||||
|
compareKeys();
|
||||||
|
ResetBuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rBytes[rByteIndex] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
IRAM_ATTR void Receiver3ByteKey::compareKeys()
|
||||||
|
{
|
||||||
|
int8_t keyFound = -1;
|
||||||
|
bool direction = false;
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
for (i=0; i<config.numberKeys; i++)
|
||||||
|
{
|
||||||
|
keyFound = i;
|
||||||
|
uint8_t iBase = i*(NUM_BYTES_PER_KEY+1u); /* there is always one more byte indicating closing */
|
||||||
|
if (rBytes[0] != config.keys[iBase+0]) { keyFound = -1; } /* byte 0 does not match */
|
||||||
|
else if (rBytes[1] != config.keys[iBase+1]) { keyFound = -1; } /* byte 1 does not match */
|
||||||
|
else if ((rBytes[2] != config.keys[iBase+2]) &&
|
||||||
|
(rBytes[2] != config.keys[iBase+3]) ) { keyFound = -1; } /* neither open , nor close byte match */
|
||||||
|
if (keyFound==i)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyFound>=0)
|
||||||
|
{
|
||||||
|
uint8_t iBase = keyFound*(NUM_BYTES_PER_KEY+1u);
|
||||||
|
direction = rBytes[2] == config.keys[ iBase + 2 ];
|
||||||
|
|
||||||
|
|
||||||
|
if ( (keyFound != lastReceivedKeyNum ) || (lastKeyOpenDirection != direction) )
|
||||||
|
{
|
||||||
|
doBuffer = false;
|
||||||
|
newKeyReceived = true;
|
||||||
|
lastReceivedKeyNum = keyFound;
|
||||||
|
lastKeyOpenDirection = direction;
|
||||||
|
|
||||||
|
InterruptHandler_PauseReceive();
|
||||||
|
|
||||||
|
#if DEBUG_LEVEL>=DEBUG_LEVEL_PRINT_ALL_RECEIVED_KEYS
|
||||||
|
sprintf(textBuf, "\n%s %d %d", config.name, keyFound, lastKeyOpenDirection);
|
||||||
|
SERIAL_PRINT(textBuf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if DEBUG_LEVEL>=DEBUG_LEVEL_PRINT_NEW_KEYS_ONLY
|
||||||
|
sprintf(textBuf, "\nnew %s %x %x %x", config.name, rBytes[0], rBytes[1], rBytes[2]);
|
||||||
|
SERIAL_PRINT(textBuf);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Receiver3ByteKey.h
|
||||||
|
*
|
||||||
|
* Created on: 12.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVER3BYTEKEY_H_
|
||||||
|
#define RECEIVER3BYTEKEY_H_
|
||||||
|
|
||||||
|
#include "ReceiverWinSensor433.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_BYTES_PER_KEY 3u
|
||||||
|
|
||||||
|
class Receiver3ByteKey : public Receiver433
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Receiver3ByteKey();
|
||||||
|
|
||||||
|
void Isr(uint32_t dtMicros, bool pinValue);
|
||||||
|
void startBuffering(){ doBuffer = true; }
|
||||||
|
|
||||||
|
uint32_t buft[10*8];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
class Config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const char *name;
|
||||||
|
uint16_t tShortMin;
|
||||||
|
uint16_t tShortMax;
|
||||||
|
uint16_t tLongMin;
|
||||||
|
uint16_t tLongMax;
|
||||||
|
uint8_t numberKeys;
|
||||||
|
const uint8_t *keys;
|
||||||
|
};
|
||||||
|
class Config config;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SignalDuration_t lastDuration;
|
||||||
|
uint8_t rBytes[NUM_BYTES_PER_KEY];
|
||||||
|
uint8_t rByteIndex = 0;
|
||||||
|
uint8_t rBitIndex = 7;
|
||||||
|
uint32_t ibuf;
|
||||||
|
|
||||||
|
//void printByteBits(byte by);
|
||||||
|
//void printBuffer();
|
||||||
|
void compareKeys();
|
||||||
|
//uint8_t correlationFunction(uint8_t buf1[], uint8_t buf2[], uint8_t sizeBufs, int8_t shift);
|
||||||
|
void ResetBuffer();
|
||||||
|
void NextBit();
|
||||||
|
void NextByte();
|
||||||
|
|
||||||
|
char textBuf[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* RECEIVER3BYTEKEY_H_ */
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverAiggend.cpp
|
||||||
|
*
|
||||||
|
* Created on: 21.10.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "Receiver3ByteKey.h"
|
||||||
|
#include "ReceiverAiggend.h"
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
#define KEY_NIBBLE_OPEN 0x0A
|
||||||
|
#define KEY_NIBBLE_CLOSE 0x0E
|
||||||
|
|
||||||
|
#define NUM_KEYS_AIGGEND 4u
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
static const char* nameAiggend = "Aiggend";
|
||||||
|
|
||||||
|
static const uint8_t keysAiggend[NUM_KEYS_AIGGEND * (NUM_BYTES_PER_KEY+1u) ] =
|
||||||
|
{
|
||||||
|
//0b10101110, 0b10110010, 0b00001010 , // 10101110 10110010 0000 1010 0 AUF, 10101110 10110010 0000 1110 0 ZU
|
||||||
|
0xae, 0xb2, 0x0a , 0x0e,
|
||||||
|
0xa4, 0x30, 0x0a , 0x0e, // 0xa auf, zu: 0xe
|
||||||
|
0xa1, 0x4a, 0x0a , 0x0e, // 0xa auf, zu: 0xe
|
||||||
|
0xe6, 0x80, 0x46 , 0x49 // 0x49 auf, zu 0x46
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
ReceiverAiggend receiverAiggend;
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
ReceiverAiggend::ReceiverAiggend() : Receiver3ByteKey()
|
||||||
|
{
|
||||||
|
config.name = nameAiggend;
|
||||||
|
config.tShortMin = 370u;
|
||||||
|
config.tShortMax = 680u;
|
||||||
|
config.tLongMin = 1100u;
|
||||||
|
config.tLongMax = 1540u;
|
||||||
|
config.numberKeys = NUM_KEYS_AIGGEND;
|
||||||
|
config.keys = keysAiggend;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverAiggend.h
|
||||||
|
*
|
||||||
|
* Created on: 21.10.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVERAIGGEND_H_
|
||||||
|
#define RECEIVERAIGGEND_H_
|
||||||
|
|
||||||
|
#include "Receiver3ByteKey.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiverAiggend : public Receiver3ByteKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReceiverAiggend();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern ReceiverAiggend receiverAiggend;
|
||||||
|
|
||||||
|
#endif /* RECEIVERAIGGEND_H_ */
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverKerui.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "ReceiverKerui.h"
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
#define KEY_NIBBLE_OPEN 0x0E
|
||||||
|
#define KEY_NIBBLE_CLOSE 0x07
|
||||||
|
#define NUM_KEYS_KERUI 3u
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
static const char* nameKerui = "Kerui";
|
||||||
|
|
||||||
|
static const uint8_t keysKerui[NUM_KEYS_KERUI* (NUM_BYTES_PER_KEY+1u) ] =
|
||||||
|
{
|
||||||
|
|
||||||
|
0x3c, 0xf3, 0x0E, 0x07 , /* key, key, open, close */
|
||||||
|
0xea, 0x3a, 0x0E, 0x07 ,
|
||||||
|
0xbd, 0x14, 0x0E, 0x07
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
ReceiverKerui receiverKerui = ReceiverKerui();
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
ReceiverKerui::ReceiverKerui() : Receiver3ByteKey()
|
||||||
|
{
|
||||||
|
config.name = nameKerui;
|
||||||
|
config.tShortMin = 250u;
|
||||||
|
config.tShortMax = 450u;
|
||||||
|
config.tLongMin = 850u;
|
||||||
|
config.tLongMax = 1150u;
|
||||||
|
config.numberKeys = NUM_KEYS_KERUI;
|
||||||
|
config.keys = keysKerui;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverKerui.h
|
||||||
|
*
|
||||||
|
* Created on: 12.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVERKERUI_H_
|
||||||
|
#define RECEIVERKERUI_H_
|
||||||
|
|
||||||
|
#include "Receiver3ByteKey.h"
|
||||||
|
|
||||||
|
class ReceiverKerui : public Receiver3ByteKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReceiverKerui();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern ReceiverKerui receiverKerui;
|
||||||
|
|
||||||
|
#endif /* RECEIVERKERUI_H_ */
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverOval.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "main.h"
|
||||||
|
#include "ReceiverOval.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
#define KEY_NIBBLE_OPEN 0x03
|
||||||
|
#define KEY_NIBBLE_CLOSE 0x09
|
||||||
|
|
||||||
|
#define NUM_KEYS_OVAL 6u
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
static const char* nameOval = "Oval";
|
||||||
|
|
||||||
|
static const uint8_t keysOval[NUM_KEYS_OVAL * (NUM_BYTES_PER_KEY+1u)] =
|
||||||
|
{
|
||||||
|
0xdc, 0x86, 0x03 , 0x09, // 0x3 auf 0x9 zu,
|
||||||
|
0x30, 0xa5, 0x03 , 0x09, // 0x3 auf 0x9 zu,
|
||||||
|
0x4c, 0xe6, 0x03 , 0x09, // 0x3 auf 0x9 zu,
|
||||||
|
0x74, 0xa5, 0x03 , 0x09, // 0x3 auf 0x9 zu,
|
||||||
|
0x29, 0x66, 0x03 , 0x09, // 0x3 auf 0x9 zu,
|
||||||
|
0xe4, 0x0f, 0x76 , 0x79 // 0x3 auf 0x9 zu,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
ReceiverOval receiverOval;
|
||||||
|
|
||||||
|
/*******************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
ReceiverOval::ReceiverOval() : Receiver3ByteKey()
|
||||||
|
{
|
||||||
|
config.name = nameOval;
|
||||||
|
config.tShortMin = 320u;
|
||||||
|
config.tShortMax = 510u;
|
||||||
|
config.tLongMin = 1100u;
|
||||||
|
config.tLongMax = 1330u;
|
||||||
|
config.numberKeys = NUM_KEYS_OVAL;
|
||||||
|
config.keys = keysOval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* ReceiverOval.h
|
||||||
|
*
|
||||||
|
* Created on: 12.10.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RECEIVEROVAL_H_
|
||||||
|
#define RECEIVEROVAL_H_
|
||||||
|
|
||||||
|
#include "Receiver3ByteKey.h"
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiverOval : public Receiver3ByteKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReceiverOval();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
extern ReceiverOval receiverOval;
|
||||||
|
|
||||||
|
#endif /* RECEIVEROVAL_H_ */
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Seconds.cpp
|
||||||
|
*
|
||||||
|
* Created on: 10.09.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
#include "Seconds.h"
|
||||||
|
|
||||||
|
uint32_t Seconds::lastMillisShifted = 0;
|
||||||
|
uint32_t Seconds::seconds = 0;
|
||||||
|
uint32_t Seconds::secondsOverflow = 0;
|
||||||
|
boolean volatile Seconds::semaphore = false;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t Seconds::Get(void)
|
||||||
|
{
|
||||||
|
uint32_t secRet;
|
||||||
|
uint32_t secNow = millis() / 1000;
|
||||||
|
|
||||||
|
if (secNow < seconds)
|
||||||
|
{
|
||||||
|
secondsOverflow += seconds + 1;
|
||||||
|
}
|
||||||
|
seconds = secNow;
|
||||||
|
|
||||||
|
secRet = seconds + secondsOverflow;
|
||||||
|
|
||||||
|
return secRet;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Seconds.h
|
||||||
|
*
|
||||||
|
* Created on: 10.09.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SECONDS_H_
|
||||||
|
#define SECONDS_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
class Seconds
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static uint32_t Get();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static uint32_t lastMillisShifted;
|
||||||
|
static uint32_t seconds;
|
||||||
|
static uint32_t secondsOverflow;
|
||||||
|
static volatile boolean semaphore;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* SECONDS_H_ */
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* UpdateHandler.c
|
||||||
|
*
|
||||||
|
* Created on: 04.08.2023
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "WebServer.h"
|
||||||
|
#include <Update.h>
|
||||||
|
#include "Version.h"
|
||||||
|
|
||||||
|
WebServer webServer;
|
||||||
|
|
||||||
|
const char* serverIndex =
|
||||||
|
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
|
||||||
|
"<br>" PROJECT_NAME " " VERSION_STR "<br><br>"
|
||||||
|
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
|
||||||
|
"<input type='file' name='update'>"
|
||||||
|
"<input type='submit' value='Update'>"
|
||||||
|
"</form>"
|
||||||
|
"<div id='prg'>progress: 0%</div>"
|
||||||
|
"<script>"
|
||||||
|
"$('form').submit(function(e){"
|
||||||
|
"e.preventDefault();"
|
||||||
|
"var form = $('#upload_form')[0];"
|
||||||
|
"var data = new FormData(form);"
|
||||||
|
" $.ajax({"
|
||||||
|
"url: '/update',"
|
||||||
|
"type: 'POST',"
|
||||||
|
"data: data,"
|
||||||
|
"contentType: false,"
|
||||||
|
"processData:false,"
|
||||||
|
"xhr: function() {"
|
||||||
|
"var xhr = new window.XMLHttpRequest();"
|
||||||
|
"xhr.upload.addEventListener('progress', function(evt) {"
|
||||||
|
"if (evt.lengthComputable) {"
|
||||||
|
"var per = evt.loaded / evt.total;"
|
||||||
|
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
|
||||||
|
"}"
|
||||||
|
"}, false);"
|
||||||
|
"return xhr;"
|
||||||
|
"},"
|
||||||
|
"success:function(d, s) {"
|
||||||
|
"$('#prg').html('success!');"
|
||||||
|
"},"
|
||||||
|
"error: function (a, b, c) {"
|
||||||
|
"}"
|
||||||
|
"});"
|
||||||
|
"});"
|
||||||
|
"</script>";
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateHandler()
|
||||||
|
{
|
||||||
|
static bool initDone = false;
|
||||||
|
if (false == WiFi.isConnected())
|
||||||
|
{
|
||||||
|
initDone = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (initDone == false)
|
||||||
|
{
|
||||||
|
initDone = true;
|
||||||
|
webServer.on("/", HTTP_GET, []()
|
||||||
|
{
|
||||||
|
Serial.printf("HTTP_GET");
|
||||||
|
webServer.sendHeader("Connection", "close");
|
||||||
|
webServer.send(200, "text/html", serverIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
/*handling uploading firmware file */
|
||||||
|
webServer.on("/update", HTTP_POST, []()
|
||||||
|
{
|
||||||
|
webServer.sendHeader("Connection", "close");
|
||||||
|
webServer.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK");
|
||||||
|
ESP.restart();
|
||||||
|
}, []()
|
||||||
|
{
|
||||||
|
HTTPUpload& upload = webServer.upload();
|
||||||
|
if (upload.status == UPLOAD_FILE_START)
|
||||||
|
{
|
||||||
|
Serial.printf("Update: %s\n", upload.filename.c_str());
|
||||||
|
if (!Update.begin(UPDATE_SIZE_UNKNOWN))
|
||||||
|
{ //start with max available size
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (upload.status == UPLOAD_FILE_WRITE)
|
||||||
|
{
|
||||||
|
/* flashing firmware to ESP*/
|
||||||
|
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize)
|
||||||
|
{
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (upload.status == UPLOAD_FILE_END)
|
||||||
|
{
|
||||||
|
if (Update.end(true))
|
||||||
|
{ //true to set the size to the current progress
|
||||||
|
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Update.printError(Serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
webServer.begin(80u);
|
||||||
|
Serial.print("IP address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
Serial.printf("webServer init done");
|
||||||
|
}
|
||||||
|
webServer.handleClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* UpdateHandler.h
|
||||||
|
*
|
||||||
|
* Created on: 04.08.2023
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UPDATEHANDLER_H_
|
||||||
|
#define UPDATEHANDLER_H_
|
||||||
|
|
||||||
|
|
||||||
|
void UpdateHandler(void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* UPDATEHANDLER_H_ */
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Version.h
|
||||||
|
*
|
||||||
|
* Created on: 04.08.2023
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VERSION_H_
|
||||||
|
#define VERSION_H_
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#if VERSION_DG_ONLY
|
||||||
|
#define PROJECT_NAME "FENSTER_PIEPSER_NODEMCU_32_S_DG"
|
||||||
|
#else
|
||||||
|
#define PROJECT_NAME "FENSTER_PIEPSER_NODEMCU_32_S_EG"
|
||||||
|
#endif
|
||||||
|
#define VERSION_STR "v1.3.2"
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VERSION_H_ */
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// Only modify this file to include
|
||||||
|
// - function definitions (prototypes)
|
||||||
|
// - include files
|
||||||
|
// - extern variable definitions
|
||||||
|
// In the appropriate section
|
||||||
|
|
||||||
|
#ifndef _fensterPIEP_H_
|
||||||
|
#define _fensterPIEP_H_
|
||||||
|
#include "Arduino.h"
|
||||||
|
//add your includes for the project fensterPIEP here
|
||||||
|
|
||||||
|
|
||||||
|
//end of add your includes here
|
||||||
|
|
||||||
|
|
||||||
|
//add your function definitions for the project fensterPIEP here
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Do not add code below this line
|
||||||
|
#endif /* _fensterPIEP_H_ */
|
||||||
@@ -0,0 +1,635 @@
|
|||||||
|
|
||||||
|
#include "ReceiverSmartWares.h"
|
||||||
|
#include "ReceiverAiggend.h"
|
||||||
|
#include "ReceiverOval.h"
|
||||||
|
#include "ReceiverKerui.h"
|
||||||
|
#include "ReceiverFunkThermometer.h"
|
||||||
|
#include "PiepMode.h"
|
||||||
|
#include "PiepPattern.h"
|
||||||
|
#include "LedBlinker.h"
|
||||||
|
#include "Fenster.h"
|
||||||
|
#include "Display.h"
|
||||||
|
#include "Display_SSD1306.h"
|
||||||
|
#include "Seconds.h"
|
||||||
|
#include "DataSender.h"
|
||||||
|
#include "InterruptHandler.h"
|
||||||
|
#include "xcp/XcpPort.h"
|
||||||
|
#include "UpdateHandler.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include "Version.h"
|
||||||
|
#include "WiFi.h"
|
||||||
|
#include "time.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* platform esp32/1.0.6
|
||||||
|
* NodeMCU-32S
|
||||||
|
* FlashFreq 80MHz
|
||||||
|
* Upload Speed 921600
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* LIBRARIES :
|
||||||
|
* -----------
|
||||||
|
* Adafruit_BusIO
|
||||||
|
* Adafruit_GFX_Library
|
||||||
|
* Adafruit_ST7735_and_ST7789_Library
|
||||||
|
* ESP8266_and_ESP32_OLED_driver_for_SSD1306_displays
|
||||||
|
* FS
|
||||||
|
* SPI
|
||||||
|
* Update
|
||||||
|
* WebServer
|
||||||
|
* WiFi
|
||||||
|
* Wire
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* COM PORT : Silicon Labs CP210x USB to UART Bridge */
|
||||||
|
|
||||||
|
/*---------------- DEFINES ------------- */
|
||||||
|
|
||||||
|
#define TEST_PIEPEN_BEI_START 0
|
||||||
|
#define SECONDS_TO_DECIS(x) ((DeciSeconds_t)10UL*x)
|
||||||
|
#define MINUTES_TO_DECIS(x) ((DeciSeconds_t)600UL*x)
|
||||||
|
#define MINUTES_TO_SECONDS(x) (60*x)
|
||||||
|
#define DAYS_TO_MILLIS(x) ((x)*24UL*3600UL*1000UL)
|
||||||
|
#define SERIAL_PRINT(x) Serial.print(x)
|
||||||
|
|
||||||
|
#define AIGGEND_KEY_INDEX_OFFSET 30u
|
||||||
|
#define OVAL_KEY_INDEX_OFFSET 40u
|
||||||
|
#define KERUI_KEY_INDEX_OFFSET 50u
|
||||||
|
|
||||||
|
#define TONE_FREQUENCY_HZ 2000
|
||||||
|
|
||||||
|
#define USE_XCP (1u)
|
||||||
|
#define USE_WIFI (1u) /* WARNING, no OTA update without wifi ! */
|
||||||
|
#define USE_DATASENDER (0u)
|
||||||
|
/*---------------- GLOBAL VARIABLES ------------- */
|
||||||
|
|
||||||
|
uint32_t gtMillis;
|
||||||
|
char textBuf[100];
|
||||||
|
DeciSeconds_t waitTimeDs = 0; /* in deciSeconds */
|
||||||
|
DeciSeconds_t tDecis = 0;
|
||||||
|
uint8_t numberWindowsOpen = 0;
|
||||||
|
ReceiverFunkThermometerData_t thermoData = {0, 0};
|
||||||
|
bool bRequestShortBeep = false;
|
||||||
|
bool bIsNightTime = false;
|
||||||
|
|
||||||
|
PiepPattern *piepPattern;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* every sensor type has a list of keys, index starting at 0.
|
||||||
|
* the handleKeyReceived adds a offset for each sensor type.
|
||||||
|
* in the config here, the key must be configured with resulting sum.
|
||||||
|
*/
|
||||||
|
/* SMART WARES */
|
||||||
|
Fenster fensterGefrier("Gefrier" ,10);
|
||||||
|
/* Aiggend keys */
|
||||||
|
Fenster fensterWz("Wohnz", 2 + KERUI_KEY_INDEX_OFFSET); /* NICHT GENUTZT AKTUELL */
|
||||||
|
Fenster fensterFlo("Flo", 2 + AIGGEND_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterBadUnten("Bad u", 3 + AIGGEND_KEY_INDEX_OFFSET);
|
||||||
|
|
||||||
|
/* OVAL keys */
|
||||||
|
Fenster fensterKeller("Keller", 0 + OVAL_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterToniNeu("Toni", 1 + OVAL_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterKueche("Kueche", 2 + OVAL_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterWz2("Wohnz", 3 + OVAL_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterFloBuero("Buero", 4 + OVAL_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterHanna("Hanna", 5 + OVAL_KEY_INDEX_OFFSET);
|
||||||
|
/** */
|
||||||
|
Fenster fensterGaeste("Gaeste" , 1 + KERUI_KEY_INDEX_OFFSET);
|
||||||
|
Fenster fensterBadOben("Bad o", 1 + AIGGEND_KEY_INDEX_OFFSET);
|
||||||
|
|
||||||
|
#if VERSION_SMALL_DISPLAY
|
||||||
|
|
||||||
|
#if VERSION_DG_ONLY /* DACHGESCHOSS */
|
||||||
|
Fenster* alleFenster[NUM_FENSTER] =
|
||||||
|
{
|
||||||
|
&fensterBadOben, &fensterFlo, &fensterHanna, &fensterFloBuero , //OG
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
Fenster* alleFenster[NUM_FENSTER] =
|
||||||
|
{
|
||||||
|
&fensterWz, &fensterBadUnten, &fensterKueche, &fensterToniNeu , //EG
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#else
|
||||||
|
#ifdef VERSION_BIG_DISPLAY
|
||||||
|
Fenster* alleFenster[NUM_FENSTER] =
|
||||||
|
{
|
||||||
|
&fensterBadUnten, &fensterKueche, &fensterWz, &fensterWz2, &fensterToniNeu, &fensterGefrier,//EG
|
||||||
|
&fensterKeller, &fensterGaeste //KG
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
Fenster* alleFenster[NUM_FENSTER] =
|
||||||
|
{
|
||||||
|
&fensterBadOben, &fensterFlo, &fensterHanna, &fensterFloBuero , //OG
|
||||||
|
&fensterBadUnten, &fensterKueche, &fensterWz, &fensterWz2, &fensterToniNeu, &fensterGefrier,//EG
|
||||||
|
&fensterKeller, &fensterGaeste //KG
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint32_t loopCountSincePause = 0u;
|
||||||
|
uint8_t toneRequest = 0u;
|
||||||
|
|
||||||
|
/*---------------- LOCAL VARIABLES ------------- */
|
||||||
|
static PiepMode *piepFast, *piepSlow, *piepPauseLong, *piepPauseShort;
|
||||||
|
static PiepMode *piepModes[3];
|
||||||
|
static int8_t manualKeyNo = -1;
|
||||||
|
static bool manualKeyDirection = false;
|
||||||
|
static bool bUpdateDisp = false;
|
||||||
|
static uint32_t tBeepingStartWithoutWindowClose = 0u;
|
||||||
|
|
||||||
|
/*---------------- LOCAL FUNCTIONS ------------- */
|
||||||
|
|
||||||
|
static void handleManualInputRequest();
|
||||||
|
static void updateWaittime(void);
|
||||||
|
static void xcpLoop(void);
|
||||||
|
#ifdef TEST_WAITTIME
|
||||||
|
static void testWaitTime(void);
|
||||||
|
#endif
|
||||||
|
static void handleDispUpdate(void);
|
||||||
|
static void handleKeyReceived(void);
|
||||||
|
static void updateIsNighttime();
|
||||||
|
static void updatePiepPattern(void);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
#if USE_XCP
|
||||||
|
XcpInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_WIFI
|
||||||
|
static const char* ssidElektro = "Elektrosmog";
|
||||||
|
static const char* password = "r4g8f-xz5av";
|
||||||
|
WiFi.setHostname(PROJECT_NAME);
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(ssidElektro, password);
|
||||||
|
|
||||||
|
dataSender.onSetup();
|
||||||
|
|
||||||
|
const char* ntpServer = "ptbtime3.ptb.de";
|
||||||
|
const long gmtOffset_sec = 3600;
|
||||||
|
const int daylightOffset_sec = 3600;
|
||||||
|
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* setup pins receiver */
|
||||||
|
pinMode(DOUT_TEST_TIMER, OUTPUT); digitalWrite(DOUT_TEST_TIMER, HIGH);
|
||||||
|
pinMode(DOUT_FUNK_VCC, OUTPUT); digitalWrite(DOUT_FUNK_VCC, HIGH);
|
||||||
|
pinMode(DOUT_FUNK_GND, OUTPUT); digitalWrite(DOUT_FUNK_GND, LOW);
|
||||||
|
pinMode(DOUT_PIEP_VCC, OUTPUT);
|
||||||
|
pinMode(DIN_FUNK, INPUT_PULLUP);
|
||||||
|
|
||||||
|
/* TONE SETUP */
|
||||||
|
ledcSetup(TONE_PWM_CHANNEL, TONE_FREQUENCY_HZ, 8);
|
||||||
|
ledcAttachPin(DOUT_PIEP_PWM, TONE_PWM_CHANNEL);
|
||||||
|
ledcWrite(TONE_PWM_CHANNEL, 127);
|
||||||
|
|
||||||
|
/* setup Serial */
|
||||||
|
Serial.begin(115200uL);
|
||||||
|
Serial.println(F("\n---\nOK\n"));
|
||||||
|
|
||||||
|
/* Piep times based on 33.3ms */
|
||||||
|
/* setup Piep mode fast*/
|
||||||
|
piepFast = new PiepMode();
|
||||||
|
piepFast->onTime = MS_TO_ISR_COUNT(20uL);
|
||||||
|
piepFast->offTime = MS_TO_ISR_COUNT(80uL);
|
||||||
|
piepFast->requestCount = 2u;
|
||||||
|
/* setup Piep mode slow*/
|
||||||
|
piepSlow = new PiepMode();
|
||||||
|
piepSlow->onTime = MS_TO_ISR_COUNT(500uL);
|
||||||
|
piepSlow->offTime = MS_TO_ISR_COUNT(100uL);
|
||||||
|
piepSlow->requestCount = 1u;
|
||||||
|
/* setup Piep mode pause*/
|
||||||
|
piepPauseLong = new PiepMode();
|
||||||
|
piepPauseLong->onTime = 0u;
|
||||||
|
piepPauseLong->offTime = MS_TO_ISR_COUNT(1000uL); /* 1s */
|
||||||
|
piepPauseLong->requestCount = 120u; /* 60s pause */
|
||||||
|
piepPauseShort = new PiepMode();
|
||||||
|
piepPauseShort->onTime = 0u;
|
||||||
|
piepPauseShort->offTime = MS_TO_ISR_COUNT(1000uL); /* 1s */
|
||||||
|
piepPauseShort->requestCount = 20u; /* 10s pause */
|
||||||
|
/* setup Piep pattern*/
|
||||||
|
piepPattern = new PiepPattern();
|
||||||
|
piepPattern->numberModes = 3u;
|
||||||
|
piepPattern->requestCount = 0u;
|
||||||
|
piepPattern->piepModes = piepModes;
|
||||||
|
piepPattern->piepModes[0] = piepFast;
|
||||||
|
piepPattern->piepModes[1] = piepSlow;
|
||||||
|
piepPattern->piepModes[2] = piepPauseLong;
|
||||||
|
|
||||||
|
#if TEST_PIEPEN_BEI_START
|
||||||
|
/* start piep pattern (just for debugging, uncomment stopping in loop for debugging)*/
|
||||||
|
piepPattern->Start(DOUT_PIEP_PWM);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
InterruptHandler_Init();
|
||||||
|
|
||||||
|
display.Init();
|
||||||
|
|
||||||
|
updateWaittime();
|
||||||
|
#ifdef TEST_WAITTIME
|
||||||
|
testWaitTime();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
handleKeyReceived();
|
||||||
|
|
||||||
|
handleDispUpdate();
|
||||||
|
|
||||||
|
#if USE_WIFI
|
||||||
|
//updateIsNighttime();
|
||||||
|
|
||||||
|
#if USE_DATASENDER
|
||||||
|
dataSender.onLoop();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UpdateHandler();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
updatePiepPattern();
|
||||||
|
|
||||||
|
#if USE_XCP
|
||||||
|
xcpLoop();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* reset ECU every day */
|
||||||
|
if (millis() > DAYS_TO_MILLIS(1uL) && numberWindowsOpen == 0)
|
||||||
|
{
|
||||||
|
Serial.print("RESET");
|
||||||
|
ESP.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
loopCountSincePause++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleDispUpdate(void)
|
||||||
|
{
|
||||||
|
/* cyclically request display update */
|
||||||
|
|
||||||
|
static DeciSeconds_t nextDispUpdateDecis = 0;
|
||||||
|
if (tDecis > nextDispUpdateDecis || bUpdateDisp)
|
||||||
|
{
|
||||||
|
bUpdateDisp = true;
|
||||||
|
if (numberWindowsOpen > 0)
|
||||||
|
{
|
||||||
|
nextDispUpdateDecis = tDecis + SECONDS_TO_DECIS(1u);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextDispUpdateDecis = tDecis + SECONDS_TO_DECIS(10u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* update display if requested*/
|
||||||
|
if (bUpdateDisp)
|
||||||
|
{
|
||||||
|
//noInterrupts();
|
||||||
|
bUpdateDisp = false;
|
||||||
|
display.Update();
|
||||||
|
//interrupts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void updateIsNighttime()
|
||||||
|
{
|
||||||
|
static DeciSeconds_t nextUpdateDecis = SECONDS_TO_DECIS(120u);
|
||||||
|
|
||||||
|
if (tDecis > nextUpdateDecis )
|
||||||
|
{
|
||||||
|
struct tm timeinfo;
|
||||||
|
if (!getLocalTime(&timeinfo, 100u))
|
||||||
|
{
|
||||||
|
Serial.println("Failed to obtain time");
|
||||||
|
nextUpdateDecis = tDecis + SECONDS_TO_DECIS(120u);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextUpdateDecis = tDecis + SECONDS_TO_DECIS(120u);
|
||||||
|
bIsNightTime = (timeinfo.tm_hour >= 22 || timeinfo.tm_hour < 6);
|
||||||
|
if (bIsNightTime)
|
||||||
|
{
|
||||||
|
Serial.print("\nNIGHT");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Serial.print("\nDAY");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reduce paus time after x minutes, when beep is active
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void updatePiepPattern(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if TEST_PIEPEN_BEI_START
|
||||||
|
piepPattern->piepModes[2] = piepPauseShort;
|
||||||
|
#else
|
||||||
|
if (tBeepingStartWithoutWindowClose == 0u)
|
||||||
|
{
|
||||||
|
piepPattern->piepModes[2] = piepPauseLong;
|
||||||
|
}
|
||||||
|
else if ((Seconds::Get() - tBeepingStartWithoutWindowClose) < MINUTES_TO_SECONDS(6u) ) /* reduce pause time after x mintues */
|
||||||
|
{
|
||||||
|
piepPattern->piepModes[2] = piepPauseLong;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
piepPattern->piepModes[2] = piepPauseShort;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**/
|
||||||
|
static void handleKeyReceived(void)
|
||||||
|
{
|
||||||
|
int8_t lastKey = - 1; /* lastKey gets an offset for each receiver type */
|
||||||
|
bool lastKeyDirection = DIRECTION_CLOSE;
|
||||||
|
|
||||||
|
//delay(10);
|
||||||
|
|
||||||
|
//handleManualInputRequest();
|
||||||
|
if (manualKeyNo >= 0)
|
||||||
|
{
|
||||||
|
lastKey = manualKeyNo;
|
||||||
|
lastKeyDirection = manualKeyDirection;
|
||||||
|
}
|
||||||
|
if (lastKey < 0)
|
||||||
|
{
|
||||||
|
/* first check if a SW key was received */
|
||||||
|
lastKey = receiverSw.GetLastReceivedKeyNum();
|
||||||
|
if (lastKey >= 0)
|
||||||
|
{
|
||||||
|
receiverSw.ResetReceivedKeyNum();
|
||||||
|
lastKeyDirection = receiverSw.GetLastReceivedDirection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastKey < 0) /* if no SW key was received, check if a aiggend key was received */
|
||||||
|
{
|
||||||
|
lastKey = receiverAiggend.GetLastReceivedKeyNum();
|
||||||
|
if (lastKey >= 0)
|
||||||
|
{
|
||||||
|
receiverAiggend.ResetReceivedKeyNum();
|
||||||
|
lastKey += AIGGEND_KEY_INDEX_OFFSET;
|
||||||
|
lastKeyDirection = receiverAiggend.GetLastReceivedDirection();
|
||||||
|
#if 0
|
||||||
|
Serial.println("--");
|
||||||
|
for (uint32_t i=0; i<24; i++)
|
||||||
|
{
|
||||||
|
Serial.println(receiverAiggend.buft[i]);
|
||||||
|
}
|
||||||
|
receiverAiggend.startBuffering();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastKey < 0)
|
||||||
|
{
|
||||||
|
lastKey = receiverOval.GetLastReceivedKeyNum();
|
||||||
|
if (lastKey >= 0)
|
||||||
|
{
|
||||||
|
receiverOval.ResetReceivedKeyNum();
|
||||||
|
lastKey += OVAL_KEY_INDEX_OFFSET;
|
||||||
|
lastKeyDirection = receiverOval.GetLastReceivedDirection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lastKey < 0)
|
||||||
|
{
|
||||||
|
lastKey = receiverKerui.GetLastReceivedKeyNum();
|
||||||
|
if (lastKey >= 0)
|
||||||
|
{
|
||||||
|
receiverKerui.ResetReceivedKeyNum();
|
||||||
|
lastKey += KERUI_KEY_INDEX_OFFSET;
|
||||||
|
lastKeyDirection = receiverKerui.GetLastReceivedDirection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the thermo data and update wait time */
|
||||||
|
if (receiverThermo.HasNewData())
|
||||||
|
{
|
||||||
|
thermoData = receiverThermo.GetData();
|
||||||
|
receiverThermo.ResetNewData();
|
||||||
|
bUpdateDisp = true;
|
||||||
|
/*
|
||||||
|
char buf[16];
|
||||||
|
sprintf(buf, "\n%d.%dC %d%%", (int)floor(thermoData.temp), (int) floor(thermoData.temp*10) -(int) floor(thermoData.temp)*10, (int)floor(thermoData.rh));
|
||||||
|
Serial.print(buf);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* update wait time according to temperature */
|
||||||
|
updateWaittime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* handle windows and possibly start/stop beep pattern */
|
||||||
|
{
|
||||||
|
static bool shallPiepPrevious = false;
|
||||||
|
bool shallPiepNew = false;
|
||||||
|
uint8_t numberWindowsOpenNew = 0;
|
||||||
|
for (uint8_t i = 0; i < NUM_FENSTER; i++)
|
||||||
|
{
|
||||||
|
bool bWindowChanged = alleFenster[i]->HandleKey(lastKey, lastKeyDirection);
|
||||||
|
numberWindowsOpenNew += alleFenster[i]->IsOpen() ? 1 : 0;
|
||||||
|
shallPiepNew |= alleFenster[i]->ShallPiep();
|
||||||
|
|
||||||
|
if (bWindowChanged)
|
||||||
|
{
|
||||||
|
bUpdateDisp = true;
|
||||||
|
dataSender.requestSend();
|
||||||
|
bRequestShortBeep = true;
|
||||||
|
if (lastKeyDirection == DIRECTION_CLOSE)
|
||||||
|
{
|
||||||
|
tBeepingStartWithoutWindowClose = 0u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* possibly stop or start beeping */
|
||||||
|
if (bIsNightTime)
|
||||||
|
{
|
||||||
|
#if (TEST_PIEPEN_BEI_START == 0)
|
||||||
|
piepPattern->Stop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (false == shallPiepNew)
|
||||||
|
{
|
||||||
|
#if (TEST_PIEPEN_BEI_START == 0)
|
||||||
|
piepPattern->Stop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if ((true == shallPiepNew) && (false == shallPiepPrevious))
|
||||||
|
{
|
||||||
|
tBeepingStartWithoutWindowClose = Seconds::Get();
|
||||||
|
piepPattern->Start(DOUT_PIEP_PWM);
|
||||||
|
bUpdateDisp = true;
|
||||||
|
}
|
||||||
|
shallPiepPrevious = shallPiepNew;
|
||||||
|
numberWindowsOpen = numberWindowsOpenNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numberWindowsOpen == 0u)
|
||||||
|
{
|
||||||
|
tBeepingStartWithoutWindowClose = 0u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TEST_WAITTIME
|
||||||
|
static void testWaitTime()
|
||||||
|
{
|
||||||
|
thermoData.rhPercent = 5;
|
||||||
|
float tempC;
|
||||||
|
for (tempC = -10; tempC < 30; tempC += 0.5f)
|
||||||
|
{
|
||||||
|
thermoData.tempC = tempC;
|
||||||
|
updateWaittime();
|
||||||
|
Serial.print(tempC);
|
||||||
|
Serial.print(" ");
|
||||||
|
Serial.print(waitTimeDs);
|
||||||
|
Serial.print("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void updateWaittime(void)
|
||||||
|
{
|
||||||
|
/** < -5 : 5min
|
||||||
|
* -5 .. 19 : 5..30 min min = 5 + t- (-5) * (30-5) / (19- (-5) ) ;
|
||||||
|
* >19 : inf
|
||||||
|
* >25 : 30 min
|
||||||
|
*/
|
||||||
|
if (thermoData.rhPercent > 0.0f)
|
||||||
|
{
|
||||||
|
/* VALUE RECEIVED */
|
||||||
|
if (thermoData.tempC > 25.0f)
|
||||||
|
{
|
||||||
|
waitTimeDs = MINUTES_TO_DECIS(30);
|
||||||
|
}
|
||||||
|
else if (thermoData.tempC > 19.5f)
|
||||||
|
{
|
||||||
|
waitTimeDs = MINUTES_TO_DECIS(60*24*14); //zwei Wochen = unendlich
|
||||||
|
}
|
||||||
|
else if (thermoData.tempC < -5.0f)
|
||||||
|
{
|
||||||
|
waitTimeDs = MINUTES_TO_DECIS(5);
|
||||||
|
piepPauseLong->requestCount = 20;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const float dy = 30.0f-5.0f;
|
||||||
|
const float dx = 19.5f-(-5.0f);
|
||||||
|
float minutes = 5.0f + (thermoData.tempC-(-5.0f)) * dy / dx ;
|
||||||
|
waitTimeDs = (DeciSeconds_t)(600.0f * minutes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* DEFAULT IF NO VALUE WAS RECEIVED YET*/
|
||||||
|
#if 0
|
||||||
|
/* calculate the wait Time from the poti value */
|
||||||
|
waitTimeDs = ((DeciSeconds_t) analogRead(AIN_POTI)
|
||||||
|
* MINUTES_TO_DECIS(19UL)) / 1023UL; /* max 19 minutes */
|
||||||
|
waitTimeDs += MINUTES_TO_DECIS(1UL); /* minimum 1 Minute */
|
||||||
|
#endif
|
||||||
|
waitTimeDs = MINUTES_TO_DECIS(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* im serial monitor zwei zahlen mit leerzeichen eingeben, um einen key zu senden :
|
||||||
|
* 1 1 sendet key 1 an,
|
||||||
|
* 2 0 sendet key 2 aus,..
|
||||||
|
*/
|
||||||
|
static void handleManualInputRequest()
|
||||||
|
{
|
||||||
|
if (Serial.available())
|
||||||
|
{
|
||||||
|
char buf[10];
|
||||||
|
size_t numBytesRead = Serial.readBytesUntil(' ', buf, 10);
|
||||||
|
if (numBytesRead > 0)
|
||||||
|
{
|
||||||
|
buf[numBytesRead] = '\0';
|
||||||
|
int n1;
|
||||||
|
sscanf(buf, "%d", &n1);
|
||||||
|
Serial.print(n1);
|
||||||
|
Serial.print(" n1 \n");
|
||||||
|
|
||||||
|
numBytesRead = Serial.readBytesUntil(' ', buf, 10);
|
||||||
|
if (numBytesRead > 0) /* send key */
|
||||||
|
{
|
||||||
|
buf[numBytesRead] = '\0';
|
||||||
|
int n2;
|
||||||
|
sscanf(buf, "%d", &n2);
|
||||||
|
Serial.print(n2);
|
||||||
|
Serial.print(" n2 \n");
|
||||||
|
|
||||||
|
if (n1 > 0 && n2 >= 0 && n2 <= 1)
|
||||||
|
{
|
||||||
|
manualKeyNo = n1;
|
||||||
|
manualKeyDirection = n2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_XCP
|
||||||
|
static void xcpLoop(void)
|
||||||
|
{
|
||||||
|
static uint32_t tNext10ms = 0;
|
||||||
|
static uint32_t tNext100ms = 0;
|
||||||
|
static uint32_t tNext500ms = 0;
|
||||||
|
static uint32_t tNext1000ms = 0;
|
||||||
|
|
||||||
|
/* trigger events */
|
||||||
|
if (millis() >= tNext10ms)
|
||||||
|
{
|
||||||
|
tNext10ms += 10;
|
||||||
|
XcpEvent(0);
|
||||||
|
}
|
||||||
|
if (millis() >= tNext100ms)
|
||||||
|
{
|
||||||
|
tNext100ms += 100;
|
||||||
|
XcpEvent(1);
|
||||||
|
}
|
||||||
|
if (millis() >= tNext500ms)
|
||||||
|
{
|
||||||
|
tNext500ms += 500;
|
||||||
|
XcpEvent(2);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (millis() >= tNext1000ms)
|
||||||
|
{
|
||||||
|
tNext1000ms += 1000;
|
||||||
|
XcpEvent(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
XcpPoll();
|
||||||
|
XcpSendLoop();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// Only modify this file to include
|
||||||
|
// - function definitions (prototypes)
|
||||||
|
// - include files
|
||||||
|
// - extern variable definitions
|
||||||
|
// In the appropriate section
|
||||||
|
|
||||||
|
#ifndef _fenster_PIEPSER_NodeMCU32S_H_
|
||||||
|
#define _fenster_PIEPSER_NodeMCU32S_H_
|
||||||
|
|
||||||
|
/* USE main.h */
|
||||||
|
|
||||||
|
#endif /* _fenster_PIEPSER_NodeMCU32S_H_ */
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* main.h
|
||||||
|
*
|
||||||
|
* Created on: 22.02.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MAIN_H_
|
||||||
|
#define MAIN_H_
|
||||||
|
|
||||||
|
/* -------------- INCLUDES --------------*/
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "typedefs.h"
|
||||||
|
#include "PiepPattern.h"
|
||||||
|
#include "ReceiverFunkThermometer.h"
|
||||||
|
#include "Fenster.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* --------------- TYPEDEFS -------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/* --------- SYMBOLIC CONSTANTS ---------*/
|
||||||
|
|
||||||
|
#define VERSION_DG_ONLY 0
|
||||||
|
|
||||||
|
#define VERSION_SMALL_DISPLAY 1
|
||||||
|
|
||||||
|
#define VERSION_BIG_DISPLAY (! VERSION_SMALL_DISPLAY)
|
||||||
|
|
||||||
|
/* singal pins */
|
||||||
|
|
||||||
|
|
||||||
|
#define TFT_PIN_CLK 14 /* SCK */
|
||||||
|
#define TFT_PIN_MOSI 13 /* SDA */
|
||||||
|
#define TFT_PIN_RST 22 // RES
|
||||||
|
#define TFT_PIN_DC 21 // RS (Data/Command = Register select)
|
||||||
|
#define TFT_PIN_CS 15 /* CS Chip select */
|
||||||
|
|
||||||
|
#define DOUT_TEST_TIMER 16
|
||||||
|
#define DOUT_FUNK_VCC 12
|
||||||
|
#define DOUT_FUNK_GND 32
|
||||||
|
#define DIN_FUNK 26
|
||||||
|
|
||||||
|
#define DOUT_PIEP_PWM 33
|
||||||
|
#define DOUT_PIEP_VCC 18
|
||||||
|
|
||||||
|
#define TONE_PWM_CHANNEL 12
|
||||||
|
#define TONE_REQUEST_ON(source) toneRequest |= (1u<<source) /* the pwm output is always active, only the supply gets switched */
|
||||||
|
#define TONE_REQUEST_OFF(source) toneRequest &= (~(1u<<source))
|
||||||
|
#define TONE_REQUEST_SOURCE_MODE 1u
|
||||||
|
#define TONE_REQUEST_SOURCE_SHORTPIEP 0u
|
||||||
|
|
||||||
|
|
||||||
|
#if VERSION_SMALL_DISPLAY
|
||||||
|
#define NUM_FENSTER 4
|
||||||
|
#elif VERSION_BIG_DISPLAY
|
||||||
|
#define NUM_FENSTER 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define DIRECTION_OPEN (1u)
|
||||||
|
#define DIRECTION_CLOSE (0u)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------- GLOBAL VARIABLES --------*/
|
||||||
|
|
||||||
|
extern uint8_t numberWindowsOpen;
|
||||||
|
extern uint32_t waitTimeDs;
|
||||||
|
extern char textBuf[100];
|
||||||
|
extern bool bRequestShortBeep;
|
||||||
|
extern bool bIsNightTime;
|
||||||
|
extern PiepPattern *piepPattern;
|
||||||
|
|
||||||
|
extern DeciSeconds_t tDecis;
|
||||||
|
extern ReceiverFunkThermometerData_t thermoData;
|
||||||
|
|
||||||
|
extern uint32_t loopCountSincePause;
|
||||||
|
extern uint8_t toneRequest;
|
||||||
|
|
||||||
|
extern Fenster fensterFloBuero;
|
||||||
|
extern Fenster fensterGefrier;
|
||||||
|
extern Fenster fensterBadOben;
|
||||||
|
extern Fenster fensterBadUnten;
|
||||||
|
extern Fenster fensterFlo;
|
||||||
|
extern Fenster fensterHanna;
|
||||||
|
extern Fenster fensterWz;
|
||||||
|
extern Fenster fensterWz2;
|
||||||
|
extern Fenster fensterX;
|
||||||
|
extern Fenster fensterToniNeu;
|
||||||
|
extern Fenster fensterKueche;
|
||||||
|
extern Fenster fensterKeller;
|
||||||
|
extern Fenster fensterGaeste;
|
||||||
|
extern Fenster* alleFenster[NUM_FENSTER];
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* MAIN_H_ */
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* typedefs.h
|
||||||
|
*
|
||||||
|
* Created on: 24.05.2020
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TYPEDEFS_H_
|
||||||
|
#define TYPEDEFS_H_
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
typedef uint32_t DeciSeconds_t;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* TYPEDEFS_H_ */
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
#ifndef RINGBUFFER_H
|
||||||
|
#define RINGBUFFER_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the buffer always begins at iRead and ends at iBufEnd
|
||||||
|
* writing is allowed as long as iWrite != iBufEnd
|
||||||
|
* reading is possible as long as iRead != iWrite
|
||||||
|
* start (no data to read, 6 elements [0..5] free to write ):
|
||||||
|
* [ 0 1 2 3 4 5 6 ]
|
||||||
|
* iRead
|
||||||
|
* iWrite x x x x x iBufEnd
|
||||||
|
*
|
||||||
|
* 4 elements available to read:
|
||||||
|
* [ x x x iBufEnd iRead x x x iWrite x x x ]
|
||||||
|
* after reading 4 elements:
|
||||||
|
* [ x x x x x x x iBufEnd iWrite x x x ]
|
||||||
|
* iRead
|
||||||
|
*
|
||||||
|
* 1 more element can be written, 8 can be read
|
||||||
|
* [ x x x iWrite iBufEnd iRead x x x x ]
|
||||||
|
* after writing 1 element:
|
||||||
|
* buffer is full, 9 to be read
|
||||||
|
* [ x x x x iBufEnd iRead x x x x ]
|
||||||
|
* iWrite
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* writing is split up into three calls :
|
||||||
|
* 1. canWrite -> check if the buffer has space left
|
||||||
|
* 2. getWritePointer returns the pointer to the element
|
||||||
|
* that can be written on (or NULL if writing is forbidden)
|
||||||
|
* 3. write moves the write index to the next position and thereby
|
||||||
|
* signals that the just written element can be read now
|
||||||
|
*
|
||||||
|
* reading is done by
|
||||||
|
* 1. canRead -> check if there are elements that have been written
|
||||||
|
* but not yet read
|
||||||
|
* 2. getReadPointer : returns pointer to the next available element
|
||||||
|
* and increments the read index. Reading from the pointer
|
||||||
|
* is safe (data will not be overwritten) until the next call of
|
||||||
|
* getReadPointer
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<class T> class RingBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* The RingBuffer does not create the underlying array itself, it must be
|
||||||
|
* created outside.
|
||||||
|
* \param : array : pointer to first element of the array
|
||||||
|
* arraySize : number of elements in the array
|
||||||
|
*/
|
||||||
|
RingBuffer<T>(T * array, uint32_t arraySize)
|
||||||
|
{
|
||||||
|
this->array = array; //constant
|
||||||
|
this->arraySize = arraySize; //constant
|
||||||
|
|
||||||
|
iBufEnd = arraySize-1;
|
||||||
|
iWrite = 0;
|
||||||
|
iRead = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return if the buffer has at least one element left to write on
|
||||||
|
* without overwriting unread elements
|
||||||
|
*/
|
||||||
|
bool canWrite(void)
|
||||||
|
{
|
||||||
|
return iWrite != iBufEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns NULL if write is not permitted!
|
||||||
|
* (Check can be done with canWrite())
|
||||||
|
* When the writing to the pointer is finished call write()!
|
||||||
|
*/
|
||||||
|
T* getWritePointer(void)
|
||||||
|
{
|
||||||
|
T* pWrite = NULL;
|
||||||
|
if (canWrite())
|
||||||
|
{
|
||||||
|
pWrite = &array[iWrite];
|
||||||
|
}
|
||||||
|
return pWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* to be called as soon as the data has been written.
|
||||||
|
* Don't put this into getWritePointer to allow reading
|
||||||
|
* the element immediately
|
||||||
|
*/
|
||||||
|
void write(void)
|
||||||
|
{
|
||||||
|
if ( canWrite() )
|
||||||
|
{
|
||||||
|
/* should always be true, otherwise there was an error before */
|
||||||
|
if (++iWrite==arraySize){
|
||||||
|
iWrite = 0; //wrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if there are elements that can be read
|
||||||
|
*/
|
||||||
|
bool canRead(void)
|
||||||
|
{
|
||||||
|
return iRead != iWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the number of received elements that haven't been read yet
|
||||||
|
*/
|
||||||
|
uint32_t getNumberUnread(void)
|
||||||
|
{
|
||||||
|
uint32_t numUnread;
|
||||||
|
if ( iRead == iWrite )
|
||||||
|
{
|
||||||
|
numUnread = 0;
|
||||||
|
}
|
||||||
|
else if ( iWrite > iRead )
|
||||||
|
{
|
||||||
|
numUnread = iWrite-iRead;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numUnread = arraySize + iWrite - iRead;
|
||||||
|
}
|
||||||
|
return numUnread;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get Pointer to next received frame that hasn't been read yet.
|
||||||
|
* the data will be safe to read until the next call of the function
|
||||||
|
* (because array[iBufEnd] will not be overwritten)
|
||||||
|
* The function increments the read index, so it may only be called once per element
|
||||||
|
*/
|
||||||
|
T* getReadPointer(void)
|
||||||
|
{
|
||||||
|
T* pEntry = &array[iRead];
|
||||||
|
iBufEnd = iRead;
|
||||||
|
if (++iRead==arraySize){
|
||||||
|
iRead = 0; //wrap
|
||||||
|
}
|
||||||
|
return pEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* array;
|
||||||
|
uint32_t arraySize;
|
||||||
|
uint32_t iWrite;
|
||||||
|
uint32_t iRead;
|
||||||
|
uint32_t iBufEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* XcpApplInterface.h
|
||||||
|
*
|
||||||
|
* Created on: 30.07.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XCP_XCPAPPINTERFACE_H_
|
||||||
|
#define XCP_XCPAPPINTERFACE_H_
|
||||||
|
|
||||||
|
#include "xcp_cfg.h"
|
||||||
|
|
||||||
|
extern const vuint8 kXcpEventDirection[kXcpMaxEvent]; //DAQ
|
||||||
|
extern const vuint8 kXcpEventCycle[kXcpMaxEvent];
|
||||||
|
extern const vuint8 kXcpEventUnit[kXcpMaxEvent];
|
||||||
|
extern const char kXcpEventName[kXcpMaxEvent][7];
|
||||||
|
extern const vuint8 kXcpEventNameLength[kXcpMaxEvent];
|
||||||
|
|
||||||
|
#endif /* XCP_XCPAPPINTERFACE_H_ */
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* XcpApplnterface.c
|
||||||
|
*
|
||||||
|
* Created on: 30.07.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
#include "XcpBasic.h"
|
||||||
|
#include "XcpFrameReceiver.h"
|
||||||
|
#include "XcpDriverCom.h"
|
||||||
|
|
||||||
|
#include "XcpAppInterface.h"
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
#define XCPFRAME_BUFFERSIZE 5 /* x frames are sufficient */
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
const vuint8 kXcpEventDirection[kXcpMaxEvent] = { 4, 4, 4, 4 }; //DAQ
|
||||||
|
const vuint8 kXcpEventCycle[kXcpMaxEvent] = { 1, 1, 5, 1 };
|
||||||
|
const vuint8 kXcpEventUnit[kXcpMaxEvent] = { 7, 8, 8, 9 };
|
||||||
|
const char kXcpEventName[kXcpMaxEvent][7] = { {"10ms "}, {"100ms "}, {"500ms "}, {"1000ms"}};
|
||||||
|
const vuint8 kXcpEventNameLength[kXcpMaxEvent] = { 4, 5, 5, 6 };
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
static XcpFrame tlComXcpRxPackets[XCPFRAME_BUFFERSIZE];
|
||||||
|
static XcpFrameReceiver xcpFrameReceiver( tlComXcpRxPackets, XCPFRAME_BUFFERSIZE, false );
|
||||||
|
#define XCP_SEND_BUFFER_SIZE 10u
|
||||||
|
static XcpFrame sendBuffer[XCP_SEND_BUFFER_SIZE];
|
||||||
|
static vuint16 xcpSendBufWritePos = 0;
|
||||||
|
static vuint16 xcpSendBufReadPos = 0;
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void XcpPoll()
|
||||||
|
{
|
||||||
|
/* receive message */
|
||||||
|
if (XCP_COM_AVAILABLE())
|
||||||
|
{
|
||||||
|
while (XCP_COM_AVAILABLE())
|
||||||
|
{
|
||||||
|
uint8_t serData = XCP_COM_READ();
|
||||||
|
if (xcpFrameReceiver.hasSpace())
|
||||||
|
{
|
||||||
|
xcpFrameReceiver.putData(1, &serData);
|
||||||
|
}
|
||||||
|
if (xcpFrameReceiver.hasFrames())
|
||||||
|
{
|
||||||
|
XcpFrame *pFrame = xcpFrameReceiver.getFrame();
|
||||||
|
XcpCommand(pFrame->data.u32);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ApplXcpSend( uint8_t len, MEMORY_ROM BYTEPTR msg )
|
||||||
|
{
|
||||||
|
uint8_t iBuf = 0;
|
||||||
|
sendBuffer[xcpSendBufWritePos].data.u8[iBuf++] = XcpFrameReceiver::ESCBYTE;
|
||||||
|
sendBuffer[xcpSendBufWritePos].data.u8[iBuf++] = len;
|
||||||
|
for (uint8_t iMsg = 0; iMsg<len; iMsg++ )
|
||||||
|
{
|
||||||
|
sendBuffer[xcpSendBufWritePos].data.u8[iBuf++] = msg[iMsg];
|
||||||
|
}
|
||||||
|
sendBuffer[xcpSendBufWritePos].len = iBuf;
|
||||||
|
if (++xcpSendBufWritePos >= XCP_SEND_BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
xcpSendBufWritePos = 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
XcpSendCallBack();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send max one frame from buffer
|
||||||
|
*/
|
||||||
|
void XcpSendLoop()
|
||||||
|
{
|
||||||
|
#define SEND_MAX_FRAMES_PER_CALL 3u
|
||||||
|
for (uint8_t i=0; i<SEND_MAX_FRAMES_PER_CALL; i++)
|
||||||
|
{
|
||||||
|
if (xcpSendBufReadPos != xcpSendBufWritePos)
|
||||||
|
{
|
||||||
|
Serial.write(sendBuffer[xcpSendBufReadPos].data.u8, sendBuffer[xcpSendBufReadPos].len);
|
||||||
|
if (++xcpSendBufReadPos >= XCP_SEND_BUFFER_SIZE)
|
||||||
|
{
|
||||||
|
xcpSendBufReadPos = 0u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
MTABYTEPTR ApplXcpGetPointer( uint8_t addr_ext, uint32_t addr )
|
||||||
|
{
|
||||||
|
//return (MTABYTEPTR)&kXcpEventName;
|
||||||
|
return (MTABYTEPTR)(addr + 0*addr_ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ApplXcpInterruptEnable()
|
||||||
|
{
|
||||||
|
//interrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void ApplXcpInterruptDisable()
|
||||||
|
{
|
||||||
|
//noInterrupts();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
uint16_t ApplXcpGetTimestamp(void)
|
||||||
|
{
|
||||||
|
return (uint16_t) millis();
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
+2368
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* XcpDriverCom.h
|
||||||
|
*
|
||||||
|
* Created on: 30.07.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XCPDRIVERCOM_H_
|
||||||
|
#define XCPDRIVERCOM_H_
|
||||||
|
|
||||||
|
#define XCP_COM_AVAILABLE() Serial.available()
|
||||||
|
#define XCP_COM_READ() Serial.read()
|
||||||
|
#define XCP_COM_WRITE_BYTE(b) Serial.write(b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* XCPDRIVERCOM_H_ */
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef XCPFRAME_H
|
||||||
|
#define XCPFRAME_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#define DTOBUF_PACKETSIZE 16u /* packet size in bytes */
|
||||||
|
|
||||||
|
class XcpFrame
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
uint16_t len;
|
||||||
|
union{
|
||||||
|
uint32_t u32[DTOBUF_PACKETSIZE/4u];
|
||||||
|
uint8_t u8[DTOBUF_PACKETSIZE];
|
||||||
|
} data; /* the xcp driver needs uint32 aligned data */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#include "XcpFrameReceiver.h"
|
||||||
|
|
||||||
|
template class RingBuffer<XcpFrame>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XcpFrameReceiver : protocol class to decode frame data with SOF byte and
|
||||||
|
* byte stuffing (with preceding escape byte). A valid frame must be transmitted
|
||||||
|
* like this:
|
||||||
|
* SOF len(LSB) len(MSB) cs(LSB) cs(MSB) data0 data1 ..
|
||||||
|
*
|
||||||
|
* len: uint16 , number of data bytes
|
||||||
|
* cs : uint16 , checksum (sum over all data bytes)
|
||||||
|
*
|
||||||
|
* if there is any escape byte or SOF byte inside the len, cs, or data field
|
||||||
|
* it must be transmitted with a preceding escape byte (this does not affect the
|
||||||
|
* len or cs itself).
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* 1. initialize with existing array
|
||||||
|
* 2. call hasSpace, putData to write and decode the received data and
|
||||||
|
* store it into the given array
|
||||||
|
* 3. call hasFrames, getFrame to get the decoded frames
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* constructor: Init everything
|
||||||
|
* \param : frameArray : pointer to first element of frame array
|
||||||
|
* arraySize : number of elements inside the array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
XcpFrameReceiver::XcpFrameReceiver(XcpFrame *frameArray, uint32_t arraySize, bool useChecksum )
|
||||||
|
{
|
||||||
|
ringBuffer = new RingBuffer<XcpFrame>(frameArray, arraySize);
|
||||||
|
state = NONE_XCP_DATA;
|
||||||
|
frameLen = 0;
|
||||||
|
frameCount = 0;
|
||||||
|
iFrameData = 0;
|
||||||
|
pWriteFrame = NULL;
|
||||||
|
numProtocolErrors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return false if the underlying buffer has no space left
|
||||||
|
*/
|
||||||
|
bool XcpFrameReceiver::hasSpace(void)
|
||||||
|
{
|
||||||
|
return ringBuffer->canWrite();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if there are readable elements in the underlying buffer
|
||||||
|
*/
|
||||||
|
bool XcpFrameReceiver::hasFrames(void)
|
||||||
|
{
|
||||||
|
return ringBuffer->canRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the available number of frames that have not been read yet
|
||||||
|
*/
|
||||||
|
uint32_t XcpFrameReceiver::getNumberFrames(void)
|
||||||
|
{
|
||||||
|
return ringBuffer->getNumberUnread();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the frame that was received next and yet not read.
|
||||||
|
* -> call only once per receive frame (increments the index)
|
||||||
|
*/
|
||||||
|
XcpFrame *XcpFrameReceiver::getFrame(void)
|
||||||
|
{
|
||||||
|
return ringBuffer->getReadPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** check canWrite before putting new data ! */
|
||||||
|
void XcpFrameReceiver::putData(uint32_t lenData, uint8_t * data)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
pWriteFrame = ringBuffer->getWritePointer();
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (i<lenData)
|
||||||
|
{
|
||||||
|
/* data must be processed byte by byte because SOF/ESC bytes need to be detected */
|
||||||
|
if ( NULL == pWriteFrame )
|
||||||
|
{
|
||||||
|
/* pWriteFrame might become NULL in processing function */
|
||||||
|
break; //while loop
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
processByte(data[i]);
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} //while (i<lenData)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void XcpFrameReceiver::processByte(uint8_t byte)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch ( state)
|
||||||
|
{
|
||||||
|
case NONE_XCP_DATA:
|
||||||
|
if (byte == ESCBYTE)
|
||||||
|
{
|
||||||
|
state = ESCAPED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
//std::cout << byte << std::flush;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ESCAPED:
|
||||||
|
if (byte == ESCBYTE)
|
||||||
|
{
|
||||||
|
//std::cout << byte << std::flush;
|
||||||
|
state = NONE_XCP_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frameLen = byte;
|
||||||
|
iFrameData = 0u;
|
||||||
|
state = XCP_DATA;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XCP_DATA:
|
||||||
|
pWriteFrame->data.u8[iFrameData++] = byte;
|
||||||
|
if (iFrameData == frameLen)
|
||||||
|
{
|
||||||
|
pWriteFrame->len = frameLen;
|
||||||
|
ringBuffer->write();
|
||||||
|
state = NONE_XCP_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef XCPFRAMERECEIVER_H
|
||||||
|
#define XCPFRAMERECEIVER_H
|
||||||
|
|
||||||
|
#include "RingBuffer.h"
|
||||||
|
#include "XcpFrame.h"
|
||||||
|
|
||||||
|
|
||||||
|
class XcpFrameReceiver
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
static const uint8_t ESCBYTE = 0xFF;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* constructor: Init everything
|
||||||
|
*/
|
||||||
|
XcpFrameReceiver(XcpFrame *frameArray, uint32_t arraySize, bool useChecksum = true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return false if the back buffer has no space left
|
||||||
|
*/
|
||||||
|
bool hasSpace(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if there are readable frames in the back buffer
|
||||||
|
*/
|
||||||
|
bool hasFrames(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the available number of frames that have not been read yet
|
||||||
|
*/
|
||||||
|
uint32_t getNumberFrames(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the frame that was received next and yet not read.
|
||||||
|
*/
|
||||||
|
XcpFrame *getFrame(void);
|
||||||
|
|
||||||
|
/** check canWrite before putting new data ! */
|
||||||
|
void putData(uint32_t lenData, uint8_t * data);
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t frameCount; /** counter for every XCP ethernet frame to be compared with received counter */
|
||||||
|
class RingBuffer<XcpFrame> *ringBuffer;
|
||||||
|
XcpFrame* pWriteFrame;
|
||||||
|
uint16_t iFrameData; /* temporary index for received Xcp Frame data */
|
||||||
|
uint8_t frameLen;
|
||||||
|
uint32_t numProtocolErrors;
|
||||||
|
|
||||||
|
enum receiveState { NONE_XCP_DATA, ESCAPED, XCP_DATA } state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* destuff escape bytes, detect start of frame, forward data bytes
|
||||||
|
*/
|
||||||
|
void processByte(uint8_t byte);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* XcpPort.h
|
||||||
|
*
|
||||||
|
* Created on: 30.07.2022
|
||||||
|
* Author: flori
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef XCP_XCPPORT_H_
|
||||||
|
#define XCP_XCPPORT_H_
|
||||||
|
|
||||||
|
#include "xcp_typedefs.h"
|
||||||
|
|
||||||
|
vuint8 XcpEvent( vuint8 event );
|
||||||
|
extern void XcpInit( void );
|
||||||
|
extern void XcpPoll();
|
||||||
|
extern void XcpSendLoop();
|
||||||
|
|
||||||
|
#endif /* XCP_XCPPORT_H_ */
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
/* -----------------------------------------------------------------------------
|
||||||
|
C O P Y R I G H T
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2001-2006 by Vector Informatik GmbH. All rights reserved.
|
||||||
|
|
||||||
|
This software is copyright protected and proprietary to Vector Informatik
|
||||||
|
GmbH.
|
||||||
|
|
||||||
|
Vector Informatik GmbH grants to you only those rights as set out in the
|
||||||
|
license conditions.
|
||||||
|
|
||||||
|
All other rights remain with Vector Informatik GmbH.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
----------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#if !defined(__XCP_CFG_H__)
|
||||||
|
#define __XCP_CFG_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
|
||||||
|
/* */
|
||||||
|
/* CPU */
|
||||||
|
#define C_CPUTYPE_LITTLEENDIAN
|
||||||
|
|
||||||
|
#define XCP_ENABLE_CANAPE_5_5_X_SUPPORT //nur fuer EVENT_TIME_UNIT bei GET_DAQ_EVENT_INFO
|
||||||
|
|
||||||
|
|
||||||
|
/* General settings */
|
||||||
|
#define XCP_ENABLE_PARAMETER_CHECK
|
||||||
|
#define XCP_ENABLE_SEND_EVENT
|
||||||
|
#define XCP_DISABLE_TESTMODE
|
||||||
|
#define XCP_DISABLE_BOOTLOADER_DOWNLOAD
|
||||||
|
#define XCP_DISABLE_WRITE_PROTECTION
|
||||||
|
#define XCP_DISABLE_READ_PROTECTION
|
||||||
|
#define XCP_ENABLE_CONTROL
|
||||||
|
#define XCP_DISABLE_GET_XCP_DATA_POINTER
|
||||||
|
#define XCP_DISABLE_OPENCMDIF
|
||||||
|
#define XCP_ENABLE_MEM_MAPPING
|
||||||
|
#define XCP_DISABLE_VERSION_INFO_API
|
||||||
|
/* */
|
||||||
|
/* EEPROM access */
|
||||||
|
#define XCP_DISABLE_READ_EEPROM
|
||||||
|
#define XCP_DISABLE_WRITE_EEPROM
|
||||||
|
/* */
|
||||||
|
/* Service request message */
|
||||||
|
#define XCP_DISABLE_SERV_TEXT
|
||||||
|
#define XCP_DISABLE_SERV_TEXT_PUTCHAR
|
||||||
|
#define XCP_DISABLE_SERV_TEXT_PRINTF
|
||||||
|
/* */
|
||||||
|
/* Standard commands */
|
||||||
|
#define XCP_ENABLE_COMM_MODE_INFO
|
||||||
|
#define XCP_DISABLE_SEED_KEY
|
||||||
|
#define XCP_ENABLE_MODIFY_BITS
|
||||||
|
#define XCP_ENABLE_SHORT_DOWNLOAD
|
||||||
|
#define XCP_DISABLE_USER_COMMAND
|
||||||
|
#define XCP_DISABLE_VECTOR_MAPNAMES
|
||||||
|
#define XCP_ENABLE_TL_COMMAND
|
||||||
|
/* */
|
||||||
|
/* Block transfer */
|
||||||
|
#define XCP_ENABLE_BLOCK_UPLOAD
|
||||||
|
#define XCP_ENABLE_BLOCK_DOWNLOAD
|
||||||
|
/* */
|
||||||
|
/* Checksum */
|
||||||
|
#define XCP_DISABLE_CHECKSUM
|
||||||
|
#define XCP_DISABLE_AUTOSAR_CRC_MODULE
|
||||||
|
#define kXcpChecksumMethod XCP_CHECKSUM_TYPE_ADD12
|
||||||
|
#define kXcpChecksumBlockSize 0
|
||||||
|
/* */
|
||||||
|
/* Synchronous Data Acquisition (DAQ) */
|
||||||
|
#define XCP_ENABLE_DAQ
|
||||||
|
#define kXcpDaqMemSize 256
|
||||||
|
#define XCP_DISABLE_STIM
|
||||||
|
#define XCP_DISABLE_UNALIGNED_MEM_ACCESS
|
||||||
|
#define XCP_ENABLE_SEND_DIRECT
|
||||||
|
#define XCP_DISABLE_SEND_QUEUE
|
||||||
|
#define kXcpStimOdtCount 0x04u
|
||||||
|
#define XCP_ENABLE_DAQ_PRESCALER
|
||||||
|
#define XCP_ENABLE_DAQ_OVERRUN_INDICATION
|
||||||
|
#define XCP_ENABLE_WRITE_DAQ_MULTIPLE
|
||||||
|
|
||||||
|
|
||||||
|
#undef XCP_ENABLE_DAQ_HDR_ODT_DAQ
|
||||||
|
#undef XCP_ALLIGN_WORD
|
||||||
|
#undef XCP_ENABLE_ODT_SIZE_WORD
|
||||||
|
|
||||||
|
#define XCP_ENABLE_DAQ_RESUME
|
||||||
|
#define XCP_ENABLE_DAQ_PROCESSOR_INFO
|
||||||
|
#define XCP_ENABLE_DAQ_RESOLUTION_INFO
|
||||||
|
/* */
|
||||||
|
// CALIBRATION
|
||||||
|
#define XCP_ENABLE_CALIBRATION
|
||||||
|
|
||||||
|
/* Events */
|
||||||
|
#define XCP_ENABLE_DAQ_EVENT_INFO
|
||||||
|
#define kXcpMaxEvent 4
|
||||||
|
/* */
|
||||||
|
/* DAQ Timestamp */
|
||||||
|
#define XCP_ENABLE_DAQ_TIMESTAMP
|
||||||
|
#define XCP_ENABLE_DAQ_TIMESTAMP_FIXED
|
||||||
|
#define kXcpDaqTimestampUnit DAQ_TIMESTAMP_UNIT_1MS
|
||||||
|
#define kXcpDaqTimestampTicksPerUnit 1
|
||||||
|
#define kXcpDaqTimestampSize DAQ_TIMESTAMP_WORD
|
||||||
|
/* */
|
||||||
|
/* Page switching */
|
||||||
|
#undef XCP_DISABLE_CALIBRATION_PAGE
|
||||||
|
#define kXcpMaxSegment 1
|
||||||
|
#undef XCP_ENABLE_PAGE_INFO
|
||||||
|
#define kXcpMaxPages 2
|
||||||
|
#define XCP_DISABLE_PAGE_COPY
|
||||||
|
#define XCP_DISABLE_PAGE_FREEZE
|
||||||
|
/* */
|
||||||
|
/* Programming */
|
||||||
|
#define XCP_DISABLE_PROGRAM
|
||||||
|
#define kXcpProgramMinStPgm 0
|
||||||
|
#define kXcpProgramMaxSector 1
|
||||||
|
#define XCP_DISABLE_PROGRAM_INFO
|
||||||
|
/* */
|
||||||
|
#define CP_XCPDLL_VERSION 0x0209u
|
||||||
|
#define CP_XCPDLL_RELEASE_VERSION 0x00u
|
||||||
|
#define XCP_SEND_QUEUE_SAMPLE_ODT
|
||||||
|
//#define XCP_TRANSPORT_LAYER_TYPE_FLEXRAY_ASR
|
||||||
|
//#define XCP_TRANSPORT_LAYER_TYPE_CAN
|
||||||
|
|
||||||
|
/* begin Fileversion check */
|
||||||
|
#ifndef SKIP_MAGIC_NUMBER
|
||||||
|
#ifdef MAGIC_NUMBER
|
||||||
|
#if MAGIC_NUMBER != 2124540520
|
||||||
|
#error "The magic number of the generated file <D:\USR\_PROJECTS\Audi\EE-82\D4_MJ09_FR\E50_Verification\XCPonFlexRay\zTsi_XcpOnFlexRay\V85x\GHS\StandardECU_TTXSWV01.12.02\_Demo\DemoXcp\schedule\xcp_cfg.h> is different. Please check time and date of generated files!"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define MAGIC_NUMBER 2124540520
|
||||||
|
#endif /* MAGIC_NUMBER */
|
||||||
|
#endif /* SKIP_MAGIC_NUMBER */
|
||||||
|
|
||||||
|
/* end Fileversion check */
|
||||||
|
|
||||||
|
#endif /* __XCP_CFG_H__ */
|
||||||
@@ -0,0 +1,172 @@
|
|||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
| File:
|
||||||
|
| XCP_DEF.H
|
||||||
|
|
|
||||||
|
| Project:
|
||||||
|
| XCP samples
|
||||||
|
|
|
||||||
|
| Description
|
||||||
|
| XCP default settings
|
||||||
|
| Don't change this file
|
||||||
|
|
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#if defined ( __XCP_DEF_H__ )
|
||||||
|
#else
|
||||||
|
#define __XCP_DEF_H__
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef VAR_DEF
|
||||||
|
#define EXTERN
|
||||||
|
#else
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------------*/
|
||||||
|
/* Default settings */
|
||||||
|
|
||||||
|
/* XCP transport layer */
|
||||||
|
#if !defined(XCP_TRANSPORT_LAYER_VERSION)
|
||||||
|
#define XCP_TRANSPORT_LAYER_VERSION 0x0100
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#undef EXTERN
|
||||||
|
|
||||||
|
#define GRANULARITY_ODT_ENTRY_SIZE_ODT 1
|
||||||
|
|
||||||
|
/* ROM memory qualifiers */
|
||||||
|
#if !defined(MEMORY_ROM)
|
||||||
|
#define MEMORY_ROM const
|
||||||
|
#endif
|
||||||
|
#if !defined(V_MEMROM0)
|
||||||
|
#define V_MEMROM0
|
||||||
|
#endif
|
||||||
|
#if !defined(MEMORY_CONST)
|
||||||
|
#define MEMORY_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Alignment requirements */
|
||||||
|
/* Specify, whether the microcontroller allows unaligned memory access or not */
|
||||||
|
#if !defined(XCP_ENABLE_UNALIGNED_MEM_ACCESS) && !defined(XCP_DISABLE_UNALIGNED_MEM_ACCESS)
|
||||||
|
#define XCP_DISABLE_UNALIGNED_MEM_ACCESS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* General settings */
|
||||||
|
#if !defined(XCP_ENABLE_PARAMETER_CHECK) && !defined(XCP_DISABLE_PARAMETER_CHECK)
|
||||||
|
#define XCP_DISABLE_PARAMETER_CHECK
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_COMM_MODE_INFO) && !defined(XCP_DISABLE_COMM_MODE_INFO)
|
||||||
|
#define XCP_ENABLE_COMM_MODE_INFO
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_USER_COMMAND) && !defined(XCP_DISABLE_USER_COMMAND)
|
||||||
|
#define XCP_DISABLE_USER_COMMAND
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Block transfer */
|
||||||
|
#if !defined(XCP_ENABLE_BLOCK_UPLOAD) && !defined(XCP_DISABLE_BLOCK_UPLOAD)
|
||||||
|
#define XCP_DISABLE_BLOCK_UPLOAD
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_BLOCK_DOWNLOAD) && !defined(XCP_DISABLE_BLOCK_DOWNLOAD)
|
||||||
|
#define XCP_DISABLE_BLOCK_DOWNLOAD
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable transmission of event messages */
|
||||||
|
#if !defined(XCP_ENABLE_SEND_EVENT) && !defined(XCP_DISABLE_SEND_EVENT)
|
||||||
|
#define XCP_DISABLE_SEND_EVENT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Service request message */
|
||||||
|
#if !defined(XCP_ENABLE_SERV_TEXT) && !defined(XCP_DISABLE_SERV_TEXT)
|
||||||
|
#define XCP_DISABLE_SERV_TEXT
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_SERV_TEXT_PUTCHAR) && !defined(XCP_DISABLE_SERV_TEXT_PUTCHAR)
|
||||||
|
#define XCP_DISABLE_SERV_TEXT_PUTCHAR
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_SERV_TEXT_PRINTF) && !defined(XCP_DISABLE_SERV_TEXT_PRINTF)
|
||||||
|
#define XCP_DISABLE_SERV_TEXT_PRINTF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Disable/Enable Interrupts */
|
||||||
|
/* Has to be defined only if xcpSendCallBack may interrupt xcpEvent */
|
||||||
|
#if !defined(XcpInterruptDisable)
|
||||||
|
#define XcpInterruptDisable()
|
||||||
|
#endif
|
||||||
|
#if !defined(XcpInterruptEnable)
|
||||||
|
#define XcpInterruptEnable()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Custom initialization not needed */
|
||||||
|
#if !defined(ApplXcpInit)
|
||||||
|
#define ApplXcpInit()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Custom background processing not needed */
|
||||||
|
#if !defined(ApplXcpBackground)
|
||||||
|
#define ApplXcpBackground()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Flush of transmit queue not needed */
|
||||||
|
#if !defined(ApplXcpSendFlush)
|
||||||
|
#define ApplXcpSendFlush()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* XCP page switching */
|
||||||
|
#if !defined ( XCP_ENABLE_CALIBRATION_PAGE ) && !defined ( XCP_DISABLE_CALIBRATION_PAGE )
|
||||||
|
#define XCP_DISABLE_CALIBRATION_PAGE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* XCP protocol data acquisition parameters (DAQ) */
|
||||||
|
#if defined(XCP_DISABLE_DAQ)
|
||||||
|
#define XCP_DISABLE_SEND_QUEUE
|
||||||
|
#define XCP_ENABLE_SEND_DIRECT
|
||||||
|
#else
|
||||||
|
#if !defined(XCP_ENABLE_DAQ) && !defined(XCP_DISABLE_DAQ)
|
||||||
|
#define XCP_ENABLE_DAQ
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_SEND_DIRECT) && !defined(XCP_ENABLE_SEND_QUEUE)
|
||||||
|
#define XCP_ENABLE_SEND_QUEUE
|
||||||
|
#define XCP_DISABLE_SEND_DIRECT
|
||||||
|
#endif
|
||||||
|
#if defined(XCP_ENABLE_SEND_QUEUE)
|
||||||
|
#define XCP_DISABLE_SEND_DIRECT
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_HDR_ODT_DAQ) && !defined(XCP_DISABLE_DAQ_HDR_ODT_DAQ)
|
||||||
|
#define XCP_DISABLE_DAQ_HDR_ODT_DAQ
|
||||||
|
#endif
|
||||||
|
#if !defined(kXcpDaqMemSize)
|
||||||
|
#define kXcpDaqMemSize 256
|
||||||
|
#endif
|
||||||
|
#if !defined(kXcpStiOdtCount)
|
||||||
|
#define kXcpStiOdtCount 1
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_PROCESSOR_INFO) && !defined(XCP_DISABLE_DAQ_PROCESSOR_INFO)
|
||||||
|
#define XCP_ENABLE_DAQ_PROCESSOR_INFO
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_RESOLUTION_INFO) && !defined(XCP_DISABLE_DAQ_RESOLUTION_INFO)
|
||||||
|
#define XCP_ENABLE_DAQ_RESOLUTION_INFO
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_PRESCALER) && !defined(XCP_DISABLE_DAQ_PRESCALER)
|
||||||
|
#define XCP_DISABLE_DAQ_PRESCALER
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_OVERRUN_INDICATION) && !defined(XCP_DISABLE_DAQ_OVERRUN_INDICATION)
|
||||||
|
#define XCP_ENABLE_DAQ_OVERRUN_INDICATION
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_RESUME) && !defined(XCP_DISABLE_DAQ_RESUME)
|
||||||
|
#define XCP_DISABLE_DAQ_RESUME
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_TIMESTAMP) && !defined(XCP_DISABLE_DAQ_TIMESTAMP)
|
||||||
|
#define XCP_DISABLE_DAQ_TIMESTAMP
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_DAQ_EVENT_INFO) && !defined(XCP_DISABLE_DAQ_EVENT_INFO)
|
||||||
|
#define XCP_DISABLE_DAQ_EVENT_INFO
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if !defined(XCP_ENABLE_STIM) && !defined(XCP_DISABLE_STIM)
|
||||||
|
#define XCP_DISABLE_STIM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
| Project Name: XCP Protocol Layer
|
||||||
|
| File Name: xcp_par.c
|
||||||
|
|
|
||||||
|
| Description: Implementation of the XCP Protocol Layer
|
||||||
|
| XCP V1.0 slave device driver
|
||||||
|
| Basic Version (see feature list below)
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|-----------------------------------------------------------------------------
|
||||||
|
| C O P Y R I G H T
|
||||||
|
|-----------------------------------------------------------------------------
|
||||||
|
| Copyright (c) 2008 by Vector Informatik GmbH. All rights reserved.
|
||||||
|
|
|
||||||
|
| This software is copyright protected and
|
||||||
|
| proporietary to Vector Informatik GmbH.
|
||||||
|
| Vector Informatik GmbH grants to you only
|
||||||
|
| those rights as set out in the license conditions.
|
||||||
|
| All other rights remain with Vector Informatik GmbH.
|
||||||
|
|
|
||||||
|
| Diese Software ist urheberrechtlich geschuetzt.
|
||||||
|
| Vector Informatik GmbH raeumt Ihnen an dieser Software nur
|
||||||
|
| die in den Lizenzbedingungen ausdruecklich genannten Rechte ein.
|
||||||
|
| Alle anderen Rechte verbleiben bei Vector Informatik GmbH.
|
||||||
|
|
|
||||||
|
|***************************************************************************/
|
||||||
|
|
||||||
|
#include "XcpBasic.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Slave device id
|
||||||
|
#if defined ( kXcpStationIdLength )
|
||||||
|
V_MEMROM0 MEMORY_ROM vuint8 kXcpStationId[kXcpStationIdLength] = kXcpStationIdString;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
| Project Name: XCP Protocol Layer
|
||||||
|
| File Name: xcp_par.h
|
||||||
|
|
|
||||||
|
| Description: Header of XCP Protocol Layer
|
||||||
|
| XCP V1.0 slave device driver
|
||||||
|
| Basic Version
|
||||||
|
|
|
||||||
|
||
|
||||||
|
|-----------------------------------------------------------------------------
|
||||||
|
| C O P Y R I G H T
|
||||||
|
|-----------------------------------------------------------------------------
|
||||||
|
| Copyright (c) 2008 by Vector Informatik GmbH. All rights reserved.
|
||||||
|
|
|
||||||
|
| This software is copyright protected and
|
||||||
|
| proporietary to Vector Informatik GmbH.
|
||||||
|
| Vector Informatik GmbH grants to you only
|
||||||
|
| those rights as set out in the license conditions.
|
||||||
|
| All other rights remain with Vector Informatik GmbH.
|
||||||
|
|
|
||||||
|
| Diese Software ist urheberrechtlich geschuetzt.
|
||||||
|
| Vector Informatik GmbH raeumt Ihnen an dieser Software nur
|
||||||
|
| die in den Lizenzbedingungen ausdruecklich genannten Rechte ein.
|
||||||
|
| Alle anderen Rechte verbleiben bei Vector Informatik GmbH.
|
||||||
|
|
|
||||||
|
|
|
||||||
|
|***************************************************************************/
|
||||||
|
#if defined ( __XCP_PAR_H__ )
|
||||||
|
#else
|
||||||
|
#define __XCP_PAR_H__
|
||||||
|
|
||||||
|
/* XCP default settings */
|
||||||
|
#include "xcp_def.h"
|
||||||
|
|
||||||
|
V_MEMROM0 extern vuint8 MEMORY_ROM kXcpStationId[];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef XCP_TYPEDEFS_H
|
||||||
|
#define XCP_TYPEDEFS_H
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
typedef uint32_t vuint32;
|
||||||
|
typedef uint16_t vuint16;
|
||||||
|
typedef uint8_t vuint8;
|
||||||
|
|
||||||
|
#endif
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
This directory is intended for PlatformIO Test Runner and project tests.
|
||||||
|
|
||||||
|
Unit Testing is a software testing method by which individual units of
|
||||||
|
source code, sets of one or more MCU program modules together with associated
|
||||||
|
control data, usage procedures, and operating procedures, are tested to
|
||||||
|
determine whether they are fit for use. Unit testing finds problems early
|
||||||
|
in the development cycle.
|
||||||
|
|
||||||
|
More information about PlatformIO Unit Testing:
|
||||||
|
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
||||||
Reference in New Issue
Block a user