I'm trying to implement a FSM which handles a button in the following way:
When in Standby mode, it just waits for button to get pressed.
When it is pressed, it moves to intButtonPress state, where a 2 second timer is started. If it times out, it means that the button was held for 2 seconds and the next state must be Action. If the button is released before timeout, state returns to Standby as the button wasn't held long enough.
When in Action mode, some action is performed, but it can be interrupted by the button press. Problem is that i can't reuse intButtonPress state since it's timeout transition would lead back to Action state, so an obvious solution is to use an identical state whose only difference is that it leads to Standby state, but it's ugly.
Are there better ways to handle this?
FSM is here: http://i.imgur.com/m57yaMw.png (can't embed pictures)
Answering my own question - use hierarchical state machines: http://i.imgur.com/DzBApeY.png
Super-Standby state is not strictly needed.
Related
The Atmel SAMD21 TCC peripheral provides a STOP command, which pauses the counter. The counter can be resumed with a RETRIGGER command.
When STOP is issued, the TCC enters a fault state, in which the outputs are either tristated, or driven to states specified in a config register. Presumably this mechanism is designed to support a fixed failsafe output state.
In my case I want the output pins to freeze in the state they're in at the time of the STOP command. The only way I can see to to do this is to update the configured fault output state register every time the outputs are updated - requiring interrupt processing which kind of defeats the purpose of much of the TCC's output waveform extension architecture, as well as being a processing load I'd prefer to avoid. There are other complications too, such as accounting for the dead time mechanism, and hardware/software races.
So I've been looking at ways to achieve this that don't involve the STOP command - but I can't see any other way of stopping the counter. There's no way to gate the peripheral clock input, and disabling it in GCLK is ruled out as it also runs TCC1. (And who knows what other effects this would have.) Negating the ENABLE bit, besides being overkill, unsurprisingly also tristates the outputs. Modifying the configuration in various other ways usually requires writing to enable-protected registers, thus requiring disabling the peripheral first.
(One idea I haven't investigated that yet is to drive the counter from the event system, and control the event generation/gating instead.)
So: is there any way of pausing the peripheral in its current state, while maintaining the state of the output pins?
All that I can think of to try is the async 'COUNT' event, which sounds like it is a gate for the clock to the counter.
(page numbers from the 03/2016 manual)
31.6.4.3. Events, p.712;
Count during active state of an asynchronous event (increment or decrement, depending on counter direction). In this case, the counter will be incremented or decremented on each cycle of the prescaled clock, as long as the event is active.
31.8.9. Event Control, p.734;
EVCTRL register,
Bits 2:0 – EVACT0[2:0]: Timer/Counter Event Input 0 Action
0x5 COUNT (async) Count on active state of asynchronous event
The downside is that software events have to be synchronous.
In my PyQt GUI app, there are a lot of spinBoxes that trigger a lengthy setup routine when their values are changed.
My problem is this:
When typing in (large) numbers the spinBox.valueChanged() signal is emitted every time I input a single digit. That leads to the setup function being called many more times than necessary.
Is there a way to delay the trigger until I'm done typing the number and then fire the signal only once?
How do you usually take care of that issue in your GUIs?
I found this but I think it would involve creating an extra timer for every unique function I want to call upon emitting. That doesn't seem very elegant.
For spinboxes there is the keyboardTracking property.
If keyboard tracking is disabled, the spinbox doesn't emit the valueChanged() signal while typing. It emits the signal later, when the return key is pressed, when keyboard focus is lost, or when other spinbox functionality is used, e.g. pressing an arrow key.
I believe this solves your issue.
You can also connect to the editingFinished signal, which isn't emitted until the user presses enter or the spinbox loses focus. However, you'll get this signal even if the value doesn't change, so you may want to check it against the last value to prevent having to run the lengthy routine unnecessarily.
In JavaFx, is there any reliable way to know at what time an event was posted ?
And since this question is too short for stackoverflow, I elaborate somwhat. In asychronous event systems, which I believe javafx is, events get posted on a queue and then at a later stage handled. The time between posting and handling is unknown, allthough it is estimated to be small. Nevertheless, there are no guarantees that this time is indeed small. Therefor I would really like to know whether it is possible to know the time of posting the event. E.g: when the user actually clicked the button (as opposed to when the program looks at it).
Short answer: no.
According to JavaFX Architecture it uses the native event queue for capturing and batching all the events. By capturing it is understood that at that moment in time the event was generated (the user clicked the button). Taking batching into account we have already lost the information about the time the event was generated (unless JavaFX internally keeps that information, you can inspect com.sun.javafx packages for lower level details). Every 1/60th of a second there is a scheduled pulse event. During the pulse event all other JavaFX events like MouseEvent, etc. are fired via the normal JavaFX event dispatching mechanism. It is at this point that your application will receive a notification from JavaFX that an event has occurred. So in an ideal world the difference between the time an event was posted and the time it was handled should be < 0.0166(6) seconds.
It is hard for me to understand the difference between signals and events in Qt, could someone explain?
An event is a message encapsulated in a class (QEvent) which is processed in an event loop and dispatched to a recipient that can either accept the message or pass it along to others to process. They are usually created in response to external system events like mouse clicks.
Signals and Slots are a convenient way for QObjects to communicate with one another and are more similar to callback functions. In most circumstances, when a "signal" is emitted, any slot function connected to it is called directly. The exception is when signals and slots cross thread boundaries. In this case, the signal will essentially be converted into an event.
Events are something that happened to or within an object. In general, you would treat them within the object's own class code.
Signals are emitted by an object. The object is basically notifying other objects that something happened. Other objects might do something as a result or not, but this is not the emitter's job to deal with it.
My impression of the difference is as follows:
Say you have a server device, running an infinite loop, listening to some external client Events and reacting to them by executing some code.
(It can be a CPU, listening to interrupts from devices, or Client-side Javascript browser code, litsening for user clicks or Server-side website code, listening for users requesting web-pages or data).
Or it can be your Qt application, running its main loop.
I'll be explaining with the assumption that you're running Qt on Linux with an X-server used for drawing.
I can distinguish 2 main differences, although the second one is somewhat disputable:
Events represent your hardware and are a small finite set. Signals represent your Widgets-layer logic and can be arbitrarily complex and numerous.
Events are low-level messages, coming to you from the client. The set of Events is a strictly limited set (~20 different Event types), determined by hardware (e.g. mouse click/doubleclick/press/release, mouse move, keyboard key pressed/released/held etc.), and specified in the protocol of interaction (e.g. X protocol) between application and user.
E.g. at the time X protocol was created there were no multitouch gestures, there were only mouse and keyboard so X protocol won't understand your gestures and send them to application, it will just interpret them as mouse clicks. Thus, extensions to X protocol are introduced over time.
X events know nothing about widgets, widgets exist only in Qt. X events know only about X windows, which are very basic rectangles that your widgets consist of. Your Qt events are just a thin wrapper around X events/Windows events/Mac events, providing a compatibility layer between different Operating Systems native events for convenience of Widget-level logic layer authors.
Widget-level logic deals with Signals, cause they include the Widget-level meaning of your actions. Moreover, one Signal can be fired due to different events, e.g. either mouse click on "Save" menu button or a keyboard shortcut such as Ctrl-S.
Abstractly speaking (this is not exactly about Qt!), Events are asynchronous in their nature, while Signals (or hooks in other terms) are synchronous.
Say, you have a function foo(), that can fire Signal OR emit Event.
If it fires signal, Signal is executed in the same thread of code as the function, which caused it, right after the function.
On the other hand, if it emits Event, Event is sent to the main loop and it depends on the main loop, when it delivers that event to the receiving side and what happens next.
Thus 2 consecutive events may even get delivered in reversed order, while 2 consecutively fired signals remain consecutive.
Though, terminology is not strict. "Singals" in Unix as a means of Interprocess Communication should be better called Events, cause they are asynchronous: you call a signal in one process and never know, when the event loop is going to switch to the receiving process and execute the signal handler.
P.S. Please forgive me, if some of my examples are not absolutely correct in terms of letter. They are still good in terms of spirit.
An event is passed directly to an event handler method of a class. They are available for you to overload in your subclasses and choose how to handle the event differently. Events also pass up the chain from child to parent until someone handles it or it falls off the end.
Signals on the other hand are openly emitted and any other entity can opt to connect and listen to them. They pass through the event loops and are processed in a queue (they can also be handled directly if they are in the same thread).
A while ago I wrote a little RAII class to wrap the setOverrideCursor() and restoreOverrideCursor() methods on QApplication. Constructing this class would set the cursor and the destructor would restore it. Since the override cursor is a stack, this worked quite well, as in:
{
CursorSentry sentry;
// code that takes some time to process
}
Later on, I found that in some cases, the processing code would sometimes take a perceptible time to process (say more than half a second) and other times it would be near instantaneous (because of caching). It is difficult to determine before hand which case will happen, so it still always sets the wait cursor by making a CursorSentry object. But this could cause an unpleasant "flicker" where the cursor would quickly turn from the wait cursor to the normal cursor.
So I thought I'd be smart and I added a separate thread to manage the cursor override. Now, when a CursorSentry is made, it puts in a request to the cursor thread to go to the wait state. When it is destroyed it tells the thread to return to the normal state. If the CursorSentry lives longer than some amount of time (50 milliseconds), then the cursor change is processed and the override cursor is set. Otherwise, the change request is discarded.
The problem is, the cursor thread can't technically change the cursor because it's not the GUI thread. In most cases, it does happen to work, but sometimes, if I'm really unlucky, the call to change the cursor happens when the GUI thread gets mixed in with some other X11 calls, and the whole application gets deadlocked. This usually only happens if the GUI thread finishes processing at nearly the exact moment the cursor thread decides to set the override cursor.
So, does anyone know of a safe way to set the override cursor from a non-GUI thread. Keep in mind that most of the time, the GUI thread is going to be busy processing stuff (that's why the wait cursor is needed after all), so I can't just put an event into the GUI thread queue, because it won't be processed until its too late. Also, it is impractical to move the processing I'm talking about to a separate thread, because this is happening during a paint event and it needs to do GUI work when its done (figuring out what to draw).
Any other ideas for adding a delay to setting the override cursor would be good, too.
I don't think there is any other way besides a Signal-Slot connection going to the GUI thread followed by a qApp->processEvents() call, but like you said, this would probably not work well when the GUI thread is tied up.
The documentation for QCoreApplication::processEvents also has some recommended usages with long event processing:
This function overloads processEvents(). Processes pending events for
the calling thread for maxtime milliseconds or until there are no more
events to process, whichever is shorter.
You can call this function
occasionally when you program is busy doing a long operation (e.g.
copying a file).
Calling this function processes events only for the
calling thread.
If possible break up the long calls in the paint event and have it periodically check to see how long it has been taking. And in any of those checks, have it set the override cursor then from in the GUI Thread.
Often a QProgressBar can go a long way to convey the same information to the user.
Another option that could help quite a bit would be to render outside of the GUI thread onto a QImage buffer and then post it to the GUI when it is done.