View previous topic :: View next topic |
Author |
Message |
z1rqdym
Joined: 14 Dec 2014 Posts: 24
|
HC05 interface issue |
Posted: Thu May 03, 2018 6:36 am |
|
|
Hello everyone,
I am on a project that should be interface over android bluetooth hardware.
I used PIC16F876A and HC05 bluetooth module.
I can receive single characters, there is no problem. But i need to send and receive string data. When i send strings there is no problem.
The problem starts when i will get strings with the HC05.
I try a lot of different algorithms to get strings. PIC16F876A has a 1 byte buffer for UART receive. So I do receive interrupt routine for it to get every characters from the string. But it is not efficient. Because while i get the string data i need to do another process on the system. While i do another process the interrupt routine will not work well.
On a Atmega uC i can do this very well with any issue but on the PIC side i can not do this.
When i disable NL and CR on the terminal i can get the string. On the android side the bluetooth is not configurable to disable NL and CR.
I do not need a example code, i need a idea for how to do this stuff.
If anyone could help to me i will be happy. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Thu May 03, 2018 6:49 am |
|
|
First, you should post a link to the 'HC05' module you're using. HC05 is a 3 volt device, the PIC 5 volt, so there could be a 'logic level interface' problem. We need to 'see the specs' for the module. AT chips have a different design for inputs, although some PICs can be set for SMB interface and that should work. This has been covered before here, try the 'search' option for 'hits' here and the code library.
Since I probably don't have your HC05 module here to test, I can't say my code will function 100% for you. |
|
|
z1rqdym
Joined: 14 Dec 2014 Posts: 24
|
|
Posted: Thu May 03, 2018 7:13 am |
|
|
https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcSVxZN4FPbs2dj1MtXquBxiS5EGo6Uu8-s6gcXUhsyinf3w0m7YhTJv3zdRBw
This the hc05 that I'm using. it has BC417 chip. I use voltage divider for logic level converting for each RX and TX pins. But it is not necessary to use voltage divider because i do a lot of projects without level converting and it is work while i send and receive only one character. But i did the level converting. So this will not solve my problem.
I can not change the microcontroller. Our teacher will to do this with PIC16F876A.
I already read the datasheet of the BC417. They use UART to communicate not with SMbus. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu May 03, 2018 6:59 pm |
|
|
Quote: | Because while i get the string data i need to do another process on the
system. While i do another process the interrupt routine will not work well. |
It should work, unless you have done something to block interrupts.
Post your interrupt routines.
Also, post your #use rs232() statement. If your program is short enough
it would be helpful to post it all. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Thu May 03, 2018 11:58 pm |
|
|
You have to do something to actually mark the end of your 'string'.
A string is just a sequence of characters. Nothing else. It is stored in C by having a terminating NULL ('\0'). When sending you need to be doing something similar by sending a similar terminating character. A line feed or a NULL would be typical selections.
Your receive interrupt code should be very simple. Ideally have _two_ receive buffers. Write the received characters sequentially to a buffer and do nothing else. When you see the terminating character, put a NULL in the buffer, and set a flag to say that you are now using the second buffer. The next time the interrupt is called it writes to start of the other buffer. Your main code can then use the string in the first buffer.
I have a nasty suspicion that you are trying to do some form of more complex processing in the receive interrupt, and this is leading to hiccups. Or that the main code is trying to access the same buffer being used by the receive. You can't do this. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri May 04, 2018 5:04 am |
|
|
As a 'follow up' to Mr. T, CCS does supply a basic Interrupt driven serial receive program called EX_SISR.C . It's in the examples folder, and with a simple modification works very well at 115K2 Baud.
Also, you may consider adding 'receive timeout' code. Again CCS shows how to do this, I believe in the FAQ section of the manual. What happens is the RCV section will 'timeout' and exit after xx milliseconds. This is required if the link to PC is broken or /0 (the terminator) doesn't get sent.
just food for though
Jay |
|
|
z1rqdym
Joined: 14 Dec 2014 Posts: 24
|
|
Posted: Fri May 04, 2018 9:50 am |
|
|
I wrote all of the stuff from scratch. this time i did it. it works well.
i will tell something about App Inventor who wants to make projects over bluetooth modules. Keep in mind that App inventors bluetooth component dont send the CR and NL characters. But they will required when a string send to the phone.
minimum sample code is there.
Code: |
#include <16F876A.h>
#device ADC=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES PUT //Power Up Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NOPROTECT //Code not protected from reading
#FUSES HS
#use delay(crystal=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS) // ERRORS Required !!! :D
#DEFINE BTN PIN_B4 // connected a buton to PIN_B4 to make test 10k pull-down resistors is need.
#DEFINE BUFFER 20 // string buffer size
char get_strng[BUFFER]; // string array variable
int8 i=0;
int8 k=0;
#INT_RDA
void RDA_isr()
{
get_strng[i]=getc(); // get every character one by one
if(get_strng[i]==13) // CR > 13 . if this recieved then finish the progress
{
i++;
if(i==BUFFER)
{
i=BUFFER-1;
}
for(k=i;k<BUFFER;k++) // erase the array from the previous characters and let the new ones only
{
get_strng[k]=0;
}
k--;
get_strng[k]=13; // the last character of the string made it CR > 13
k--;
get_strng[k]=10; // the last second character of the string made it NL> 10
i=0;
}
else // get the next character
{
i++;
}
}
void main()
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE)
{
// example for testing the string are correct
if(input(BTN)==1)
{
while(input(BTN)==1);
printf("%s",get_strng);
}
}
}
|
Last edited by z1rqdym on Fri May 04, 2018 3:05 pm; edited 1 time in total |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Fri May 04, 2018 12:09 pm |
|
|
re:
Quote: | #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) // No ERROR Required |
Actually the option ERROR is required unless you can be 100% sure the PIC will process all characters in the HW UART buffer BEFORE the next character arrives. Do almost anything inside the ISR (like 'math', prints, long IF statements, etc.) and you'll overrun the UART buffer and 'lockup' the PIC. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19549
|
|
Posted: Fri May 04, 2018 1:34 pm |
|
|
ERRORS not ERROR!....
ERRORS should _always_ be enabled on the hardware UART, unless you add code to the interrupt handler to handle these yourself. Otherwise, miss one character, or get a transmission problem and receive a malformed character, and the UART will become hung. |
|
|
|