Inconsistent Interrupt behavior

I am having issues where sometimes my interrupts will trigger upon button press, other times there is zero response from the G30. Code remains unchanged in both cases - if the interrrupt fails I just reload my code and start the test over…it will suddenly be working again.

The button is pulled low when pressing buts it like the G30 missed it when scanning its pins/interrupts/threads.

Can someone please shed some light on why this is happening? Haven’t encountered this before.

Here is the part of my code where the interrupts are used, is this code too tight?

                    fwdflag = false;
                    revflag = false;
                    saveflag = false;
                    do
                    {

                        do
                        {

                            Thread.Sleep(1);

                        } while (!fwdflag && !revflag && !saveflag);


                        if (fwdflag)
                        {
                            oled.DisplayAll(I2C, new string[] { "Moving Forward..." });
                            uint steppz = 474;
                            stepperDriver.dSPIN_Move(dSPIN_Direction_TypeDef.FWD, steppz);
                            while (stepperDriver.dSPIN_Busy_SW() == 1)
                            {
                                Thread.Sleep(1);

                            }
                            fwdflag = false;
                            totalPos -= steppz;
                            Debug.Print(totalPos.ToString());

                        }

                        if (revflag)
                        {
                            oled.DisplayAll(I2C, new string[] { "Moving in Reverse..." });
                            uint steppz = 474;
                            stepperDriver.dSPIN_Move(dSPIN_Direction_TypeDef.REV, steppz);

                            while (stepperDriver.dSPIN_Busy_SW() == 1)
                            {
                                Thread.Sleep(1);

                            }
                            revflag = false;
                            totalPos += steppz;
                            Debug.Print(totalPos.ToString());
                        }

                    } while (!saveflag);

                    if (saveflag)
                    {
                        oled.DisplayAll(I2C, new string[] { "Cal Point Saved" });
                        TabsFinal[j] = (int)totalPos;
                        Debug.Print(totalPos.ToString());
                    }
                }

How did you wire the button to the device? Is the pin configured for pull up or pull down?

@Mr_John_Smith buttons are configured for pull down, voltages test out fine.

I just noticed that the G30 appears to be hanging and becomes completely unresponsive - I have to reset it for the computer to even detect it again. I also noted that it is hanging right before break points. If I get rid of a breakpoint, it will hang at a different spot just before the next breakpoint.

if this is your interrupt handler, then yes your code is wrong.

Where can I start…

Thread.Sleep(1). Shakes head. How many times have I said 10 or 50msec ? a loop like

do
{
Thread.Sleep(1);
} while (!fwdflag && !revflag && !saveflag);

completely blocks the processor for tasking in anything else

You can’t keep throwing bits of code like this at us without context. You need to give us working code that we can use to reproduce an issue. You show nothing about if this is an interrupt handler or not - if it is, then you frankly misunderstand what interrupts do. If all you’re doing here is checking flags that get altered in the interrupt, that’s a little better, but you are clearly showing your lack of understanding timescales - do you know how long it takes for a signal to stabilise in your hardware (de-bounce the signal), and how insignificant a thread.sleep(1) is within that ?

It is not the interrupt handler. Interrupt handler simply sets the flag true. This is an infinite loop responsible that waits/monitors for buttons to be pressed during a certain step of my code.

I am only authorized to share so much, I am doing the best I can. If I can’ get it soon I will put it in a separate working test program that doesn’t contain important information.

probably best that you don’t share any more - we’ve clearly pointed out the areas you’ve got to fix.

In all honesty, why bother with an interrupt? Your code (this block I quoted) explicitly loops until a flag that happens within the button press event; why not just poll the IO pin instead? The idea of interrupts is, well, to asynchronously interrupt whatever other processing is happening, and an interrupt is kind of pointless for a wait-until construct

@Brett That is how I originally had it but was getting very odd response from the buttons. That is when @Justin told me that buttons should always be interrupts, maybe I misunderstood what he was talking about.

There seems to be another issue happening, not sure if it is related. The G30 is randomly hanging when it gets to that interrupt scanning loop posted above but also earlier on too…the screen will randomly just go blank, if I go to restart the code, the G30 can’t be detected and must be reset.

yep. ITS YOUR CODE. Irrelevant if you think its a good idea or not, your thread.sleep pattern should be expanded out at least while you’re in development. Create a global value that you can change once and use everywhere. Make it 50 to start with. The reason you need to reset the device is that the debugger can’t attach because you have the processor consuming all other cycles elsewhere - it seems to me the work we did last week with a wait for button or long startup delay are no longer in place otherwise this would be a non-issue?

@Justin is absolutely correct - a button really is an async interrupt event. But the way you have structured your code, or the use-case of this wait loop, is synchronous and doesn’t need an interrupt. Can you use one? Absolutely. Will your code, as demonstrated earlier, work efficiently? Nope, it’ll unnecessarily consume cycles and not give any ability for other threads to run, including the framework core parts like GC and the debugging engine.

You’re assumption is incorrect, everything is still in place. The error where it hangs waiting for button presses seems to only happen about 10% of the times I run my code. About 1% of the time I run the code it will randomly start jumping ahead without waiting the sensor to trigger it then the screen will go blank.

I deleted the above part of the code so it is just this now:

 for(int i=0;i<=Taba.Length;i++){
                fwdflag = false;
                revflag = false;
                saveflag = false;
                do
                {

                    if (fwdflag)
                    {
                        oled.DisplayAll(I2C, new string[] { "Moving Forward..." });
                        uint steppz = 474;
                        stepperDriver.dSPIN_Move(dSPIN_Direction_TypeDef.FWD, steppz);
                        while (stepperDriver.dSPIN_Busy_SW() == 1)
                        {
                            Thread.Sleep(1);

                        }
                        fwdflag = false;
                        totalPos -= steppz;
                        Debug.Print(totalPos.ToString());

                    }

                    if (revflag)
                    {
                        oled.DisplayAll(I2C, new string[] { "Moving in Reverse..." });
                        uint steppz = 474;
                        stepperDriver.dSPIN_Move(dSPIN_Direction_TypeDef.REV, steppz);

                        while (stepperDriver.dSPIN_Busy_SW() == 1)
                        {
                            Thread.Sleep(1);

                        }
                        revflag = false;
                        totalPos += steppz;
                        Debug.Print(totalPos.ToString());
                    }

                } while (!saveflag);

                if (saveflag)
                {
                    oled.DisplayAll(I2C, new string[] { "Cal Point Saved" });
                    TabsFinal[j] = (int)totalPos;
                    Debug.Print(totalPos.ToString());
                }
            }
   }

Still getting the error, its like the G30 is still stuck on some other thread (because it executes the line before, then just hangs when it should be monitoring the buttons. I don’t have much else running…

What else can I change here?

….
:frowning2:

@Brett Haha sorry I did change that on the code I am running, copied that snippet from above and just made my changes

BTW, I think I’m done. I’ve helped a LOT on this job you’ve got, as have others. Many of us here have tried to educate you in how the framework works and how to troubleshoot, heck even how to report a problem to us, but you repeatedly have ignored good advice (and I know some of that is the constraints of sharing you’ve been told - but you need to repro the behaviour outside so that it doesn’t infringe anything). All the best for getting it done

2 Likes

@Brett Thanks for your help. I am doing the best I can and have implemented every single suggestion you told me to do. The Thread.Sleep(1) was changed before I even posted the last bit of code I am not sure why you are still saying I am ignoring your advice. I even apologized for the typo and explained that I had already changed it.

My code only fails at that one spot and only on the first entrance of that loop if it is going to fail at all. Everywhere around it I have tried sprinkling in Thread.Sleeps with no luck.

thread.sleeps are not magic salt to fix logic errors.

You’ve ignored us by not giving us reproducible code that explains the logic you want to implement, and that we can unit test without your hardware. You’ve not added any diagnostics to know where the code is or isn’t up to (and if you have, you haven’t shown us any of that). You haven’t tried to simplify - for example, are you sure your motor busy statement isn’t the cause?

2 Likes

Brett is right; you need to isolate the problem by simplifying the code. Comment out that OLED display to start with.

Your do while() has no thread.sleep() unless one of the flags is set. If there is no flag set, this loop will never yield and you will have an issue with it. Suggest you change the second if statement to an else if and add a final else with a single thread.sleep() in it.