added new radio433 driver with collision detection
modified gpio class
This commit is contained in:
parent
8a90e7153d
commit
aa528079b0
@ -40,7 +40,7 @@
|
|||||||
|
|
||||||
/*! Constructs a \l{Gpio} object to represent a GPIO with the given \a gpio number and the \a parent. */
|
/*! Constructs a \l{Gpio} object to represent a GPIO with the given \a gpio number and the \a parent. */
|
||||||
Gpio::Gpio(QObject *parent, int gpio) :
|
Gpio::Gpio(QObject *parent, int gpio) :
|
||||||
QThread(parent),m_gpio(gpio)
|
QObject(parent),m_gpio(gpio)
|
||||||
{
|
{
|
||||||
exportGpio();
|
exportGpio();
|
||||||
}
|
}
|
||||||
@ -51,52 +51,6 @@ Gpio::~Gpio()
|
|||||||
unexportGpio();
|
unexportGpio();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! The starting point for the thread. After calling start(), this thread calls this function and starts
|
|
||||||
* to poll the GPIO file. If an interrupt happens to this GPIO pin, the signal pinInterrupt() gets
|
|
||||||
* emited.
|
|
||||||
*/
|
|
||||||
void Gpio::run()
|
|
||||||
{
|
|
||||||
struct pollfd fdset[2];
|
|
||||||
int gpio_fd = openGpio();
|
|
||||||
int nfds = 2;
|
|
||||||
int rc;
|
|
||||||
int timeout = 3000;
|
|
||||||
char buf[64];
|
|
||||||
|
|
||||||
bool enabled = true;
|
|
||||||
|
|
||||||
m_mutex.lock();
|
|
||||||
m_enabled = true;
|
|
||||||
m_mutex.unlock();
|
|
||||||
|
|
||||||
|
|
||||||
while(enabled){
|
|
||||||
memset((void*)fdset, 0, sizeof(fdset));
|
|
||||||
fdset[0].fd = STDIN_FILENO;
|
|
||||||
fdset[0].events = POLLIN;
|
|
||||||
|
|
||||||
fdset[1].fd = gpio_fd;
|
|
||||||
fdset[1].events = POLLPRI;
|
|
||||||
|
|
||||||
rc = poll(fdset, nfds, timeout);
|
|
||||||
|
|
||||||
if (rc < 0) {
|
|
||||||
qDebug() << "ERROR: poll failed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(rc == 0){
|
|
||||||
//timeout
|
|
||||||
}
|
|
||||||
if (fdset[1].revents & POLLPRI) {
|
|
||||||
read(fdset[1].fd, buf, 64);
|
|
||||||
emit pinInterrupt();
|
|
||||||
}
|
|
||||||
m_mutex.lock();
|
|
||||||
enabled = m_enabled;
|
|
||||||
m_mutex.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*! Returns true if the GPIO could be exported in the system file "/sys/class/gpio/export".*/
|
/*! Returns true if the GPIO could be exported in the system file "/sys/class/gpio/export".*/
|
||||||
bool Gpio::exportGpio()
|
bool Gpio::exportGpio()
|
||||||
{
|
{
|
||||||
@ -321,11 +275,3 @@ bool Gpio::setEdgeInterrupt(int edge)
|
|||||||
close(fd);
|
close(fd);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Stop the polling of the \l{run()} method.*/
|
|
||||||
void Gpio::stop()
|
|
||||||
{
|
|
||||||
m_mutex.lock();
|
|
||||||
m_enabled = false;
|
|
||||||
m_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|||||||
@ -68,15 +68,13 @@
|
|||||||
**********************************
|
**********************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Gpio : public QThread
|
class Gpio : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Gpio(QObject *parent = 0, int gpio = 0);
|
explicit Gpio(QObject *parent = 0, int gpio = 0);
|
||||||
~Gpio();
|
~Gpio();
|
||||||
|
|
||||||
void run() override;
|
|
||||||
|
|
||||||
bool exportGpio();
|
bool exportGpio();
|
||||||
bool unexportGpio();
|
bool unexportGpio();
|
||||||
|
|
||||||
@ -87,17 +85,12 @@ public:
|
|||||||
int getValue();
|
int getValue();
|
||||||
|
|
||||||
bool setEdgeInterrupt(int edge);
|
bool setEdgeInterrupt(int edge);
|
||||||
void stop();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_gpio;
|
int m_gpio;
|
||||||
int m_dir;
|
int m_dir;
|
||||||
QMutex m_mutex;
|
|
||||||
bool m_enabled;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/*! This signal is emited if the INPUT value changed, depending on the edge set in \l{setEdgeInterrupt}*/
|
|
||||||
void pinInterrupt();
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
|||||||
@ -20,160 +20,43 @@
|
|||||||
\class Radio433
|
\class Radio433
|
||||||
\brief The Radio433 class helps to interact with the 433 MHz Receiver and Transmitter.
|
\brief The Radio433 class helps to interact with the 433 MHz Receiver and Transmitter.
|
||||||
|
|
||||||
\l{http://tech.jolowe.se/home-automation-rf-protocols/}
|
|
||||||
|
|
||||||
\inmodule libguh
|
\inmodule libguh
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "radio433.h"
|
#include "radio433.h"
|
||||||
#include <QDebug>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*! Constructs a \l{Radio433} object with the given \a parent and initializes the \l{Gpio} pins
|
|
||||||
* for the transmitter and the receiver.
|
|
||||||
*/
|
|
||||||
Radio433::Radio433(QObject *parent) :
|
Radio433::Radio433(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
// Set up receiver
|
m_receiver = new Radio433Receiver();
|
||||||
m_receiver = new Gpio(this,27);
|
m_transmitter = new Radio433Trasmitter();
|
||||||
m_receiver->setDirection(INPUT);
|
|
||||||
m_receiver->setEdgeInterrupt(EDGE_BOTH);
|
|
||||||
|
|
||||||
// Set up transmitter
|
connect(m_receiver,SIGNAL(readingChanged(bool)),this,SLOT(readingChanged(bool)));
|
||||||
m_transmitter = new Gpio(this,22);
|
|
||||||
m_transmitter->setDirection(OUTPUT);
|
|
||||||
m_transmitter->setValue(LOW);
|
|
||||||
|
|
||||||
connect(m_receiver, &Gpio::pinInterrupt, this, &Radio433::handleInterrupt);
|
m_receiver->startReceiver();
|
||||||
|
m_transmitter->startTransmitter();
|
||||||
m_receiver->start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Destroyes the \l{Radio433} object and stops the running threads. */
|
|
||||||
Radio433::~Radio433()
|
Radio433::~Radio433()
|
||||||
{
|
{
|
||||||
m_receiver->quit();
|
|
||||||
m_receiver->wait();
|
m_receiver->wait();
|
||||||
|
m_receiver->quit();
|
||||||
|
|
||||||
|
m_transmitter->wait();
|
||||||
|
m_transmitter->quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433::readingChanged(bool reading)
|
||||||
|
{
|
||||||
|
if(reading){
|
||||||
|
m_transmitter->allowSending(false);
|
||||||
|
}else{
|
||||||
|
m_transmitter->allowSending(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Sends the given \a rawData over the transmitter. The sync signal has to be already in the
|
|
||||||
* \a rawData.
|
|
||||||
*/
|
|
||||||
void Radio433::sendData(QList<int> rawData)
|
void Radio433::sendData(QList<int> rawData)
|
||||||
{
|
{
|
||||||
|
m_transmitter->sendData(rawData);
|
||||||
//first we have to disable our receiver, to prevent reading this signal
|
|
||||||
m_receiver->stop();
|
|
||||||
|
|
||||||
m_transmitter->setValue(LOW);
|
|
||||||
int flag=1;
|
|
||||||
|
|
||||||
for(int i = 0; i <= 8; i++){
|
|
||||||
foreach (int delay, rawData) {
|
|
||||||
// 1 = High, 0 = Low
|
|
||||||
m_transmitter->setValue(flag %2);
|
|
||||||
flag++;
|
|
||||||
delayMicros(delay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_transmitter->setValue(LOW);
|
|
||||||
// re-enable it
|
|
||||||
m_transmitter->setValue(LOW);
|
|
||||||
m_receiver->start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Returns the current system time in microseconds. */
|
|
||||||
int Radio433::micros()
|
|
||||||
{
|
|
||||||
struct timeval tv ;
|
|
||||||
int now ;
|
|
||||||
|
|
||||||
gettimeofday (&tv, NULL) ;
|
|
||||||
now = (int)tv.tv_sec * (int)1000000 + (int)tv.tv_usec ;
|
|
||||||
|
|
||||||
return (int)(now - m_epochMicro) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Creates a delay of a certain time (\a microSeconds). */
|
|
||||||
void Radio433::delayMicros(int microSeconds)
|
|
||||||
{
|
|
||||||
struct timespec sleeper;
|
|
||||||
|
|
||||||
sleeper.tv_sec = 0;
|
|
||||||
sleeper.tv_nsec = (long)(microSeconds * 1000);
|
|
||||||
|
|
||||||
nanosleep (&sleeper, NULL) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! This method handels an interrupt on the receiver pin and recognizes, if a valid message of
|
|
||||||
* 48 bit or 64 bit was received.
|
|
||||||
*/
|
|
||||||
void Radio433::handleInterrupt()
|
|
||||||
{
|
|
||||||
long currentTime = micros();
|
|
||||||
m_duration = currentTime - m_lastTime;
|
|
||||||
|
|
||||||
// filter nois
|
|
||||||
if (m_duration > 5000 && m_duration > m_timings[0] - 200 && m_duration < m_timings[0] + 200) {
|
|
||||||
|
|
||||||
m_repeatCount++;
|
|
||||||
m_changeCount--;
|
|
||||||
|
|
||||||
if(m_repeatCount == 2) {
|
|
||||||
// if we have a regular signal (1 bit sync + 48 bit data or 1bit sync + 64 bit data)
|
|
||||||
if(m_changeCount == 49 || m_changeCount == 65){
|
|
||||||
QList<int> rawData;
|
|
||||||
|
|
||||||
switch (m_changeCount) {
|
|
||||||
case 49:
|
|
||||||
// write rawdata to a List and reset values to 0
|
|
||||||
for(int i = 0; i < 49; i++ ){
|
|
||||||
rawData.append(m_timings[i]);
|
|
||||||
m_timings[i] = 0;
|
|
||||||
}
|
|
||||||
qDebug() << "-----------------------------------------------------------";
|
|
||||||
qDebug() << "| GENERIC signal |";
|
|
||||||
qDebug() << "-----------------------------------------------------------";
|
|
||||||
qDebug() << "signal length :" << 49;
|
|
||||||
qDebug() << "delay :" << rawData.first() /31;
|
|
||||||
qDebug() << rawData;
|
|
||||||
|
|
||||||
emit dataReceived(rawData);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 65:
|
|
||||||
// write rawdata to a List and reset values to 0
|
|
||||||
for(int i = 0; i < 65; i++ ){
|
|
||||||
rawData.append(m_timings[i]);
|
|
||||||
m_timings[i] = 0;
|
|
||||||
}
|
|
||||||
qDebug() << "-----------------------------------------------------------";
|
|
||||||
qDebug() << "| GENERIC signal |";
|
|
||||||
qDebug() << "-----------------------------------------------------------";
|
|
||||||
qDebug() << "signal length :" << 65;
|
|
||||||
qDebug() << "delay :" << rawData.first() /10;
|
|
||||||
qDebug() << rawData;
|
|
||||||
|
|
||||||
emit dataReceived(rawData);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_repeatCount = 0;
|
|
||||||
}
|
|
||||||
m_changeCount = 0;
|
|
||||||
|
|
||||||
}else if(m_duration > 5000){
|
|
||||||
m_changeCount = 0;
|
|
||||||
}
|
|
||||||
if (m_changeCount >= RC_MAX_CHANGES) {
|
|
||||||
m_changeCount = 0;
|
|
||||||
m_repeatCount = 0;
|
|
||||||
}
|
|
||||||
m_timings[m_changeCount++] = m_duration;
|
|
||||||
m_lastTime = currentTime;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,48 +17,34 @@
|
|||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
#ifndef RADIO433_H
|
#ifndef RADIO433_H
|
||||||
#define RADIO433_h
|
#define RADIO433_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QThread>
|
|
||||||
#include <hardware/gpio.h>
|
|
||||||
|
|
||||||
#define RC_MAX_CHANGES 67
|
#include "radio433receiver.h"
|
||||||
|
#include "radio433transmitter.h"
|
||||||
|
|
||||||
class Radio433: public QObject
|
class Radio433 : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Radio433(QObject *parent = 0);
|
explicit Radio433(QObject *parent = 0);
|
||||||
~Radio433();
|
~Radio433();
|
||||||
|
|
||||||
public:
|
|
||||||
void sendData(QList<int> rawData);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Gpio *m_receiver;
|
Radio433Receiver *m_receiver;
|
||||||
Gpio *m_transmitter;
|
Radio433Trasmitter *m_transmitter;
|
||||||
|
|
||||||
unsigned int m_timings[RC_MAX_CHANGES];
|
|
||||||
unsigned int m_duration;
|
|
||||||
unsigned int m_changeCount;
|
|
||||||
unsigned long m_lastTime;
|
|
||||||
unsigned int m_repeatCount;
|
|
||||||
unsigned int m_epochMicro;
|
|
||||||
|
|
||||||
int micros();
|
|
||||||
void delayMicros(int microSeconds);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void handleInterrupt();
|
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/*! This signal is emitted whenever a valid signal of 48 bits was recognized over the
|
|
||||||
* 433 MHz receiver. The sync signal and the message are in the integer list \a rawData.
|
|
||||||
*/
|
|
||||||
void dataReceived(QList<int> rawData);
|
void dataReceived(QList<int> rawData);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void readingChanged(bool reading);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void sendData(QList<int> rawData);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // RADIO433_H
|
||||||
|
|
||||||
|
|||||||
244
libguh/hardware/radio433receiver.cpp
Normal file
244
libguh/hardware/radio433receiver.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* This file is part of guh. *
|
||||||
|
* *
|
||||||
|
* Guh is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, version 2 of the License. *
|
||||||
|
* *
|
||||||
|
* Guh is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileSystemWatcher>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include "radio433receiver.h"
|
||||||
|
|
||||||
|
Radio433Receiver::Radio433Receiver(QObject *parent, int gpio) :
|
||||||
|
QThread(parent),m_gpioPin(gpio)
|
||||||
|
{
|
||||||
|
stopReceiver();
|
||||||
|
|
||||||
|
connect(this,SIGNAL(timingReady(int)),this,SLOT(handleTiming(int)),Qt::DirectConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Radio433Receiver::~Radio433Receiver()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Receiver::startReceiver()
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
m_enabled = true;
|
||||||
|
m_mutex.unlock();
|
||||||
|
|
||||||
|
m_timings.clear();
|
||||||
|
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Receiver::stopReceiver()
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
m_enabled = false;
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Receiver::run()
|
||||||
|
{
|
||||||
|
// init the gpio
|
||||||
|
setUpGpio();
|
||||||
|
|
||||||
|
struct pollfd fdset[2];
|
||||||
|
int gpio_fd = m_gpio->openGpio();
|
||||||
|
char buf[1];
|
||||||
|
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
|
m_mutex.lock();
|
||||||
|
m_enabled = true;
|
||||||
|
m_mutex.unlock();
|
||||||
|
|
||||||
|
int lastTime = micros();
|
||||||
|
// poll the gpio file, if something changes...emit the signal wit the current pulse length
|
||||||
|
while(enabled){
|
||||||
|
memset((void*)fdset, 0, sizeof(fdset));
|
||||||
|
fdset[0].fd = STDIN_FILENO;
|
||||||
|
fdset[0].events = POLLIN;
|
||||||
|
|
||||||
|
fdset[1].fd = gpio_fd;
|
||||||
|
fdset[1].events = POLLPRI;
|
||||||
|
int rc = poll(fdset, 2, 3000);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
|
qDebug() << "ERROR: poll failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(rc == 0){
|
||||||
|
//timeout
|
||||||
|
}
|
||||||
|
if (fdset[1].revents & POLLPRI){
|
||||||
|
read(fdset[1].fd, buf, 1);
|
||||||
|
int currentTime = micros();
|
||||||
|
int duration = currentTime - lastTime;
|
||||||
|
lastTime = currentTime;
|
||||||
|
emit timingReady(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_mutex.lock();
|
||||||
|
enabled = m_enabled;
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Radio433Receiver::setUpGpio()
|
||||||
|
{
|
||||||
|
m_gpio = new Gpio(this,m_gpioPin);
|
||||||
|
m_gpio->setDirection(INPUT);
|
||||||
|
m_gpio->setEdgeInterrupt(EDGE_BOTH);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Radio433Receiver::micros()
|
||||||
|
{
|
||||||
|
struct timeval tv ;
|
||||||
|
int now ;
|
||||||
|
gettimeofday (&tv, NULL) ;
|
||||||
|
now = (int)tv.tv_sec * (int)1000000 + (int)tv.tv_usec ;
|
||||||
|
|
||||||
|
return (int)(now - m_epochMicro) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Radio433Receiver::valueInTolerance(int value, int sollValue)
|
||||||
|
{
|
||||||
|
// in in range of +- 35% of sollValue return true, eles return false
|
||||||
|
if(value >= (double)sollValue-200 && value <= (double)sollValue+200){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Radio433Receiver::checkValue(int value)
|
||||||
|
{
|
||||||
|
if(valueInTolerance(value,m_pulseProtocolOne) || valueInTolerance(value,2*m_pulseProtocolOne) || valueInTolerance(value,3*m_pulseProtocolOne) || valueInTolerance(value,4*m_pulseProtocolOne) || valueInTolerance(value,8*m_pulseProtocolOne)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(valueInTolerance(value,m_pulseProtocolTwo) || valueInTolerance(value,2*m_pulseProtocolTwo) || valueInTolerance(value,3*m_pulseProtocolTwo) || valueInTolerance(value,4*m_pulseProtocolTwo) || valueInTolerance(value,8*m_pulseProtocolTwo)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Radio433Receiver::checkValues(Protocol protocol)
|
||||||
|
{
|
||||||
|
switch (protocol) {
|
||||||
|
case Protocol48:
|
||||||
|
for(int i = 1; i < m_timings.count(); i++){
|
||||||
|
if(!(valueInTolerance(m_timings.at(i),m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),2*m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),3*m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),4*m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),8*m_pulseProtocolOne))){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
case Protocol64:
|
||||||
|
for(int i = 1; i < m_timings.count(); i++){
|
||||||
|
if(!(valueInTolerance(m_timings.at(i),m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),2*m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),3*m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),4*m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),8*m_pulseProtocolTwo))){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Receiver::changeReading(bool reading)
|
||||||
|
{
|
||||||
|
if(reading != m_reading){
|
||||||
|
m_reading = reading;
|
||||||
|
emit readingChanged(reading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Receiver::handleTiming(int duration)
|
||||||
|
{
|
||||||
|
|
||||||
|
// to short...
|
||||||
|
if(duration < 50){
|
||||||
|
changeReading(false);
|
||||||
|
m_timings.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// could by a sync signal...
|
||||||
|
bool sync = false;
|
||||||
|
if(duration > 2400 && duration < 14000){
|
||||||
|
changeReading(false);
|
||||||
|
sync = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// got sync signal and list is not empty...
|
||||||
|
if(!m_timings.isEmpty() && sync){
|
||||||
|
// 1 sync bit + 48 data bit
|
||||||
|
if(m_timings.count() == 49 && checkValues(Protocol48)){
|
||||||
|
qDebug() << "48 bit ->" << m_timings << "\n--------------------------";
|
||||||
|
changeReading(false);
|
||||||
|
emit dataReceived(m_timings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 sync bit + 64 data bit
|
||||||
|
if(m_timings.count() == 65 && checkValues(Protocol64)){
|
||||||
|
qDebug() << "64 bit ->" << m_timings << "\n--------------------------";
|
||||||
|
changeReading(false);
|
||||||
|
emit dataReceived(m_timings);
|
||||||
|
}
|
||||||
|
m_timings.clear();
|
||||||
|
m_pulseProtocolOne = 0;
|
||||||
|
m_pulseProtocolTwo = 0;
|
||||||
|
changeReading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// got sync signal and list is empty...
|
||||||
|
if(m_timings.isEmpty() && sync){
|
||||||
|
m_timings.append(duration);
|
||||||
|
m_pulseProtocolOne = (int)((double)m_timings.first()/31);
|
||||||
|
m_pulseProtocolTwo = (int)((double)m_timings.first()/10);
|
||||||
|
changeReading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// list not empty and this is a possible value
|
||||||
|
if(!m_timings.isEmpty() && checkValue(duration)){
|
||||||
|
m_timings.append(duration);
|
||||||
|
|
||||||
|
// check if it could be a signal -> if we have a sync and 15 valid values
|
||||||
|
// set reading true to prevent a collision from own transmitter
|
||||||
|
if(m_timings.count() > 20 && (checkValues(Protocol48) || checkValues(Protocol64))){
|
||||||
|
changeReading(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we have allready a vallid protocol
|
||||||
|
// 1 sync bit + 48 data bit
|
||||||
|
if(m_timings.count() == 49 && checkValues(Protocol48)){
|
||||||
|
qDebug() << "48 bit -> " << m_timings << "\n--------------------------";
|
||||||
|
emit dataReceived(m_timings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 sync bit + 64 data bit
|
||||||
|
if(m_timings.count() == 65 && checkValues(Protocol64)){
|
||||||
|
qDebug() << "64 bit -> " << m_timings << "\n--------------------------";
|
||||||
|
changeReading(false);
|
||||||
|
emit dataReceived(m_timings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
libguh/hardware/radio433receiver.h
Normal file
75
libguh/hardware/radio433receiver.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* This file is part of guh. *
|
||||||
|
* *
|
||||||
|
* Guh is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, version 2 of the License. *
|
||||||
|
* *
|
||||||
|
* Guh is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef RADIO433RECEIVER_H
|
||||||
|
#define RADIO433RECEIVER_H
|
||||||
|
|
||||||
|
#include <QThread>
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
class Radio433Receiver : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Radio433Receiver(QObject *parent = 0, int gpio = 27);
|
||||||
|
~Radio433Receiver();
|
||||||
|
|
||||||
|
enum Protocol{
|
||||||
|
Protocol48,
|
||||||
|
Protocol64,
|
||||||
|
ProtocolNone
|
||||||
|
};
|
||||||
|
|
||||||
|
void startReceiver();
|
||||||
|
void stopReceiver();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_gpioPin;
|
||||||
|
Gpio *m_gpio;
|
||||||
|
unsigned int m_epochMicro;
|
||||||
|
|
||||||
|
unsigned int m_pulseProtocolOne;
|
||||||
|
unsigned int m_pulseProtocolTwo;
|
||||||
|
|
||||||
|
QList<int> m_timings;
|
||||||
|
|
||||||
|
QMutex m_mutex;
|
||||||
|
bool m_enabled;
|
||||||
|
bool m_reading;
|
||||||
|
|
||||||
|
void run();
|
||||||
|
bool setUpGpio();
|
||||||
|
int micros();
|
||||||
|
bool valueInTolerance(int value, int sollValue);
|
||||||
|
bool checkValue(int value);
|
||||||
|
bool checkValues(Protocol protocol);
|
||||||
|
void changeReading(bool reading);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleTiming(int duration);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void timingReady(int duration);
|
||||||
|
void dataReceived(QList<int> rawData);
|
||||||
|
void readingChanged(const bool &reading);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RADIO433RECEIVER_H
|
||||||
120
libguh/hardware/radio433transmitter.cpp
Normal file
120
libguh/hardware/radio433transmitter.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* This file is part of guh. *
|
||||||
|
* *
|
||||||
|
* Guh is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, version 2 of the License. *
|
||||||
|
* *
|
||||||
|
* Guh is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#include "radio433transmitter.h"
|
||||||
|
|
||||||
|
Radio433Trasmitter::Radio433Trasmitter(QObject *parent, int gpio) :
|
||||||
|
QThread(parent),m_gpioPin(gpio)
|
||||||
|
{
|
||||||
|
stopTransmitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
Radio433Trasmitter::~Radio433Trasmitter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Trasmitter::startTransmitter()
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
m_enabled = true;
|
||||||
|
m_mutex.unlock();
|
||||||
|
|
||||||
|
run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Trasmitter::stopTransmitter()
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
m_enabled = false;
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Trasmitter::run()
|
||||||
|
{
|
||||||
|
bool enabled = true;
|
||||||
|
|
||||||
|
m_mutex.lock();
|
||||||
|
m_enabled = true;
|
||||||
|
m_mutex.unlock();
|
||||||
|
|
||||||
|
QList<int> rawData;
|
||||||
|
|
||||||
|
while(enabled){
|
||||||
|
|
||||||
|
m_queueMutex.lock();
|
||||||
|
m_allowSendingMutex.lock();
|
||||||
|
//check if we have data in the sending queue and we are allowed to send...
|
||||||
|
if(!m_rawDataQueue.isEmpty() && m_allowSending){
|
||||||
|
m_allowSendingMutex.unlock();
|
||||||
|
|
||||||
|
rawData = m_rawDataQueue.dequeue();
|
||||||
|
m_queueMutex.unlock();
|
||||||
|
|
||||||
|
m_gpio->setValue(LOW);
|
||||||
|
int flag=1;
|
||||||
|
|
||||||
|
// send raw data 8 times
|
||||||
|
for(int i = 0; i <= 8; i++){
|
||||||
|
foreach (int delay, rawData) {
|
||||||
|
// 1 = High, 0 = Low
|
||||||
|
m_gpio->setValue(flag %2);
|
||||||
|
flag++;
|
||||||
|
usleep(delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if we can continue or we should stop
|
||||||
|
m_allowSendingMutex.lock();
|
||||||
|
if(!m_allowSending){
|
||||||
|
m_allowSendingMutex.unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_allowSendingMutex.unlock();
|
||||||
|
}
|
||||||
|
m_gpio->setValue(LOW);
|
||||||
|
}
|
||||||
|
m_queueMutex.unlock();
|
||||||
|
m_allowSendingMutex.unlock();
|
||||||
|
|
||||||
|
m_mutex.lock();
|
||||||
|
enabled = m_enabled;
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Trasmitter::allowSending(bool sending)
|
||||||
|
{
|
||||||
|
m_allowSendingMutex.lock();
|
||||||
|
m_allowSending = sending;
|
||||||
|
m_allowSendingMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Radio433Trasmitter::setUpGpio()
|
||||||
|
{
|
||||||
|
m_gpio = new Gpio(this,m_gpioPin);
|
||||||
|
if(!m_gpio->setDirection(OUTPUT) || m_gpio->setValue(LOW)){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Radio433Trasmitter::sendData(QList<int> rawData)
|
||||||
|
{
|
||||||
|
m_queueMutex.lock();
|
||||||
|
m_rawDataQueue.enqueue(rawData);
|
||||||
|
m_queueMutex.unlock();
|
||||||
|
}
|
||||||
66
libguh/hardware/radio433transmitter.h
Normal file
66
libguh/hardware/radio433transmitter.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
|
* *
|
||||||
|
* This file is part of guh. *
|
||||||
|
* *
|
||||||
|
* Guh is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation, version 2 of the License. *
|
||||||
|
* *
|
||||||
|
* Guh is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with guh. If not, see <http://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
#ifndef RADIO433TRASMITTER_H
|
||||||
|
#define RADIO433TRASMITTER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMutex>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include "gpio.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Radio433Trasmitter : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit Radio433Trasmitter(QObject *parent = 0, int gpio = 22);
|
||||||
|
~Radio433Trasmitter();
|
||||||
|
|
||||||
|
void startTransmitter();
|
||||||
|
void stopTransmitter();
|
||||||
|
|
||||||
|
void sendData(QList<int> rawData);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_gpioPin;
|
||||||
|
Gpio *m_gpio;
|
||||||
|
|
||||||
|
QMutex m_mutex;
|
||||||
|
bool m_enabled;
|
||||||
|
|
||||||
|
QMutex m_allowSendingMutex;
|
||||||
|
bool m_allowSending;
|
||||||
|
|
||||||
|
void run();
|
||||||
|
bool setUpGpio();
|
||||||
|
|
||||||
|
QMutex m_queueMutex;
|
||||||
|
QQueue<QList<int> > m_rawDataQueue;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void allowSending(bool sending);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RADIO433TRASMITTER_H
|
||||||
@ -13,8 +13,10 @@ SOURCES += plugin/device.cpp \
|
|||||||
plugin/deviceplugin.cpp \
|
plugin/deviceplugin.cpp \
|
||||||
plugin/devicedescriptor.cpp \
|
plugin/devicedescriptor.cpp \
|
||||||
devicemanager.cpp \
|
devicemanager.cpp \
|
||||||
hardware/radio433.cpp \
|
|
||||||
hardware/gpio.cpp \
|
hardware/gpio.cpp \
|
||||||
|
hardware/radio433.cpp \
|
||||||
|
hardware/radio433transmitter.cpp \
|
||||||
|
hardware/radio433receiver.cpp \
|
||||||
types/action.cpp \
|
types/action.cpp \
|
||||||
types/actiontype.cpp \
|
types/actiontype.cpp \
|
||||||
types/state.cpp \
|
types/state.cpp \
|
||||||
@ -26,15 +28,17 @@ SOURCES += plugin/device.cpp \
|
|||||||
types/paramtype.cpp \
|
types/paramtype.cpp \
|
||||||
types/param.cpp \
|
types/param.cpp \
|
||||||
types/paramdescriptor.cpp \
|
types/paramdescriptor.cpp \
|
||||||
types/statedescriptor.cpp
|
types/statedescriptor.cpp \
|
||||||
|
|
||||||
HEADERS += plugin/device.h \
|
HEADERS += plugin/device.h \
|
||||||
plugin/deviceclass.h \
|
plugin/deviceclass.h \
|
||||||
plugin/deviceplugin.h \
|
plugin/deviceplugin.h \
|
||||||
plugin/devicedescriptor.h \
|
plugin/devicedescriptor.h \
|
||||||
devicemanager.h \
|
devicemanager.h \
|
||||||
hardware/radio433.h \
|
|
||||||
hardware/gpio.h \
|
hardware/gpio.h \
|
||||||
|
hardware/radio433.h \
|
||||||
|
hardware/radio433transmitter.h \
|
||||||
|
hardware/radio433receiver.h \
|
||||||
types/action.h \
|
types/action.h \
|
||||||
types/actiontype.h \
|
types/actiontype.h \
|
||||||
types/state.h \
|
types/state.h \
|
||||||
@ -47,5 +51,5 @@ HEADERS += plugin/device.h \
|
|||||||
types/paramtype.h \
|
types/paramtype.h \
|
||||||
types/param.h \
|
types/param.h \
|
||||||
types/paramdescriptor.h \
|
types/paramdescriptor.h \
|
||||||
types/statedescriptor.h
|
types/statedescriptor.h \
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,11 @@ TcpServer::TcpServer(QObject *parent) :
|
|||||||
qDebug() << "network interfaces:";
|
qDebug() << "network interfaces:";
|
||||||
foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()){
|
foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()){
|
||||||
qDebug() << " -------------------------";
|
qDebug() << " -------------------------";
|
||||||
qDebug() << " name:" << interface.name();
|
qDebug() << " name :" << interface.name();
|
||||||
qDebug() << " mac: " << interface.hardwareAddress();
|
if(!interface.addressEntries().isEmpty()){
|
||||||
|
qDebug() << " ip :" << interface.addressEntries().first().ip().toString();
|
||||||
|
}
|
||||||
|
qDebug() << " mac : " << interface.hardwareAddress();
|
||||||
}
|
}
|
||||||
qDebug() << "----------------------------";
|
qDebug() << "----------------------------";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user