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
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Tue Dec 05, 2017 3:03 am     Reply with quote

Before doing anything else, step back and verify your chip is running at the clock rate you think.
The most basic 'flash an LED' test.

The symptom you have, is classic for the chip not actually running at the speed you think it is.

Your setup says you have a 8MHz crystal on the primary oscillator, with the PLL set to give a 120MHz master clock to the CPU, but you also have the auxiliary PLL enabled for the USB. Have you done a basic test that the CPU is actually running at the rate you expect?.

Do you have any code for your module from another application?. Are you sure the module is running at 19200bps?. The unit defaults to 19200 from the factory, but can be reprogrammed to a different rate. If it has been used in another project, it is very likely that it has been set to different rate.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 1:58 am     Reply with quote

Dear all, I tested with a flash an LED test and the clock signal should run at the rate which I'm thinking. The code is pretty simple with all the header of my code, which looks like this.
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, RECEIVE_BUFFER=128, stream=BT)
//enable interrupt receive buffer

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

void main()
{
while(TRUE)
  {
    output_high(PIN_F3); //LED ON
    delay_ms(1000);      //1 Second Delay
    output_low(PIN_F3);  //LED OFF
    delay_ms(1000);      //1 Second Delay
  }
}

The LED on for 1 sec and off for another sec as expected so I don't think the problem was coming from the clock.
Anyhow, compared to previous code, I slightly modified the #use delay part.
Previously it was
Code:
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz,LOCK)


Now it become
Code:
#use delay(crystal=8Mhz, clock=120Mhz, LOCK)


The reason is that the previous code are from a senior which worked on a usb module, so he use an aux clock. However, mine are working on bluetooth module, so i guessed the aux clock is not needed. So the issue on the mismatch clock signal should be ok.

As for the baud rate, the default value are 19200 bps and the module is brand new so it shouldn't have any problem with that also. Although it is possible to change the baud rate, I'm not so sure whether I do it correctly or not as the manual are in Japanese and I can only rely on Google translate to translate it and only 2 example I found working on this Bluetooth module on the net >.< Anyway I'll KIV this part.

Lastly, I suspect that maybe I got some data lost somewhere during the transmission using Bluetooth, either during transmission from the smartphone to the pic via Bluetooth or the other way round. The reason is that I get "C0" "FF" and "EE" outputted previously simply because I put them in an infinity do-while loop so I would surely got "C0" "FF" and "EE" outputted somehow. This time, I try to put the output in a while loop instead. As expected, I get absolutely NOTHING outputted, neither the introductory message of "BA" and "B1" when the chip is first turned on nor the "C0" "FF" and "EE" when "0x01" is key in.

I suspect that the data is lost when transmitting from the pic to the smartphone through Bluetooth. This is because unless I broadcast the output in an infinity loop, for example like in the very first code I posted, I will not get the output. (One thing to note is the rate of output is same as what I expected)

Anyhow I'm posting my latest code below. Please comment if u guys found some error in it.
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
#define STRING_SIZE 40
#include <stdlib.h>
#include <stdio.h>
#include <string.h> 

#define BUFFER_SIZE 32
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 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)
{
   BT_wake (); //wake the chip up
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
   char input_str[STRING_SIZE] = "0";
//output some message after startup
puts("TXDT 0xBA '\n' '\r'"); //Output BA
delay_ms (1000);
puts("TXDT 0xB1 '\n' '\r'");  //Output B1
delay_ms (1000);
while (true)
{
delay_ms (5000); //wait 5 seconds for user to key in
gets(input_str);
while (input_str == 0x01)
{
puts("TXDT 0xC0 '\n' '\r'"); //Output C0
delay_ms (1000);
puts("TXDT 0xFF '\n' '\r'");  //Output FF
delay_ms (1000);
puts("TXDT 0xEE '\n' '\r'");  //Output EE
delay_ms (1000);
input_str = "0"; //clear the string so that it will not run when no user input
delay_ms (5000); //wait 5 seconds for user to key in
gets(input_str);
}
}
}


So here is my questions:
1. Does the data lost have something to do with the baud rate? If so I have to try work on changing the baud rate.
2. Do you think I need a transmission buffer as well? I think that some data lost might be caused by the absent of a transmission buffer.
Please advise.
Thank you.

Additional information: The Bluetooth module do have a CTS and RTS pin, which called "Sleep request" and "Busy". They are being connected as followed:
CTS --> PIN_F1
RTS --> PIN_E4
One part of my code involve setting the sleep request pin (CTS) to low in order to send and receive data.
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 3:23 am     Reply with quote

Data is never lost as the result of not having a TX buffer.
All it means is that the PIC code has to stop and wait for the data to transmit.
The point about receive is that data can arrive when the PIC is doing other things, and if more arrives than the hardware can handle, this is lost (with a UART error), unless you have a buffer.

CTS is 'Clear To Send'. It is a signal to a modem to say 'you can send me data'. On 5v logic, it must be held _low_ to allow the modem to work. Setting it high disables the modem from sending. If you are setting it high, then no wonder stuff is being lost.....

You have to remember that on the old RS232 signalling standard, low on the RS232 lines is the 'idle' state. The signals are all inverted when they are at 'logic' levels on a processor. So the RX and TX lines 'idle high', and are low when driven., The same applies to CTS.

The RTS line is an output from the modem. You should not really send data to the modem, if this is high. When it is low it says the modem is 'Ready To Send', and can accept data being sent to it.

As a general comment, you should clear your buffer before you stop and wait for replies. There may well be some garbage in the buffer soon after the start. Things often take a while to wake up, and if the receive line changes during this time, the PIC UART will see this as data.

You are also going to have data you are not expecting/handling.

After the module is physically reset, it is still not available to you as a link. The link only opens when it 'pairs' with the device at the other end. It'll drop RTS when this happens, and should send you a string to say it is connected. According to the translated sheet it should send:

When connected to the central device, the following message is output.
CONECT xx: xx: xx: xx: xx: xx <CR> <LF>
xx represents the Bluetooth address of the connected device with 2 hexadecimal digits.

You code is going to have to accept this, and not get confused by this arriving.

They say the unit will raise RTS, while it is sending you data, or processing commands, and it should be low before you send.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 4:15 am     Reply with quote

In the mean time I think I was doing it right. I output low on the CTS when the chip start up so that it able to accept and receive command and I didn't do anything on the RTS. It should go low by itself when processing command, according to the Bluetooth's manual.

And according to the manual as well, I should get the Bluetooth address once connected to the central device (I presume this is my smartphone in my case), but I didn't get any. Anyhow the microcontroller program should start to run after the Bluetooth address is outputted (whether or not I received it on my smartphone) and the message it suppose to send are not displayed on my smartphone, unless I put them in an infinity loop like the very first code I posted.

Also I tried with read a string I inputted and output it in an infinity loop. This also not working. All I get is 0000000000000000000.....
The code for this part is at 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
#define STRING_SIZE 40
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 32
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 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)
{
   BT_wake (); //wake the chip up
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
   char input_str[STRING_SIZE];
   char out [100] = "TXDT 0x";
   char outt [100] = " '\n' '\r'";
   int i;
//output some message after startup
puts("TXDT 0xBA '\n' '\r'"); //Output BA
delay_ms (1000);
puts("TXDT 0xB1 '\n' '\r'");  //Output B1
delay_ms (1000);
while (true)
{
delay_ms (5000);
while(bkbhit)
{
input_str [i] = bgetc() ; //read input value
if (input_str[i] != '\n')
      input_str[i++] == '\0';
      else i++;
}
strncat (out, input_str, 100);
strncat (out, outt, 100);
while (true)
{
puts(out);
delay_ms (1000);
}
}
}

Any idea what's going wrong?
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 4:54 am     Reply with quote

RTS.

It is an output from the modem.
You should not send data to the modem _unless_ it is low.

Add CTS=PIN_xx to your #use RS232, where this is the pin to which you have the modem RTS pin connected.

(CTS at the PIC is RTS at the modem, and RTS at the PIC is CTS at the modem).

However even with this done, you should check the pin yourself before you transmit anything to the modem. Otherwise if this line is high, your code can hang waiting for it to drop.
temtronic



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

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 6:10 am     Reply with quote

ideas...
1) increase your receive buffer. Currently it's 32 bytes, I'd prefer 64 or 2x the longest msg you can get from the BT device. It's an 'old sckool' rule.

2) I'd connect a spare PC running Realterm or other terminal program and SEE exactly what is being transmitted and sent to the PIC. 2 USB<>TTL modules and 4 wires allows you to SEE the data. While a scope will show you 1s and 0s, being able to read the data( red for rcv, grn for go ) makes like a bit easier.

3) if possible, slow down the baud rate to say 1200 (300 is nicer,110 is best for me...) it's a 'human' thing,slower speed gives US time to think as to what is happening,concentrate on the task.

just some ideas..
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 8:04 am     Reply with quote

Agreed.
However the key thing is a misunderstanding about 'what happens'.
It's not immediate like a wired connection.
When you drop the line to wake the chip, it takes some time to wake, and only then will start to try to negotiate a link. When this succeeds (depending on the speed of the device at the other end), the modem will send the 'CONECT' message (that's how it is spelt in the data sheet...), and drop the RTS line to say it is ready to take data. Only once this happens should data be sent to the modem. This message needs to be read out of the buffer.

The chip wakes at 19200, so he had better stay at this rate.

He needs to be testing that the RTS line has dropped before sending. It can also go high at any time if the link gets lost.

It's not a simple 'turn it on and have a connection'. This is a modem, and needs to be treated as one.....
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Thu Dec 07, 2017 7:39 pm     Reply with quote

Quick question:
after I declare the CTS pin in the header, is that it will automatically check whether it is ok to send data (the output from the pin is low) or do I have to do it in the code, for example:
Code:
while (!input(PIN_E4)) //when output from CTS pin is low
puts ("TXDT 0xC0FFEE); //output something
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Fri Dec 08, 2017 2:42 am     Reply with quote

It'll automatically not send if the pin is high, but this brings the problem that the code will hang waiting for this to happen.
Hence you should test it yourself before the start of a transaction (and possibly call a reset, or display an error if it is high), but can then rely on the internal check during actual transmissions.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 08, 2017 3:05 am     Reply with quote

Yup that's what happened when I tried this morning. It just hang there after first output.
Anyway I tried work on the code again and I found that it actually perform better without the CTS in #use rs232. I also found that the "data lost" I think occurred previously actually happened because the microcontroller start working once power on, but it take sometimes for the Bluetooth module to connect with my smartphone. After the connection is established, those introductory message that should be outputted no longer shown on my smartphone's screen. By add in a delay time in the very first line of the main function solved this problem. Now all output message are performed correctly. However, the CONECT xx: xx: xx: xx: xx: xx <CR> <LF> that should be outputted when connection is established is still missing. But since my smartphone can received the introductory message, it should means the connection is established, right?

Now only problem remained are with the reading string inputted from my smartphone. I tried to verify it by asking the pic to echoed back what I key in. I setup the interrupt with refer to ex.sisr.c but it does not performed as expected. From the reading at various post in the forum, it was confirmed that ex.sisr.c surely works, just that I dunno which part I messed up with. Also, I found that the buffer are full with "garbage". I tried to clear it but it seems like it is not working as well, so my code end up echoed back all those "garbage".
My code are listed below, please comment. Thank you.
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
#define STRING_SIZE 40
#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)
{
   char ch[100];
   char out[100] = "TXDT 0x";
   char out2[100] = "'\n' '\r'";
   char input_str[100];
   int i;
   mtbuf();
   delay_ms (20000); //delay 1/3 minutes to wait for connection to established
   BT_wake(); //wake the chip
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL); //start the receive buffer
   delay_ms (1000);
   //Output some introductory message when startup
   puts("TXDT 0xBA '\n' '\r'"); //Output BA
   delay_ms (1000);
   puts("TXDT 0xB1 '\n' '\r'");  //Output B1
   delay_ms (1000);
   while (true)
   {
   mtbuf();
   delay_ms (10000); //delay 10 sec for user input
   while(bkbhit)
   {
   input_str [i] = bgetc() ; //read input value
     if (input_str[i] != '\n')
      input_str[i++] == '\0';
      else i++;
   } 
   strncat (out, ch, 100);
   strncat (out, out2, 100);
   puts (out);
   delay_ms (1000);
   input_str = "0"; //clear the string
  }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Fri Dec 08, 2017 4:51 am     Reply with quote

Is the buffer full of garbage, or just the memory?.

The memory in the chip will contain 'garbage' on boot, but this doesn't matter at all. If next_in==next_out, the buffer is empty.
You can clear the buffer 'instantly', by just setting next_out=next_in;

If next_out is not equal to next_in, then something genuinely has been received. If something invalid is received, you have to work out 'what', and 'why'.

Being 'garbage', is what makes be suspect a baud problem...

Do you have a USB to logic serial adapter unit?. If so, can you do some basic tests with this?. Start by having the PIC just send a sequence of characters, and verify that a PC set to the same baud rate connected to the adapter, does see the data correctly. If it doesn't, then what is sees, relative to what is being sent (and particularly 'how many characters'), gives a clue as to what is wrong.

It's the 'one step at a time' necessity in debugging. You need to actually prove that you have got serial I/O working correctly, before trying to talk to another device.

The suspicion is that the 'garbage' is actually the CONECT string, but because of a baud rate problem you are seeing this incorrectly. Also if this is being received, you need to not be sending if the modem is saying "I can't take this". Otherwise this will be be sent back as garbage. It _will_ say this until the transmission has completed.
temtronic



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

View user's profile Send private message

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

The 'buffer' is a section of RAM and will be filled with 'garbage' when the PIC powers up. Normally to 'clear' the buffer, you'd write zeros , into every location of the buffer.CCS has the ZERO_RAM directive that does this for ALL of the RAM,though it's seldom used.This puts RAM into a KNOWN state( all zeros.
When you make the BUFFER 'pointers' next_in and next_out the same value you aren't really clearing or erasing the actual data in RAM.Whatever was in those memory locations is still there. Buffer data only changes when new data is received by the ISR. If the pointers are wrong,you will get 'garbage'.

The ex_sisr.c code is good so I suspect that the 'garbage' you see is the result of delays in the BT communications portion of your program. If you have a 2nd PC, use it for testing to 'simulate' the cellphone<>BT interface.
Wireless communications is very tricky compared to solid wires that's why it is critical to have some kind of 'monitoring' of the data streams and a 'Bt for dummies' book available !
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 08, 2017 6:49 am     Reply with quote

OK I'll try to explore the ZERO_RAM. next_in = next_out doesn't seems t work for me. On the other hand, I'll also try to play with the baud rate. Maybe that's a reason for me to receive some "garbage".
So a quick question here. The default baud rate for the Bluetooth module is 19200 bps and I'm going to change it to 9600 bps using some command. So in the #use RS232 header I should define the baud rate as 9600 right?
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 08, 2017 7:12 am     Reply with quote

yes, but changing to 9600 won't be better if some of the data is correct now. mismatched speeds usually give 'garbage' all the time.

I would confirm the BT is in the factory defaults and configure the PIC to be identical. ALL the options must be the same. # of bits, parity, etc.
Ttelmah



Joined: 11 Mar 2010
Posts: 13389

View user's profile Send private message

PostPosted: Fri Dec 08, 2017 7:42 am     Reply with quote

If you are changing baud rate, you would setup the #USE to the baud rate you want to use at the start to send the command.
Then send the command to change the rate.
Then use 'set_uart_speed' to select the new rate.
Now talk to the UART.

I agree with Jay. I had this suspicion early on, that possibly the unit you have is not set to the speed that the data sheet says is the default.
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 2 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