CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Using watchdog timer for timeout function
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

Using watchdog timer for timeout function
PostPosted: Tue Oct 23, 2012 5:56 pm     Reply with quote

What I'm trying to do seems quite simple, but after 2 days of searching the forums, I have yet to come up with a solution.

I'm using a PIC 18F4520, MP LAB ver. 8.80.00.00, and PCW ver. 3.249.23.12.

My application is for GPS vehicle tracking. In the receiver I'm using RS-232 for internal communication with a data radio module. If the GPS data from the vehicle satisfies a certain condition, I send an output pin high, and if it meets a different condition, I send it low. I need to provide for the contingency that I send the pin high, and then I stop receiving data from the transmitter. After 4-8 seconds, if I don't get a low start bit, I need to send the output pin back to low.

I was told that the watchdog timer can handle this, but I can't figure out how to get it to work. I tried modifying the library file ex_wdt18.c, but I haven't been able to figure out how to set the conditions for resetting the timer (start bit) and executing a command when it times out (no start bit after 4-8 s).

I did manage to set the configuration bits to WDT and WDT1024, but that's about as far as I've gotten.

Any help would be very much appreciated.
_________________
Always remember, things are never so bad that they can't get worse.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 23, 2012 7:39 pm     Reply with quote

Look at the TIMEOUT parameter in the #use rs232() statement in the manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 23, 2012 7:50 pm     Reply with quote

Thanks much! I didn't think to look there. This should work even better than the WDT. Very Happy
_________________
Always remember, things are never so bad that they can't get worse.
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Tue Oct 23, 2012 9:15 pm     Reply with quote

Well, I tried it, and it didn't work. I think the problem is that every second I am getting 28 bytes (8-bit integers) of GPS data, and if I throw in an extra getc() to watch for the timeout, that will shift all my data up by 1 byte and cause the entire system to fail.

I tried using an if conditional to look at the first byte in the 28-byte data stream by its currently assigned name and send the pin low if it equals zero, but that didn't do anything. When I killed the power to the transmitter, the output pin in the receiver just stayed high.

Any idea what I'm doing wrong here?
_________________
Always remember, things are never so bad that they can't get worse.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 23, 2012 9:36 pm     Reply with quote

I don't understand what you mean by an extra getc ? How do you get
the incoming bytes ? What do you use other than getc ?
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Wed Oct 24, 2012 1:13 am     Reply with quote

In the Main loop I have
Code:

if(input(RXData) == 0)      // Did we get a low start bit ?
{
   GetBurst();         // Get data packet

Then have a subroutine with 28 consecutive lines of getc()s to get 28 bytes of GPS data from the radio.
Code:

void GetBurst()
{
   data01=getc(ac);
   if(data01 == 0)         // Did we get a timeout from RS-232?
   {
      putc(0xCA, mc);   // Send cancellation byte to 2nd MCU.
      Reset();         // Reset variables.
      return;
   }
   data02=getc(ac);
   data03=getc(ac);
   data04=getc(ac);
   .
   .
   .
   data27=getc(ac);
   data28=getc(ac);
   return;
}

As you can see, I have tried looking at my first data byte, data01, to check for the timeout byte, but it simply doesn't work, and I can't figure out why.

The sample code shows a getc() to get the zero-value byte from the RS-232 timeout, but if I put that in, it will get my first byte of data, then my second byte will be assigned to data1 and the third byte to data2...

I have tried putting this code
Code:

   if(data01 == 0)         // Did we get a timeout from RS-232?
   {
      putc(0xCA, mc);   // Send cancellation byte to 2nd MCU.
      Reset();         // Reset variables.
      return;
   }

in the main loop, but it doesn't work there, either.

Any ideas?
_________________
Always remember, things are never so bad that they can't get worse.
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 25, 2012 2:14 pm     Reply with quote

Update:

I tried adding an extra non-zero char byte (all others are int 8) at the beginning of my data from the TX for the timeout byte. The idea was that if this byte is a zero character (0x30), that will cause the if statement to be true and send the cancellation byte. I then added an extra getc() at the beginning of the GetBurst() routine to get this character.
Code:
void GetBurst()
{
char killbyte;
   killbyte=getc(ac);
   if(killbyte == 0)         // Did we get a timeout from RS-232?
   {
      putc(0xCA, mc);     // Send cancellation byte to 2nd MCU.
      Reset();                 // Reset variables.
      return;
   }
   data01=getc(ac);
   data02=getc(ac);
   data03=getc(ac);
   data04=getc(ac);
   .
   .
   .
   data27=getc(ac);
   data28=getc(ac);
   return;
}

However, this somehow messed up the data causing the entire system not to function.

The problem is that the documentation assumes you will only be receiving a single byte of data and not a stream of multiple bytes. How can I apply the RS-232 timeout function when my data comes in a stream of 28 bytes? Question
_________________
Always remember, things are never so bad that they can't get worse.


Last edited by jlucas on Thu Oct 25, 2012 2:20 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 25, 2012 2:20 pm     Reply with quote

You shouldn't have multiple getc() statements. You should have a for()
loop with one getc() in it. If the getc() returns 0, and the RS232_ERRORS
variable is also 0, then it timed out. In that case, break out of the for()
loop.
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 25, 2012 2:29 pm     Reply with quote

Well, then, I'm going to have to come up with a completely different solution. In normal operation it is highly likely that one of my data bytes will equal 0x30, and I can't have it cancelling every time I get a byte with that value. If each event lasts 10 sec, and I'm getting 28 bytes each second, that means there's a better than even chance that one of my data bytes will equal 0x30 and cause a premature cancellation.

Any hope for getting the watchdog timer to work for this? I don't need precise timing. I just can't leave the system hung up indefinitely if it doesn't get a cancellation from the TX.
_________________
Always remember, things are never so bad that they can't get worse.
Ttelmah



Joined: 11 Mar 2010
Posts: 19568

View user's profile Send private message

PostPosted: Thu Oct 25, 2012 2:42 pm     Reply with quote

0x30 != 0......

The return value is _binary_ 0 or 1.
The digit '0' is 0x30.

Best Wishes
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 25, 2012 2:56 pm     Reply with quote

The instructions were to declare this variable as a char, not an int 1.

The point is, my data can contain ANY 8-bit value from 0 to 255, so I can't have any value cause a timeout every time it comes in. I just need a timeout for when I stop receiving data for 4-8 sec .
_________________
Always remember, things are never so bad that they can't get worse.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Oct 25, 2012 3:32 pm     Reply with quote

Quote:
my data can contain ANY 8-bit value from 0 to 255

The CCS getc() timeout feature works with any data from 0 to 255. The
RS232_ERRORS variable normally returns a value of 0x90 (with the
18F4520) for any character received, if there is no timeout. This is true
even if the character that is received is a NULL (0x00).

RS232_ERRORS will only return 0x00 if you get a timeout with getc().
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 25, 2012 3:43 pm     Reply with quote

I don't think I'm ever going to get the RS232 timeout function to work in my system as I have it now, and it's going to take a MAJOR rewrite of the code to make it compatible with this scheme.

All I want is for the 18F4520 to send a byte to the other chip if it doesn't receive any data for 4-8 sec. Is there any other way to do this that doesn't use RS232_ERRORS?

I've tried using the delay_ms(n) function, but that brings the entire system to a halt while it runs.

I think the watchdog timer might be my only hope, but that doesn't seem to work as advertised, either. Sad
_________________
Always remember, things are never so bad that they can't get worse.
jlucas



Joined: 08 May 2011
Posts: 41
Location: Carthage, MO

View user's profile Send private message Visit poster's website

PostPosted: Thu Oct 25, 2012 4:54 pm     Reply with quote

Quote:
I want to clarify something before going any further:

1. If you don't get any characters from the GPS device for 4-8 seconds
then you want to send a character to the GPS device. Is that true?


Actually, I want to send the character to a different device, a 16F685. I already have one-way RS-232 communication with that chip.
Code:
#use rs232(baud=9600, xmit=PIN_B0, stream=mc)


Quote:
2. Are you using the hardware UART in the 18F4520 to send and receive characters to/from the GPS?


I'm not using the UART. I have RS-232 set up to send and receive data to and from a data radio module.
Code:
#use rs232(baud=57600, xmit=PIN_E1, rcv=PIN_C0, timeout=10, stream=ac)

The GPS receiver is in the vehicle transmitter, and it sends only the 28 bytes of data that I need. Right now, I'm working on the code for the receiver to get it to send a byte to the 16F685 when I don't get data from the RF module for 4-8 sec.
_________________
Always remember, things are never so bad that they can't get worse.
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Thu Oct 25, 2012 5:06 pm     Reply with quote

Why not use one of the hardware timers?

Mike
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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