I have som code that i found for accessing the gpio pins on the rpi with intellij.
I also built some simple javaFx code, a simple window with 3 buttons. I want those 3 buttons to turn pin on, turn pin off, and shutdown window. I have all the code I need i just dont know how to put it toghether. Both
codes works on their own.
I am building an irregation system for plants and I have all the hardware working, In this first version I just want to use simple on off function.
This is my javafx code without imports, verry simple.
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Title of Window");
button1 = new Button("Start");
button2 = new Button("Stop");
button3 = new Button("Exit");
button1.setOnAction(e -> ); // Start gpio
button2.setOnAction(e -> ); // Stop gpio
button3.setOnAction(e -> primaryStage.close());
StackPane layout = new StackPane();
layout.getChildren().add(button1);
button1.setTranslateX(0);
button1.setTranslateY(20);
layout.getChildren().add(button2);
button2.setTranslateX(50);
button2.setTranslateY(20);
layout.getChildren().add(button3);
button3.setTranslateX(108);
button3.setTranslateY(20);
Scene scene = new Scene(layout, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
}
And this is the method I want to link button to 1 & 2.
public class gpio {
public static void main(String[] args) throws InterruptedException {
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalOutput pin =
gpio.provisionDigitalOutputPin(RaspiPin.GPIO_07, "MyLED", PinState.HIGH);
pin.setShutdownOptions(true, PinState.LOW);
// toggle the current state of gpio pin #01 (should turn on)
pin.toggle();
System.out.println("--> GPIO state should be: ON");
// toggle the current state of gpio pin #01 (should turn off)
pin.toggle();
System.out.println("--> GPIO state should be: OFF");
}
}
code found here https://pi4j.com/1.2/example/control.html
This is pobably easy to solve but its a hard nut for me to crack so I was hoping to learn from someone more gifted in java then me, or if I could be pointed to someone eith similar problems.
Same thing for button2
button1.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
final GpioController gpio = GpioFactory.getInstance();
final GpioPinDigitalOutput pin =
gpio.provisionDigitalOutputPin(RaspiPin.GPIO_07, "MyLED", PinState.HIGH);
pin.setShutdownOptions(true, PinState.LOW);
// toggle the current state of gpio pin #01 (should turn on)
pin.toggle();
System.out.println("--> GPIO state should be: ON");
}
});
PS : Don't forget the necessary imports
Related
I want to use a QTimer object to control a LED indictor status. A QLed class inherited QWidget is created to control the LED indicator. Here below its two major functions relevant:
void QLed::setLEDFlashing(bool value)
{
ledStatus = value; //Boolean value to accept a user-defined LED status
m_value = ledStatus; //m_value is used in painting LED (with QtSvgRenderer)
QTimer ledTimer;
ledTimer.setInterval(300);
if(!ledTimer.isActive())
{
ledTimer.start();
}
//Here is the connection between the timer and this (i.e., QLed*) object
connect(&ledTimer, SIGNAL(timeout()), this, SLOT(setLEDFlashingTimerHandler()));
}
//I want to use this function to make LED keep flashing
void QLed::setLEDFlashingTimerHandler()
{
//qDebug()<<"setLEDFlashingTimerHandler()";
if (ledStatus)
{
m_value = TRUE;
ledStatus = FALSE;
}
else
{
m_value = FALSE;
ledStatus =TRUE;
}
}
//This is to paint the LED widget
void QLed::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
//based on m_value, different svg file is loaded
if(m_value)
ledShapeAndColor.append(colors[m_onColor]);
else
ledShapeAndColor.append(colors[m_offColor]);
renderer->load(ledShapeAndColor);
renderer->render(&painter);
//qDebug()<<"paintEvent m_value="<<m_value;
}
In the mainwindow.ui, I add a QLabel object (named led) and promote it to QLed, and in the mainwindow.cpp:
ui->led->setLEDFlashing(TRUE);
The above codes cannot result in a flashing LED indicator. Actually, the connection between ledTimer and setLEDFlashingTimerHandler does NOT take effect for some reason, and m_value is not updated in paintEvent. Anyone can help debug my codes? Thanks!
Edits:
I have solved the connection issue by using QTimer *ledTimer in stead of QTimer ledTimer. But the painting still not works as expected, since m_value is not updated in that function or the function is only invoked for the very first time?
In your function QLed::setLEDFlashing, you create a local instance of QTimer which will be destroyed at the end of your function.
You should declare your QTimer as an attribute of your class or use a inner timer with QObject::startTimer
I am trying to connect mainwindow and dialog using signal and slot. I am very new to qt. I have a lineEdit and a pushButton in mainwindow.ui, a lineEdit in dialog.ui. And I have those very basic code:
mainwindow.h:
signals:
void sendString(QString);
mainwindow.cpp:
void MainWindow::on_pushButton_clicked()
{
Dialog *mDialog = new Dialog(this);
emit sendString(ui->lineEdit->text());
connect(this, SIGNAL(sendString(QString)), mDialog, SLOT(showString(QString)));
mDialog->show();
}
dialog.h:
private slots:
void showString(QString);
dialog.cpp:
void Dialog::showString(QString str)
{
ui->lineEdit->setText(str);
}
But after I clicked the pushButton, the dialog showed, but nothing changed in the lineEdit.I hope I explain this clearly enough?
Can someone explain to me why and how to solve this? Thanks.
emit signal after connect
void MainWindow::on_pushButton_clicked()
{
Dialog *mDialog = new Dialog(this);
connect(this, SIGNAL(sendString(QString)), mDialog, SLOT(showString(QString)));
mDialog->show();
emit sendString(ui->lineEdit->text());
}
You have to create the connection before the emit.
But in your case you dont need the signal of the of the mainwindow at all. You invoke the showString method directly.
Hi I have a bellowing code. I want to add some delay (6second) for appering QMesaageBox. But in background reading 2 ports. I dont want to delay block port value.
motorStart();
QString msv = "msv?0;";
loadcellPort->write(msv.toStdString().c_str(),msv.length());
plotFlag = true;
newPlot = true;
ui->startButton->setEnabled(false);
ui->cancelButton->setEnabled(false);
QTimer::singleShot(5000,this,SLOT(onSerialLoadcellData()));
QMessageBox::information(this,"Bastak Test",json_map["QWater"].toString(),json_map["QFinishAccept"].toString());
I was use QThread before and this thread bloking port value ?
class Sleeper : public QThread
{
public:
static void msleep(unsigned long msecs){QThread::msleep(msecs);}
};
I have this two classes: board.h and scene.h.When I run program like this everything works fine:
scene.cpp
scene::scene()
{
basescene=new QGraphicsScene;
additem();
}
void scene::additem()
{
board *_board=new board;
QPixmap boarditem (":/images/board.png");
_board->setPixmap(boarditem);
basescene->addItem(_board);
}
scene.h
class scene:public QGraphicsScene
{
public:
scene();
QGraphicsScene *basescene;
void additem();
};
board.h
class board:public QGraphicsPixmapItem
{
public:
board();
};
board.cpp
board::board()
{
}
But when i run it like this:
scene.h
class scene:public QGraphicsScene
{
public:
scene();
QGraphicsScene *basescene;
};
scene.cpp
scene::scene()
{
basescene=new QGraphicsScene;
board _board;
}
board.h
class board:public QGraphicsPixmapItem,public scene
{
public:
board();
void additem();
board *_board;
};
board.cpp
board::board()
{
additem();
}
void board::additem()
{
board *_board=new board;
QPixmap boarditem (":/images/board.png");
_board->setPixmap(boarditem);
basescene->addItem(_board);
}
The program crashes and debugger says that the error is in scene class and the code has a segment fault.I googling and it said that is some pointer issue... I'm newbie in c++ and debug thing and sorry about my bad english.
You inherited class board from scene.
When you create an instance of board the scene constructor is executed, then the board constructor is executed.
But in the scene constructor you create a new instance of board. And scene constructor of this new instance creates another instance of board. And so on till infinity.
If you need more info about constuctors calling:
Order of calling constructors/destructors in inheritance
EDIT:
Actually if it has overcome this issue and walk further it would come to the board constructor which calls addItem which creates another board instance. In the constructor of this new instance addItem will be called again and it will try to create another one board and again, and again.
So you have a couple of recursive constructor calls.
I am trying to build an QT State Maschine. I have some States, and for those States i need Transition that alter the Graphics on my gui.
The Problem i having and the only reason i am asking, i am Stuck and Point 1.
The compiler cant identifie the QTEventTransition. I have QT 4.6 wroking with QT Creator on Windows.
The compiler does not find Header #include < QtEventTransition >
This is what i did i never did this bevor but i think it should be correct, I have A Header File where i have my Transitions Declareted like this:
class validateBoatTransition : public QtEventTransition
{
public:
validateBoatTransition(Widget *widget,ServerSkeleton* server);
protected:
bool eventTest(QEvent *e);
void onTransition(QEvent *);
private:
Chart* ourChart;
Message current;
BarelySocket* myBarelySocket;
};
Than i have my Cpp File where i have this:
validateBoatTransition::validateBoatTransition(Widget *widget,ServerSkeleton* server)
{
}
void validateBoatTransition::onTransition(QEvent *e)
{
/*
My Logik should go here
*/
}
What i want is that if the Transition is activated by an Button (clicked) it should fire this transition!
I searched the net, but cant find an solution. Can i do that? I should i think.
Yours Thomas
Maybe you should take a look to signals/slot mechanism. I think this is what you need to achieve what you want.
Make your onTransition function a slot instead of an event handler and connect it to the signal clicked of the button.
class validateBoatTransition : public QtEventTransition
{
...
public slots:
void onTransition();
...
}
Somewhere in your code, connect the button to the slot:
QObject::connect(myButton, signal(clicked()), myValidateBoatTransition, slot(onTransition());
Each time the button will be clicked the execution will go through the onTransition function.
I think you're trying to use wrong classes/mechanisms to achieve your goals. If I understand you correctly, you have some GUI and after clicking some button you want to validate some stuff and if this validation is successful the state machine should change it's state. I'd write it this way:
Create some class to handle validation:
class BoatValidator : public QObject
{
Q_OBJECT
// boring stuff like constructor, etc.
public slots:
void validate()
{
if ( /*your validation logic goes here*/ ) {
emit boatTransition();
}
}
signals:
void boatTransition(); // emitted if validation is succesful
};
Then you connect your QPushButton::clicked() to BoatValidator::validate() and use BoatValidator::boatTransition() signal to drive the state machine:
QStateMachine machine;
QState *state1 = new QState(&machine);
QState *state2 = new QState(&machine);
// more state machine setup
// connect validator and button
QPushButton button;
BoatValidator validator;
connect(&button, SIGNAL(clicked()), &validator, SLOT(validate()));
// use validator to change states
state1->addTransition(&validator, SIGNAL(boatTransition()), state2);
Generally I'd use signal to drive state machine, unless some transitions are obviously event driven (for example some QEvent::Enter/QEvent::Leave on GUI widgets, etc.).
What i wanted to do is build a Qt State Machine. The Problem was that i could not trigger my own Transitions (let alone with my own Events). The answers given are good but would lead to a messy code. Why should i use a QT State Machine if i could not use the QT Transitions?
The First Problem above is solved, if you create a new Project. QT Creater is very annoying.
But here now my solution , may it help others.
First my State:
class ServerState : public QState
{
Q_OBJECT
public:
ServerState(QPushButton * pushButton);
~ServerState();
public slots:
void buttonWasClicked();
protected:
void onEntry(QEvent *e);
void onExit(QEvent *e);
private:
QPushButton * pushButton;
};
Normal, but you see i added an Slot. This slot enables me to connect a bottom signal or a Widget Mouse Press Signal to it !
Like this:
QStateMachine *machine = new QStateMachine(this);
ServerState *s1 = new ServerState(connectButton);
connect(connectButton, SIGNAL(clicked()), s1, SLOT(buttonWasClicked()));
machine->addState(s1);
s1->addTransition(connectTransition);
all i needed to to is now fire a declared Event like this one :
#define RegisterToServerEventIndex User+5
class ConnectToServerEvent : public QEvent
{
public:
ConnectToServerEvent() : QEvent(QEvent::Type(QEvent::ConnectToServerEventIndex))
{}
};
when the slot was called:
void ServerState::buttonWasClicked()
{
this->machine()->postEvent(new ConnectToServerEvent());
qDebug("ServerState::buttonWasClicked");
}
The QT State Machine would now call all the Transitions , link with this state:
ConnectToServerTransition::ConnectToServerTransition(QPushButton * pushButtonB,ServerSkeleton* serverSkeleton)
{
this->pushButtonB = pushButtonB;
this->pushButtonB->hide();
this->serverSkeleton = serverSkeleton;
qDebug("ConnectToServerTransition::ConnectToServerTransition");
}
bool ConnectToServerTransition::eventTest(QEvent *e)
{
return (e->type() == QEvent::ConnectToServerEventIndex);
}
void ConnectToServerTransition::onTransition(QEvent *e)
{
if (true == this->serverSkeleton->initalisieren())
{
this->pushButtonB->show();
}else{
qDebug("Conection to Server faild");
}
emit kill();
return;
}
Whats so great that i dare to post?
Well first you can link a Qt SM to a widget where a mouse press event , or somthing else, is called and process the raw data to a an level you need later in your program. All you then need to do is, to emit the singal:
void Widget::mousePressEvent(QMouseEvent *event){
Coordinates current;
current.line = 0;
current.row = A;
current.row = (Row) (event->x() / 30); // 30 = breite von einen Feld
current.line = event->y() / 30; // 30 = länge von einen Feld
emit this->clicked(current);
return;
}
Then this enhenced information (current) is passed to the slot at my state, where i chose to call the correct transition that does the work. You could link more transitions to it, if you need it.
But most importend you dont need to reprogramm the Transition, a think i realy disliked.
Thank you for your help , i could not done it alone.