I have a doubt about building a menu with pushbuttons.
Initially, I have to wait for a button to be pressed.
When someone goes, I have to open the option for the button pressed. I tried as follows but I was not successful. Does anyone have any suggestions?
void loop() {
int button1 = digitalRead(but1);
int button2 = digitalRead(but2);
while (button1 == LOW && button2 ==LOW) {};
while (button1 == HIGH || button2 ==HIGH) {
if (button1 == HIGH) {
Serial.print("RFID")
rfid_menu();
}
if (button2 == HIGH) {
Serial.print("FingerPrint")
fingerprint_menu();
}
};
}
the reason your code gets stuck is because of the values button1 and button2 in the line:
while (button1 == LOW && button2 ==LOW) {};
when the code first runs, it assigns the values LOW to both of these variables.
While both of these values are LOW, the code within the loop (in this case, nothing) will loop forever until the value of button1 or button2 changes. However, as there is no code within the loop, this will never happen
to fix this, I would just delete that line of code. your code will still work as the other two while loops will only execute when one of the buttons is pressed (assuming everything is wired up correctly)
Related
For a project I'm trying to get out of the Arduino loop() function and 'loop' in another function. I'm trying to make a sort of menu where the user can loop through and press an OK-button to confirm.
My setup is as follows;
Up button, OK button, Down button, set temperature button
Whenever the user pushes the temperature button, I'd like to give the user 2 options (using a LCD); change the minimum or the maximum temperature. I'd like to cycle through these options using the up and down button and give the user the option to confirm either of these temperature changes with the OK button. For some reason the Arduino doesn't listen to any button presses after I press the temperature button anymore. See code example below.
const int UpButton = 3;
const int OKButton = 4;
const int DownButton = 5;
const int ChangeTemperatureButton = 6;
void setup() {
pinMode(UpButton, INPUT_PULLUP);
pinMode(OKButton, INPUT_PULLUP);
pinMode(DownButton, INPUT_PULLUP);
pinMode(ChangeTemperatureButton, INPUT_PULLUP);
}
void loop() {
if (!digitalRead(ChangeTemperatureButton)) {
changeTemperature();
}
if (!digitalRead(OKButton)) {
// set LCD to 'not good'
}
}
void changeTemperature() {
// set LCD to 'Changing temperature'
if (!digitalRead(OKButton)) {
// set LCD to 'Set max temperature'
}
}
Whenever I press the button to change the temperature it does set the LCD to 'Changing temperature'. After that I press the OK button and instead of it changing to 'Set max temperature' it changes to 'not good', which is in the loop. I think I fundamentally understand something wrong here, can anyone help me out with this one?
TL;DR: I'm trying to get and stay out of the loop when I press a certain button so my button can do something else than is defined in the loop. After everything in the changeTemperature function is set and done, I'd like to return to the loop function.
When you press the ChangeTemperatureButton, and your program enters the changeTemperature() function, it immediately sets the LCD to 'Changing temperature' as you said.
The next thing it does is evaluate the condition of the if statement.
if (!digitalRead(OKButton)) {
If the condition of an if statement is false, then it is skipped over.
So if you are not simultaneously holding down the OKButton when you press the ChangeTemperatureButton, then that code will be skipped, and hence you are not seeing the 'Set max temperature' on your LCD.
I think I see though what you after, which is basically having a sub-menu, which is a very common feature of menus in general.
You might consider looking at some example code for LCD menus that use submenus to get an idea of how to implement your code.
You've gotten a good suggestion from YouJeng. To expand on that answer...
In your loop you'll do your initial button detection and debouncing work. Once the user presses the ChangeTemperatureButton your loop should call another function say "changeTemp()". You'll keep yourself in this function until you hit "OK".
There are tons of ways to accomplish this, but here's some simple pseudo-code:
void loop() {
//Draw your main menu buttons
//Handle button presses
if(ChangeTemperatureButton) {
changeTemp()
}
//Anything else your sketch needs to do
}
void changeTemp() {
bool okPressed = false;
//Display your text for the buttons in this mode
//Increase, decrease, OK (for example)
if(increase) {
//do something
}
if(decrease) {
//do something
}
if(OK) {
okPressed = true;
}
if(!okPressed) { //This essentially keeps you in this mode until you hit the OK button
changeTemp();
}
}
There are certainly cleaner ways to do this, but this is exactly how I've done it on other projects and it works great for a quick prototype.
I’m try to get it to work but it turns when I press the button and goes back when I let go of the button at the moment
//sketch created by Akshay Joseph follow me on Instagra: five_volt_player
include<Servo.h>
Servo Myservo;
int pos=0;
void setup()
{
pinMode(2,INPUT);
Myservo.attach(3);
}
void loop()
{
if(digitalRead(2)==LOW){
Myservo.write(180);
}
else
Myservo.write(0);
}
Many times a second it is "checking" to see what it should be doing. Right now your code says, "If at this exact moment I am pushing the button, then go to 180. Otherwise (If I'm not pushing the button) go to 0."
There are a few different ways to do what you're trying to do. Keep experimenting!
I would probably create a variable at the top of your code before void loop(), something like this:
int motorState = 0;
Then have the Myservo.write(motorState) each time just inside void loop().
For the if else statement in, I would say (unformatted) something like: if the button is pressed and motorState==180, then motorState==0.
Else if button pressed and motorState=180, then motorState==0.
I've written a program with different functions in Qt. Now I want to make a Gui. For example I have two buttons, button1 and button2. I open the application, i see button1 first. Then I click button1, it executes its function (like "start") and disappears. Then button2 should appear and when I click button2 it executes its function (like "stop") and disappears and button1 shows up again to be clicked to execute start.
My question now is, how to solve this in an easy way?
void gui::on_pushButton_clicked()
{
//execute start, switch to be button2
}
void gui::on_pushButton_2_clicked()
{
//execute stop, switch to be button 1
}
The following seems to be the easiest solution, but a bit cumbersome in case you want to add more buttons. In that case you might want to consider storing them in a list and iterating the list.
void gui::on_pushButton_clicked()
{
//execute start, switch to be button2
ui->pushButton->hide();
ui->pushButton_2->show();
}
void gui::on_pushButton_2_clicked()
{
//execute stop, switch to be button 1
ui->pushButton->show();
ui->pushButton_2->hide();
}
If you further on decide to implement even more logic, you should consider using QStateMachine and setting certain buttons to visible or hidden when entering or exiting certain states.
I am connecting Processing and an Arduino pushbutton. It's successfully connected with Standard Firmata. What I want to happen is that when the button is pressed, an image will show up in Processing but also stay on the screen, just like the LED, and then when the button is pressed again, the image will disappear from the screen. I'm just testing it with shapes for now. I have tested it with an LED and that works fine. Any ideas what I'm doing wrong? This is the code I have:
void draw()
{
buttonState = arduino.digitalRead(buttonPin);
if (buttonState == arduino.HIGH && buttonPressed == 0)
{
buttonPressed = 1;
rect(10, 10, 10, 10);
text("hello", 10, 10);
}
if (buttonState == arduino.LOW && buttonPressed == 1)
{
buttonPressed = 0;
rect(50, 50, 10, 10);
}
}
I'm not sure how you've wired up your button. I'm assuming it goes HIGH when you press it.
Currently, your first if statement will get triggered when the button is pressed, but only if it wasn't pressed last time you checked (i.e. it's effectively rising edge triggered).
Your second if statement will get triggered when the button is released, but only if it wasn't released last time you checked (i.e. it's effectively falling edge triggered).
If you want the button to toggle something each time it's pressed, then you will probably need to put most of your logic into the first if statement (except the buttonPressed stuff). You will need to store some kind of value which says if the image is currently visible. If it's visible when the button is pressed, then hide it (and vice versa).
For example:
boolean imageVisible = false;
void draw()
{
buttonState = arduino.digitalRead(buttonPin);
if (buttonState == arduino.HIGH && buttonPressed == 0)
{
buttonPressed = 1;
if (imageVisible) {
// Hide image here...
} else {
// Show image here...
}
imageVisible = !imageVisible;
}
if (buttonState == arduino.LOW)
{
buttonPressed = 0;
}
}
Note: I removed the buttonPressed check from the second if statement. It's only necessary if you actually need to respond to a falling-edge event. For a simple toggle, it's not important.
I have a QMainWindow, and want to handle the "clicked" signal from a smaller widget (such as tableview) inside it.
Originally I connect the signal to a slot of this QMainWindow, this is the most common approach.
Now I need to tell which mouse button is clicked, and do different things for left and right button, I found that the "clicked" signal don't have the mouse event information.
I tried to implement the "mousePressEvent" function,but there are still some problem. if the mouse action is acted on the smaller widget, the MainWindow won't go into its mousePressEvent.
Some document says that we can tell the button by QQApplication::mousebuttons()
http://bugreports.qt-project.org/browse/QTBUG-1067
and I also found some sample code. However, this is for "press event", but I want to get the mouse button for "click event".
Follows is the sample code :
connect(moduleTree,SIGNAL(itemPressed(QTreeWidgetItem *, int)),this,SLOT(SlotItemClicked(QTreeWidgetItem *, int)));
void CGuiMainwindow::SlotItemClicked(QTreeWidgetItem *item, int column)
{
if (qApp->mouseButtons() == Qt::LeftButton)
{ return; }
if (qApp->mouseButtons() == Qt::RightButton)
{
......
}
}
When I try to do this, neither of the 2 if statements will be satisfied, I don't know why. the qApp->mouseButtons() always return 0, how can I get the clicked mouse button by QApplication::mouseButtons?
In my code, the slot looks like that :
void clickItem( const QModelIndex & idx){.....}
You get 0 becouse clicked is emited after mouse release, not at mouse press. What do you want to achieve ? Maybe try settings on you widget contextMenuPolicy to custom, and than connect to signal contextMenuRequested (for the right click) and clicked for the left click ?
for "connect" use this:
connect(moduleTree,SIGNAL(itemClicked(QTreeWidgetItem *,int )),this
,SLOT(SlotItemClicked(QTreeWidgetItem *, int)));
define a global flag:
public:
Qt::MouseButton mouseClickedBtnFlag;
and then reimplement "mouseReleaseEvent":
CGuiMainwindow::mouseReleaseEvent ( QMouseEvent * event )
{
mouseClickedBtnFlag = event->button();
}
and then:
void CGuiMainwindow::SlotItemClicked(QTreeWidgetItem *item, int column)
{
if (mouseClickedBtnFlag == Qt::LeftButton)
{ return; }
if (mouseClickedBtnFlag == Qt::RightButton)
{
......
}
}
Qt::MouseButtons is a QFlags type. You can't test it with == operator. Use & operator for testing:
if(QApplication::mouseButtons() & Qt:LeftButton) {
...
}