-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
APP_NAME=event_sensors | ||
|
||
# DEFINES=NO_SENSORS | ||
CPPFLAGS=-Wall -Werror -pedantic -std=c++17 -O2 -g -Wno-psabi $(addprefix -D,$(DEFINES)) | ||
# Attention: the lib diretory where the MQTT is installed into may not be in the LD path! | ||
LDFLAGS=-lpaho-mqtt3as -lpaho-mqttpp3 -lfpgaregion -lpthread -lz | ||
|
||
SOURCES=$(wildcard *.cpp) | ||
OBJECTS=$(SOURCES:.cpp=.o) | ||
|
||
|
||
all: $(APP_NAME) | ||
|
||
$(APP_NAME): $(OBJECTS) | ||
$(CXX) $^ $(LDFLAGS) -o $@ | ||
|
||
%.o: %.cpp | ||
$(CXX) -c $< $(CPPFLAGS) -o $@ | ||
|
||
clean: | ||
rm -rf $(OBJECTS) | ||
rm -rf $(APP_NAME) | ||
|
||
deploy: all | ||
scp $(APP_NAME) $(DEPLOYSSH):$(DEPLOYSSHPATH)/$(APP_NAME) | ||
ssh $(DEPLOYSSH) $(DEPLOYSSHPATH)/$(APP_NAME) | ||
|
||
|
||
.PHONY: all clean deploy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
#include "apds9301.h" | ||
|
||
#include <cstring> | ||
#include <iostream> | ||
#include <sstream> | ||
|
||
#include "fpga.h" | ||
#include "tsu.h" | ||
|
||
struct APDS9301POD { | ||
uint32_t timestamp_lo; | ||
uint32_t timestamp_hi; | ||
uint16_t value; | ||
} __attribute__((packed)); | ||
|
||
|
||
std::string APDS9301::getTopic() const { | ||
static const std::string TOPIC_NAME = "compressed/sensors/apds9301"; | ||
return TOPIC_NAME; | ||
} | ||
|
||
|
||
void APDS9301::doProcess(APDS9301Data const &data) { | ||
#ifdef NO_SENSORS | ||
// nothing to process here | ||
return; | ||
#endif | ||
|
||
// | ||
// dimm 7-segment display according to the latest light intensity | ||
// | ||
|
||
static const int SEGMENT_COUNT = 6; | ||
static const std::string CHARACTER_DEVICE = "/dev/sevensegment"; | ||
|
||
uint8_t brightness = data.value >> 8; | ||
uint8_t values[SEGMENT_COUNT] = {0}; | ||
|
||
auto _lck = lockFPGA(); | ||
|
||
// open character device | ||
auto fd = fopen(CHARACTER_DEVICE.c_str(), "wb"); | ||
if (!fd) { | ||
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl; | ||
return; | ||
} | ||
|
||
// write display values | ||
for (int i = 0; i < SEGMENT_COUNT; ++i) { | ||
if (fputc(values[i], fd) == EOF) { | ||
std::cerr << "Failed to write character (index " << i << ")" << std::endl; | ||
fclose(fd); | ||
return; | ||
} | ||
} | ||
|
||
// write brightness level | ||
if (fputc(brightness, fd) == EOF) { | ||
std::cerr << "Failed to write brightness level" << std::endl; | ||
fclose(fd); | ||
return; | ||
} | ||
|
||
// write enable bits | ||
if (fputc(0xff, fd) == EOF) { | ||
std::cerr << "Failed to write enable bits" << std::endl; | ||
fclose(fd); | ||
return; | ||
} | ||
|
||
(void) fclose(fd); | ||
} | ||
|
||
std::optional<APDS9301Data> APDS9301::doPoll() { | ||
#ifdef NO_SENSORS | ||
static int c = 0; | ||
|
||
APDS9301Data data{}; | ||
data.timeStamp = TimeStampingUnit::getCurrentTimeStamp(); | ||
data.value = 10 * c; | ||
|
||
c = (c + 1) % 100; | ||
return data; | ||
#endif | ||
|
||
static const std::string CHARACTER_DEVICE = "/dev/apds9301"; | ||
|
||
static const int READ_SIZE = sizeof(APDS9301POD); | ||
APDS9301Data results {}; | ||
APDS9301POD pod = {}; | ||
|
||
|
||
// lock fpga device using a lock guard | ||
// the result is never used, but it keeps the mutex locked until it goes out of scope | ||
auto _lck = lockFPGA(); | ||
|
||
// open character device | ||
auto fd = fopen(CHARACTER_DEVICE.c_str(), "rb"); | ||
if (!fd) { | ||
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl; | ||
return {}; | ||
} | ||
|
||
if (fread(&pod, READ_SIZE, 1, fd) != 1) { | ||
std::cerr << "Failed to read sensor values" << std::endl; | ||
return {}; | ||
} | ||
|
||
auto timestamp = (((uint64_t) pod.timestamp_hi) << 32) | pod.timestamp_lo; | ||
results.timeStamp = TimeStampingUnit::getResolvedTimeStamp(timestamp); | ||
results.value = pod.value; | ||
|
||
// close character device | ||
(void) fclose(fd); | ||
|
||
return std::make_optional(results); | ||
} | ||
|
||
std::string APDS9301Data::toJsonString() const { | ||
std::stringstream ss; | ||
ss << "{"; | ||
ss << "\"ambient_light\":" << value << ","; | ||
ss << "\"timestamp\":" << timeStamp; | ||
ss << "}"; | ||
return ss.str(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef APDS9301_H | ||
#define APDS9301_H | ||
|
||
#include "sensors.h" | ||
|
||
|
||
struct APDS9301Data : public Serializable { | ||
std::string toJsonString() const override; | ||
|
||
uint64_t timeStamp; | ||
uint16_t value; | ||
}; | ||
|
||
class APDS9301 : public StreamingSensor<APDS9301Data> { | ||
public: | ||
using StreamingSensor::StreamingSensor; | ||
|
||
std::string getTopic() const override; | ||
|
||
protected: | ||
std::optional<APDS9301Data> doPoll() override; | ||
void doProcess(APDS9301Data const &data) override; | ||
}; | ||
|
||
#endif // APDS9301_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIIEBTCCAu2gAwIBAgIUdpw+vK5pmaDJIzpinZAe9owU45gwDQYJKoZIhvcNAQEL | ||
BQAwgZExCzAJBgNVBAYTAkFVMRgwFgYDVQQIDA9PYmVyb2VzdGVycmVpY2gxEjAQ | ||
BgNVBAcMCUhhZ2VuYmVyZzEMMAoGA1UECgwDU1NMMQ4wDAYDVQQLDAVGSE9PRTEY | ||
MBYGA1UEAwwPMTkzLjE3MC4xOTIuMjI0MRwwGgYJKoZIhvcNAQkBFg1mcmFuekB0 | ||
ZXN0LmF0MB4XDTIwMDEwODA5MDgzNVoXDTI1MDEwNzA5MDgzNVowgZExCzAJBgNV | ||
BAYTAkFVMRgwFgYDVQQIDA9PYmVyb2VzdGVycmVpY2gxEjAQBgNVBAcMCUhhZ2Vu | ||
YmVyZzEMMAoGA1UECgwDU1NMMQ4wDAYDVQQLDAVGSE9PRTEYMBYGA1UEAwwPMTkz | ||
LjE3MC4xOTIuMjI0MRwwGgYJKoZIhvcNAQkBFg1mcmFuekB0ZXN0LmF0MIIBIjAN | ||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8lOPnJCOuOIMMZMkHXipDVTmpGDS | ||
X+PIktJBn2buwHb5UcOq5HyyhVu6l0b1LLKPfF4wyEW3TbueShME58UMg2+xigrN | ||
hrgHA/XUi/FhhOE1jcqaIlxZ/yVouANtiVVSGx6X1c0va0aSznp4Eo7Up7Lj2Eh8 | ||
ksWhk/r6/ylRjbyhpAJVnUkdKY2hAk72zfarAjTSpOivgfl3QoqR0ZENSkEs2Ztd | ||
2D2L05eqndEmxQTOOvIQxTCcFujTwqQFskhDpaG0cWvcgE9TzP+T9t1o1g5aTCb7 | ||
LPvdeCuGOdPkSKFXF2+YFrL1vBiKgdq5FZRBLPsIO5vq9jJND0ijP666uQIDAQAB | ||
o1MwUTAdBgNVHQ4EFgQUp8+SKO6i3q1IQrWC2Uj6KGyv6WEwHwYDVR0jBBgwFoAU | ||
p8+SKO6i3q1IQrWC2Uj6KGyv6WEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B | ||
AQsFAAOCAQEANTdqsNfWWebI+DG9QtERaXu1p+9Vv2LjYLA6mS7Z6YrFpqBYorRf | ||
EOc99RzSn4QGyvJgNAzEtM9qDNcmIzG3iKrXy+//WFkDwQu33U89SqjRBj/4T5RS | ||
Lt2xVMtcXN47vqsBZzLgkP90D7Mt7OMeh1NaOxiy3Q2QP8qQ2XXl01ZR/Q8rGelp | ||
JoEcwhgkuIni/3D9J3jjE0T4GQ0o53LJGBoAJKoIdq6FPTHK00YUMSTGC7twicKg | ||
kvD3qd/tDYnjN7azGjmJfNdG6sIj3OwYHc+2C29GbRBNWplUUHW3nmzonOgOOhak | ||
d7rPsop1H0XVXMFEWw7iBK97DcyVBChrQQ== | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#include "fpga.h" | ||
|
||
#include <libfpgaregion.h> | ||
|
||
#include <cassert> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
|
||
static std::mutex fpgaMutex; | ||
static std::unique_ptr<FpgaRegion> fpga; | ||
|
||
|
||
static void ReconfigRequested() { | ||
std::cout << "Reconfiguration in progres" << std::endl; | ||
fpgaMutex.lock(); | ||
fpga->Release(); | ||
std::cout << "Reconfiguration requested" << std::endl; | ||
} | ||
|
||
static void ReconfigDone() { | ||
std::cout << "Reconfiguration done" << std::endl; | ||
fpga->Acquire(); | ||
fpgaMutex.unlock(); | ||
} | ||
|
||
|
||
|
||
void initFPGA(std::string name) { | ||
fpga = std::make_unique<FpgaRegion>(name, ReconfigRequested, ReconfigDone); | ||
fpga->Acquire(); | ||
} | ||
|
||
|
||
std::lock_guard<std::mutex> lockFPGA() { | ||
assert(fpga); | ||
return std::lock_guard(fpgaMutex); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ifndef FPGA_H | ||
#define FPGA_H | ||
|
||
#include <mutex> | ||
#include <string> | ||
|
||
|
||
void initFPGA(std::string name); | ||
std::lock_guard<std::mutex> lockFPGA(); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#include "hdc1000.h" | ||
|
||
#include <cstring> | ||
#include <iostream> | ||
#include <sstream> | ||
|
||
#include "fpga.h" | ||
#include "tsu.h" | ||
|
||
|
||
std::string HDC1000::getTopic() const { | ||
static const std::string TOPIC_NAME = "compressed/sensors/hdc1000"; | ||
return TOPIC_NAME; | ||
} | ||
|
||
std::optional<HDC1000Data> HDC1000::doPoll() { | ||
#ifdef NO_SENSORS | ||
static int c = 0; | ||
|
||
HDC1000Data data{}; | ||
data.timeStamp = TimeStampingUnit::getCurrentTimeStamp(); | ||
data.temperature = 1 * c; | ||
data.humidity = 1 * (100 - c); | ||
|
||
c = (c + 1) % 100; | ||
return data; | ||
#endif | ||
|
||
static const std::string CHARACTER_DEVICE = "/dev/hdc1000"; | ||
|
||
static const int READ_SIZE = 12; | ||
static const int OFFSET_TEMPERATURE = 0; | ||
static const int OFFSET_HUMIDITY = OFFSET_TEMPERATURE + 2; | ||
static const int OFFSET_TIMESTAMP = OFFSET_HUMIDITY + 2; | ||
|
||
HDC1000Data results; | ||
uint16_t temperature; | ||
uint16_t humidity; | ||
uint32_t timeStamp; | ||
uint8_t readBuf[READ_SIZE]; | ||
|
||
// lock fpga device using a lock guard | ||
// the result is never used, but it keeps the mutex locked until it goes out of scope | ||
auto _lck = lockFPGA(); | ||
|
||
// open character device | ||
auto fd = fopen(CHARACTER_DEVICE.c_str(), "rb"); | ||
if (!fd) { | ||
std::cerr << "Failed to open character device '" << CHARACTER_DEVICE << "'" << std::endl; | ||
return {}; | ||
} | ||
|
||
if (fread(readBuf, READ_SIZE, 1, fd) != 1) { | ||
std::cerr << "Failed to read sensor values" << std::endl; | ||
return {}; | ||
} | ||
|
||
// copy sensor values to struct | ||
memcpy(&temperature, readBuf + OFFSET_TEMPERATURE, sizeof(temperature)); | ||
memcpy(&humidity, readBuf + OFFSET_HUMIDITY, sizeof(humidity)); | ||
memcpy(&timeStamp, readBuf + OFFSET_TIMESTAMP, sizeof(timeStamp)); | ||
|
||
|
||
|
||
results.timeStamp = TimeStampingUnit::getResolvedTimeStamp(timeStamp); | ||
// calculations according to the datasheet | ||
results.humidity = (humidity * 100) / 65536.; | ||
results.temperature = (temperature * 165) / 65536. - 40; | ||
|
||
// close character device | ||
(void) fclose(fd); | ||
|
||
return std::make_optional(results); | ||
} | ||
|
||
std::string HDC1000Data::toJsonString() const { | ||
std::stringstream ss; | ||
ss << "{"; | ||
ss << "\"tmp\":" << temperature << ","; | ||
ss << "\"hum\":" << humidity << ","; | ||
ss << "\"timestamp\":" << timeStamp; | ||
ss << "}"; | ||
return ss.str(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#ifndef HDC1000_H | ||
#define HDC1000_H | ||
|
||
#include "sensors.h" | ||
|
||
|
||
struct HDC1000Data : public Serializable { | ||
std::string toJsonString() const override; | ||
|
||
uint64_t timeStamp; | ||
double temperature; | ||
double humidity; | ||
}; | ||
|
||
class HDC1000 : public StreamingSensor<HDC1000Data> { | ||
public: | ||
using StreamingSensor::StreamingSensor; | ||
|
||
std::string getTopic() const override; | ||
|
||
protected: | ||
std::optional<HDC1000Data> doPoll() override; | ||
}; | ||
|
||
#endif // HDC1000_H |
Oops, something went wrong.