View previous topic :: View next topic |
Author |
Message |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
Educated Guesses - Solved |
Posted: Thu Apr 30, 2015 6:24 am |
|
|
hi guys, i have gsm/sms temperature monitor running in my country house and every 5 hours, the sensor readings go nuts, alarms trigger and chaos ensues (Hypotetical caos).
i have implemented the "end of RX" code previosly discussed and suggested by some of you in this forum.
i went with the timer/Int + reset counter in the serial ISR. it worked nicely, by the way.
i Believe that the interrupt is messing with functions that read the sensor DS18B20 code from the library.
The interrupt is set at just over 500ms ... t_div_by_ 256...Timer0.
so i think its every 5 hours cause thats how long it takes for it to sych with the moment the sensor is being read.
I will have to drive a long way to get to the sensor and before i go, id like to have your educated guesses or opinions on my diagnose.
My solution will be to disable the interrupt and enable them only during the "delay"(end of rx) function.
G.[/url] _________________ CCS PCM 5.078 & CCS PCH 5.093
Last edited by Gabriel on Fri May 01, 2015 12:43 pm; edited 2 times in total |
|
![](templates/subSilver/images/spacer.gif) |
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Apr 30, 2015 6:58 am |
|
|
If your MAIN() loop is fast enough to execute - can you switch to POLLING the timer flag in MAIN and getting rid of the repetitive timer ISR component with your received data ?
You don't have to nail the precise time of flag rollover for timekeeping so long as you don't routinely miss / clear the rollover flag before another one comes along.
ie: you have a max of TWO rollover "times" to play with before you are at risk of losing time ......
My general rule is NEVER set up an ISR unless there is no other choice.
That means that for me the RDA ISR is often the ONLY one i enable with the second most common being a port B INT on CHANGE. Even then i will design MAIN() to be able to poll pins fast enough to matter.
The kind of issue you are seeing is about as bad as a PIC code problem gets IMHO, BTW......... |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Thu Apr 30, 2015 7:47 am |
|
|
I use the same sensor in every new board I've been making at my present employer.
I rolled my own interface driver/code that employs a one-shot timer to actually interface to the 1820, as I couldn't afford the time spent "twiddling my thumbs" in the delays between asserting the data line and then letting it go.
The approach works well except in the read routine, and only for code/situations where the processor is running close to its limit. Since the time between asserting the data line, letting it go, and then subsequently reading the line is small, even in a high performance dsPIC, there is no advantage in setting the one-shot timer to expire 9 us from now in order to read the state of the line.
Of the 3 projects I've used this approach on, 1 has occasional erroneous temperature issues. This project is the "busiest" of the 3, and does a lot of time sensitive comm routing. It's a two port CAN to/from two port serial bridge, and all 4 ports have high traffic.
The simplest approach is to do a sanity check on the temperature. Check the trend and if the present reading is outside of the trend, discard it and use the last known good temperature instead. I've found that when a read of the 1820 screws up, it screws up badly. It's not out by 2-3C, it's out by 100C+. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Thu Apr 30, 2015 8:06 am |
|
|
The obvious thing is that if there is one part of the interface code that _requires_ a tight timing (9uSec), then this section (and this section _only_). should have the interrupt disabled. Key is that as soon as the timing critical section is complete, then let the interrupt be serviced, and ensure that the timing critical part itself cannot become hung. If (for instance) it loops waiting for some event from the chip, then have a enable the interrupts during the loop, and have a timeout counter, so it the chip does not respond as expected, the code will exit and re-try. Anything with a tight deterministic timing, requires that interrupts are disabled.
The other obvious thing (once that short time is allowed to continue as it should), is that long times shouldn't change at all significantly _provided your ISR is quick_. Is it?. This is one of the 'golden rules' of writing ISR's. |
|
![](templates/subSilver/images/spacer.gif) |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Thu Apr 30, 2015 12:59 pm |
|
|
Timing is absolutely not critical with the roll over... i just wanted to avoid a fix delay on the GSM functions (the ones on the driver i have posted on the library)
with the interrupt, now i have a maximum of ~500ms of pointless waiting.
instead of whole seconds... which is a whole lot better and the code moves faster - i could dial it down to where i wait less with faster interrupts but at this speed im happy.
My main loop is pretty slow... i didn't need it to be fast... i needed it to be readable via LCD as it goes through its paces.... and its very linear at that. it works quite well and its stable.
ive modified the delay function to this:
Code: | int1 DELAY()
{
enable_interrupts(INT_TIMER0);
while(Main_Buffer_Index==0) // stay here until modem responds
{ // (X Seconds is arbitrary)
RX_DONE=0;
SET_TIMER0(0);
}
while(RX_DONE==0){}
RX_DONE=0;
disable_interrupts(INT_TIMER0);
return(0);
} |
Here is an example of how its used:
Code: | int1 DIS_CSDH()
{
Main_Buffer_Index=0; // Reset buffer counter
fprintf(U1,"AT+CSDH=0\r"); // text part of the command.
//delay_ms(2000);
DELAY(); // Delay a maximum of X seconds
return(STRING_SEARCH(OK)); // Check for OK response*/
return(PASS);
}
|
The idea is that the modem takes time to respond from the moment the command is entered.... i wait untill my buffer gets one char, and then wait for the roll over.
here is the ISR:
Code: | #INT_TIMER0
void Timer0_int()
{
RX_DONE=1;
}
|
Code: | #INT_RDA2
void SerialInt2()
{
SET_TIMER0(0);
Main_Buffer[Main_Buffer_Index]=fgetc(U1); // Gets chars from uart
Main_Buffer_Index++; // Increment counter
if(Main_Buffer_Index==MAIN_BUFFER_SIZE)
{
Main_Buffer_Index=MAIN_BUFFER_SIZE-4;
//Main_Buffer_Index=0; // Circle Buffer
Long_Message=TRUE;
}
} |
during the times the interrupt is necesary ive enabled it and disabled it when im done...
that should* eliminate the issue of interrupts during the 1-wire reads.
let me know what you guys think.
G. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
![](templates/subSilver/images/spacer.gif) |
Gabriel
Joined: 03 Aug 2009 Posts: 1067 Location: Panama
|
|
Posted: Fri May 01, 2015 12:35 pm |
|
|
.... that moment when your realize your freezer has a defrosting setting that cycles every 5 hours that you didnt know of since you never read the instructions cause you plugged it in, roared and filled it with food.
sigh. _________________ CCS PCM 5.078 & CCS PCH 5.093 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri May 01, 2015 12:40 pm |
|
|
In an industrial setting, I would have been thinking about some large motor doing something.
Delightful..... |
|
![](templates/subSilver/images/spacer.gif) |
|