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 support@ccsinfo.com

Bluetooth not receiving data on UART
Goto page Previous  1, 2, 3, 4  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 2:05 am     Reply with quote

After days working on my code, I can somehow managed to capture the input from my smartphone and echoed it back, but i a weird manner using the code below:
Code:
#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, LOCK)
#fuses NOWDT, NOPROTECT

#pin_select U1TX=PIN_F4
#pin_select U1RX=PIN_F3
#use rs232(baud=19200, UART1, bits=8, parity=N, errors) //enable interrupt receive buffer

#define pixels 5324
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 128
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);
}

void mtbuf(void) // clear all recived chars in buffer

 while (bkbhit)
 bgetc();
}

void BT_wake (void)
{
   output_low(PIN_F1); //disable sleep on Bluetooth module
   while (input(PIN_G6)==0)
       ; //wait if chip is in a hardware reset
   output_low(PIN_G6); //set low to mode pin on Bluetooth module
   delay_ms(1);
   output_float(PIN_G6); //release line
   while (input(PIN_G6)==0)
       ; //wait for the chip to finish resetting
}

void main(void)
{
   int i = 0;
   char out[100] = "TXDT ";
   char input_str[100] = "0";
   BT_wake(); //wake the chip
   delay_ms (20000); //delay 1/3 minutes to establish connection
   //output some introductory message after startup
   puts("TXDT BA '\n' '\r'"); //Output BA
   delay_ms (1000);
   puts("TXDT B1 '\n' '\r'");  //Output B1
   delay_ms (1000);
   while (true)
   {
   mtbuf(); //clear the buffer
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL); //start the receive buffer
   delay_ms (10000); //delay 10 sec for user input
   while(bkbhit)
   {
   input_str [i] = bgetc() ; //read input value
      i++;
   }
   input_str [i] = '\0';//add a null terminator
   strncat (out, input_str, 20);
   puts (out);
   delay_ms (1000);
   out = "TXDT ";
   input_str = "0"; //clear the string
   i = 0; //reset the value for next loop
   disable_interrupts(int_rda);
   disable_interrupts(GLOBAL); //disable the receive buffer
   }
}

Why I said it is weird is that:
1. I surely cannot capture the input I key in (lets say 31, which is the hex value of 1) after the introductory message of "BA" and "B1" and I'll get output of 000000000000000.......
Anyhow I key in again the same thing and here comes the second weird thing.

2. This time I can get something outputted on my smartphone and it reads as: 00 00 00 00 A3 00 00 00
It is getting close as I can get the "3" but the "1" is missing. So this time I tried to key in 31 32 instead, which is the hex value of 1 and 2.
This time I get 00 00 00 00 A3 13 00 00 outputted on my smartphone screen. Again, "2" is missing.
Now I try with 31 32 0a as my input (hex value for 1, 2 and LF) and I get 00 00 00 00 A3 13 20 00
Pretty much close to what I am inputted. However, I am not sure why there are 4 sets of "00" and a "A" in front of my input data. It just mess up with the data echoed back to my smartphone. Further test with random set of values give the similar results, e.g.:
48 96 0a ---> 00 00 00 00 A4 89 60 00
94 53 0a ---> 00 00 00 00 A9 45 30 00
01 23 40 0a ---> 00 00 00 00 A0 12 34 00
etc..

What I would like to do is that when I key in a value the micrcontroller will do something. Let say when I key in "1", it will output "Hi" and "0" it will output "Bye" for example. But with the above result, I cannot "extract" information from what I key in and failed to control the microcontroller using it.

So is there any idea or suggestion? Many thanks for that.
temtronic



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

View user's profile Send private message

PostPosted: Wed Dec 13, 2017 6:13 am     Reply with quote

these...
48 96 0a ---> 00 00 00 00 A4 89 60 00
94 53 0a ---> 00 00 00 00 A9 45 30 00
01 23 40 0a ---> 00 00 00 00 A0 12 34 00

do show a pattern
IE:
0123400a is on the right, if you eliminate the 1st 8 '00' bytes leaving A0123400

This to me suggests the ring buffer pointers are not correct and baudrate isn't the issue. The byte data is correct, but out of order.

also

Your function mtbuf() doesn't really 'clear the buffer'. The data in buffer[] is not erased. I'd like to see a function (maybe called fill_buffer) that fills buffer[0] to buffer[127] with 0xFF. This way the entire buffer is filled with KNOWN data.
You should also have a 'display_buffer' function, where the entire buffer is printed out, at least for test purposes.

There is 'something' going on, but I need to see all the data....
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 2:30 am     Reply with quote

I replace the mtbuf with a fill buffer function and the results are still the same as previous. The code are listed below.
Code:
#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, LOCK)
#fuses NOWDT, NOPROTECT

#pin_select U1TX=PIN_F4
#pin_select U1RX=PIN_F3
#use rs232(baud=19200, UART1, bits=8, parity=N, errors) //enable interrupt receive buffer

#define pixels 5324
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 64
byte buffer[BUFFER_SIZE];
byte next_in = 0;
byte next_out = 0;

int buf = 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);
}

void fill_buffer (void) //fill the buffer with "!" (a known character)
{
   for (buf=0; buf<64; buf++)
   buffer[buf] = 0xFF;
}

void BT_wake (void)
{
   output_low(PIN_F1); //disable sleep on Bluetooth module
   while (input(PIN_G6)==0)
       ; //wait if chip is in a hardware reset
   output_low(PIN_G6); //set low to mode pin on Bluetooth module
   delay_ms(1);
   output_float(PIN_G6); //release line
   while (input(PIN_G6)==0)
       ; //wait for the chip to finish resetting
}

void main(void)
{
   int i = 0;
   char out[100] = "TXDT ";
   char input_str[100] = "0";
   BT_wake(); //wake the chip
   delay_ms (20000); //delay 1/3 minutes to establish connection
   //output some introductory message after startup
   puts("TXDT BA"); //Output BA
   putc('\n');
   putc('\r');
   delay_ms (1000);
   puts("TXDT B1");  //Output B1
   putc('\n');
   putc('\r');
   delay_ms (1000);
   while (true)
   {
   fill_buffer (); //fill the buffer
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL); //start the receive buffer
   delay_ms (10000); //delay 10 sec for user input
   while(bkbhit)
   {
   input_str [i] = bgetc() ; //read input value
      i++;
   }
   input_str [i] = '\0';//add a null terminator
   strncat (out, input_str, 100); //changing the strncat value here
   puts (out);
   putc('\n');
   putc('\r');
   delay_ms (1000);
   out = "TXDT "; //reset the header
   input_str = "0"; //clear the string
   i = 0; //reset the value for next loop
   disable_interrupts(int_rda);
   disable_interrupts(GLOBAL); //disable the receive buffer
   }
}

However, I do find that if I change the value of n in the strncat function, the results are slightly different.
For example, I key in 22314857a and below are the results with different n value.
00 00 00 00 A2 31 48 57 for n = 100,
00 00 00 00 A2 31 48 57 for n = 29,
00 00 00 00 A2 31 48 00 for n = 26-28
00 00 00 00 A2 31 00 00 for n = 23-25
00 00 00 00 A2 00 00 00 for n = 20-22
00 00 00 00 00 00 00 00 for n <= 19
So I was thinking of trying to capture the characters in position 23-25 by using
Code:
 for (i=0; i<3; i++)
   input[i] = input[23+i];
   input[3] = '\0';//add a null terminator
   strncat (outt, input_str, 100); //outt = "TXDT " already declared previously
   puts (outt);
   putc('\n');
   putc('\r');

and put them after puts (out). However, I didn't get anything in return.

I also tried to remove the fill buffer function, then move the enable_interrupts outside of the infinity while loop and remove the disable_interrupts at the end of the while loop. This time, the only output I get is 94 00 00 00..... no matter what I key in.

So I was wondering whats wrong with it. I'm thinking maybe it is with the array that hold the string I input from the smartphone. However, with only the smartphone I cannot do much debugging. While some previous comment suggest me to connect it to PC and try the code, however I don't have the equipment to connect my PCB to the PC. So I was wondering can I test with only my code on serial monitor tools on the compiler or is there is any other way that I can do it. Any comment on what gone wrong with my code is also extremely welcome.

Thank you.
Ttelmah



Joined: 11 Mar 2010
Posts: 12655

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 3:18 am     Reply with quote

Don't disable the INT_RDA.

The whole point of the ring buffer, is that once enabled, you should let it keep receiving. Problem is that characters take time to arrive. bkbhit will therefore go 'false' if you have dealt with a character, and the next hasn't yet arrived. Your receive needs to wait for the line feed, not the lack of a character.

Leave INT_RDA permanently enabled.
Receive characters till you see a line feed.
At this point put the null in the buffer and do your handling.
Then go back to receiving characters.

Meanwhile the buffer will receive anything that arrives.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 5:51 am     Reply with quote

I tried with keeping INT_RDA all the time but the results are like what I describe previously. I can only get 94 00 00 00 00 00 00 00 (in hex) repeatably no matter what I inputted. I'm pretty sure this 94 hex are not from me because I tried to reinitialize the module a few time with different input each time, I get the same thing and what I inputted does not get echoed back. It seems like this 94 hex keep occupying the buffer and hence always get transmitted. I remember reading some similar case in the forum but I cant find it back Sad
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 6:16 am     Reply with quote

OK...some progress, have a few comments.
since the buffer is filled with all 0xFFs, why are there 4 00s in your printed data ?

you send 22314857a
you show 00 00 00 00 A2 31 48 57

two problems with that data
1) 22 is sent, A2 is displayed
2) a is sent, missing( though I suspect it's the A in front)

Have to ask WHY the 00 00 00 00 ? If buffer[] is full of 0xFF,the incoming data will only replace some of the locations. There will be one 0x00 that YOU code in , the /0 or 'end of string'.

The 'pattern' of data is the same as before , 8 bytes ,where #8 is actually in #1 spot assuming you meant 23... and not 223... (typo ?)
This suggests the ringbuffer counters are corrupted somehow.

You should add code to printout the data as it comes in,byte by byte and for debugging purposes use a PC/terminal instead of the BT module so that you have KNOWN data coming into the PIC.


I know the serial ISR is good code so I suspect the BT devices are adding data somehow. Without a monitor I can't 'see' what's going on.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 7:07 am     Reply with quote

First of all, ya its a typo. The one I key in should be 2314857a.
Second, the Bluetooth module only allows to transmit 8 bytes at once. So as the pattern goes, if I key in 2314857a it will output 00 00 00 00 A2 31 48 57 and the "a" is out of the 8 bytes so it will be truncated. I tried to translate the manual of the Bluetooth device (it is in Japanese) and it do mentioned something like 00, 0000, 00 will be added in front of the receiving data, but nothing had been mentioned about the "A" (no matter what i key in or how long (short) the string is, the "A" will still be there).

I do think that I should try debugging on a PC or so but I don't have items to connect my PCB to the PC. Maybe I will discuss with my supervisor and see how it goes. Of course if anyone can give me other suggestion on the coding side it is very much welcome.

Thanks.
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 8:54 am     Reply with quote

To me it still seems as though you have the correct data, just in the wrong order

2314857a
00 00 00 00 A2 31 48 57
if you eliminate the 00 00 00 00 you get
A2 31 48 57
and if you rotate left that
you get
23 14 85 7A

which IS the data you originally send !

Since the BT can only send 8 bytes at once, try transmitting ABCDEFGH and see what comes back.

I'm sorry you don't have proper manuals/datasheet on the BT device. Perhaps post the mke/model info. If I get time, I'll google it.
without a PC/terminal pgm you can't be 100% sure of the data,
Ttelmah



Joined: 11 Mar 2010
Posts: 12655

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 1:35 pm     Reply with quote

Try with something like this:
Code:


#int_rda
void serial_isr()
{
   static int1 have_data=FALSE;
   int t;
   t =getc();
   if (t==0) //we have received a break
   {
      if (have_data)
      {
          buffer[next_in]=0; //terminate buffer
          have_data=FALSE; //stop receiving
      }
      else
          break; //throw if no data
   }
   else
   {
       have_data=TRUE;
       buffer[next_in]=t;
   }
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
     next_in=t;           // Buffer full !!
}


Then leave the interrupt enabled, and wait for the data with:
Code:

   while(TRUE)
   {
      if (bkbhit)
      {
          input_str [i] = bgetc() ; //read input value
          if (input_str[i]==0) //data finished
             break; //exit
          i++;
      }
   }


I suspect the module is sending 'break' characters between the packets.
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 15, 2017 2:15 pm     Reply with quote

OK I downloaded the manual had Google translate, so really the translated manual is online (be nice to figure out how to save it in English...)

Anyway it sends the data as CSV or comma separated variables !
from online manual...

Received data is output from the first byte up to the 16th byte in comma-
separated format.

An example of the data...
00, 0000, 00: 01, 23, 45, 67, 89, AB, CD, EF

I didn't see how or if there's an 'End of File' marker however this really needs to have 'parsing' done after the entire 'stream' of data is acquired.
It appears that 'user data' starts after the colon ':' and consists of 2 bytes a comma ',' repeated 8 times. So 16 bytes of data are sent.

Further into the manual, for transmitting data the command is
TXDA data <CR> <LF> , where data is 16 hex characters (0-F).
If less than 16 char are to be sent...
the command
TXDT data <CR> <LF> is to be used and it inserts a 00 at the end as well as <cr> <lf>.

So it appears that it's NOT as simple as waiting for some data, you'll need to parse it as well. Honestly a PC with a terminal program to look at the data would have picked this up. Even if you just use the PIC and display every character that comes in will work. Just add an LCD module and send the data to it.

They also talk about 2 delays, an 'advertisment delay' as well as a 'connection interval' delay.
Ttelmah



Joined: 11 Mar 2010
Posts: 12655

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 3:07 am     Reply with quote

That makes sense then.
The simplest way would probably be to have the interrupt look for the : character, and start storing data when it sees this. Then stop when it sees either the '00' or a line feed.
temtronic



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

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 5:57 am     Reply with quote

Hmm.. exiting on '00' may not be proper as the sender could have sent them as real data, say as 'switch position #3 and #4 data', representing 'off' condition.
It would be prudent to have a 'timed' response exit though. Similar to the CCS example in the manual FAQ section, it terminates the receive function. The 'exit timer' should be started when the ' : " is seen and last no longer than 2X the time it takes to obtain the data string ( 01,23,45,67,89,ab,cd,ef cr lf).
Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 12655

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 7:11 am     Reply with quote

I'm not actually sure. The translation I found seemed to imply it actually sent 0 (\0) as the terminator, or a line feed, as opposed to ASCII '00'.
It's difficult to know without the simple expedient of actually playing with the module and monitoring what is really received.
temtronic



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

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 8:17 am     Reply with quote

The real 'fun' is that the transmitter can send data in TWO different formats ! That makes the receiving code a bit of a challenge, though I'd opt for a 'sync on colon ':' and then timeout after 30 characters should have arrived. I can't see any other way of getting the data 'packet' properly.
As Mr T says, without real hardware and a good manual it is a 'challenge' !

Jay
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Sat Dec 16, 2017 10:31 pm     Reply with quote

This is certainly many information after one day break. I'll try to digest it and come back if I have other problem.
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 Previous  1, 2, 3, 4  Next
Page 3 of 4

 
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