I am trying to write a simple application on Linux in C. when a push button is press, a motor is started, after 20 seconds it is stop by a timer. apparently, I don't need a repeating timer, a one-shot timer is can do the job.
what I need to know is which timer api i can use set timeout and trigger my function when timer expires.
thanks a lot.
Finally I figured it out.
For my case, using alarm if sufficient.basically,you need to define you StartMotor() and stopMotor() function and attach StopMotor function to signal(SIGALRM, StopMotot);
RUN_DURATION 30 // 30 seconds
static bool MotorStarted = false;
static void StopMotor(int sig);
void main(void){
while(1)
{
if (IsPBPressed( )) //polling status of push button.
{
if(!MotorStarted) //if motor is running, preceed startmotor,
{ // otherwise, ignore this subsequent request.
MotorStarted = true;
startMotor()
signal(SIGALRM, StopMotor);// start a timer. motor stop when the timer expires.
alarm(RUN_DURATION);
}
}
} //IsPBPressed( )
}
Related
I have an ESP8266 (NodeMCU) development board. I'm trying to implement software debounce on a tactile push-button connected to GPIO5 while using an interrupt. For the "relayPin" I'm temporarily using the onboard LED (GPIO16).
The debounce works for the most part when I try to push the button down and wiggle it very rapidly. However, it fails on rare occasion and only when the time gap is zero between two different detected pulses. So essentially, it never fails when the time gap is above 0 and below the debounce time (200ms). Please see the image of the serial monitor.
While this issue occurs under extreme conditions (the switch will not be used in this manner), I'd still like to figure out if this is something to do with my code or another aspect I'm not aware of.
Image 1: Push-button circuit
Image 2: Code & serial monitor
int swButton = 5;
int relayPin = 16;
bool relayOn = false; // Present on/off state of the relay.
int debounceTime = 200; // Debounce time in ms.
volatile bool switchToggle = false; // True when button press is valid (and not bounce noise).
volatile unsigned long nowPush = 0; // The millis() time of the present button press.
volatile unsigned long lastPush = 0; // The millis() time of the previous button press.
volatile unsigned long timeGap = 0; // The difference of the nowPush and lastPush times.
// Interrupt Service Routine on button press (falling edge).
ICACHE_RAM_ATTR void swButtonISR() {
nowPush = millis();
timeGap = nowPush - lastPush;
// Debouncing stuff, recognizing this button-press as a valid one.
if (timeGap > debounceTime) {
switchToggle = true;
lastPush = nowPush;
}
}
// Function that toggles the relay when called upon.
void toggleRelay () {
if (relayOn) {
digitalWrite(relayPin, LOW); // Turn off relay.
relayOn = false;
Serial.println((String)"Relay ON. Time gap: "+timeGap);
return;
}
else {
digitalWrite(relayPin, HIGH); // Turn on relay.
relayOn = true;
Serial.println((String)"Relay OFF. Time gap: "+timeGap);
return;
}
return;
}
void setup() {
Serial.begin(115200);
pinMode(swButton, INPUT);
pinMode(relayPin, OUTPUT);
pinMode(greenLED, OUTPUT);
attachInterrupt(digitalPinToInterrupt(swButton), swButtonISR, FALLING);
}
void loop() {
if (switchToggle == true) {
toggleRelay();
switchToggle = false;
}
}
There are a couple of changes you can make to also force a longer delay after "button release". (You could also just attach ONE interrupt handler with the CHANGE condition, to catch both FALLING and RISING edges.)
Add this
attachInterrupt(digitalPinToInterrupt(swButton), swButtonISR2, RISING);
change this
ICACHE_RAM_ATTR void swButtonISR() {
nowPush = millis();
timeGap = nowPush - lastPush;
// Debouncing stuff, recognizing this button-press as a valid one.
if (timeGap > debounceTime) {
switchToggle = true;
}
lastPush = nowPush;
}
add this
ICACHE_RAM_ATTR void swButtonISR2() {
lastPush = millis();
}
My scenario is to wait for a particular element. It might take 2,3,4,5 days.
Can that be achieved using explicit wait or fluent wait?
If not what can be the maximum time we can give for explicit wait or fluent wait?
Use below code :-
int MINUTES = 1; // The delay in minutes
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() { // Function runs every MINUTES minutes.
YOURFUNCTIONNAME();
}
}, 0, 1000 * 60 * MINUTES);
Add the time as per your requirement
I'm trying to capture mouse and keyboard events from SDL2 using the SDL2-CS binding library. The events are polled for but these events are never raised.
I think this is because the polling needs to happen on the UI thread. I tried initializing SDL from the UI thread by calling App.Current.Dispatcher.Invoke(Init) but no events are polled.
Basic implementation of my class:
public override void Initialize()
{
if (hooked)
{
return;
}
App.Current.Dispatcher.Invoke(Init); //Run on the UI thread
}
private void Init()
{
var init = SDL.SDL_Init(SDL.SDL_INIT_VIDEO);
if (init != 0)
{
throw new Exception("Could not initialize SDL");
}
hooked = true;
ListenForEvents();
}
private void ListenForEvents()
{
SDL.SDL_Event ev;
while (true)
{
if (SDL.SDL_PollEvent(out ev) != 1) //This is continuously trigged
{
continue;
}
switch (ev.type) //This is never reached
{
case SDL.SDL_EventType.SDL_MOUSEMOTION:
if (MouseMoved != null) { MouseMoved(this, ev.motion); }
break;
...
}
}
}
I'm wondring if I'm invoking the Init on the UI thread wrong, or if the SDL initialization is wrong.
P.S. Hooking with user32.dll is not desired because this code will run on non windows environments as well.
Looking at your code I would say your UI is blocked because ListenForEvents is not running on a different thread and invoking the Init call will run the method - that never returns - on the UI thread.
It might be a good idea to call Init invoked, but then you should start a new thread for polling.
I'm using a Threading.Timer to execute a task on the hour every hour, but when the timer ticks, the app always crashes when processing the code to execute in the tick. It crashes with no exceptions or warnings, even if I put the whole thin in a try/catch. Very strange. Below is my setup and any help would be appreciated! It seems like crashes when it tries to access the TextBox GrepCmdTextBox, but I thought reading from another thread was okay, just not writing.
Setting up timer:
var timeOfDay = DateTime.Now.TimeOfDay;
var nextHour = TimeSpan.FromHours(Math.Ceiling(timeOfDay.TotalHours));
var delta = (nextHour - timeOfDay).TotalMilliseconds;
System.Threading.Timer NextHourTimer = new System.Threading.Timer(new System.Threading.TimerCallback(NextHourTimer_Tick), null, (long)delta, (long)TimeSpan.FromHours(1).TotalMilliseconds);
Tick event:
private void NextHourTimer_Tick(object sender)
{
// If thread is not null and is busy, cancel and restart
if (MonitoringThread != null)
{
if (MonitoringThread.TailThread.IsBusy)
{
MonitoringThread.TailThread.CancelAsync();
System.Threading.Thread.Sleep(50);
// Get grep command, if specified
string optionalGrep = String.Empty;
if (GrepCmdTextBox.Text.StartsWith("grep") || GrepCmdTextBox.Text.StartsWith("egrep"))
optionalGrep = " | " + GrepCmdTextBox.Text;
MonitoringThread.TailThread.RunWorkerAsync(optionalGrep);
}
}
}
Cancelling the asynchronous process can take time, the background thread will have to 'finalize', returning from DoWork() and waiting for an opportunity to run the RunWorkerCompleted event, if any.
Instead of cancellation, in this case it would be better to cancel then Dispose() the object, creating a new BGW, as they are as 'cheap-as-chips'.
I hope this helps.
Hy, I just wanted to find out how to implement a loop that takes around 80 to 120ms (mostly 80ms) to execute. The loop has to execute for about 30 minutes... basically it is a SURF matching algorithm.
Currently I am using a System.Threading.Timer to create a timer that executes after every 90ms, but the problem is that since the computation time is variable, so after some time the stack overflows and the program closes.
I'm using WPF to create the GUI.
Is there a better way to implement such a loop using threading? Any help would be much appreciated! Thanks in advance.
//initialization
private System.Threading.Timer Visual_AR1;
Visual_AR1 = new System.Threading.Timer(new TimerCallback(Video_AR1), null, 0, 90);
private void Video_AR1(object state)
{
lock (this)
{
// SURF matching
modelImage_AR1 = new Image<Gray, byte>(droneControl_AR1.BitmapImage).Resize(1.8, INTER.CV_INTER_NN);
map_image_d1 = DrawMatches_gpu.GPU_0(wayx, modelImage_AR1, observedImage, pgpuObservedKeyPoints_imp, pgpuObservedDescriptors_imp, out matchTime_0, out pX1, out pY1);
Dispatcher.BeginInvoke((Action)delegate()
{
label4.Content = "Time Taken by GPU_0 : " + matchTime_0.ToString();
});
mask_selector_d1();
}
}
is this a viable solution ?
private Thread threadTask = null;
private void threadTask_Start()
{
if (threadTask == null) {
threadTask = new Thread(SURF);
threadTask.Start();
}
}
private void SURF()
{
while(true)
{
lock (this)
{
// SURF matching
modelImage_AR1 = new Image<Gray, byte>(droneControl_AR1.BitmapImage).Resize(1.8, INTER.CV_INTER_NN);
map_image_d1 = DrawMatches_gpu.GPU_0(wayx, modelImage_AR1, observedImage, pgpuObservedKeyPoints_imp, pgpuObservedDescriptors_imp, out matchTime_0, out pX1, out pY1);
Dispatcher.BeginInvoke((Action)delegate()
{
label4.Content = "Time Taken by GPU_0 : " + matchTime_0.ToString();
});
mask_selector_d1();
}
thread.sleep(40);
}
}
Instead of making the timer tick perform the work, make the timer tick queue up a job and have something else (presumably threads from the thread pool) consume the jobs. You can use a semaphore to throttle the number of jobs running simultaneously and you can examine the state of the queue to avoid this sort of over-commit problem.