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

Bluetooth not receiving data on UART
Goto page 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

Bluetooth not receiving data on UART
PostPosted: Fri Dec 01, 2017 12:57 am     Reply with quote

Guys I'm seriously need some help with my project. I'm a beginner in programming.
I'm currently trying to build a wireless device using a Bluetooth module and a microcontroller.
The microcontroller I used is DSPIC33EP256MU806 and my Bluetooth module is called IMBLE (a local Japanese product which my supervisor insist for me to use it). In the meantime I'm connecting it to the smartphone apps developed by the Bluetooth company.

Well let's get on the the coding part.
Firstly, I tried to asked the microcontroller to send some data to the smartphone and it works fine.
Below are the source code that is working.
Code:

#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz,LOCK)
#fuses NOWDT
#define pixels 5324
#include <stdlib.h>
#include <stdio.h>
#use rs232(baud=19200, xmit=PIN_F4, rcv=PIN_F3, bits=8, parity=N, errors)

void BT_wake ()
{
   output_low(PIN_F1); //set low to sleep pin on bluetooth module
   output_low(PIN_G6); //set low to mode pin on bluetooth module
   delay_ms (100);
}

void main()
{
char out1[100] = "TXDT 0xC0";
char out2[100] = "TXDT 0xFF";
char out3[100] = "TXDT 0xEE";
while (1)
{
BT_wake ();
puts(out1);
delay_ms (1000);
puts(out2);
delay_ms (1000);
puts(out3);
delay_ms (1000);
/* start a new line (CR + LF) */
putc('\n');
putc('\r');
}
}

However, when I tried to send some data from the smartphone to the microcontroller and then asked the microcontroller to echo it back, it failed. I suspect the microcntroller failed to receive the data I send.
Below are my source code.
Code:
#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz,LOCK)
#fuses NOWDT
#define pixels 5324
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#pin_select U1TX=PIN_F4
#pin_select U1RX=PIN_F3
#use rs232(baud=19200, UART1, bits=8, parity=N, errors)


void BT_wake ()
{
   output_low(PIN_F1); //set low to sleep pin on bluetooth module
   output_low(PIN_G6); //set low to mode pin on bluetooth module
   delay_ms (1000);
}

void main()
{
   char* ch[100];
   char out[100] = "TXDT 0x";
   while (1)
{
BT_wake ();
if (kbhit())
{
gets(ch);
strncat (out, ch, 100);
BT_wake ();
puts (out);
}
}
}


Some additional information: to send data from the Bluetooth module, I must include a header of "TXDT".
Please help me.
Thank you!
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 2:23 am     Reply with quote

First thing. The good news is 3.3v module 3.3v PIC. Hurrah!... Smile

Second, the fact you are getting transmission to work, suggests you have got the required capacitor on it's supply. Hurrah2....

Now I'd suspect the problem in the echo back is the way you are working. You are resetting the chip every loop. During reset, it won't receive, and data will be lost. This is OK for a transmission, but not is the second device is sending you data. Once the connection is established, you need to be looping leaving the chip awake.

At the start, wait for the reset line to go high. This is an 'open collector' type line, and the internal hardware will hold it low when the chip is resetting on power on. So read the line, wait for it to go high, then pulse it low to ensure a clean reset, then release it (output_float). Wait till the line goes high, and the chip is ready to use. Don't reset it again, unless something goes wrong, or you do an operation that requires this (like changing the baud rate).
If you are holding the sleep request line low, the chip will then be ready to receive.
I'd use an interrupt driven receive buffer at this point. Otherwise if you receive data while transmitting stuff will be lost.

So something like:
Code:

#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz,LOCK)
#fuses NOWDT

#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>

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";
   BT_wake(); //wake the chip
   enable_interrupts(GLOBAL); //start the receive buffer

   while (TRUE)
   {

       if (kbhit(BT))
       {
           fgets(ch, BT);
           strncat (out, ch, 100);
           fputs (out, BT);
       }
   }
}

It's rather crude, personally I'd re-write gets, using the buffered data so it can be called and will append data and return immediately if the string is not complete (hasn't seen an end of line), allowing your chip to be doing other things while waiting. However within that limitation this should be 'close'.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

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

Thanks Ttelmah for your reply.
I tried to compile the code you modified but I encounter an error.
It said "*** Error 51 "BT_preliminary.c" Line 33(22,29): A numeric expression must appear here :: Not a valid interrupt".
Basically the problem is with the enable_interrupts(global).
I tried to search this issue on the net but didn't came across any solution.
While I search for details in the ccs c compiler manual, it said that "global" should be defined in the device's .h files.
I checked with the files and yes it is defined as followed.

Code:
#define GLOBAL   0x400  // For compatibility with PIC16/18


So now I don't understand why it don't work.

Anyway, what I'm thinking is changing the code from
Code:
 enable_interrupts(global);

to
Code:
enable_interrupts(1024);

since 0x400 is the hexadecimal value of 1024.
Or do you have any other suggestion?
Please advise.
Thank you.

Edit:
Just tried with replace global with 1024 and it is not working =p
alan



Joined: 12 Nov 2012
Posts: 357
Location: South Africa

View user's profile Send private message

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

Compiles fine under 5.075
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 3:23 am     Reply with quote

Hmm... That's strange. I'm compiling using PCD 24 bit and its version is 5.064...
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 5:45 am     Reply with quote

Ok, I've only had 1/2 cup of java but WHERE's the RCV or any ISR ? I see the global enable but no ISR...While I'd 'like' to assume the code won't crash, enabling_global 'might' be a problem if any device interrupt bit is set,say due to a complier bug.

Also I'd like to see a simple BT module test program. Something that reads a BT register and displays the result. While I've never used them, I suspect they have a lot of registers to setup the device, like speed, ID, buffers, etc. This 'low level' test should confirm hardware and basic firmware is OK.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 5:52 am     Reply with quote

For the PCD compiler with your PIC, you should use this:
Code:
enable_interrupts(INTR_GLOBAL);
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 6:46 am     Reply with quote

temtronic wrote:
Ok, I've only had 1/2 cup of java but WHERE's the RCV or any ISR ? I see the global enable but no ISR...While I'd 'like' to assume the code won't crash, enabling_global 'might' be a problem if any device interrupt bit is set,say due to a complier bug.

Also I'd like to see a simple BT module test program. Something that reads a BT register and displays the result. While I've never used them, I suspect they have a lot of registers to setup the device, like speed, ID, buffers, etc. This 'low level' test should confirm hardware and basic firmware is OK.



The receive ISR is generated automatically by the compiler.
Using 'RECEIVE_BUFFER=xx' enables this.

It does work. However if (for instance) another interrupt is getting enabled, then there would be a problem if there is no handler for it.

On 'GLOBAL', the headers normally have GLOBAL defines as an alternative to INTR_GLOBAL for 'reverse compatibility'. It's not complaining about that.

BT should be being defined by the #USE. Only thing that would cause a problem.

I've just taken the code as I posted it, and it compiles fine on 5.061, and 5.058, the two nearest versions I have to 5.060.
temtronic



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

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 7:49 am     Reply with quote

Thanks Mr. T for the ISR info ! I'm always leary about 'stuff done behind the scenes', I prefer the 'in my face' approach. Got bit( no pun intended ) on a PDP-8 assembler 'quirk' where the exact OPPOSITE of a couple register bits was done 'behind the scenes', that was during the good ol' paper tape dayze....
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 7:57 am     Reply with quote

As an update, I went and found 5.064 on an archive, and compiled the code. It compiles as posted with no errors.

I'd suspect there might be a fault with the compiler installation. Try re-installing. Sometimes oddities like this are the result of something not setup right in this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Fri Dec 01, 2017 8:07 am     Reply with quote

Agreed Jay, it is much nicer to see what happens. However the built in ISR handler is pretty basic, and works well. Makes it really easy to have a receive interrupt (or a transmit one), without the complexity of loading the handler code from ex_sisr.c (or stisr).
He needs an ISR, since otherwise as soon as he starts sending stuff, if the link is full duplex, then he risks missing things.
I'm a great believer in removing the #nolist default at the start of all the processor header files, so you can see the code that is generated by these routines. Smile
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Mon Dec 04, 2017 1:45 am     Reply with quote

Thanks all for the reply.
The problem with
Code:
enable_interrupts(GLOBAL)
had been solving by reverting the compiler to older version.

However the code Ttelmah suggested previously does not work.
Nothing had been echoed back and I don't know why.
So I go to search for more examples on the forum and I came out with the code below
Code:

#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz,LOCK)
#fuses NOWDT

#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>

#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);
}
#define STRING_SIZE 40

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";
while (1)
{
do
{
puts("TXDT 0xC0"); //Output C0
delay_ms (1000);
puts("TXDT 0xFF");  //Output FF
delay_ms (1000);
puts("TXDT 0xEE");  //Output EE
delay_ms (1000);
/* start a new line (CR + LF) */
putc('\n');
putc('\r');
get_string(input_str, STRING_SIZE-1);
delay_ms (5000); //wait 5 seconds for user to key in
} while (input_str == 0x01);
}
}


What I expect is that I'll first get "C0" "FF" and "EE" at the first time and then the same thing everytime I key in 0x01 (hex value of 1).
However, what I got is "FF" and "EE" repeatably for quite a few times and then followed by "C0" "FF" and "EE" and again "FF" and "EE" repeatably again. After some time nothing else being outputted.

Can you guys advise me on what is going wrong with this version of the code?

Many thanks.
temtronic



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

View user's profile Send private message

PostPosted: Mon Dec 04, 2017 6:15 am     Reply with quote

quick comment

One possible problem I see is that you're using BOTH the CCS UART RCV buffer AND your own.
Others will know for sure but I'd get rid of the RECEIVE_BUFFER=128.
Do that, recompile, and test.
I know the ex_sisr.c code works and there is a tweak for it to be better.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Mon Dec 04, 2017 7:22 am     Reply with quote

Yes. That will not work. The second buffer is wasted. One or the other, not both.
Billy9689



Joined: 01 Dec 2017
Posts: 24

View user's profile Send private message

PostPosted: Tue Dec 05, 2017 2:59 am     Reply with quote

OK. By removing the RECEIVE_BUFFER = 128 and edit the code a bit I can somehow made it works better, but still something not right about it.
Below are my new code.
Code:
#include <33EP256MU806.h>
#device ADC=12
#use delay(crystal=8Mhz, clock=120Mhz, AUX:clock=48Mhz,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>
#include <input.c>

#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);
}
#define STRING_SIZE 40

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"); //Output BA
delay_ms (1000);
puts("TXDT 0xB1");  //Output B1
delay_ms (1000);
while (1)
{
do
{
puts("TXDT 0xC0"); //Output C0
delay_ms (1000);
puts("TXDT 0xFF");  //Output FF
delay_ms (1000);
puts("TXDT 0xEE");  //Output EE
delay_ms (1000);
/* start a new line (CR + LF) */
putc('\n');
putc('\r');
gets(input_str);
delay_ms (5000); //wait 5 seconds for user to key in
} while (input_str == 0x01);
}
}


I add in the output of "BA" and "B1" to distinguish the output after starting the chip to that outputted from the loop.

However, when I test it, the output "BA" and "B1" were not there and "C0" "FF" and "EE" were not outputted.
Anyhow I try to key in 0x01.
After a few input (varies. Sometimes twice, sometimes 5 times), i get the output of "C0" "FF" and "EE" (again varies. Sometimes once, sometimes 3/4 times).

Any idea whats gone wrong here?
Please advise.

Thank you.
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, 3, 4  Next
Page 1 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