radioreceiver has now a singleton for the pin interrupts

pull/1/head
Simon Stuerz 2013-08-25 13:59:10 +02:00
parent df6ce3af06
commit 94580e3925
6 changed files with 400 additions and 280 deletions

View File

@ -11,5 +11,8 @@ HiveClientCore::HiveClientCore(QObject *parent) :
m_client->connectToHost("10.10.10.40","1234"); m_client->connectToHost("10.10.10.40","1234");
m_viewer = new QtQuick2ApplicationViewer; m_viewer = new QtQuick2ApplicationViewer;
m_viewer->setMainQmlFile(QStringLiteral("qml/hive_client/main.qml"));
m_viewer->showExpanded(); m_viewer->showExpanded();
} }

View File

@ -1,40 +1,41 @@
import QtQuick 2.0 import QtQuick 2.0
import QtQuick.Controls 1.0 import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0 import QtQuick.Layouts 1.0
import QtQuick.Window 2.0
Rectangle{ ApplicationWindow{
id: mainItem id: mainItem
title: "Hive Client"
width: 600 width: 600
height: 360 height: 360
ColumnLayout { // ColumnLayout {
id: mainLayout // id: mainLayout
anchors.fill: parent // anchors.fill: parent
GroupBox{ // GroupBox{
id: connectionBox // id: connectionBox
title: "Connection" // title: "Connection"
anchors.horizontalCenter: parent.horizontalCenter // anchors.horizontalCenter: parent.horizontalCenter
RowLayout{ // RowLayout{
Button{ // Button{
id: connectionButton // id: connectionButton
text: "Connect" // text: "Connect"
} // }
TextInput{ // TextInput{
id: ipText // id: ipText
text: "10.10.10.40" // text: "10.10.10.40"
} // }
TextInput{ // TextInput{
id: portText // id: portText
text: "1234" // text: "1234"
} // }
} // }
} // }
} // }
@ -46,8 +47,6 @@ Rectangle{
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
} }

View File

@ -21,6 +21,7 @@ HiveCore::HiveCore(QObject *parent) :
// create 433.92 MHz receiver // create 433.92 MHz receiver
m_reciver = new RadioReciver(this); m_reciver = new RadioReciver(this);
m_reciver->setFrequency(RadioReciver::RF433MHz); m_reciver->setFrequency(RadioReciver::RF433MHz);
m_reciver->setPin(2);
m_reciver->enableReceiver(); m_reciver->enableReceiver();

View File

@ -6,282 +6,389 @@
#include <QStringList> #include <QStringList>
#include <QDateTime> #include <QDateTime>
static bool m_enable = false;
static unsigned int timings[RC_MAX_CHANGES];
static float lastTemperature = 0; static float lastTemperature = 0;
// #####################################################################################################
// this class handels the interrupts from the INPUT Pins
class ISRHandler{
private:
static ISRHandler* s_instance;
ISRHandler(){
if(wiringPiSetup() == -1){
qDebug() << "ERROR: GPIO setup for 433.92 MHz receiver failed.";
}
qDebug() << "GPIO setup for receiver ok.";
}
// one handler for each pin
// on pin 0
static void handleInterrupt0(){
}
// on pin 1
static void handleInterrupt1(){
}
// on pin 2
static void handleInterrupt2(){
foreach (RadioReciver *receiver, s_receivers){
if(receiver->getPin() == 2){
receiver->handleInterrupt();
}
}
}
// ... and so on -> implement if needed
static QList<RadioReciver*> s_receivers;
public:
// create a instance if not allready created
static ISRHandler* instance(){
if(!s_instance){
s_instance = new ISRHandler();
}
return s_instance;
}
// register a receiver
void registerReceiver(RadioReciver* receiver){
bool pinAllreadyRegistred = false;
foreach (RadioReciver* tmpReceiver, s_receivers) {
if(tmpReceiver->getPin() == receiver->getPin()){
pinAllreadyRegistred = true;
}
}
int ok = 0;
if(!pinAllreadyRegistred){
pinMode(receiver->getPin(),INPUT);
// TODO: for more pins I would need more interruptHandlerX...
switch (receiver->getPin()) {
case 0:
ok = wiringPiISR(receiver->getPin(), INT_EDGE_BOTH, &handleInterrupt0);
break;
case 1:
ok = wiringPiISR(receiver->getPin(), INT_EDGE_BOTH, &handleInterrupt1);
break;
case 2:
ok = wiringPiISR(receiver->getPin(), INT_EDGE_BOTH, &handleInterrupt2);
break;
default:
break;
}
}
// check if register the ISR for this pin worked, else the programm exit...
if(ok != -1){
s_receivers.append(receiver);
}
}
void unregisterReceiver(RadioReciver* receiver){
// TODO: delete ISR wiringPi??
s_receivers.removeAll(receiver);
}
};
ISRHandler* ISRHandler::s_instance = 0;
QList<RadioReciver*> ISRHandler::s_receivers;
// #####################################################################################################
// The main RadioReceiver class
RadioReciver::RadioReciver(QObject *parent) : RadioReciver::RadioReciver(QObject *parent) :
QObject(parent) QObject(parent)
{ {
m_enable = false;
m_pin = -1;
m_duration = 0;
m_changeCount = 0;
m_lastTime = 0;
m_repeatCount = 0;
for(int i = 0; i < RC_MAX_CHANGES; i++ ){
m_timings[i] = 0;
}
} }
void RadioReciver::setFrequency(RadioReciver::Frequency frequency)
{
m_frequency = frequency;
}
RadioReciver::Frequency RadioReciver::getFrequency() const
{
return m_frequency;
}
void RadioReciver::setPin(int pin)
{
m_pin = pin;
}
int RadioReciver::getPin() const
{
return m_pin;
}
void RadioReciver::handleInterrupt() void RadioReciver::handleInterrupt()
{
}
void RadioReciver::handleRC433Interrupt()
{ {
if(!m_enable){ if(!m_enable){
return; return;
} }
static unsigned int duration; long currentTime = micros();
static unsigned int changeCount; m_duration = currentTime - m_lastTime;
static unsigned long lastTime;
static unsigned int repeatCount;
long time = micros();
duration = time - lastTime;
// filter nois // filter nois
if (duration > 5000 && duration > timings[0] - 200 && duration < timings[0] + 200) { if (m_duration > 5000 && m_duration > m_timings[0] - 200 && m_duration < m_timings[0] + 200) {
repeatCount++; m_repeatCount++;
changeCount--; m_changeCount--;
if(repeatCount == 2) {
detectProtocol(changeCount);
if(m_repeatCount == 2) {
// if we have a regular signal (1 bit sync + 48 bit data)
if(m_changeCount == RC_MAX_CHANGES){
// write rawdata to a List and reset values to 0
QList<int> rawData;
for(int i = 0; i < RC_MAX_CHANGES; i++ ){ for(int i = 0; i < RC_MAX_CHANGES; i++ ){
timings[i] = 0; rawData.append(m_timings[i]);
m_timings[i] = 0;
}
detectProtocol(rawData);
}
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;
} }
repeatCount = 0; void RadioReciver::detectProtocol(QList<int> rawData)
}
changeCount = 0;
}else if(duration > 5000){
changeCount = 0;
}
if (changeCount >= RC_MAX_CHANGES) {
changeCount = 0;
repeatCount = 0;
}
timings[changeCount++] = duration;
lastTime = time;
}
void RadioReciver::handleRC868Interrupt()
{ {
}
void RadioReciver::detectProtocol(int signalCount)
{
if(signalCount < 49){
//qDebug() << "ERROR: got a signal with just" << signalCount << "signals";
return;
}
qDebug() << "==========================================================================="; qDebug() << "===========================================================================";
QList <int> rawData; qDebug() <<"VALID SIGNAL (48 bit)" << " --> pulse width =" << rawData.first()/31;
qDebug() << rawData;
// go trough all 49 timings
for(int i = 0; i <= 48; i+=1 ){
rawData.append(timings[i]);
}
qDebug() << "raw data:" << rawData;
unsigned long delay = timings[0] / 31;
// #########################################################################
if(delay > 250 && delay < 260){
qDebug() << "-----------------------------------------------------------";
qDebug() << " seems to be a TERMOMETER signal";
qDebug() << "-----------------------------------------------------------";
qDebug() << "delay :" << delay;
qDebug() << "bits :" << signalCount-1;
QByteArray binCode;
// __
// | |________ = 0 1100000000
// __
// | |________________ = 1 110000000000000000
for(int i = 1; i <= 48; i+=2 ){
if(timings[i] < 1000 && timings[i+1] < 3000 && timings[i+1] > 1000){
binCode.append('0');
}else if(timings[i] < 1000 && timings[i+1] > 3000){
binCode.append('1');
}else{
qDebug() << "ERROR: could not read code...error in transmission";
return;
}
} }
qDebug() << "bin CODE :" << binCode; // if(signalCount < 49){
parseTemperature(binCode); // //qDebug() << "ERROR: got a signal with just" << signalCount << "signals";
// return;
return; // }
} // qDebug() << "===========================================================================";
// QList <int> rawData;
// #########################################################################
if(delay > 310 && delay < 340){
qDebug() << "-----------------------------------------------------------";
qDebug() << " seems to be a REMOTE signal";
qDebug() << "-----------------------------------------------------------";
qDebug() << "delay :" << delay;
qDebug() << "bits :" << signalCount-1;
QByteArray binCode;
QList <int> rawData;
// go trough all 48 timings
for(int i = 1; i <= 48; i+=2 ){
rawData.append(timings[i]);
rawData.append(timings[i+1]);
int div;
int divNext;
// if short
if(timings[i] / delay < 2){
div = 1;
}else{
div = 3;
}
// if long
if(timings[i+1] / delay < 2){
divNext = 1;
}else{
divNext = 3;
}
// _
// if we have | |___ = 0 -> in 4 delays => 1000
// _
// if we have ___| | = 1 -> in 4 delays => 0001
if(div == 1 && divNext == 3){
binCode.append("0");
}else if(div == 3 && divNext == 1){
binCode.append("1");
}else{
qDebug() << "ERROR: could not read code...error in transmission";
return;
}
}
// // go trough all 49 timings
// for(int i = 0; i <= 48; i+=1 ){
// rawData.append(timings[i]);
// }
// qDebug() << "raw data:" << rawData; // qDebug() << "raw data:" << rawData;
qDebug() << "bin CODE :" << binCode;
QStringList byteList; // unsigned long delay = timings[0] / 31;
for(int i = 4; i <= 24; i+=4){
byteList.append(binCode.left(4)); // // #########################################################################
binCode = binCode.right(binCode.length() -4); // if(delay > 250 && delay < 260){
} // qDebug() << "-----------------------------------------------------------";
qDebug() << byteList; // qDebug() << " seems to be a TERMOMETER signal";
// qDebug() << "-----------------------------------------------------------";
// qDebug() << "delay :" << delay;
// qDebug() << "bits :" << signalCount-1;
// QByteArray binCode;
// // __
// // | |________ = 0 1100000000
// // __
// // | |________________ = 1 110000000000000000
// for(int i = 1; i <= 48; i+=2 ){
// if(timings[i] < 1000 && timings[i+1] < 3000 && timings[i+1] > 1000){
// binCode.append('0');
// }else if(timings[i] < 1000 && timings[i+1] > 3000){
// binCode.append('1');
// }else{
// qDebug() << "ERROR: could not read code...error in transmission";
// return;
// }
// }
// qDebug() << "bin CODE :" << binCode;
// parseTemperature(binCode);
// return;
// }
// // #########################################################################
// if(delay > 310 && delay < 340){
// qDebug() << "-----------------------------------------------------------";
// qDebug() << " seems to be a REMOTE signal";
// qDebug() << "-----------------------------------------------------------";
// qDebug() << "delay :" << delay;
// qDebug() << "bits :" << signalCount-1;
// QByteArray binCode;
// QList <int> rawData;
// // go trough all 48 timings
// for(int i = 1; i <= 48; i+=2 ){
// rawData.append(timings[i]);
// rawData.append(timings[i+1]);
// int div;
// int divNext;
// // if short
// if(timings[i] / delay < 2){
// div = 1;
// }else{
// div = 3;
// }
// // if long
// if(timings[i+1] / delay < 2){
// divNext = 1;
// }else{
// divNext = 3;
// }
// // _
// // if we have | |___ = 0 -> in 4 delays => 1000
// // _
// // if we have ___| | = 1 -> in 4 delays => 0001
// if(div == 1 && divNext == 3){
// binCode.append("0");
// }else if(div == 3 && divNext == 1){
// binCode.append("1");
// }else{
// qDebug() << "ERROR: could not read code...error in transmission";
// return;
// }
// }
// //qDebug() << "raw data:" << rawData;
// qDebug() << "bin CODE :" << binCode;
// QStringList byteList;
// for(int i = 4; i <= 24; i+=4){
// byteList.append(binCode.left(4));
// binCode = binCode.right(binCode.length() -4);
// }
// qDebug() << byteList;
}else{ // }else{
// ######################################################################### // // #########################################################################
qDebug() << "-----------------------------------------------------------"; // qDebug() << "-----------------------------------------------------------";
qDebug() << " seems to be a GENERIC signal"; // qDebug() << " seems to be a GENERIC signal";
qDebug() << "-----------------------------------------------------------"; // qDebug() << "-----------------------------------------------------------";
qDebug() << "delay :" << delay; // qDebug() << "delay :" << delay;
qDebug() << "bits : " << signalCount-1; // qDebug() << "bits : " << signalCount-1;
QList <int> rawData; // QList <int> rawData;
QFile file("/root/rc433_log_data.ods"); // QFile file("/root/rc433_log_data.ods");
file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); // file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
QTextStream out(&file); // QTextStream out(&file);
for(int i = 0; i < signalCount; i+=1 ){ // for(int i = 0; i < signalCount; i+=1 ){
out << timings[i] << ","; // out << timings[i] << ",";
rawData.append(timings[i]); // rawData.append(timings[i]);
} // }
out << ";\n"; // out << ";\n";
file.close(); // file.close();
qDebug() << "raw data:" << rawData; // qDebug() << "raw data:" << rawData;
} // }
} //}
float RadioReciver::parseTemperature(QByteArray codeBin) //float RadioReciver::parseTemperature(QByteArray codeBin)
{ //{
// { ID },{-+}{ temp, },{Batt},{,temp} // // { ID },{-+}{ temp, },{Batt},{,temp}
// "XXXX","XXXX","X XXX","XXXX","XXXX","XXXX", // // "XXXX","XXXX","X XXX","XXXX","XXXX","XXXX",
QList<QByteArray> byteList; // QList<QByteArray> byteList;
for(int i = 4; i <= 24; i+=4){ // for(int i = 4; i <= 24; i+=4){
byteList.append(codeBin.left(4)); // byteList.append(codeBin.left(4));
codeBin = codeBin.right(codeBin.length() -4); // codeBin = codeBin.right(codeBin.length() -4);
} // }
qDebug() << byteList; // qDebug() << byteList;
QByteArray temperatureBin(byteList.at(2) + byteList.at(3)); // QByteArray temperatureBin(byteList.at(2) + byteList.at(3));
QByteArray batteryBin(byteList.at(4)); // QByteArray batteryBin(byteList.at(4));
QByteArray temperatureTenthBin(byteList.at(5)); // QByteArray temperatureTenthBin(byteList.at(5));
// check sign of temperature -> if first bit of temperature byte is 1 -> temp is negativ // // check sign of temperature -> if first bit of temperature byte is 1 -> temp is negativ
int sign = 0; // int sign = 0;
if(temperatureBin.left(1).toInt() == 1){ // if(temperatureBin.left(1).toInt() == 1){
sign = -1; // sign = -1;
}else{ // }else{
sign = 1; // sign = 1;
} // }
//qDebug() << temperatureBin << "=" << temperatureBin.left(1) << temperatureBin.right(7) << temperatureBin.right(7).toInt(0,2) << "," << temperatureTenthBin.toInt(0,2) ; // //qDebug() << temperatureBin << "=" << temperatureBin.left(1) << temperatureBin.right(7) << temperatureBin.right(7).toInt(0,2) << "," << temperatureTenthBin.toInt(0,2) ;
// calc temperature // // calc temperature
float temperature = sign*(temperatureBin.right(7).toInt(0,2) + (float)temperatureTenthBin.toInt(0,2)/10); // float temperature = sign*(temperatureBin.right(7).toInt(0,2) + (float)temperatureTenthBin.toInt(0,2)/10);
// check if the battery is low // // check if the battery is low
QString batteryStatus; // QString batteryStatus;
if(batteryBin.toInt(0,2) == 0){ // if(batteryBin.toInt(0,2) == 0){
batteryStatus = "ok"; // batteryStatus = "ok";
}else{ // }else{
batteryStatus = "low"; // batteryStatus = "low";
} // }
qDebug() << "Temperature:" << temperature << "Battery: " << batteryStatus; // qDebug() << "Temperature:" << temperature << "Battery: " << batteryStatus;
if(temperature == lastTemperature){ // if(temperature == lastTemperature){
return temperature; // return temperature;
}else{ // }else{
lastTemperature = temperature; // lastTemperature = temperature;
QString timeStamp = QDateTime::currentDateTime().toString("dd.MM.yyyy, hh:mm");; // QString timeStamp = QDateTime::currentDateTime().toString("dd.MM.yyyy, hh:mm");;
qDebug() << timeStamp; // qDebug() << timeStamp;
QFile file("/root/temperature_log.ods"); // QFile file("/root/temperature_log.ods");
file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text); // file.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
QTextStream out(&file); // QTextStream out(&file);
out << timeStamp << "," << temperature << "," << batteryStatus << "\n"; // out << timeStamp << "," << temperature << "," << batteryStatus << "\n";
file.close(); // file.close();
} // }
return temperature; // return temperature;
} //}
void RadioReciver::enableReceiver() void RadioReciver::enableReceiver()
{ {
// check if we have all needed info...pin, freq...
if(m_pin == -1){
qDebug() << "ERROR: pin not set for RadioReceiver";
return;
}
m_enable = true; m_enable = true;
ISRHandler::instance()->registerReceiver(this);
qDebug() << "receiver for GPIO pin" << m_pin << "enabled.";
} }
void RadioReciver::disableReceiver() void RadioReciver::disableReceiver()
{ {
m_enable = false; m_enable = false;
}
void RadioReciver::setFrequency(RadioReciver::Frequency frequency)
{
if(frequency == RadioReciver::RF433MHz){
if(wiringPiSetup() == -1){
qDebug() << "ERROR: GPIO setup for 433.92 MHz receiver failed.";
}
m_pin433 = 2;
pinMode(m_pin433,INPUT);
wiringPiISR(m_pin433, INT_EDGE_BOTH, &handleRC433Interrupt);
qDebug() << "GPIO setup for 433.92 MHz receiver ok.";
}
if(frequency == RadioReciver::RF868MHz){
qDebug() << "ERROR: 868 MHz Module not connected yet";
}
} }

View File

@ -1,40 +1,49 @@
#ifndef RADIORECIVER_H #ifndef RADIORECIVER_H
#define RADIORECIVER_H #define RADIORECIVER_H
#define RC_MAX_CHANGES 50 #define RC_MAX_CHANGES 49
#include <QObject> #include <QObject>
class ISRHandler;
class RadioReciver : public QObject class RadioReciver : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit RadioReciver(QObject *parent = 0); explicit RadioReciver(QObject *parent = 0);
friend class ISRHandler;
enum Frequency{ enum Frequency{
RF433MHz = 0x0, RF433MHz = 0x0,
RF868MHz = 0x1 RF868MHz = 0x1
}; };
void setFrequency(Frequency frequency);
Frequency getFrequency() const;
void setPin(int pin);
int getPin() const;
private: private:
void handleInterrupt(); void handleInterrupt();
static void handleRC433Interrupt(); void detectProtocol(QList<int> rawData);
static void handleRC868Interrupt(); float parseTemperature(QByteArray codeBin);
static void detectProtocol(int signalCount); bool m_enable;
static float parseTemperature(QByteArray codeBin); int m_pin;
Frequency m_frequency;
int m_pin433; unsigned int m_timings[RC_MAX_CHANGES];
int m_pin868; unsigned int m_duration;
unsigned int m_changeCount;
unsigned long m_lastTime;
unsigned int m_repeatCount;
signals: signals:
public slots: public slots:
void enableReceiver(); void enableReceiver();
void disableReceiver(); void disableReceiver();
void setFrequency(Frequency frequency);
}; };
#endif // RADIORECIVER_H #endif // RADIORECIVER_H

View File

@ -146,8 +146,9 @@ void RadioSender::setFrequency(RadioSender::Frequency frequency)
if(wiringPiSetup() == -1){ if(wiringPiSetup() == -1){
qDebug() << "ERROR: GPIO setup for 433.92 MHz sender failed."; qDebug() << "ERROR: GPIO setup for 433.92 MHz sender failed.";
} }
qDebug() << "GPIO setup for sender ok.";
pinMode(m_pin,OUTPUT); pinMode(m_pin,OUTPUT);
qDebug() << "GPIO setup for 433.92 MHz sender ok."; qDebug() << "sender for GPIO pin" << m_pin << "enabled.";
} }
if(m_frequenze == RadioSender::RF868MHz){ if(m_frequenze == RadioSender::RF868MHz){
qDebug() << "ERROR: 868 MHz Module not connected yet"; qDebug() << "ERROR: 868 MHz Module not connected yet";