Checking if my user button on stm32 is functioning or not - button

this is my first time of asking a question in stackoverflow, sorry if my english is not really good. I hope this is a good start.
I am currently trying to use my stm32's key button/ user button (i mean the one button which already included on it in buying written "key") and i want to use the button to do some project. I did some research and found the key button is on pin A0, so i labelled it to BUTTON. So i try to check if the button is functioning using this code:
on private variable section
int a; //variable declare
on while section
while (1){
a = 0
if (HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin)){
a = 1;
} else {
a = 0;
}
}
i'm expecting that when i debug the code and then see the live variable, i will find that variable "a" is gonna turn into 1 when i press the key button, but it is not working as i expected. The variable "a" is still on 0 whatever i do.
im kinda desperate, please help, i appreciate all of the answer :D.

You are setting a = 0; every time around the loop. It might briefly be set to 1 if the button is pressed, but then it will be set back to zero.
Also, the compiler may well detect that the variable a is not actually used for anything, so it might just optimize out the setting of a.
Lastly, HAL_GPIO_ReadPin() can return GPIO_PIN_RESET or GPIO_PIN_SET. So you should test that it is one of those.
Try this:
volatile int a = 0; // Tell compiler not to optimize out setting of 'a'
while (1) {
// No need to set 'a' to zero here
if (HAL_GPIO_ReadPin(BUTTON_GPIO_Port, BUTTON_Pin) == GPIO_PIN_SET){
a = 1;
} else {
a = 0;
}
}

Related

Button debounce intermittent in Arduino

What I'd like to accomplish is for the button to be called once after I press it with my fingers. Sometimes it works but there are also times it doesn't. Let's say I need to select from a menu. There are times that when I press down or up button, it moves perfectly but sometimes, it will move twice with a single press. I'd like to get that issue fixed.
Somewhere in global:
int debounceDelay = 50;
The code inside the loop
a3StateDownButton = digitalRead(A3);
if (a3StateDownButton != a3DownButtonLastState) {
a3DownButtonLastDebounceTime = millis();
}
if ((millis() - a3DownButtonLastDebounceTime) > debounceDelay) {
if (a3StateDownButton != currenta3ButtonState) {
currenta3ButtonState = a3StateDownButton;
if (currenta3ButtonState == HIGH) {
isDownButtonPressed = true;
// do what ever you need to do when button is high
} else if (currenta3ButtonState == LOW) {
isDownButtonPressed = false;
}
}
}
a3DownButtonLastState = a3StateDownButton;
The button I am using is very similar to this, almost exactly the same.
I only have a resistor connected to one of the pins but I forgot the value I put, most likely 2.2k.
So again, sometimes it's good but not constantly perfect. I'm also thinking that playing with the value of debounceDelay might affect my menu, which I remember it did. The response became slower when the value was increased. I think this is called software debouncing. Maybe there is something I can add to make it a hardware debouncing.

How do I use a variable from another class in Unreal Script?

I am working on a game, and that game has a battery life function for a flash light. Basically, when the flash light is turned on, it reduces the life and when it's off, it stops.
But to achieve this, I need to access a variable that will determine whether or not the flash light is turned on or off.
var UTWeap_FlashLight light; // declaring a new variable from the class UTWeap_FlashLight.uc
// reduces battery life of the flash light
exec function ReducePower()
{
if(light.bCheck==true)
{
if(0<power) // loops till power 1 is = 0
{
power--; // reduce the value of power
if(power==0) // if it equals 0
{
power2 = power2 - 1; // set power2 to it's own value - 1
power=100; // reset power back to 100
}
}
}
}
but whenever I compile the code, it tells me that it can't find the variable bCheck, meaning I can't check whether or not the flash light is on. I want to call that variable from this class
UTWeap_FlashLight.uc
exec function TurnOff()
{
if(!Flashlight.LightComponent.bEnabled)
{
Flashlight.LightComponent.SetEnabled(true);
bCheck = true;
}
else
{
Flashlight.LightComponent.SetEnabled(false);
}
}
this part of the code is where I turn on/off the flash light. When I turn it on, I want to set bCheck to 1 so I can then later use it as a condition to detect whether or not the flash light is on. But I can't use the variable, it will just not change it's value. I later found out you CAN'T use variables from other classes, which is pretty dumb. Any help appreciated.
Well, I figured out how to use variables from other classes in unreal script.
IF you're wondering how to do the same use this:
class'<yourclassname>'.default.<yourvariablename>; // remove the < >

Basic PIC Programming issues

I am writing PIC code in C and encountered the following problems:
When I write my delay as _delay_ms(500), my code doesn't compile, it says it didn't recognize this instruction. I am using MPLAB.
I want to write a program that would count how many time the push button is pressed then return that value and display it using LED's. I know how to display it, but not how to make the program to wait for the push of the push button on the pickit.
main()
{
TRISA=0;//Sets all ports on A to be outputs
TRISB=1;//Sets all ports on B to be inputs
for(;;){
if(PORTBbits.RB0==1){//When the button is pressed the LED is off
PORTAbits.RA1 =0;
count=count+1;
}
else{
PORTAbits.RA1=1;
count = count +1;
}
if (count > 20){//if count =20 aka 20 button presses the LED turns on
PORTAbits.RA0=1;
}
else{
PORTAbits.RA0=0;
}
}
}
There are a few issues:
Assuming you're using a PIC24 or a dsPIC, you need to include libpic30.h
Before you include libpic30.h you need to #define FCY to be your instruction rate so that the delay takes the correct number of cycles. See the comments in the libpic30.h file for details.
The function is __delay_ms not _delay_ms. Note that there are two underscores at the beginning.
The name is all lower case, not Delay_ms as in your comment.
You need to add delay in your code when you detect a key is pressed. As you are saying the _delay_ms(500) is not recognized, You can try something like following:
unsigned char x;
// Just waste a few cycles to create delay
for (x = 0; x < 100; x++)
{
// No operation instruction
Nop();
}
You can create your own delay function with specific number of iterations of this for loop. Measure the exact delay created by this function using a profiler if you need. IMO any arbitrary delay, like say 100 iterations as stated above shall work.

QTextEdit and cursor interaction

I'm modifying the Qt 5 Terminal example and use a QTextEdit window as a terminal console. I've encountered several problems.
Qt does a strange interpretation of carriage return ('\r') in incoming strings. Ocassionally, efter 3-7 sends, it interprets ('\r') as new line ('\n'), most annoying. When I finally found out I choose to filter out all '\r' from the incoming data.
Is this behaviour due to some setting?
Getting the cursor interaction to work properly is a bit problematic. I want the console to have autoscroll selectable via a checkbox. I also want it to be possible to select text whenever the console is running, without losing the selection when new data is coming.
Here is my current prinout function, that is a slot connected to a signal emitted as soon as any data has arrived:
void MainWindow::printSerialString(QString& toPrint)
{
static int cursPos=0;
//Set the cursorpos to the position from last printout
QTextCursor c = ui->textEdit_console->textCursor();
c.setPosition(cursPos);
ui->textEdit_console->setTextCursor( c );
ui->textEdit_console->insertPlainText(toPrint);
qDebug()<<"Cursor: " << ui->textEdit_console->textCursor().position();
//Save the old cursorposition, so the user doesn't change it
cursPos= ui->textEdit_console->textCursor().position();
toPrint.clear();
}
I had the problem that if the user clicked around in the console, the cursor would change position and the following incoming data would end up in the wrong place. Issues:
If a section is marked by the user, the marking would get lost when new data is coming.
When "forcing" the pointer like this, it gets a rather ugly autoscroll behaviour that isn't possible to disable.
If the cursor is changed by another part of the program between to printouts, I also have to record that somehow.
The append function which sound like a more logical solution, works fine for appending a whole complete string but displays an erratic behaviour when printing just parts of an incoming string, putting characters and new lines everywhere.
I haven't found a single setting regarding this but there should be one? Setting QTextEdit to "readOnly" doesn't disable the cursor interaction.
3.An idea is to have two cursors in the console. One invisible that is used for printouts and that is not possible at all to manipulate for the user, and one visible which enables the user to select text. But how to do that beats me :) Any related example, FAQ or guide are very appreciated.
I've done a QTextEdit based terminal for SWI-Prolog, pqConsole, with some features, like ANSI coloring sequences (subset) decoding, command history management, multiple insertion points, completion, hinting...
It runs a nonblocking user interface while serving a modal REPL (Read/Eval/Print/Loop), the most common interface for interpreted languages, like Prolog is.
The code it's complicated by the threading issues (on user request, it's possible to have multiple consoles, or multiple threads interacting on the main), but the core it's rather simple. I just keep track of the insertion point(s), and allow the cursor moving around, disabling editing when in output area.
pqConsole it's a shared object (I like such kind of code reuse), but for deployment, a stand-alone program swipl-win is more handy.
Here some selected snippets, the status variables used to control output are promptPosition and fixedPosition.
/** display different cursor where editing available
*/
void ConsoleEdit::onCursorPositionChanged() {
QTextCursor c = textCursor();
set_cursor_tip(c);
if (fixedPosition > c.position()) {
viewport()->setCursor(Qt::OpenHandCursor);
set_editable(false);
clickable_message_line(c, true);
} else {
set_editable(true);
viewport()->setCursor(Qt::IBeamCursor);
}
if (pmatched.size()) {
pmatched.format_both(c);
pmatched = ParenMatching::range();
}
ParenMatching pm(c);
if (pm)
(pmatched = pm.positions).format_both(c, pmatched.bold());
}
/** strict control on keyboard events required
*/
void ConsoleEdit::keyPressEvent(QKeyEvent *event) {
using namespace Qt;
...
bool accept = true, ret = false, down = true, editable = (cp >= fixedPosition);
QString cmd;
switch (k) {
case Key_Space:
if (!on_completion && ctrl && editable) {
compinit2(c);
return;
}
accept = editable;
break;
case Key_Tab:
if (ctrl) {
event->ignore(); // otherwise tab control get lost !
return;
}
if (!on_completion && !ctrl && editable) {
compinit(c);
return;
}
break;
case Key_Backtab:
// otherwise tab control get lost !
event->ignore();
return;
case Key_Home:
if (!ctrl && cp > fixedPosition) {
c.setPosition(fixedPosition, (event->modifiers() & SHIFT) ? c.KeepAnchor : c.MoveAnchor);
setTextCursor(c);
return;
}
case Key_End:
case Key_Left:
case Key_Right:
case Key_PageUp:
case Key_PageDown:
break;
}
you can see that most complexity goes in keyboard management...
/** \brief send text to output
*
* Decode ANSI terminal sequences, to output coloured text.
* Colours encoding are (approx) derived from swipl console.
*/
void ConsoleEdit::user_output(QString text) {
#if defined(Q_OS_WIN)
text.replace("\r\n", "\n");
#endif
QTextCursor c = textCursor();
if (status == wait_input)
c.setPosition(promptPosition);
else {
promptPosition = c.position(); // save for later
c.movePosition(QTextCursor::End);
}
auto instext = [&](QString text) {
c.insertText(text, output_text_fmt);
// Jan requested extension: put messages *above* the prompt location
if (status == wait_input) {
int ltext = text.length();
promptPosition += ltext;
fixedPosition += ltext;
ensureCursorVisible();
}
};
// filter and apply (some) ANSI sequence
int pos = text.indexOf('\x1B');
if (pos >= 0) {
int left = 0;
...
instext(text.mid(pos));
}
else
instext(text);
linkto_message_source();
}
I think you should not use a static variable (like that appearing in your code), but rely instead on QTextCursor interface and some status variable, like I do.
Generally, using a QTextEdit for a feature-rich terminal widget seems to be a bad idea. You'll need to properly handle escape sequences such as cursor movements and color mode settings, somehow stick the edit to the top-left corner of current terminal "page", etc. A better solution could be to inherit QScrollArea and implement all the needed painting–selection-scrolling features yourself.
As a temporary workaround for some of your problems I can suggest using ui->textEdit_console->append(toPrint) instead of insertPlainText(toPrint).
To automatically scroll the edit you can move the cursor to the end with QTextEdit::moveCursor() and call QTextEdit::ensureCursorVisible().

How to maintain vertical scroll position in a QTableWidget

This a very simple problem to which I can find no solution:
This is my code:
qint32 pos = ui->twShow->verticalScrollBar()->value();
ui->twShow->blockSignals(true);
//Code for updating the contents QTableWidget twShow, this is done by erasing all cells and adding them again, in case it matters.
ui->twShow->blockSignals(false);
if (pos > 0){
ui->twShow->verticalScrollBar()->setValue(pos);
}
What I want to accomplish is simply to maintain the vertical scroll position. However the setValue function ignores the value pos (I've checked by printing the value before and after the instruction and both times its cero).
I have also tried:
QScrollBar *bar = ui->twShow->verticalScrollBar();
// Same code as before
ui->twShow->setVerticalScrollBar(bar); //This line crashes de program
However the last line crashes the program (which I've checked by commenting it, and it works fine).
Any advice would be greatly appreciated...
Thank you very much
QTableWidget * tw;
int desiredRow;
// before update
desiredRow = tw->row(tw->itemAt(1,1));
...
// update code
...
tw->scrollToItem( tw->item( desiredRow, 0),
QAbstractItemView::EnsureVisible | QAbstractItemView::PositionAtTop );
QAbstractItemView::EnsureVisible = 0.
The 'or' flag converts the result to an integer which is not allowed as parameter of the scrollToItem method. On the other hand enums are not intended to be used as combined flags.

Resources