|
|
View previous topic :: View next topic |
Author |
Message |
qwwe
Joined: 17 Sep 2017 Posts: 59
|
Reset the microcontroller on the WDT |
Posted: Sun Oct 08, 2017 2:10 am |
|
|
Hello, you have the problem with the following program settings.
I'm writing a program for a GSM modem.
The microcontroller receives the first SMS and responds.
But once the SMS is received, the microcontroller is reset by the WDT.
Code: |
#include <16f1829.h>
#fuses HS //High speed Osc (> 4mhz for PCM/PCH)
#fuses WDT //Watch Dog Timer
#fuses PUT //Power Up Timer
#FUSES NOLVP //No low voltage programing
#fuses NOCPD //No EE protection
#fuses NOPROTECT //Code not protected from reading
#fuses NOWRT //Program memory not write protected
#fuses NODEBUG //No Debug mode for ICD
#fuses NOBROWNOUT //No brownout reset
#use delay(crystal=11059200,restart_wdt)
#use RS232(ENABLE=PIN_A0,baud=9600,xmit=PIN_C4,RCV=PIN_C5,parity=n,bits=8,errors,restart_wdt)
#include <stdio.h>
#include <string.h>
/////////////////////////Define variables and arrays////////////////////////
int16 i=0;
int16 len,j;
char zero='0';
char one='1';
char recive[256];
char phnum[17];
char smstext[25];
char w[12];
char l[13];
char hi[9];
char sp[8];
char fixstatus[2];
char cmt[]="+CMT:";
char cgnsinf[]="+CGNSINF:";
char ons[]="ons";
char onl[]="onl";
char off[]="off";
char ussdi[]="usir";
char ussdm[]="usmci";
char dq=34,enter=13,cz=26,linfeed=10;
//////////////////////////////Definition of functions////////////////////////
void geti();
void editcmt();
void clear();
void gpsinf();
void lwhsclear();
///////////////Definition buffer and isr and read character/////////////////
#define BUFFER_SIZE 256
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
#int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
| |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sun Oct 08, 2017 2:28 am |
|
|
You don't show us anything of your program....
However the answer is probably 'of course'.
You have enabled the watchdog. You don't specify 'how long', so by default the shortest time is selected. 1mSec.
Sending an SMS, a modem will often take several _seconds_ to reply. If you are relying on the RS232 code to reset the modem, then 'of course' it'll timeout....
You like many posters here have the wrong attitude to the watchdog. Thinking it is something that you just 'turn on', that will magically improve the reliability of code. It isn't.
For development, your watchdog should be off.
Then once you have a running program, you need to sit and look at critical timings, and critical events. So (for instance), if the code is running properly, perhaps the display should update every second, and the keyboard must be scanned every 1/4 second. The unit needs to respond to events in a minimum of 10 seconds (say). So you set the watchdog to be just slightly longer than the display update interval (1.2 seconds say), and you have the watchdog reset in the display routine every second with a second test that the keyboard routine has been called four times, and that everything that must happen in the main loop is happening). You only reset the watchdog, if _all_ the required conditions are being met (scattering 'restart_wdt' instructions round the code stops the watchdog from being useful, and these can be reached even if the unit is not working correctly...). With this done, the chip will reset if things are not being done in the times required. |
|
|
qwwe
Joined: 17 Sep 2017 Posts: 59
|
|
Posted: Sun Oct 08, 2017 2:44 am |
|
|
Hi this is the program
Last edited by qwwe on Sun Oct 08, 2017 5:33 am; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Sun Oct 08, 2017 5:03 am |
|
|
Like Mr. T points out, don't enable the WDT until your product is ready for shipping! It's the last bit of code you add AFTER the rest works 100%.
also...
I see a LOT of delay_ms(3000); in your code. You may find that if you create a function and call it, the program will be smaller.
ie;
Code: |
// three second delay function
void Dly_3_sec(void)
{
delay_ms(3000); delay for 3 seconds
}
|
and...
You should (must) add comments to your code. They cost nothing but are priceless ! Almost EVERY line of code should have a comment on the end. While the use of variables may be obvious to you, now.... a week or month goes by and you'll wonder 'what is 'w' used for ? Anyone debugging (helping you) needs to know as well.
Case in point....
this..
Code: |
}while(recive[i-1]!=linfeed); |
I can't see where 'linfeed' is defined AND I 'think' it's a mistype, should be 'linefeed'.
and..
in the USE RS232(..)
you have a pin defined for enable. That normally only applies to RS-485, are you really using RS-485 ? Also, get rid of the restart_wdt' option, at least until program is 99.44% working.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 08, 2017 7:47 am |
|
|
Why did you erase your program ? I noticed you had some stuff in there
that is unnecessary.
You have stuff like this:
That is not necessary. With '&*' you are taking the contents of the
location pointed to by 'ptr', and then getting the address of it.
But that's the same thing as this:
You can delete every place where you have '&*'. Just use the pointer.
Below is a test program that proves this. When this program is run in
MPLAB vs. 8.92 simulator, it displays this result in the Output window:
The same RAM address is returned by either method, which proves that
your usage of '&*' is not needed.
The symbol table is shown below. You can see that 0005 is the
RAM address of the first byte in the 'term' array.
Quote: |
000 @SCRATCH
001 @SCRATCH
001 _RETURN_
002 @SCRATCH
003 @SCRATCH
004 rs232_errors
005-006 main.term
007-008 main.ptr
009 main.@SCRATCH1
00A main.@SCRATCH2
|
Test program:
Code: | #include <18F46K22.h>
#fuses INTRC_IO,NOWDT,PUT,BROWNOUT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//=====================================
void main(void)
{
char term[]=",";
char *ptr;
ptr = term;
printf("%lx \r", &*ptr); // This method is not necessary
printf("%lx \r", ptr); // This is the correct way to get the pointer address
while(TRUE);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Sun Oct 08, 2017 12:07 pm |
|
|
Generally, the poster needs to learn the first step of debugging. Test things one at a time. Get each item working and understood first.
He is posting in another thread about a problem with strncmp, and when he posted the code, it was visible that he was putting the pointer for the string he wanted to search for as the second variable, not the first.
A basic test with some strings and the function would show how it works.
Trying to run before walking.... |
|
|
qwwe
Joined: 17 Sep 2017 Posts: 59
|
|
Posted: Tue Oct 10, 2017 1:28 am |
|
|
Hello, since the program was long, I cleared it
If I need to re-send
This program responds with no flaws when I connect the microcontroller to a computer and test it with the bray v1.9_termimal software.
And the module answers without any errors when I connect to the computer and test it using the bray v1.9_termimal.
I am in this bray v1.9_termimal software.
Hex code I have seen the strings the module sends.And I wrote up with that program.
This module has a and <CR> and linefeed<LF> at the beginning and end of each response.
Mr.PCM programmer
I want by strcpy function Save the content that Ptr points to in an array. I used to do the way you said before, but did not answer, but I wrote that the answer was correct.
Mr.temtronic
A variable I have defined and I have set it to 10 because it is equivalent to code ascii linefeed
I've tested the program in all scenarios, but on the computer it works well, but when I connect the microcontroller to the module, for example: it receives an SMS, and the microphone works fine and another SMS does not work properly. I'm really confused about what's wrong with that, and another message works fine again. I do not do it in the logic that I've defined.
I just wrote an application that only receives SMS and recognizes its number and text and send it again, which worked well. However, it did not work well at first, because I also plugged the module into a microphone and the computer I can see the output, but when I plugged the module into the microphone, I responded correctly.
But now that I'm writing the program, it does not answer right.
Thanks for help. |
|
|
qwwe
Joined: 17 Sep 2017 Posts: 59
|
|
Posted: Tue Oct 10, 2017 1:33 am |
|
|
Module name SIM808 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Oct 10, 2017 2:23 am |
|
|
If you are using a SIM808, when you connect it to the PC, you have got some form of hardware interface between the unit and the PC.
Now (hurrah), you have a 3v PIC. That's a great start, otherwise we would be starting the conversation about the PIC not being able to see the output from the module.
The honest place to start is to step backwards. You need to actually verify that the PIC is seeing what the module sends properly. So wire the serial output of the module to the PIC serial input, attach an LCD to the PIC (you seem to have this already). Then attach the serial output from the PC to the module input, and then just have a program displaying what the module returns.
No watchdog.
Then send commands to the module and see what is genuinely being seen by the PIC.
Note that quite small changes in the network for example, will give replies from the module you may not expect. For instance if you send an SMS, you may well see a network error returned sometimes. Your code needs to be able to at the least recover from such a different message, and even better then retry.
You need to start understanding, that to program, you have to handle _every_ thing that the devices throw at you, either coding directly, or having a clean recovery. Also that you need to work one step at a time. So prove that you are sending messages. Then sit down and look carefully at the replies. and work out ways of handling the changes in these. Then draw out your 'strategy' that you want the code to perform, and test this one small part at a time.
Now I see one possible problem mentioned already. The SIM808 expects lines to be terminated with CR (0xD) codes, not LF (0xA) codes. It should not be responding with CR and LF, but just with CR. I suspect your terminal program on the PC is setup to automatically add LF, when it sees CR, which is a common setting for such programs. If you are sending LF codes to terminate commands, then the modem will not respond, and then (of course) you will get a timeout, and possibly a watchdog....
In C, you send CR with '\r', so the command to ask the modem to respond, is simply:
printf("AT\r");
for example. |
|
|
qwwe
Joined: 17 Sep 2017 Posts: 59
|
|
Posted: Tue Oct 10, 2017 2:54 am |
|
|
Module responses according to the datasheet:
<cr><lf>respons<cr><lf>
for example: According to my own observations on the PC.
OK
Hex code:
0D
0A
4F
4B
0D
0A
Thanks, but I've already tested the ways you said
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Oct 10, 2017 4:56 am |
|
|
You are slightly missing the point.
It responds with CR LF, but it does not respond _to_ LF. It responds to CR.
The syntax of commands sent to it, must be command<CR> not command<LF>.
Quote: |
The "AT" or "at" or “aT” or “At”prefix must be set at the beginning of each Command line. To terminate a Command line enter <CR>.
|
Your PC will automatically be sending CR LF. The LF will be ignored (it is treated as 'whitespace'), but it is CR you must send for your commands to work, not LF. |
|
|
qwwe
Joined: 17 Sep 2017 Posts: 59
|
|
Posted: Tue Oct 10, 2017 7:27 am |
|
|
Yes, the commands I send from the microcontroller to the module will only be <cr>
for example:
printf("ATE0%c",enter);
But the response that the modem sends is <cr> <lf>
for example:
<cr><lf>response<cr><lf>
<cr><lf>Which are not visible but are |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Oct 10, 2017 12:01 pm |
|
|
The point was that the character you had defined as LF, was 0xA. It was this character that was being sent to terminate the command, which won't work.
As I said anyway, get rid of the %c, and just use \r. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Oct 10, 2017 1:53 pm |
|
|
If you are using the INT_RDA to handle data from this modem, then let me suggest a modification:
Code: |
int1 have_line=FALSE;
#int_rda
void serial_isr() {
int t;
t=getc();
if (t==0xA)
return; //Throw LF
if (t==0xD)
have_line=TRUE; //set flag that there is a line
buffer[next_in]=t; //store the character
t=next_in++;
if (next_in==BUFFER_SIZE)
next_in=0; //wrap at buffer end
if(next_in==next_out)
next_in=t; // Buffer full !!
}
|
Now changes here. Not using %, means this will work efficiently with sizes that are not 'binary'. So numbers like 10, 15 etc..
The LF character is simply thrown. It's not significant for any of the modem commands (exception here if you are doing something like ASCII ftp), so can just normally be got rid of.
Key though is 'have_line'. This gets set whenever a CR character comes.
So your main code after it has sent a command can stop bothering to read characters till this goes TRUE. When it does, simply set it to FALSE, and read the line. |
|
|
qwwe
Joined: 17 Sep 2017 Posts: 59
|
|
Posted: Thu Oct 12, 2017 12:37 am |
|
|
Thank you for this code
In your opinion, these lines:
The output of the getc() function is of type character and (t) of type int
Does not this make a problem?
But another question
In the following code when it returns.
Returns to the beginning of the routine interrupt.
Code: |
if (t==0xA)
return; //Throw LF
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|