Order by
Group by
Topic

Looking for all posts by Gismofx

Page 1 of 6 out of 112 messages.

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Sep 8, 2016 at 5:36pm

I'm still at a loss of how to continue to diagnose this. Any other ideas?

RE:LCD Manager by Gismofx on Sep 8, 2016 at 5:31pm

@anthonys -

What type of display are you using? I'm trying to get the library I have cleaned up and I can share the code.

RE:LCD Manager by Gismofx on Aug 30, 2016 at 9:13pm

@anthonys -

Aside from your LCD driver, I've written an Interface/Classes to manage a menu system. The display class has methods that draw menus when you feed it a list of menu items. In my case, I pass the list of menu items names from the collection of device settings to the draw menu method. Overall, I use an interrupt driven state machine as the general code pattern for the system.

What do you have so far? What are you requirements? What device are you using?

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Aug 27, 2016 at 4:53pm

Here's another video which seems to be a little more clear with how I get more events than expected.

https://www.youtube.com/watch?v=MBw2vIq4K_0


If I put a break-point on the event subscriber, I can't re-produce the result. When I remove the break point, I will get the repeated events.

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Aug 27, 2016 at 11:35am

Mike says:

@Gismofx - how often does the issue appear?

you are showing snippets of code. hard to figure out what. is happening with methods be called in the code you posted.

nothing in the code you posted seems to explain the problem, unless the methods you are calling take a long time to complete.

you still have not addresses a GC issue.is anything appearing in the debug window when the problem appears.

It occurs often enough to be noticeable. I would say about 15% of the time i rotate the encoder.

The IncrementValue Method simply adds the input value of the property to itself in the class. Fast code.
The UpdateEEprom Method probably takes a little longer to execute, but it's not an very intense operation, I convert a value to bytes, compute a CRC, combine the byte arrays and write it. Then, I read it back to verify and move along. The EEprom SPI runs at 10Mhz. I timed the operation. I get about 5ms to complete the eeprom update.

I don't see anything coming up about the GC in the debug window while this happens. Is there code I need to implement to debug GC?

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Aug 27, 2016 at 10:12am

@Mike -

Here's the code for my two sensor threads:

private static void RunOdometer() //int waitMS
        {
            uint maxValue = 65535;//highest number before overflow/reset
            uint cStart;
            uint cPrev;
            uint diff;
            double distanceKM;
            cPrev = 0;

            while (true)
            {
                //ticks1 = System.DateTime.Now.Ticks;
                cStart = InternalSpeedSensor.Ticks;
                if (cStart < cPrev)//detected a roll over
                {
                    diff = (maxValue - cPrev) + cStart;
                }
                else
                {
                    diff = cStart - cPrev;
                }
                cPrev = cStart;
                distanceKM = (DeviceSetting.WheelCircumference.Value / DeviceSetting.NumberOfSpeedPickups.Value) * diff * .000001;
                DeviceSetting.Odometer1.IncrementValue(distanceKM);//update odometer
                DeviceSetting.Tripometer.IncrementValue(distanceKM);//update trip
                Thread.Sleep(500);
            }

        }
        
        /// <summary>
        /// 
        /// </summary>
        private static void UpdateOdometerEEprom()
        {
            while (true)
            {
                DeviceSetting.Odometer1.UpdateEEProm(DeviceSetting.Odometer1.Value);
                Thread.Sleep(10000);
            }
        }


What could I modify?

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Aug 27, 2016 at 10:06am

godefroi says:
Is it possible you're just not reading interrupts fast enough?

I would think that I should be capturing all the interrupts, but I suppose stranger things could occur. How could that happen?

Here's a link to a post I made about the encoder with the code:
https://www.ghielectronics.com/community/forum/topic?id=20019&page=2#msg218355

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Aug 27, 2016 at 9:50am

@mcalsyn -
That's my fear.. I won't be able to do much with normal debug statements without interfering with the actual timing of the system. I'm still trying find a way to figure out what's going on.

RE:Multiple Threads Interfering With Interrupts. How to Diagnose and … by Gismofx on Aug 27, 2016 at 8:35am

@Dave McLaughlin -
Signal is clean: Here's a shot where I spin Clockwise and then Count-Clockwise. The signal looks no different when enable or disable the sensor threads(see atttached image)

Multiple Threads Interfering With Interrupts. How to Diagnose and Fix? by Gismofx on Aug 26, 2016 at 6:47pm

I'm running a few threads on my device per this thread:
https://www.ghielectronics.com/community/forum/topic?id=23551

When I rotate the encoder to drive a menu, It should scroll one menu item at a time. On occasion, the menu will jump several items. Here's a video of the behavior(starting around the 9 second mark you see the jump):

https://www.youtube.com/watch?v=z_Ew_MWtQvY


When I eliminate the sensor threads, this behavior goes away.
How can I diagnose this? Any ideas on what is happening?

RE:Multithreading - Reading Sensors in Sub Threads - How To Optimize … by Gismofx on Aug 5, 2016 at 7:05pm

@David@Leclanche I was thinking locks too, but wanted to make sure that's a "good" way to do it.

mcalsyn says:


Not easily, especially if you want to guarantee a steady cadence of execution without much 'jitter' in the timing. But the statement you just made above is the very definition of 'sequential execution' - that is, a single thread with two blocks of code that run exclusive of each other.

If task 1 needs to run every N milliseconds and it takes M milliseconds to complete, then you can use the idle time of N-M to perform task 2. If task 2 takes less than N-M mS to complete, then you're good. If it takes more than N-M mS to complete then it won't work sequentially, and no amount of threading magic will make it work either because you only have one CPU core and threading gives you separation of state - not more CPU capacity.

I'm not too concerned about a steady cadence. I want my main thread which is displaying the data to be smooth and uninterrupted. I don't want to be half way through updating my display and have some kind of pause giving a clunky user experience. Maybe I lock my display write/SPI transfer method?)

I just want to be always collecting and saving data from some specific sensors so any method can have the current value and I'm so not duplicating too much code in every state or having to worry about missing some readings while in a different state that doesn't display that sensor data.

Multithreading - Reading Sensors in Sub Threads - How To Optimize … by Gismofx on Aug 4, 2016 at 8:55pm

I've got a device that I think multi-threading is the way to go, but I want to make sure I'm implementing it in the correct/best way to make sure performance is not affected negatively.

My device is using an interrupt driven state-pattern/machine to operate it normally. Typically, each state runs a tight-ish loop to read some sensors and display them on an GLCD. This runs on off the "main" thread.

There are some sensors that need to ALWAYS read and collect data incremental data which can be displayed from any state. Also, this data needs to be written to EEPROM periodically.

for example(pseduo code)

public static void Main()
{
//setup code...

Thread S2 = new Thread(new ThreadStart(ReadSensor2));
Thread SaveS2 = new Thread(new ThreadStart(SaveSensor2));

S2.Start();
SaveS2.Start();
While(true)
{
     ModeContext.RunStateTask();
}
}


//Run State Task
void MainTask()//this method is within a state class
{
   Sensor1.Update();
   Display.Write(Sensor1.Value);
   Display.Write(Sensor2.Value);
   Thread.Sleep(250);

//in another thread
public void ReadSensor2()
{
     while(true)
{
   Sensor2.Update();
   thread.sleep(250);
}
}

//in another thread
public void SaveSensor2()
{
while(true)
{
   EEPROM.WriteSensorData(Sensor2);
   thread.sleep(30000);//30 seconds
}
}

}


All of the threads would typically run indefinitely.

Can you specify a thread to run while another is sleeping so the main task thread is not interrupted? Am I overthinking this? What's the best way to implement this? Any tips would be appreciated.

RE:G30 HDR 0.1 SPI and Graphical Display by Gismofx on Jul 30, 2016 at 10:31pm

Can you post your code? Also, the specifications of your display and your setup? If the SPI bus speed change has no effect of the refresh speed of your display, likely you have something else going on in your code which is slowing you down.

RE:Interrupt Driven Rotary Encoder Becomes Un-Responsive and then … by Gismofx on Jul 23, 2016 at 8:36am

@Dave McLaughlin -

I want the code to be clean and elegant..it does feel a bit "off" right now...I remember there was a reason the method you suggest wasn't acceptable: Anyway I quicly re-wrote to detect Pin A edge low and reading Pin B's state in the Interrupt to determine direction:

private void RotationInterrupt(uint data1, uint data2, DateTime time)//Data1 Is Pin Data 2 Is Pin.Read()
        {

            if (PinB.Read() == true)
            {
                RotationEventHandler(CLOCKWISE, 0, DateTime.Now);
            }
            else
            {
                RotationEventHandler(COUNTERCLOCKWISE, 0, DateTime.Now);
            }
        }



And excerpt from the constructor/class:
//global class members
private InterruptPort PinA = null;
private InputPort PinB = null;

//in constructor
PinA = new InterruptPort(pinA, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);//Pins are pulled high.
PinB = new InputPort(pinB, false, Port.ResistorMode.Disabled);

PinA.OnInterrupt += RotationInterrupt;


This works, but I still have some false reads, about 10%-25% of the time depending on a moderate speed of rotation...I'm wondering if this is because by the time the interrupt can run, Pin B's state would have changed. The higher the speed of rotation, the more unreliable the encoder results become. It's probably 50% when I spin a full rotation/second. Useless at this point. I think this stemmed the longer code to try to capture all the pulses and match to some type of pattern.

Any ideas on how to improve this?

RE:Interrupt Driven Rotary Encoder Becomes Un-Responsive and then … by Gismofx on Jul 22, 2016 at 8:02pm

Digging up an old thread and finding the same issues... getting odd reads. Again, I'm confident the hardware is giving the proper signals, but I'm getting some bizarre results. I want to preface that I understand if I do half of a detent rotation or something weird i get a bad result, but with a normal "click" clockwise or counter-clockwise, I do get a correct signal.

I'm tried to rewrite the interrupt routine; In this case, I wait for the 4 interrupts and try to detect some type of pattern. At first, this works, but after about 10-20 rotations, it's starts to get weird. The pattern will be something like:
Pin A Low
Pin A High
Pin B Low
Pin B High
or
Pin B High
Pin B Low
Pin A Low
Pin A High

Unexpected Results.

Any ideas? Can the interrupt queue get messed up? Can I prevent this?

Here's my current code:
private void RotationInterrupt(uint data1, uint data2, DateTime time)//Data1 Is Pin Data 2 Is Pin.Read()
        {
            //Debug.Print("Pin A: " + PinA.Read().ToString() + " || " + "Pin B: " + PinB.Read().ToString());

            uint currentState= 0;
            //int resultCount = 0;

            if (RotationEventHandler == null)//Check to see if user has added an external event handler
            {
                throw new Exception("You must define a handler in your main code. Ex: RotaryEncoder.RotationEventHanlder+=DoSomething;");
            }


            currentState = data1 << 1 | data2;

            states[StateCount] = currentState;
            StateCount++; //INCREMENT STATECOUNT
            /* testing error
            if (RotaryError)
            {
                StateCount = 0;
                Array.Clear(states, 0, 4);
                RotaryError = false;
                return;
            }
            */
            if (StateCount < 4)
            {
                return;
            }

            byte result = FindPattern();

            if (result == CLOCKWISE)
            {
                RotationEventHandler(CLOCKWISE, 0, DateTime.Now);
            }
            else if (result == COUNTERCLOCKWISE)
            {
                RotationEventHandler(COUNTERCLOCKWISE, 0, DateTime.Now);
            }
            else
            {
                RotaryError = true;
            }


            StateCount = 0;
            Array.Clear(states, 0, 4);
    }


I've implemented a find pattern function which compares part the 4 states to the known pattern of the encoder It's pretty loose, but still fails.
private byte FindPattern()
        {
            int patternPositionCW=0;
            int patternPositionCCW=0;
            int patternStart=0;
            int i=0;
            for (i=0; i < 4; i++)
            {
                if (states[0] == BasePattern[i])
                {
                    patternStart = i;
                }
            }
            patternPositionCW = (patternStart==3)? 0 : patternStart+1;
            patternPositionCCW = (patternStart==0)? 3 : patternStart-1;
            if (states[1] == BasePattern[patternPositionCW])
            {
                return CLOCKWISE;
            }
            else if (states[1] == BasePattern[patternPositionCCW])
            {
                return COUNTERCLOCKWISE;
            }
            
            return 3;
            
        }


and excerpt from the constructor:
PinA = new InterruptPort(pinA, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);//Pins are pulled high.
            PinB = new InterruptPort(pinB, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);//Interrupt Needed here.

            PinA.OnInterrupt += RotationInterrupt;
            PinB.OnInterrupt += RotationInterrupt;

            PinAHigh = (uint)PinA.Id << 1 | 1;
            PinALow = (uint)PinA.Id << 1;
            PinBHigh = (uint)PinB.Id << 1 | 1;
            PinBLow = (uint)PinB.Id << 1;
            BasePattern[0] = PinALow;
            BasePattern[1] = PinBLow;
            BasePattern[2] = PinAHigh;
            BasePattern[3] = PinBHigh;

RE:Peer Review Of PCB design by Gismofx on Jul 21, 2016 at 10:15pm

Here's an album of some assembly photos:
http://imgur.com/a/yqZ5D

Reflow oven worked very well, I misplaced one 0603 cap and had to fix it with an iron..not too bad. The FFC for the LCD was soldered manually and a bit of a pain, but finally got it. I wonder if I could reflow the bottom parts after I reflow the top? I would think not...

Detecting Double-Click Via Interrupt Driven Momentary Button by Gismofx on Jul 17, 2016 at 12:27pm

I've been mulling it over for quite some time and haven't uncovered any "simple" way to detect a double click via a momentary push button.

I've got a momentary button, hardware debounced, and I can detect a single-click and a "press and hold" events, but double-click has me stumped. Are there an techniques to facilitate this? (Detecting a double-click without running a single-click event twice)

What I'm thinking of is looking into the interrupt queue when I get a single click to see if there's another interrupt pending/queued and within a specific time to detect a double-click.

Is this possible? If so, how can it be implemented?

RE:Peer Review Of PCB design by Gismofx on Jul 15, 2016 at 6:18pm

PCBs arrived! Components were supposed to arrive same day, but didn't :/ Hopefully tomorrow...

RE:Peer Review Of PCB design by Gismofx on Jul 5, 2016 at 11:44am

Dave McLaughlin says:

Looks good. Your text for D3 will be missing when you get the baord back as it covers the pins of another device.

Look forward to seeing the finished boards.

Thanks. Regarding that D3, it's actually a 5 pin device. That middle pin is actually gone where the text is, but D4 in the power supply area overlaps a little and might be weird.

I'm excited!

RE:Peer Review Of PCB design by Gismofx on Jul 4, 2016 at 1:08pm

I've finally ordered the board via OSHPark! I had to make a few tweaks to some pins and footprints that I use and move the regulator to the opposite corner of the board. I will post some pictures once I receive the board! (hopefully I connected everything else correctly)Thanks!

Page 1 of 6 out of 112 messages.