The Netduino forums have been replaced by new forums at community.wildernesslabs.co.
This site has been preserved for archival purposes only
and the ability to make new accounts or posts has been turned off.
Bizarre Behavior with N2 with Events, Interrupts, and other peripherals. Need Help.
I am working through my projects and getting all the individual components working and now I'm bringing them together. When I've pulled it all together, I seem to be getting some bizarre behavior from my interrupts / event handlers.
I have a modified driver for a rotary encoder which works as I expected which triggers an event for each rotation "click"(right now its a simple debug.print). Next, I am pulling in some modified drivers for the TLC5940 chips based on Mark's work seen here. Those also work as expected. When I initialize the rotary encoder class and then then TLC5940 class, the interrupts/events seem to go haywire. When I spin the encoder, I get a very inconsistent output. Sometimes a few clicks and no response and then a single click and I get 4 outputs. another click and I get one output but the direction is wrong. Same thing goes for the push button. I get single events without the TLC driver, but erratic events with it initialized. Both rotary encoder and push button are hardware debounced.
Seems like there is something conflicting between the two, but I have no overlaps in the pins. What could it be? How should I go about checking this? Is there something fundamental that I'm missing? Or is this some deep issue? I'm a little baffled.
Hi gismo,
Is it possible that you're receiving events quicker than your code can handle them (on the rotary encoder)? If you just turn it one "click", do you consistently get a single event?
One thing to be aware of is that NETMF is cooperatively multitasking. That means that threads are by default given up to 20ms of time before the CLR takes execution away and gives it to another thread. So generally you'll want to keep your functions simple and put your threads to sleep when they're not doing anything (rather than spinning in the background).
Chris
Hey Chris,
Thanks for the quick reply! When the rotary encoder is the only object initialized, interrupts/events are fired almost as fast as I can spin it...Also it does seems to queue the interrupts(I think I read that in another post) That being said, my actual usage will be slower single "clicks" during the actual application. With the TLC object loaded, the erratic behavior occurs on single deliberate "clicks" with sufficient pauses between. At first I thought it was getting stuck in the queue, which still may be the case, but it doesn't add up. For example, I will make two deliberate clicks with no events fired and with the third deliberate click it will fire 4 events in a row.
Regarding multitasking, interesting point. I'm not sure my project is there just yet and I'm starting to wrap my head around threading, let alone event handlers and subscribers. In short, my rotary encoder will be used to switch what sensor data is being sent to the TLC5950s.
Update: I have further modified the rotary encoder driver. It uses significantly less code to get the results I'm looking for. I only have ONE interrupt on the rising edge. Now, the results see to be a bit more repeatable. With just the rotary encoder object loaded, I get single repeatable events and correct direction results. One "click" one event. Button works just fine.
When I initialize both the TLC and the Rotary Encoder, I get precisely 32 events fired with each "click" of the encoder and the direction is incorrect. This happens in both directions.
The code looks something like this:
public static void Main()
{
// write your code here
#region Initialize harware/drivers
RotaryEncoderTEST Rotary = new RotaryEncoderTEST(Pins.GPIO_PIN_D0, Pins.GPIO_PIN_D1, Pins.GPIO_PIN_D2);
Tlc5940 leds = new Tlc5940(32, Pins.GPIO_PIN_D7, PWMChannels.PWM_PIN_D6, Pins.GPIO_PIN_D4, PWMChannels.PWM_PIN_D10);
//Rnd = new Random(0);
GaugeSettings Settings = new GaugeSettings(Rotary);
Another thing I'd like to add...Inside the event handler attached to the interruptport, I put a little bit of code to flash the onboard led and also put in a debug.print. It seems like the when the TLC is loaded with the Rotary Encoder, the interrupt is constantly triggered. I got an memory error in output window. Is there some circuit or electrical noise from SPI that's causing this? Some bug in my code?
Hi gismo,
I don't have the other component you're using, but what I'd normally do to debug something like this is to rebuild that other component one piece at a time (comment it all out, and then uncomment one chunk at a time)--until things break. Knowing what was added that broke things can help understand what is broken.
Also--if that component has any long loops on a background thread which keep its thread alive constantly, that could affect things. Threads run up to 20ms before the NETMF runtime forces execution to another thread--so a class which doesn't give up MCU cycles could cause you to miss events (or overflow a queue if too many pile up) in another thread.
Chris
Thanks Chris. I seemed to have isolated the issue and found fix that works. Maybe you can shed some light on this as well.
I'm using SPI to drive the TLC5940 chips and also using PWM to drive the GSCLK signal for the chips as well(instead of an external clock). I'm using Pin10 on the Netduino 2. When I comment out the PWM constructor for pin 10 the interrupts work as expected with SPI for the encoder!
So...I moved the PWM GSCLK to PIN9 and it now works! Is there something going on with Pin10 while SPI is being used?
On the side, I was reading a lot of other posts about getting the PWM frequency up in the Mhz range. Has that been implemented yet?
When you are using SPI, what pin are you using for SPI_CS? Pin D10? That's usually the pin used for SPI_CS--but you can use any unused pin.
For PWM MHz+ frequencies...what type of applications are you looking at? There are some intricacies with PWM clocks across different MCU types which is why there's a lower base clock frequency. But if we can build a library extension to support additional speeds and could enable additional usage scenarios...we'd like to explore that
Thanks for the info. I'll consider that moving forward. I only have one SPI device currently connected, so I am using ChipSelect_Port: Pins.GPIO_NONE.
RE: Higher PWM frequencies. I'm using the PWM to drive the greyscale clock signal on the TLC 5940 chips. I'm doing this to simplify the circuitry and not wanting to create an external clock signal. I'd like to be able to accomplish this with the Netduino. From what I've read, when driving LEDs, they behave much better with a higher frequency. 8Mhz for example. I'm currently using 500kHz(anything higher and debugger locks up) and have some dimming issues. There's a little bit of pulsation and flickering in some scenarios.
I'm really excited to see some extensions to the PWM/clock signal and test it with TLC5940. Where is this on the totem pole of features being worked on?
Hi gismo,
Right now we're making some enhancements to SPI idle clock support for an upcoming Netduino 4.3 beta firmware release.
If you want to start a conversation about applications using custom PWM speeds and we can get some feedback on how people would use this so we expose it the best way...we can get an official feature task item in our system and work on this for a future firmware update.
Chris
Back to SPI issue...Was the issue I was having something in the firmware?Bug? Were you able to reproduce the error on your end with CS=GPIO_NONE and then trying to use Pin 10 for something else while having some interrupts fire?
Hi gismo,
The issue we're looking at with SPI is the timing of when the SPI chip select pin is asserted and when the SPI clock goes to idle state. In "idle high" mode, this can happen in backwards order and some devices might get 0.5 to 1.0 bits off.
If we need to file a bug report on a SPI_CS + timer interrupt pin issue, then we can work through that process here. We'd need a simple repro (<= 10-20 lines of code), expected and actual results, etc.
Chris
I'm still having this problem on 4.3. Interrupts from the rotary encoder get whacky when I'm using SPI and PWM and can't make any more progress with the components I am trying to use together.
Essentially, I have some SPI device doing something then introduce an interrupt and the interrupt response is bouncy and results are unreliable.
I'll work on some simplified code and paste it here in the thread.
Is anyone else able to reproduce the same thing I am seeing?
Based on the code above, I tried the available PWM Pins individually with the PWMPin statement and here are my results.
Fail/Extra Interrupts:
PWMChannels.PWM_PIN_D9
PWMChannels.PWM_PIN_D11
PWMChannels.PWM_PIN_D6
Works Properly:
PWMChannels.PWM_PIN_D10
PWMChannels.PWM_PIN_D3
PWMChannels.PWM_PIN_D5
Edit:
They all fail when a Jumper wire is plugged into the PWM pin. With no jumper wire, they work fine.
I'm really having trouble pin-pointing this issue(pun intended). Thinking that I have found a work-around solution so I could move forward, I switched back to the code with the SPI and changed the PWM pins to the "working" pwm pins and the issue is still present! :wacko:Here's the weird thing, IF I UNPLUG the two PWM wires connected to the pins while the program is running, the Interrupts begin to work properly. As soon as I plug the PWM wires back in, the interrupts go bonkers. I can reproduce this with a single PWM with the code above. Simply pulling the jumper wire from the Netduino pin header and the interrupts will work fine.
I've tried different pins for PWM with the exact same result. Another even more bizarre thing to me is that the PWM jumper wire doesn't even need to be connected to a load(ex: LED) for this to happen.
Lastly, the amount of "jitter" in the interrupt behavior seems to be a function of the PWM frequency as well. If you lower the frequency, there's less interrupt jitter.
It turns out, the PWM jumper wire(s) introduce some kind of noise or error in the interrupt jumper lines. When the PWM jumper gets within 1" of the interrupt jumper, the interrupts go haywire. So, I need to create a physical separation to get everything to work correctly. It's isn't ideal.
How can this PWM "noise" be eliminated in both the prototyping jumpers and with PCB traces.