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

Missing character input on non-UART input pin

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

Missing character input on non-UART input pin
PostPosted: Tue Jul 07, 2020 10:12 am     Reply with quote

Hi -

I'm using a PIC 18F2680. I need to use the two CAN pins (RB2/3) for a CAN bus, , RS232 I/O going through the hardware UART (RC6/7), and yet another RS232 port using pins RB5/7 called XBEE.

In my code, if I delete the delay_ms(250), it works flawlessly, but if I include it, some of the input characters are missed. kbhit isn't set for some of the character inputs, so they are missed.

I've spent a lot of time looking through this forum, and the solution to this common problem is via Int_RDA and the use of RS232_ERRORS, but these aren't available using a non hardware connection to the UART. I've tried an interrupt on change of RB ports, but it is getting too many interrupts from the RS232 bits, and I can't TRIS out the rest of the port since some of the pins on the RB port are also inputs for other purposes. I tried setting a short timeout for the input, thinking that might clear the error with a read without kbhit, but it doesn't work.

Is there any solution to this? I've spend hours, but can't find one - would appreciate any help any of you might offer.

Thanks,

Brian


Code:

#device   PIC18F2680 ADC=8  *=16

#include <18F2680.h>

#define  LED   PIN_A1 // LED output port

#include <stdlib.h>


// the fuses specify use of external 10 MHz oscillator
#fuses    HS, NOLVP, NOWDT, PUT, NOWRTD, NOPROTECT
#use      delay (clock=10000000)

char      char_received;  // buffer for data coming from shore

// set up the RS-232 channels
#use rs232 (stream=XBEE, baud=9600, xmit=PIN_B7, rcv=PIN_B4, PARITY=N, BITS=8, FORCE_SW, TIMEOUT=1, ERRORS)
#use rs232 (stream=SOUNDER, baud=4800, xmit=PIN_c7, rcv=PIN_c6, PARITY=N, BITS=8, FORCE_SW, INVERT, ERRORS)
 
// LED off - turn off the LED
Void LED_off(Void)  { output_high(LED); }

// LED on - turn on the LED
Void LED_on(Void)   { output_low(LED); }

void main (void) {

   LED_on();            // LED on for a little bit to know we're running
   delay_ms(500);       // delay
   LED_off();
   
   // sit here and loop, monitoring the XBEE input
   while (TRUE) {
   
       if (kbhit(XBEE)) { 
          char_received = getc(XBEE);
          LED_on();
          delay_ms(50);
          LED_off();
          }
      delay_ms(250);
      }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 12:50 pm     Reply with quote

On the XBEE stream, characters can come in at about a 1 ms rate.
The CCS software UART reads incoming characters by camping on the
input pin and polling it. But with your 250 ms delay, you have shut down
this polling process for 1/4 second. It's going to miss characters.

Look in the Ex_CRC.c example file for code that shows how to use an
external interrupt pin to interrupt on the beginning of an incoming char.
Then use getc() to read the char inside the interrupt routine.


Last edited by PCM programmer on Tue Jul 07, 2020 1:02 pm; edited 1 time in total
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

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

PostPosted: Tue Jul 07, 2020 1:02 pm     Reply with quote

CCS manual states that if using software UART then kbhit must be called at least 10 times the baud rate in order to *reliably* catch incoming characters.

With software UART sending is pretty good but receiving really limits what you can do with your processor cycles. Are you locked into using this PIC or can you substitute one with more than one UART?
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 1:09 pm     Reply with quote

Key thing to understand about the receive on 'software serial', is that the
processor has to actually be sitting in the code 'waiting' for the character
to arrive. If it is doing anything else, the characters are lost. No buffering
etc..

I've posted here:
<http://www.ccsinfo.com/forum/viewtopic.php?t=51403&highlight=timer+serial>

an alternative way of doing serial receive using a timer interrupt,
that avoids this.
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 2:10 pm     Reply with quote

point of confusion.....
easy as it's +40*C here...

// set up the RS-232 channels
#use rs232 (stream=XBEE, baud=9600, xmit=PIN_B7, rcv=PIN_B4, PARITY=N, BITS=8, FORCE_SW, TIMEOUT=1, ERRORS)
#use rs232 (stream=SOUNDER, baud=4800, xmit=PIN_c7, rcv=PIN_c6, PARITY=N, BITS=8, FORCE_SW, INVERT, ERRORS)


Both serial are setup as 'force_sw' , so 'sounder' doesn't use the UART hardware.

Can you use the HW UART for the XBEE module, SW for the 'sounder' ?
AS 'sounder' is only 4800 this might work for you ??

Other possible options are
'bigger' PIC with 2 HW UARTS and CAN...
UART<>I2C peripheral
UART<> SPI peripheral

Whichever you decide, be sure to use ISRs and 'serial buffers' to capture the data.

Jay
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 2:19 pm     Reply with quote

Thank you for your help.

I copied the code from the example, and couldn't get an interrupt using INT_EXT, but changing to INT_RB worked.

It seems to be reliable with this interrupt. Not sure why it doesn't cause an interrupt when I send data out via RB4, but it doesn't, and I'm happy about that. And I seldom will output from RB5 and RB6, so that shouldn't be an issue.

The example didn't use KBHIT in the interrupt, seems reliable if I do or don't. But is there risk that you could do the GetC before it's done getting the charactor? Would it be a good idea to put a 1mS delay in the interrupt routine before the GetC so ensure that the character is done before requesting it or leaving the routine? And to prevent another RB interrupt for the far end of this character if you leave before this character is done?

I really appreciate your comments - I can see a win after days of frustration.

- Brian
dluu13



Joined: 28 Sep 2018
Posts: 395
Location: Toronto, ON

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

PostPosted: Tue Jul 07, 2020 2:36 pm     Reply with quote

There isn't a risk of that. getc() actually sits and waits for a character to come in.

According to the manual:
Quote:
This function waits for a character to come in over the RS232 RCV pin and returns the character.

In order to not hang forever waiting for an incoming character use kbhit() to test for a character available.

If a built-in USART is used the hardware can buffer 3 characters otherwise getc() must be active while the character is being received by the device.


I wonder what happens if you are doing getc on a "false" start bit that could be caused by noise or something...
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 4:43 pm     Reply with quote

You can add a 'timeout' while receiving serial data. That's in the FAQ section of the manual. Real handy in case the serial cable gets pulled out by a curious kitty.... Smile
OldGuy



Joined: 03 Feb 2013
Posts: 27
Location: Seattle Area

View user's profile Send private message

PostPosted: Tue Jul 07, 2020 6:43 pm     Reply with quote

I'm really appreciative of all the tips. They are coming in faster than I can try them and make individual responses.

Unfortunately, I compiled with debug on with my U64, and it worked, but since then I can't program it since it returns the wrong processor ID. I think I might need to erase the PIC if I can figure out how to do it. Sounds like this can happen if certain things are changed by the debugger.

But, I'm getting good clean input now (once I get this fixed)! Thanks to all of you who contributed the useful tips.

Next design I'm going to take more care to ensure that the pic I choose has enough UARTs.

Brian
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Wed Jul 08, 2020 4:31 am     Reply with quote

Years ago I finally got smart... and chose the 18F46K22 for my 'pick of PICs'. I wanted a silicon 'Swiss Army Knife' and with 2 HW UARTS, 2 I2C, lots of memories,speed, 3-5 volt it's served me well. While a 40 pin device is overkill for 99.44% of the products having ONE PIC has been handy. I've been able to create my library of solid,good drivers,functions and code which allows me to concentrate on programming instead of fighting 'bugs' using the 'latest and greatest' PIC. I started this gig with PCM 2.543+- and haven't updated since the mid 4000s, though I do have an early five 'somewhere'...
Yeesh 1/2 my lifetime playing with PICs...and I STILL fine they can do neat stuff !!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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