renew gpio and pwm classes

This commit is contained in:
Simon Stürz 2016-04-27 13:28:04 +02:00 committed by Michael Zanetti
parent f5ee163c48
commit 4191b8f37c
15 changed files with 846 additions and 660 deletions

View File

@ -40,8 +40,6 @@
No Resource required.
\value HardwareResourceRadio433
Refers to the 433 MHz radio.
\value HardwareResourceRadio868
Refers to the 868 MHz radio.
\value HardwareResourceTimer
Refers to the global timer managed by the \l{DeviceManager}. Plugins should not create their own timers,
but rather request the global timer using the hardware resources.
@ -207,7 +205,6 @@ DeviceManager::DeviceManager(QObject *parent) :
connect(&m_pluginTimer, &QTimer::timeout, this, &DeviceManager::timerEvent);
m_radio433 = new Radio433(this);
connect(m_radio433, &Radio433::dataReceived, this, &DeviceManager::radio433SignalReceived);
m_radio433->enable();
// TODO: error handling if no Radio433 detected (GPIO or network), disable radio433 plugins or something...

View File

@ -57,13 +57,12 @@ class LIBGUH_EXPORT DeviceManager : public QObject
public:
enum HardwareResource {
HardwareResourceNone = 0x00,
HardwareResourceRadio433 = 0x01,
HardwareResourceRadio868 = 0x02,
HardwareResourceTimer = 0x04,
HardwareResourceNetworkManager = 0x08,
HardwareResourceUpnpDisovery = 0x10,
HardwareResourceBluetoothLE = 0x20
HardwareResourceNone = 0,
HardwareResourceRadio433 = 1,
HardwareResourceTimer = 2,
HardwareResourceNetworkManager = 4,
HardwareResourceUpnpDisovery = 8,
HardwareResourceBluetoothLE = 16
};
Q_DECLARE_FLAGS(HardwareResources, HardwareResource)

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2015 -2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
@ -37,32 +37,44 @@
General Purpose Input/Output (a.k.a. GPIO) is a generic pin on a chip whose
behavior (including whether it is an input or output pin) can be controlled
through this class. An object of of the Gpio class represents a pin.
*/
\chapter Example
/*! \enum Gpio::Direction
Following example shows how to initialize and interact with a GPIO. The GPIO will be configured as an input,
set active high and the edge interrupt will be set to EDGE_BOTH.
This enum type specifies the dirction a \l{Gpio}.
\code
Gpio *gpio = new Gpio(this, 22);
if (!gpio->exportGpio() || !gpio->setDirection(INPUT) || !gpio->setEdgeInterrupt(EDGE_BOTH) || !gpio->setActiveLow(true)) {
return;
}
int value = gpio->getValue();
qDebug() << "value = " << value;
\endcode
\value DirectionInput
The \l{Gpio} is configured as \b input.
\value DirectionOutput
The \l{Gpio} is configured as \b output.
\value DirectionInvalid
The direction is not valid.
*/
\chapter Raspberry Pi GPIOs
In following table is a list of all GPIO's of the Raspberry Pi Rev. 2.0:
/*! \enum Gpio::Value
\image Raspberry_Pi_GPIO_Map.png "Raspberry Pi GPIO map"
This enum type specifies the value a \l{Gpio}.
Valid GPIO's for this class are those with a GPIO number (for example GPIO 22, which is on pin Nr. 15)
\value ValueLow
The \l{Gpio} is low.
\value ValueHigh
The \l{Gpio} is high.
\value ValueInvalid
The value is not valid.
*/
\chapter Beaglebone Black GPIOs
In following table is a list of all GPIO's of the Beaglebone Black (\l{http://pix.cs.olemiss.edu/csci581/BBBlackGPIOMap.png}{Source}):
/*! \enum Gpio::Edge
\image Beaglebone_Black_GPIO_Map.png "Beaglebone Black GPIO map"
This enum type specifies the edge interrupt type of a \l{Gpio}.
\value EdgeFalling
The \l{Gpio} reacts on falling edge interrupt.
\value EdgeRising
The \l{Gpio} reacts on rising edge interrupt.
\value EdgeBoth
The \l{Gpio} reacts on both, rising and falling edge interrupt.
\value EdgeNone
The \l{Gpio} does not react on interrupts.
*/
@ -71,339 +83,299 @@
#include <QDebug>
/*! 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) :
QObject(parent),m_gpio(gpio)
/*! Constructs a \l{Gpio} object to represent a GPIO with the given \a gpio number and \a parent. */
Gpio::Gpio(int gpio, QObject *parent) :
QObject(parent),
m_gpio(gpio)
{
m_gpioDirectory = QDir(QString("/sys/class/gpio/gpio%1/").arg(QString::number(m_gpio)));
}
/*! Destroys the Gpio object and unexports the GPIO. */
/*! Destroys and unexports the \l{Gpio}. */
Gpio::~Gpio()
{
unexportGpio();
}
/*! Returns true if this GPIO could be exported in the system file "/sys/class/gpio/export". */
/*! Returns true if the directory \tt {/sys/class/gpio} does exist. */
bool Gpio::isAvailable()
{
return QDir("/sys/class/gpio").exists();
}
/*! Returns true if this \l{Gpio} could be exported in the system file \tt {/sys/class/gpio/export}. */
bool Gpio::exportGpio()
{
unexportGpio();
char buf[64];
int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0) {
//qCWarning(dcHardware) << "could not open /sys/class/gpio/export";
QFile exportFile("/sys/class/gpio/export");
if (!exportFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "Could not export GPIO" << m_gpio;
return false;
}
ssize_t len = snprintf(buf, sizeof(buf), "%d", m_gpio);
if(write(fd, buf, len) != len){
qCWarning(dcHardware) << "could not write to gpio (export)";
close(fd);
return false;
}
close(fd);
QTextStream out(&exportFile);
out << m_gpio;
exportFile.close();
return true;
}
/*! Returns true if this GPIO could be unexported in the system file "/sys/class/gpio/unexport". */
/*! Returns true if this \l{Gpio} could be unexported in the system file \tt {/sys/class/gpio/unexport}. */
bool Gpio::unexportGpio()
{
char buf[64];
int fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0) {
//qCWarning(dcHardware) << "could not open /sys/class/gpio/unexport";
QFile unexportFile("/sys/class/gpio/unexport");
if (!unexportFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "Could not unexport GPIO" << m_gpio;
return false;
}
ssize_t len = snprintf(buf, sizeof(buf), "%d", m_gpio);
if(write(fd, buf, len) != len){
//qCWarning(dcHardware) << "could not write to gpio (unexport)";
close(fd);
return false;
}
close(fd);
QTextStream out(&unexportFile);
out << m_gpio;
unexportFile.close();
return true;
}
/*! Returns true if the file of this GPIO could be opend.*/
int Gpio::openGpio()
/*! Returns true if the \a direction of this GPIO could be set. */
bool Gpio::setDirection(Gpio::Direction direction)
{
char buf[64];
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", m_gpio);
int fd = open(buf, O_RDONLY | O_NONBLOCK );
if (fd < 0) {
qCWarning(dcHardware) << "could not open /sys/class/gpio" << m_gpio << "/direction";
return fd;
}
return fd;
}
/*! Returns true if the direction \a dir of this GPIO could be set correctly.
*
* Possible directions are:
*
* \table
* \header
* \li {2,1} Pin directions
* \row
* \li 0
* \li INPUT
* \row
* \li 1
* \li OUTPUT
* \endtable
*/
bool Gpio::setDirection(int dir)
{
char buf[64];
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", m_gpio);
int fd = open(buf, O_WRONLY);
if (fd < 0) {
qCWarning(dcHardware) << "could not open /sys/class/gpio" << m_gpio << "/direction";
QFile directionFile(m_gpioDirectory.path() + "/direction");
if (!directionFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "direction file.";
return false;
}
if(dir == INPUT){
if(write(fd, "in", 3) != 3){
qCWarning(dcHardware) << "could not write to gpio (set INPUT)";
close(fd);
return false;
}
m_dir = INPUT;
close(fd);
return true;
QTextStream out(&directionFile);
switch (direction) {
case DirectionInput:
out << "in";
break;
case DirectionOutput:
out << "out";
break;
default:
directionFile.close();
return false;
}
if(dir == OUTPUT){
if(write(fd, "out", 4) != 4){
qCWarning(dcHardware) << "could not write to gpio (set OUTPUT)";
close(fd);
return false;
}
m_dir = OUTPUT;
close(fd);
return true;
directionFile.close();
return true;
}
/*! Returns the direction of this \l{Gpio}. */
Gpio::Direction Gpio::direction()
{
QFile directionFile(m_gpioDirectory.path() + "/direction");
if (!directionFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "direction file.";
return Gpio::DirectionInvalid;
}
close(fd);
QString direction;
QTextStream in(&directionFile);
in >> direction;
directionFile.close();
if (direction == "in") {
m_direction = DirectionInput;
return Gpio::DirectionInput;
} else if (direction == "out") {
m_direction = DirectionOutput;
return Gpio::DirectionOutput;
}
return Gpio::DirectionInvalid;
}
/*! Returns true if the digital \a value of this \l{Gpio} could be set correctly. */
bool Gpio::setValue(Gpio::Value value)
{
if (value == Gpio::ValueInvalid || m_direction == Gpio::DirectionInput)
return false;
QFile valueFile(m_gpioDirectory.path() + "/value");
if (!valueFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "value file.";
return false;
}
QTextStream out(&valueFile);
switch (value) {
case ValueLow:
out << "0";
break;
case ValueHigh:
out << "1";
break;
default:
valueFile.close();
return false;
}
valueFile.close();
return true;
}
/*! Returns the current digital value of this \l{Gpio}. */
Gpio::Value Gpio::value()
{
QFile valueFile(m_gpioDirectory.path() + "/value");
if (!valueFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "value file.";
return Gpio::ValueInvalid;
}
QString value;
QTextStream in(&valueFile);
in >> value;
valueFile.close();
if (value == "0") {
return Gpio::ValueLow;
} else if (value == "1") {
return Gpio::ValueHigh;
}
return Gpio::ValueInvalid;
}
/*! This method allows to invert the logic of this \l{Gpio}. Returns true, if the GPIO could be set \a activeLow. */
bool Gpio::setActiveLow(bool activeLow)
{
QFile activeLowFile(m_gpioDirectory.path() + "/active_low");
if (!activeLowFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "active_low file.";
return false;
}
QTextStream out(&activeLowFile);
if (activeLow) {
out << "0";
} else {
out << "1";
}
activeLowFile.close();
return true;
}
/*! Returns true if the logic of this \l{Gpio} is inverted (1 = low, 0 = high). */
bool Gpio::activeLow()
{
QFile activeLowFile(m_gpioDirectory.path() + "/active_low");
if (!activeLowFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "active_low file.";
return false;
}
QString value;
QTextStream in(&activeLowFile);
in >> value;
activeLowFile.close();
if (value == "0")
return true;
return false;
}
/*! Returns the direction of this GPIO.
* \sa setDirection()
*/
int Gpio::getDirection()
{
return m_dir;
}
/*! Returns true if the digital \a value of the GPIO could be set correctly.
*
* Possible \a value 's are:
*
* \table
* \header
* \li {2,1} Pin value
* \row
* \li 0
* \li LOW
* \row
* \li 1
* \li HIGH
* \endtable
*/
bool Gpio::setValue(unsigned int value)
{
// check if gpio is a output
if( m_dir == OUTPUT){
char buf[64];
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", m_gpio);
int fd = open(buf, O_WRONLY);
if (fd < 0) {
qCWarning(dcHardware) << "could not open /sys/class/gpio" << m_gpio << "/value";
return false;
}
if(value == LOW){
if(write(fd, "0", 2) != 2){
qCWarning(dcHardware) << "could not write to gpio (set LOW)";
close(fd);
return false;
}
close(fd);
return true;
}
if(value == HIGH){
if(write(fd, "1", 2) != 2){
qCWarning(dcHardware) << "could not write to gpio (set HIGH)";
close(fd);
return false;
}
close(fd);
return true;
}
close(fd);
return false;
}else{
qCWarning(dcHardware) << "Gpio" << m_gpio << "is not an OUTPUT.";
return false;
}
}
/*! Returns the current digital value of the GPIO.
*
* Possible values are:
*
* \table
* \header
* \li {2,1} Pin directions
* \row
* \li 0
* \li LOW
* \row
* \li 1
* \li HIGH
* \endtable
*/
int Gpio::getValue()
{
char buf[64];
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", m_gpio);
int fd = open(buf, O_RDONLY);
if (fd < 0) {
qCWarning(dcHardware) << "could not open /sys/class/gpio" << m_gpio << "/value";
return -1;
}
char ch;
int value = -1;
ssize_t len = read(fd, &ch, 1);
if(len != 1){
close(fd);
return -1;
}
if (ch != '0') {
value = 1;
}else{
value = 0;
}
close(fd);
return value;
}
/*! Returns true if the \a edge of this GPIO could be set correctly. The \a edge parameter specifies,
* when an interrupt occurs.
*
* Possible values are:
*
* \table
* \header
* \li {2,1} Edge possibilitys
* \row
* \li 0
* \li EDGE_FALLING
* \row
* \li 1
* \li EDGE_RISING
* \row
* \li 2
* \li EDGE_BOTH
* \endtable
*/
bool Gpio::setEdgeInterrupt(int edge)
* when an interrupt occurs. */
bool Gpio::setEdgeInterrupt(Gpio::Edge edge)
{
char buf[64];
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/edge", m_gpio);
int fd = open(buf, O_WRONLY);
if (fd < 0) {
qCWarning(dcHardware) << "could not open /sys/class/gpio" << m_gpio << "/edge";
if (m_direction == Gpio::DirectionOutput) {
qCWarning(dcHardware()) << "Could not set edge interrupt, GPIO is configured as an output.";
return false;
}
if(edge == EDGE_FALLING){
if(write(fd, "falling", 8) != 8){
qCWarning(dcHardware) << "could not write to gpio (set EDGE_FALLING)";
close(fd);
return false;
}
close(fd);
return true;
}
if(edge == EDGE_RISING){
if(write(fd, "rising", 7) != 7){
qCWarning(dcHardware) << "could not write to gpio (set EDGE_RISING)";
close(fd);
return false;
}
close(fd);
return true;
}
if(edge == EDGE_BOTH){
if(write(fd, "both", 5) != 5){
qCWarning(dcHardware) << "could not write to gpio (set EDGE_BOTH)";
close(fd);
return false;
}
close(fd);
return true;
}
close(fd);
return false;
}
/*! This method allows to invert the logic of this GPIO.
* Returns true, if the GPIO could be set \a activeLow.
*/
bool Gpio::setActiveLow(bool activeLow)
{
char buf[64];
snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/active_low", m_gpio);
int fd = open(buf, O_WRONLY);
if (fd < 0) {
qCWarning(dcHardware) << "could not open /sys/class/gpio" << m_gpio << "/active_low";
QFile edgeFile(m_gpioDirectory.path() + "/edge");
if (!edgeFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "edge file.";
return false;
}
if(activeLow){
if(write(fd, "0", 2) != 2){
qCWarning(dcHardware) << "could not write to gpio (set Active LOW)";
close(fd);
return false;
}
close(fd);
return true;
QTextStream out(&edgeFile);
switch (edge) {
case EdgeFalling:
out << "falling";
break;
case EdgeRising:
out << "rising";
break;
case EdgeBoth:
out << "both";
break;
case EdgeNone:
out << "none";
break;
default:
return false;
}
if(!activeLow){
if(write(fd, "1", 2) != 2){
qCWarning(dcHardware) << "could not write to gpio (set Active HIGH)";
close(fd);
return false;
}
close(fd);
return true;
}
close(fd);
return false;
edgeFile.close();
return true;
}
/*! Returns the number of this GPIO.
* \sa Gpio::Gpio()
*/
int Gpio::gpioNumber()
/*! Returns the edge interrupt of this \l{Gpio}. */
Gpio::Edge Gpio::edgeInterrupt()
{
QFile edgeFile(m_gpioDirectory.path() + "/edge");
if (!edgeFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "Could not open GPIO" << m_gpio << "edge file.";
return Gpio::EdgeNone;
}
QString edge;
QTextStream in(&edgeFile);
in >> edge;
edgeFile.close();
if (edge.contains("falling")) {
return Gpio::EdgeFalling;
} else if (edge.contains("rising")) {
return Gpio::EdgeRising;
} else if (edge.contains("both")) {
return Gpio::EdgeBoth;
} else if (edge.contains("none")) {
return Gpio::EdgeNone;
}
return Gpio::EdgeNone;
}
/*! Returns the number of this \l{Gpio}. */
int Gpio::gpioNumber() const
{
return m_gpio;
}
/*! Returns true if the directory /sys/class/gpio does exist.
*/
bool Gpio::isAvailable()
QDebug operator<<(QDebug d, Gpio *gpio)
{
QDir gpioDirectory("/sys/class/gpio");
return gpioDirectory.exists();
d << "-----------------------------------";
d << "\n--> gpio" << gpio->gpioNumber() << ":";
d << "\n------------------";
if (gpio->direction() == Gpio::DirectionInput) {
d << "\n direction: input";
} else if (gpio->direction() == Gpio::DirectionOutput) {
d << "\n direction: output";
}
d << "\n value:" << gpio->value();
d << "\n active low:" << gpio->activeLow();
switch (gpio->edgeInterrupt()) {
case Gpio::EdgeFalling:
d << "\n edge interrupt:" << "falling";
break;
case Gpio::EdgeRising:
d << "\n edge interrupt:" << "rising";
break;
case Gpio::EdgeBoth:
d << "\n edge interrupt:" << "both";
break;
case Gpio::EdgeNone:
d << "\n edge interrupt:" << "none";
break;
default:
break;
}
d << "\n-----------------------------------\n";
return d;
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2015 -2016 Simon Stürz <simon.stuerz@guh.guru> *
* *
* This file is part of guh. *
* *
@ -22,86 +22,65 @@
#define GPIO_H
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QMutexLocker>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include "libguh.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
#define INPUT 0
#define OUTPUT 1
#define LOW 0
#define HIGH 1
#define EDGE_FALLING 0
#define EDGE_RISING 1
#define EDGE_BOTH 2
/**********************************
* Raspberry Pi Rev. 2.0 P1 Header Raspberry Pi Rev. 2.0 P5 Header
* __________________________________ __________________________________
* |______________________|__________| |______________________|__________|
* | Name | PIN NR. | Function | | Name | PIN NR. | Function |
* |___________|__________|__________| |___________|__________|__________|
* | GPIO 2 | 3 | SDA | | GPIO 28 | 3 | SDA |
* | GPIO 3 | 5 | SCL | | GPIO 29 | 4 | SCL |
* | GPIO 4 | 7 | | | GPIO 30 | 5 | |
* | GPIO 7 | 26 | CE1 | | GPIO 31 | 6 | |
* | GPIO 8 | 24 | CE0 | |___________|__________|__________|
* | GPIO 9 | 21 | MISO |
* | GPIO 10 | 19 | MOSI |
* | GPIO 11 | 23 | SCLK |
* | GPIO 14 | 8 | TXD |
* | GPIO 15 | 10 | RXD |
* | GPIO 17 | 11 | |
* | GPIO 18 | 12 | PCM_CLK |
* | GPIO 22 | 15 | |
* | GPIO 23 | 16 | |
* | GPIO 24 | 18 | |
* | GPIO 25 | 22 | |
* | GPIO 27 | 13 | |
* |___________|__________|__________|
*
**********************************
*/
class LIBGUH_EXPORT Gpio : public QObject
{
Q_OBJECT
public:
explicit Gpio(QObject *parent = 0, int gpio = 0);
enum Direction {
DirectionInput,
DirectionOutput,
DirectionInvalid
};
enum Value {
ValueLow = 0,
ValueHigh = 1,
ValueInvalid = -1
};
enum Edge {
EdgeFalling,
EdgeRising,
EdgeBoth,
EdgeNone
};
explicit Gpio(int gpio = 0, QObject *parent = 0);
~Gpio();
static bool isAvailable();
bool exportGpio();
bool unexportGpio();
int openGpio();
bool setDirection(int dir);
int getDirection();
bool setDirection(Gpio::Direction direction);
Gpio::Direction direction();
bool setValue(unsigned int value);
int getValue();
bool setValue(Gpio::Value value);
Gpio::Value value();
bool setEdgeInterrupt(int edge);
bool setActiveLow(bool activeLow);
bool activeLow();
int gpioNumber();
bool isAvailable();
bool setEdgeInterrupt(Gpio::Edge edge);
Gpio::Edge edgeInterrupt();
int gpioNumber() const;
private:
int m_gpio;
int m_dir;
Gpio::Direction m_direction;
QDir m_gpioDirectory;
};
QDebug operator<< (QDebug d, Gpio *gpio);
#endif // GPIO_H

View File

@ -19,246 +19,144 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*!
\class GpioMonitor
\brief The GpioMonitor class allows to monitor GPIOs.
\class GpioMonitor
\brief The GpioMonitor class allows to monitor GPIOs.
\ingroup hardware
\inmodule libguh
\ingroup hardware
\inmodule libguh
An instance of this class creates a thread, which monitors each of the added GPIOs. The object
emits a signal if one of the added GPIOs changes its value. The GpioMonitor configures a GPIO as an
input, with the edge interrupt EDGE_BOTH (\l{Gpio::setEdgeInterrupt()}{setEdgeInterrupt}).
An instance of this class creates a thread, which monitors each of the added GPIOs. The object
emits a signal if one of the added GPIOs changes its value. The GpioMonitor configures a GPIO as an
input, with the edge interrupt EDGE_BOTH (\l{Gpio::setEdgeInterrupt()}{setEdgeInterrupt}).
\chapter Example
Following example shows how to use the GpioMonitor class for a button on the Raspberry Pi. There are two possibilitys
to connect a button. Following picture shows the schematics:
\chapter Example
Following example shows how to use the GpioMonitor class for a button on the Raspberry Pi. There are two possibilitys
to connect a button. Following picture shows the schematics:
\image Raspberry_Pi_Button_Example.png "Raspberry Pi button example"
\image Raspberry_Pi_Button_Example.png "Raspberry Pi button example"
Button A represents a clean solutin with a 10 k\unicode{0x2126} resistor (set up as activeLow = false).
Button B represents a "dirty" solution, were the 3.3V will be directly connected to the GPIO if the button is pressed (set activeLow = true).
Button A represents a clean solutin with a 10 k\unicode{0x2126} resistor (set up as activeLow = false).
Button B represents a "dirty" solution, were the 3.3V will be directly connected to the GPIO if the button is pressed (set activeLow = true).
Here is the code example for a button class:
Here is the code example for a button class:
\code
Button::Button(QObject *parent) :
QObject(parent)
{
m_button = new GpioMonitor(110, this);
connect(m_button, &GpioMonitor::valueChanged, this, &Button::stateChanged);
}
\tt{guhbutton.h}
\code
#include <QObject>
#include <QDebug>
#include <QTimer>
bool Button::init()
{
return m_button->enable();
}
#include "hardware/gpiomonitor.h"
class GuhButton : public QObject
{
Q_OBJECT
public:
explicit GuhButton(QObject *parent = 0, int gpio = 4);
bool enable();
void disable();
private:
GpioMonitor *m_monitor;
int m_gpioPin;
Gpio *m_gpio;
bool m_buttonPressed;
QTimer *m_longpressedTimer;
QTimer *m_debounceTimer;
signals:
void buttonPressed();
void buttonReleased();
void buttonLongPressed();
private slots:
void gpioChanged(const int &gpioPin, const int &value);
};
\endcode
\tt{guhbutton.cpp}
\code
#include "guhbutton.h"
GuhButton::GuhButton(QObject *parent, int gpio) :
QObject(parent), m_gpioPin(gpio)
{
m_buttonPressed = false;
}
bool GuhButton::enable()
{
qDebug() << "setup button on GPIO " << m_gpioPin;
m_monitor = new GpioMonitor(this);
m_gpio = new Gpio(this, m_gpioPin);
if(!m_monitor->addGpio(m_gpio, false)){
return false;
}
connect(m_monitor, &GpioMonitor::changed, this, &GuhButton::gpioChanged);
// Timer to generate the long pressed signal
m_longpressedTimer = new QTimer(this);
m_longpressedTimer->setInterval(500);
m_longpressedTimer->setSingleShot(true);
connect(m_longpressedTimer, &QTimer::timeout, this, &GuhButton::buttonLongPressed);
// Timer to debounce the button
m_debounceTimer = new QTimer(this);
m_debounceTimer->setSingleShot(true);
m_debounceTimer->setInterval(50);
m_monitor->enable();
return true;
}
void GuhButton::disable()
{
m_monitor->disable();
}
void GuhButton::gpioChanged(const int &gpioPin, const int &value)
{
if (gpioPin == m_gpioPin){
if(m_debounceTimer->isActive()){
return;
}
// check button state
bool buttonState = !QVariant(value).toBool();
if (m_buttonPressed != buttonState) {
if (buttonState) {
emit buttonPressed();
m_longpressedTimer->start();
m_debounceTimer->start();
} else {
emit buttonReleased();
m_longpressedTimer->stop();
}
m_buttonPressed = buttonState;
}
}
}
\endcode
void Button::stateChanged(const bool &value)
{
if (m_pressed != value) {
m_pressed = value;
if (value) {
emit buttonPressed();
} else {
emit buttonReleased();
}
}
}
\endcode
*/
/*! \fn void GpioMonitor::changed(const int &gpioPin, const int &value);
* This signal will be emited, if one of the monitored \l{Gpio}{Gpios} changed his \a value. The \a gpioPin
* paramter describes which \l{Gpio} changed his \a value.
* \sa Gpio::gpioNumber()
*/
/*! \fn void GpioMonitor::valueChanged(const bool &value);
* This signal will be emited, if the monitored \l{Gpio}{Gpios} changed his \a value. */
#include "gpiomonitor.h"
#include "loggingcategories.h"
/*! Constructs a \l{GpioMonitor} object with the given \a parent. */
GpioMonitor::GpioMonitor(QObject *parent) :
QThread(parent)
/*! Constructs a \l{GpioMonitor} object with the given \a gpio number and \a parent. */
GpioMonitor::GpioMonitor(int gpio, QObject *parent) :
QObject(parent),
m_gpioNumber(gpio)
{
m_valueFile.setFileName("/sys/class/gpio/gpio" + QString::number(m_gpioNumber) + "/value");
}
/*! Destructs the object of this \l{GpioMonitor}.*/
GpioMonitor::~GpioMonitor()
/*! Returns true if this \l{GpioMonitor} could be enabled successfully. With the \a activeLow parameter the values can be inverted.
With the \a edgeInterrupt parameter the interrupt type can be specified. */
bool GpioMonitor::enable(bool activeLow, Gpio::Edge edgeInterrupt)
{
foreach (Gpio* gpio, m_gpioList) {
gpio->unexportGpio();
}
quit();
wait();
deleteLater();
}
if (!Gpio::isAvailable())
return false;
/*! Starts the \l{GpioMonitor}. While the \l{GpioMonitor} is running there can not be added new \l{Gpio}{Gpios}.
* \sa disable(), */
void GpioMonitor::enable()
{
m_enabledMutex.lock();
m_enabled = true;
m_enabledMutex.unlock();
start();
}
/*! Stops the \l{GpioMonitor}. No changes on the \l{Gpio} will be recognized.*/
void GpioMonitor::disable()
{
m_enabledMutex.lock();
m_enabled = false;
m_enabledMutex.unlock();
}
/*! Adds the given \l{Gpio} \a gpio to the monitor. This function can only be called if the monitor is not running.
* The given \a gpio will be configured as \a activeLow.
* Return true if the gpio could be added and set up correctly.
* \sa Gpio::setActiveLow(), */
bool GpioMonitor::addGpio(Gpio *gpio, bool activeLow)
{
if (!gpio->exportGpio() || !gpio->setDirection(INPUT) || !gpio->setEdgeInterrupt(EDGE_BOTH) || !gpio->setActiveLow(activeLow)) {
m_gpio = new Gpio(m_gpioNumber, this);
if (!m_gpio->exportGpio() ||
!m_gpio->setDirection(Gpio::DirectionInput) ||
!m_gpio->setActiveLow(activeLow) ||
!m_gpio->setEdgeInterrupt(edgeInterrupt)) {
qDebug() << "ERROR: while initializing GPIO" << m_gpio->gpioNumber();
return false;
}
m_gpioListMutex.lock();
m_gpioList.append(gpio);
m_gpioListMutex.unlock();
if (!m_valueFile.open(QFile::ReadOnly)) {
qWarning() << "ERROR: could not open value file for gpio monitor" << m_gpio->gpioNumber();
return false;
}
m_notifier = new QSocketNotifier(m_valueFile.handle(), QSocketNotifier::Exception);
connect(m_notifier, &QSocketNotifier::activated, this, &GpioMonitor::readyReady);
m_notifier->setEnabled(true);
return true;
}
/*! Returns the list of \l{Gpio}{Gpios} which currently are monitored.
* \sa addGpio(), */
QList<Gpio *> GpioMonitor::gpioList()
/*! Disables this \l{GpioMonitor}. */
void GpioMonitor::disable()
{
m_gpioListMutex.lock();
QList<Gpio*> gpioList = m_gpioList;
m_gpioListMutex.unlock();
return gpioList;
delete m_notifier;
delete m_gpio;
m_notifier = 0;
m_gpio = 0;
m_valueFile.close();
}
/*! This method represents the reimplementation of the virtual void QThread::run() method. This method will be called from
* QThread by calling the method void QThread::start(). Never call this method directly.
* \sa enable(), */
void GpioMonitor::run()
/*! Returns true if this \l{GpioMonitor} is running. */
bool GpioMonitor::isRunning() const
{
struct pollfd *fds;
char val;
int ret;
int retVal;
fds = (pollfd*) malloc(sizeof(pollfd) * m_gpioList.size());
m_gpioListMutex.lock();
for (int i = 0; i < m_gpioList.size(); i++) {
fds[i].fd = m_gpioList[i]->openGpio();
fds[i].events = POLLPRI | POLLERR;
if (!m_notifier) {
return false;
}
m_gpioListMutex.unlock();
bool enabled = true;
m_enabledMutex.lock();
m_enabled = true;
m_enabledMutex.unlock();
while (enabled) {
m_gpioListMutex.lock();
ret = poll(fds, m_gpioList.size(), 2000);
if (ret > 0) {
for (int i=0; i < m_gpioList.size(); i++) {
if ((fds[i].revents & POLLPRI) || (fds[i].revents & POLLERR)) {
lseek(fds[i].fd, 0, SEEK_SET);
retVal = read(fds[i].fd, &val, 1);
emit changed(m_gpioList[i]->gpioNumber(), m_gpioList[i]->getValue());
if (retVal < 0) {
qCWarning(dcHardware) << "GpioMonitor poll failed";
}
}
}
} else if (ret < 0) {
qCWarning(dcHardware) << "poll failed: " << errno;
}
m_gpioListMutex.unlock();
m_enabledMutex.lock();
enabled = m_enabled;
m_enabledMutex.unlock();
}
free(fds);
return m_notifier->isEnabled();
}
/*! Returns the current value of this \l{GpioMonitor}. */
bool GpioMonitor::value() const
{
return m_currentValue;
}
/*! Returns the \l{Gpio} of this \l{GpioMonitor}. */
Gpio *GpioMonitor::gpio()
{
return m_gpio;
}
void GpioMonitor::readyReady(const int &ready)
{
Q_UNUSED(ready)
m_valueFile.seek(0);
QByteArray data = m_valueFile.readAll();
bool value = false;
if (data[0] == '1') {
value = true;
} else if (data[0] == '0') {
value = false;
} else {
return;
}
m_currentValue = value;
emit valueChanged(value);
}

View File

@ -21,41 +21,41 @@
#ifndef GPIOMONITOR_H
#define GPIOMONITOR_H
#include <QThread>
#include <QObject>
#include <QDebug>
#include <fcntl.h>
#include <stdio.h>
#include <poll.h>
#include <errno.h>
#include <QSocketNotifier>
#include <QFile>
#include "libguh.h"
#include "hardware/gpio.h"
#include "gpio.h"
class LIBGUH_EXPORT GpioMonitor : public QThread
class LIBGUH_EXPORT GpioMonitor : public QObject
{
Q_OBJECT
public:
explicit GpioMonitor(QObject *parent = 0);
~GpioMonitor();
explicit GpioMonitor(int gpio, QObject *parent = 0);
void enable();
bool enable(bool activeLow = false, Gpio::Edge edgeInterrupt = Gpio::EdgeBoth);
void disable();
bool addGpio(Gpio *gpio, bool activeLow);
QList<Gpio*> gpioList();
bool isRunning() const;
bool value() const;
Gpio* gpio();
private:
QMutex m_enabledMutex;
bool m_enabled;
QMutex m_gpioListMutex;
QList<Gpio*> m_gpioList;
protected:
void run();
int m_gpioNumber;
Gpio *m_gpio;
QSocketNotifier *m_notifier;
QFile m_valueFile;
bool m_currentValue;
signals:
void changed(const int &gpioPin, const int &value);
void valueChanged(const bool &value);
private slots:
void readyReady(const int &ready);
};

280
libguh/hardware/pwm.cpp Normal file
View File

@ -0,0 +1,280 @@
#include "pwm.h"
#include "loggingcategories.h"
Pwm::Pwm(int chipNumber, QObject *parent) :
QObject(parent),
m_chipNumber(chipNumber),
m_period(0),
m_dutyCycle(0)
{
m_pwmDirectory = QDir("/sys/class/pwm/pwmchip" + QString::number(chipNumber) + "/");
}
Pwm::~Pwm()
{
unexportPwm();
}
bool Pwm::isAvailable()
{
QDir pwmDirectory("/sys/class/pwm");
return pwmDirectory.exists() && !pwmDirectory.entryList().isEmpty();
}
bool Pwm::exportPwm()
{
QFile exportFile(m_pwmDirectory.path() + "/export");
if (!exportFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not export PWM" << m_chipNumber;
return false;
}
QTextStream out(&exportFile);
out << 0;
exportFile.close();
return true;
}
bool Pwm::enable()
{
QFile enableFile(m_pwmDirectory.path() + "/pwm0/enable");
if (!enableFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not enable PWM" << m_chipNumber;
return false;
}
QTextStream out(&enableFile);
out << 1;
enableFile.close();
return true;
}
bool Pwm::disable()
{
QFile enableFile(m_pwmDirectory.path() + "/pwm0/enable");
if (!enableFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not disable PWM" << m_chipNumber;
return false;
}
QTextStream out(&enableFile);
out << 0;
enableFile.close();
return true;
}
bool Pwm::isEnabled()
{
QFile enableFile(m_pwmDirectory.path() + "/pwm0/enable");
if (!enableFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "ERROR: could not read" << enableFile.fileName();
return false;
}
QString value;
QTextStream in(&enableFile);
in >> value;
enableFile.close();
if (value == "1")
return true;
return false;
}
int Pwm::chipNumber()
{
return m_chipNumber;
}
long Pwm::period()
{
// period = active + inactive time
QFile periodFile(m_pwmDirectory.path() + "/pwm0/period");
if (!periodFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "ERROR: could not open" << periodFile.fileName();
return false;
}
QString value;
QTextStream in(&periodFile);
in >> value;
periodFile.close();
m_period = value.toLong();
return m_period;
}
bool Pwm::setPeriod(long nanoSeconds)
{
// the current duty cycle can not be greater than the period
if (dutyCycle() > nanoSeconds && !setDutyCycle(nanoSeconds))
return false;
// period = active + inactive time
QFile periodFile(m_pwmDirectory.path() + "/pwm0/period");
if (!periodFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not open" << periodFile.fileName();
return false;
}
QTextStream out(&periodFile);
out << QString::number(nanoSeconds);
periodFile.close();
m_period = nanoSeconds;
return true;
}
double Pwm::frequency()
{
return (100000000.0 / (period() * 1000));
}
bool Pwm::setFrequency(double kHz)
{
// p = 1 / f
long nanoSeconds = (long)(100000000 / (kHz * 1000));
return setPeriod(nanoSeconds);
}
// active time
long Pwm::dutyCycle()
{
QFile dutyCycleFile(m_pwmDirectory.path() + "/pwm0/duty_cycle");
if (!dutyCycleFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "ERROR: could not open" << dutyCycleFile.fileName();
return false;
}
QString value;
QTextStream in(&dutyCycleFile);
in >> value;
dutyCycleFile.close();
m_dutyCycle = value.toLong();
return m_dutyCycle;
}
bool Pwm::setDutyCycle(long nanoSeconds)
{
// can not be greater than period or negative
if (nanoSeconds > m_period || nanoSeconds < 0) {
qCWarning(dcHardware()) << "ERROR: duty cycle has to be positive and smaller than the period";
return false;
}
QFile dutyCycleFile(m_pwmDirectory.path() + "/pwm0/duty_cycle");
if (!dutyCycleFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not open" << dutyCycleFile.fileName();
return false;
}
QTextStream out(&dutyCycleFile);
out << QString::number(nanoSeconds);
dutyCycleFile.close();
m_dutyCycle = nanoSeconds;
return true;
}
Pwm::Polarity Pwm::polarity()
{
QFile polarityFile(m_pwmDirectory.path() + "/pwm0/polarity");
if (!polarityFile.open(QIODevice::ReadOnly)) {
qCWarning(dcHardware()) << "ERROR: could not open" << polarityFile.fileName();
return PolarityInvalid;
}
QString value;
QTextStream in(&polarityFile);
in >> value;
polarityFile.close();
if (value == "normal") {
return PolarityNormal;
} else if(value == "inversed") {
return PolarityInversed;
}
return PolarityInvalid;
}
bool Pwm::setPolarity(Pwm::Polarity polarity)
{
if (polarity == Pwm::PolarityInvalid)
return false;
// Note: the polarity can only be changed if the pwm is disabled.
bool wasEnabled = isEnabled();
if (wasEnabled && !disable())
return false;
QFile polarityFile(m_pwmDirectory.path() + "/pwm0/polarity");
if (!polarityFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not open" << polarityFile.fileName();
return false;
}
QTextStream out(&polarityFile);
switch (polarity) {
case PolarityNormal:
out << "normal";
break;
case PolarityInversed:
out << "inversed";
break;
default:
break;
}
polarityFile.close();
if (wasEnabled)
enable();
return true;
}
int Pwm::percentage()
{
return (int)(dutyCycle() * (100.0 / period()) + 0.5);
}
bool Pwm::setPercentage(int percentage)
{
long nanoSeconds = period() * (percentage / 100.0);
return setDutyCycle(nanoSeconds);
}
bool Pwm::unexportPwm()
{
QFile unexportFile(m_pwmDirectory.path() + "/unexport");
if (!unexportFile.open(QIODevice::WriteOnly)) {
qCWarning(dcHardware()) << "ERROR: could not unexport PWM" << m_chipNumber;
return false;
}
QTextStream out(&unexportFile);
out << 0;
unexportFile.close();
return true;
}
QDebug operator<<(QDebug d, Pwm *pwm)
{
d << "-----------------------------------";
d << "\n--> pwm0 on pwmChip" << pwm->chipNumber() << ":";
d << "\n------------------";
d << "\n enabled:" << pwm->isEnabled();
d << "\n period:" << pwm->period() << "[ns]";
d << "\n duty cycle:" << pwm->dutyCycle() << "[ns]";
d << "\n frequency:" << pwm->frequency() << "[kHz]";
d << "\n percentage:" << pwm->percentage() << "[%]";
switch (pwm->polarity()) {
case Pwm::PolarityNormal:
d << "\n polarity:" << "normal";
break;
case Pwm::PolarityInversed:
d << "\n polarity:" << "inversed";
break;
default:
d << "\n polarity:" << "invalid";
break;
}
d << "\n-----------------------------------\n";
return d;
}

88
libguh/hardware/pwm.h Normal file
View File

@ -0,0 +1,88 @@
#ifndef PWM_H
#define PWM_H
#include <QObject>
#include <QDebug>
#include <QFile>
#include <QDir>
#include "libguh.h"
/* i.MX6 PWMs
*
* /sys/class/pwm/pwmchip0 -> pwm1 (npwm = 1)
* /sys/class/pwm/pwmchip1 -> pwm2 (npwm = 1)
* /sys/class/pwm/pwmchip2 -> pwm3 (npwm = 1)
* /sys/class/pwm/pwmchip3 -> pwm4 (npwm = 1)
*
* each chip has 1 pwm ( -> pwm0)
*
* example:
* echo 0 > /sys/class/pwm/pwmchip1/export
*
* ls -l /sys/class/pwm/pwmchip1/pwm0/
* duty_cycle => nano seconds active time
* enable => 0 = disable, 1 = enable
* period => nano seconds active + inactive
* polarity => "normal" or "inversed"
*
* |<--------- period --------->|
*
* |<--duty cycle -->|
* 1_ _________________ _________________ _____
* | | | | |
* 0_ _| |___________| |___________| .......
*
*/
class LIBGUH_EXPORT Pwm : public QObject
{
Q_OBJECT
public:
enum Polarity {
PolarityNormal,
PolarityInversed,
PolarityInvalid
};
explicit Pwm(int chipNumber, QObject *parent = 0);
~Pwm();
static bool isAvailable();
bool exportPwm();
bool enable();
bool disable();
bool isEnabled();
int chipNumber();
long period();
bool setPeriod(long nanoSeconds);
double frequency();
bool setFrequency(double kHz);
long dutyCycle();
bool setDutyCycle(long nanoSeconds);
Pwm::Polarity polarity();
bool setPolarity(Pwm::Polarity polarity);
int percentage();
bool setPercentage(int percentage);
private:
int m_chipNumber;
long m_period;
long m_dutyCycle;
QDir m_pwmDirectory;
bool unexportPwm();
};
QDebug operator<< (QDebug d, Pwm *pwm);
#endif // PWM_H

View File

@ -42,16 +42,13 @@
\note: Radio 433 on GPIO's is by default disabled. If you want to enable it, you need to compile the source with the qmake config \tt{CONFIG+=radio433gpio}
*/
/*! \fn void Radio433::dataReceived(QList<int> rawData)
This signal is emitted when the receiver recognized a signal. The \a rawData parameter describes the signal.
*/
#include "radio433.h"
#include "loggingcategories.h"
#include "guhsettings.h"
#include "hardware/gpio.h"
#include <QFileInfo>
@ -63,14 +60,10 @@ Radio433::Radio433(QObject *parent) :
GuhSettings settings(GuhSettings::SettingsRoleGlobal);
qCDebug(dcHardware) << "Loading GPIO settings from:" << settings.fileName();
settings.beginGroup("GPIO");
int receiverGpioNumber = settings.value("rf433rx",27).toInt();
int transmitterGpioNumber = settings.value("rf433tx",22).toInt();
settings.endGroup();
m_receiver = new Radio433Receiver(this, receiverGpioNumber);
m_transmitter = new Radio433Trasmitter(this, transmitterGpioNumber);
connect(m_receiver, &Radio433Receiver::readingChanged, this, &Radio433::readingChanged);
connect(m_receiver, &Radio433Receiver::dataReceived, this, &Radio433::dataReceived);
#endif
m_brennenstuhlTransmitter = new Radio433BrennenstuhlGateway(this);
@ -81,7 +74,6 @@ Radio433::Radio433(QObject *parent) :
Radio433::~Radio433()
{
#ifdef GPIO433
m_receiver->quit();
m_transmitter->quit();
#endif
}
@ -94,24 +86,19 @@ bool Radio433::enable()
#ifdef GPIO433
// check if GPIOs are available
QFileInfo gpioFile("/sys/class/gpio/export");
if (gpioFile.exists()) {
// bool receiverAvailable = m_receiver->startReceiver();
// if (!receiverAvailable) {
// //qWarning() << "ERROR: radio 433 MHz receiver not available on GPIO's";
// }
if (Gpio::isAvailable()) {
// bool transmitterAvailable = m_transmitter->startTransmitter();
// if (!transmitterAvailable) {
// //qWarning() << "ERROR: radio 433 MHz transmitter not available on GPIO's";
// }
bool transmitterAvailable = m_transmitter->startTransmitter();
if (!transmitterAvailable) {
//qCWarning(dcHardware) << "ERROR: radio 433 MHz transmitter not available on GPIO's";
}
// if (!receiverAvailable && !transmitterAvailable) {
// qWarning() << "--> Radio 433 MHz GPIO's not available.";
// return false;
// }
if (!transmitterAvailable) {
qCWarning(dcHardware) << "--> Radio 433 MHz GPIO's not available.";
return false;
}
}
qCDebug(dcDeviceManager) << "--> Radio 433 MHz GPIO's enabled.";
qCDebug(dcDeviceManager()) << "--> Radio 433 MHz GPIO's enabled.";
#endif
return true;
@ -121,22 +108,15 @@ bool Radio433::enable()
bool Radio433::disabel()
{
m_brennenstuhlTransmitter->disable();
#ifdef GPIO433
if (m_receiver->stopReceiver()) {
return true;
}
return false;
#endif
return true;
}
void Radio433::brennenstuhlAvailableChanged(const bool &available)
{
if (available) {
qCDebug(dcDeviceManager) << "--> Radio 433 MHz Brennenstuhl LAN Gateway available.";
qCDebug(dcHardware()) << "--> Radio 433 MHz Brennenstuhl LAN Gateway available.";
} else {
qCWarning(dcHardware) << "--> Radio 433 MHz Brennenstuhl LAN Gateway NOT available.";
qCWarning(dcHardware()) << "--> Radio 433 MHz Brennenstuhl LAN Gateway NOT available.";
}
}

View File

@ -24,7 +24,6 @@
#include <QObject>
#ifdef GPIO433
#include "radio433receiver.h"
#include "radio433transmitter.h"
#endif
@ -43,15 +42,11 @@ public:
private:
#ifdef GPIO433
Radio433Receiver *m_receiver;
Radio433Trasmitter *m_transmitter;
#endif
Radio433BrennenstuhlGateway *m_brennenstuhlTransmitter;
signals:
void dataReceived(QList<int> rawData);
private slots:
void brennenstuhlAvailableChanged(const bool &available);

View File

@ -52,17 +52,18 @@ void Radio433Trasmitter::run()
rawData = m_rawDataQueue.dequeue();
m_queueMutex.unlock();
m_gpio->setValue(LOW);
m_gpio->setValue(Gpio::ValueLow);
int flag=1;
foreach (int delay, rawData) {
// 1 = High, 0 = Low
m_gpio->setValue(flag %2);
int value = flag %2;
m_gpio->setValue((Gpio::Value)value);
flag++;
usleep(delay);
}
m_gpio->setValue(LOW);
m_gpio->setValue(Gpio::ValueLow);
}
m_queueMutex.unlock();
}
@ -76,9 +77,9 @@ void Radio433Trasmitter::allowSending(bool sending)
bool Radio433Trasmitter::setUpGpio()
{
m_gpio = new Gpio(this,m_gpioPin);
m_gpio = new Gpio(m_gpioPin, this);
if(!m_gpio->exportGpio() || !m_gpio->setDirection(OUTPUT) || !m_gpio->setValue(LOW)){
if(!m_gpio->exportGpio() || !m_gpio->setDirection(Gpio::DirectionOutput) || !m_gpio->setValue(Gpio::ValueLow)){
m_available = false;
return false;
}

View File

@ -28,7 +28,7 @@
#include <QDebug>
#include "libguh.h"
#include "../gpio.h"
#include "hardware/gpio.h"
class LIBGUH_EXPORT Radio433Trasmitter : public QThread

View File

@ -34,7 +34,6 @@ HEADERS += devicemanager.h \
hardware/gpiomonitor.h \
hardware/radio433/radio433.h \
hardware/radio433/radio433transmitter.h \
hardware/radio433/radio433receiver.h \
hardware/radio433/radio433brennenstuhlgateway.h \
network/upnpdiscovery/upnpdiscovery.h \
network/upnpdiscovery/upnpdevice.h \
@ -65,6 +64,7 @@ HEADERS += devicemanager.h \
types/ruleaction.h \
types/ruleactionparam.h \
types/statedescriptor.h \
hardware/pwm.h
SOURCES += devicemanager.cpp \
@ -79,7 +79,6 @@ SOURCES += devicemanager.cpp \
hardware/gpiomonitor.cpp \
hardware/radio433/radio433.cpp \
hardware/radio433/radio433transmitter.cpp \
hardware/radio433/radio433receiver.cpp \
hardware/radio433/radio433brennenstuhlgateway.cpp \
network/upnpdiscovery/upnpdiscovery.cpp \
network/upnpdiscovery/upnpdevice.cpp \
@ -110,6 +109,7 @@ SOURCES += devicemanager.cpp \
types/ruleaction.cpp \
types/ruleactionparam.cpp \
types/statedescriptor.cpp \
hardware/pwm.cpp
# install plugininfo python script for libguh-dev

View File

@ -614,9 +614,6 @@ bool DevicePlugin::transmitData(int delay, QList<int> rawData, int repetitions)
switch (requiredHardware()) {
case DeviceManager::HardwareResourceRadio433:
return deviceManager()->m_radio433->sendData(delay, rawData, repetitions);
case DeviceManager::HardwareResourceRadio868:
qCDebug(dcDeviceManager) << "Radio868 not connected yet";
return false;
default:
qCWarning(dcDeviceManager) << "Unknown harware type. Cannot send.";
}

View File

@ -1,6 +1,6 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* Copyright (C) 2015 Simon Stuerz <simon.stuerz@guh.guru> *
* Copyright (C) 2015 Simon Stürz <simon.stuerz@guh.guru> *
* Copyright (C) 2014 Michael Zanetti <michael_zanetti@gmx.net> *
* *
* This file is part of guh. *