2020/11/24 17:07:43
rmz22
Hi everyone,
 
Though I've been consulting this forum for a while, this is my absolute first thread, so I apologize in advance if I haven't included some critical information needed to troubleshoot my issue. I've looked around here (and other online resources) for hours but I haven't seen anything that really describes my issue, so here goes:
 
Device: dsPIC30F4013, MPLAB X IDE v5.40, Compiler: XC 16, Programming device: PICkit3. OS: Windows 10
 
Functionality description: The program's main loop counts up the number of times a button is pressed (pin RFO[30]) and prints the current count to an LCD screen (this part works fine). I need to write 3 interrupt routines which will read 3 NPN inductive sensors, each of which shall print a unique alarm message to the screen. Only after the sensors are reset (they're "seeing" metal again) AND a Reset button programmed at pin RB1[3] is pushed (as an acknowledge button), should the program return to the main loop where it can count again.
 
The NPN sensors I'm using work at 12VDC, and I'm using 3 PC817 optocouplers to isolate this high voltage from the 5VDC I'm supplying to the dsPIC30F4013 (and the signals the optocouplers send). I have checked that these devices work properly and that they're only sending a signal when they're supposed to.
 
I programmed the 1st interrupt at pin INT0/RA11[18] and this worked as expected. I then copied most of this code (modifying the appropriate registers) and am now also using INT1/RD8 [23] as input for the 2nd interrupt routine. The program compiles with no errors, however, when I test this on my PCB, only one of the interrupts works. When I comment INT0, INT1 works as expected, and vice versa. They cannot work simultaneously. To clarify, I don't mean that I can't use nested interrupts (this isn't what I'm trying to do), but that when I energize the dsPIC, only 1 interrupt works at all. Note that the interrupt that works is always the same one (whichever was the most recent one to NOT be commented before I uncommented both interrupts).
 
For the sake of brevity, I've included my code in a .txt file for your consideration.
 
Thank you very much for any help you might be able to provide.
 
Best regards,
Rob

Attachment(s)

Code.txt (4.26 KB)
2020/11/25 11:14:17
davea
while(PORTAbits.RA11==1){ 
and
while(PORTDbits.RD8==1){
what do you expect to happen
while waiting waiting in 1 ISR
it cant do the other
restructure the code use flag bits 
and evaluate the bits in main
using delays in a ISR is bad thing to do..
2020/11/25 11:52:14
Jerry Messina
using delays in a ISR is bad thing to do..

As is trying to write to an LCD... if it interrupts an ongoing LCD operation you're hosed.
2020/11/25 11:53:23
rmz22
Hi davea,
 
First of all, thanks for reading my question and going through the code.
 
davea
while(PORTAbits.RA11==1){ 
and
while(PORTDbits.RD8==1){
what do you expect to happen



The reason why I'm using nested "while" loops inside the Interrupts to check RA11 and RD8 for "1" and "0" is because in order to come back from the ISR, 2 conditions must be true simultaneously, in either INT0/INT1, the sensor must detect the guard/wrench (RA11/RD8 == 0) AND the operator must click a "Reset/Acknowledge" button, to make sure a motor (I'm not handling this part of the code, which is on another device anyway) can't just go into operation as soon as a sensor is back in place. So if I reset the guard/remove the wrench, the LCD will display something like "Sensor OK, press Reset to return to Run mode" but, if at any time the sensor stops detecting, the LCD should go back to displaying the Alarm code, which is why I'm constantly polling these 2 bits.
 
davea
while waiting waiting in 1 ISR
it cant do the other



I don't mean to enable the activation of 2 ISRs simultaneously (I think these would be Nested Interrupts), what I mean by INT0 and INT1 not working "together" is that, when I start up the dsPIC, only INT0 works. Which one of the 2 interrupts I trigger first by manually triggering the sensors is irrelevant. In other words, if I turn on the circuit, I can go into INT0 just fine and come back from it after tending to the sensor and pressing the acknowledge button, but when I come back into the normal operation mode, even if I trigger the second sensor, the dsPIC doesn't go into INT1.
 
davea
restructure the code use flag bits 
and evaluate the bits in main
using delays in a ISR is bad thing to do..

 
I'll look into this, and thanks for pointing out the issue with delays in ISR, I knew this but unfortunately, this is the only way I currently know how to deal with LCD issues (if I don't include the delays, the LCD Screen will sometimes display symbols which it isn't supposed to). If you could mention any workarounds, I'd really appreciate it.
 
Thanks again,
Rob
2020/11/25 11:59:13
rmz22
Jerry Messina
using delays in a ISR is bad thing to do..

As is trying to write to an LCD... if it interrupts an ongoing LCD operation you're hosed.



Hi Jerry,
 
Do you have any suggestions as to how I might print to an LCD screen without including said part of the code inside the ISR? We have a working example of the machine we're trying to reproduce and it operates the way I described. Normal operation-> Blinking alarm code -> Alarm code stops blinking when the triggering sensor has been tended to -> Reset button returns to Normal operation. So I suppose there has to be a better way to interact with the LCD screen?
 
Thanks,
Rob
2020/11/25 12:21:16
ric
As already stated, NEVER put blocking code inside an ISR.
This statement concerns me greatly

because in order to come back from the ISR, 2 conditions must be true simultaneously,

Any ISR should be written to exit as soon as possible. There should never be any condition holding you inside the ISR. Otherwise it's pointless using interrupts at all.

Do you have any suggestions as to how I might print to an LCD screen without including said part of the code inside the ISR? We have a working example of the machine we're trying to reproduce and it operates the way I described. Normal operation-> Blinking alarm code -> Alarm code stops blinking when the triggering sensor has been tended to -> Reset button returns to Normal operation. So I suppose there has to be a better way to interact with the LCD screen?

Restructure the code so all slow actions happen outside the ISR. You will need to learn how to code "state machines" to do this effectively.
 
2020/11/25 12:32:12
Jerry Messina
What ric said.
 
Looking at the code, you could easily ditch the interrupts entirely and just poll the input pins.
As it stands, the isrs display messages and wait for a human operator to press a button... hardy something that requires an interrupt.
 
2020/11/25 12:35:33
rmz22
Hi ric,
 
Thanks very much for your suggestions, what I gather from all answers is that I may be able to make this work with ISRs by using them to only set flag bits which will be linked to the different States of the State Machine you mention, whose "slow actions", to borrow from your comment, will include polling the necessary conditions to reestablish functions and printing to the screen, so I'll give that a go and come back to share my results.
 
Best regards,
Rob
2020/11/25 12:38:28
rmz22
Hi Jerry,
 
Thank you, I'll give that a go. I wonder though, would it not be better practice (as the sensors are important safety features) to use the ISRs if only just to raise said flag bits that will then go into the States/Subroutines ric mentioned?
 
Best,
Rob
 
2020/11/25 12:43:51
ric
You only need to the interrupt to handle things that must happen with minimum latency.
e.g. If a power source must be shut down as soon as possible, you could flip a pin inside the ISR, but leave less critical actions, like updating an LCD, to later.
 
© 2021 APG vNext Commercial Version 4.5

Use My Existing Forum Account