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

Why working serial data not working on bluetooth module?

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



Joined: 03 Dec 2008
Posts: 12

View user's profile Send private message

Why working serial data not working on bluetooth module?
PostPosted: Tue May 12, 2009 6:32 am     Reply with quote

Hi,

I have done serial sending and receiving using usb-serial port cable and it's working. Here is the code

Code:

#include <16F877A.h>
#include <string.h>
#use delay(clock=20000000)
#fuses hs, noprotect, nowdt,nolvp
#byte PORTB=6
#byte PORTC=7
#define door PIN_B2
#define window PIN_B1
#define bumper PIN_B3
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define ChannelA PIN_A0
#define ChannelB PIN_A1
#define REDLED PIN_B4
#define GREENLED PIN_B6
#define YELLOWLED PIN_B3
#define DIRECTION PIN_D7
#include <input.c>
#include <stdlib.h>
#define STRING_SIZE 40

#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

#define bkbhit (next_in!=next_out)
char cmd_str[20];
long t0 = 0;
long t1 = 1;

byte bgetc()
{
   byte c;

   while(!bkbhit) ;
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

void get_cmd_str(char * s, int max) {
   int len;
   char c;

   max--;
   len = 0;

   do {
      c = bgetc();
      if(c > 0x00) {
         if(len < max) {
            s[len++] = c;
         }
      }
   }
   while(bkbhit);
   s[len]= 0x00;
}

#int_rda
void serial_received()
{
   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 !!
}

#int_ext
void interrupt()
{
BYTE  time3;

set_tris_b(0b00000001);
output_high(bumper);
time3 = get_timer0();
time3 += -1;
set_timer0(time3);
}

#int_rtcc
void timer0_isr()
{
t0 += 1;
}

#int_timer1
void timer1_isr()
{
t1 += 1;
set_timer1(0xFF00);
}

void main()
{
int PwM;

set_tris_b(0b00110001);
portb=0;
set_tris_d(0b00000001);
portb=0;

output_low(GREENLED);
output_low(REDLED);
output_low(YELLOWLED);

setup_timer_2(T2_DIV_BY_16, 127, 1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(0);

setup_counters( RTCC_EXT_H_TO_L, RTCC_DIV_1 );
set_rtcc(0);

setup_timer_1 ( T1_EXTERNAL | T1_DIV_BY_1 );
set_timer1(0xFFF4);

enable_interrupts(INT_RTCC);
enable_interrupts(INT_TIMER1);
EXT_INT_EDGE(L_TO_H);
ENABLE_INTERRUPTS(INT_EXT);
ENABLE_INTERRUPTS(INT_RDA);
enable_interrupts(GLOBAL);

main_program:
do
{
printf("%2x",t0);
printf("%2x",get_rtcc());
printf("%2x",t1);
printf("%2x\n\r",get_timer1());

output_high(GREENLED);
output_low(REDLED);
output_low(YELLOWLED);

if(bkbhit)
{
      delay_ms(15);              //Delay allows full string to arrive
      get_cmd_str(cmd_str, 10);
}

PwM=atoi(cmd_str);

if(PwM >= 129)
{
PwM -= 129;
set_pwm1_duty(PwM);
output_high(DIRECTION);
}
else if(PwM <= 128)
{
set_pwm1_duty(PwM);
output_low(DIRECTION);
}
}while(TRUE);

goto main_program;

again:

output_low(GREENLED);
output_high(REDLED);
output_low(YELLOWLED);

goto  again;
}


Then I implement this code to bluetooth but it is not working so i took reference from a sample from mplab picc.

Code:

#include <16f877a.h>

__CONFIG(0x3F32);

#define seg PORTD                     // define 7 segment as PORTD

unsigned char a;

void init(void)                        // subroutine to initialize
{
   SPBRG=0x0A;                        // set baud rate as 115200 baud
   BRGH=1;
   TXEN=1;
   CREN=1;
   SPEN=1;
   TRISD = 0b00000000;
   seg   = 0b00000000;
}

void display(unsigned char c)            // subrountine to display the text on the screen
{
   while (TXIF == 0);
   TXREG = c;
}

unsigned char receive(void)               // subrountine to receive text from PC
{
   while (RCIF == 0);
   a = RCREG;
   return a;
}

void main(void)
{
   init();

   while(1)                        // wait for 'ok' to be entered
   {
      a = receive();
      if (a == 'o')
         {
            a = receive();
            if (a == 'k') break;
         }
   }


      display('C');                  // change the text for different display
      display('y');
      display('t');
      display('r');
      display('o');
      display('n');
      display(0x0a);
      display(0x0d);
      display('P');
      display('r');
      display('e');
      display('s');
      display('s');
      display(0x20);
      display('a');
      display('n');
      display('y');
      display(0x20);
      display('n');
      display('u');
      display('m');
      display('b');
      display('e');
      display('r');

      seg = 1;

      while(1)                     // wait for number and display it on 7 segment
      {
         a = receive();
         if (a=='1'||a=='2'||a=='3'||a=='4'||a=='5'||a=='6'||a=='7'||a=='8'||a=='9'||a=='0')
         {
            seg = a-0x30;
         }
      }


}



and i modify my ccs picc to this

Code:

#include <16F877A.h>
#device ADC=8
#use delay(clock=20000000)
#fuses hs, nowdt,nolvp, nowrt, noput
#use rs232(STREAM=serial, baud=115200, xmit=PIN_C6, rcv=PIN_C7,PARITY=N,BITS=8)
#define REDLED PIN_B4
#define GREENLED PIN_B6
#define YELLOWLED PIN_B3

#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;

#define bkbhit (next_in!=next_out)
char cmd_str[20];
long t0 = 0;
long t1 = 1;


byte bgetc()
{
   byte c;

   while(!bkbhit) ;
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

void get_cmd_str(char * s, int max) {
   int len;
   char c;

   max--;
   len = 0;

   do {
      c = bgetc();
      if(c > 0x00) {
         if(len < max) {
            s[len++] = c;
         }
      }
   }
   while(bkbhit);
   s[len]= 0x00;
}

#int_rda
void serial_received()
{
}

void main()
{
float temp;
int temp1,temp2;
char ans;

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
set_tris_a(0b11111111);

output_low(GREENLED);
output_high(REDLED);
output_low(YELLOWLED);

setup_port_a(ANALOG_RA3_RA2_REF);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(120000);

//while(1)                        // wait for 'o' to be entered
   //{
   //if(bkbhit)
   //{
      //delay_ms(15);              //Delay allows full string to arrive
      //get_cmd_str(cmd_str, 10);
   //}
   //if (cmd_str == 'o') break;
   //ans=getc();
   //if (ans == 'o') break;
   //}
//printf("ready\n\r");

main_program:
do
{
output_high(GREENLED);
output_low(REDLED);
output_low(YELLOWLED);

temp = read_adc();
temp1 = temp * 150 / 255;
temp2 = (temp * 1500 / 255) - (temp1 * 10);
printf("Temperature: %d.%d degree\n\r",temp1,temp2);
delay_ms(2000);
}while(TRUE);

goto main_program;

again:

output_low(GREENLED);
output_high(REDLED);
output_low(YELLOWLED);

goto  again;
}



this code works as well because i removed the 'wait for 'o' to be pressed' code. but when i try to use the use the code i turned off in the middle, the process wont starts. When i press 'o' then program starts working. Using sample code, when i press 'ok', the process starts. Any idea how to solve this. Thanks for your attention to such a long post.

Rdgs,
ericchee
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue May 12, 2009 4:12 pm     Reply with quote

If I understand your long question correctly you want know why the code below does not continue when you send "ok". Is this correct?
Code:
while(1)                        // wait for 'o' to be entered
  {
    if(bkbhit)
    {
      delay_ms(15);              //Delay allows full string to arrive
      [code]get_cmd_str(cmd_str, 10);[/code]
    }
      if (cmd_str == 'o') break;
      ans=getc();
      if (ans == 'o') break;
  }
  printf("ready\n\r");


Code:
      delay_ms(15);              //Delay allows full string to arrive
 
This is tricky. You assume that 15ms is long enough to receive the string. At the full 115200 baud this is enough time to receive 11 characters, but sometimes the Windows PC or Bluetooth chipset can add long delays.
It is also a waste of time when the data is received faster than the 15ms.

Code:
get_cmd_str(cmd_str, 10);
This function is difficult to use as it can stop on three conditions:
1) Reading a 0x00 character
2) After 10 characters read
3) When no more data is waiting to be processed.
So, when it returns you never know why. Was data received? How much? Was the string complete?

Why not use the code from the given example and modify it for CCS?
Code:
   // wait for 'ok' to be entered
   while(1)       
   {
      a = bgetc();       // bgetc will wait until a character is received
      if (a == 'o')
         {
            a = bgetc();
            if (a == 'k') break;
         }
   }


A few remarks:
Code:
goto main_program;

again:

output_low(GREENLED);
output_high(REDLED);
output_low(YELLOWLED);

goto  again;
Using goto in a C-program is considered poor programming skills. A do-while or other loop-construct results in easier to read code.
Besides, the above code is never executed as your while(TRUE) loop never exits.
ericchee



Joined: 03 Dec 2008
Posts: 12

View user's profile Send private message

PostPosted: Tue May 12, 2009 7:53 pm     Reply with quote

Yes, you are correct.


Code:

goto main_program;

again:

output_low(GREENLED);
output_high(REDLED);
output_low(YELLOWLED);

goto  again;


I never intend to use it anyway. All color LED is just for indication on which parts of the code is executing. And i know the code wouldn't exit because of the TRUE in while loop. I just prepare this in case any incident happen. Anyway, thanks for your remark. I'll avoid goto in future.

Code:
bgetc()

how exactly does this works? I just take from the sample and use it without really understand how it works. There should be mo termination condition just like

Code:

a = RCREG;


Am I right?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 14, 2009 6:23 am     Reply with quote

Code:
a = RCREG;
This is reading the data from the hardware UART directly. When no new data is available it will return the last received value, that is, this code will always return directly and not stop waiting for a new value.

Code:
a = getc();
This is similar to the above code, but it will wait for new data to arrive. That's why it is called a 'blocking' call.
Additionally, if you have the ERRORS directive in the '#use rs232' line this function will also clear the UART's error flags preventing the UART from stalling on a receive buffer overrun.

The getc function has a limitation:
- The hardware UART can only buffer up to 3 received characters, if you are late reading you will miss data.

Code:
a = bgetc();
bgetc is identical to getc but uses the receive interrupt to create a large receive buffer.

if you combine bgetc with bkbhit, you can create a program that has time to perform other actions while in the background data is received. For example the program below will toggle a led every 500ms while data is received in the background.
Code:
#define LED     PIN_B1

while(TRUE)
  output_toggle(LED);
  delay_ms(500);

  if (bkbhit())   // Is data received?
  {
    a = bgetc();  // read data
    putc(a);      // echo received data to PC
  }
}
ericchee



Joined: 03 Dec 2008
Posts: 12

View user's profile Send private message

PostPosted: Wed May 20, 2009 6:15 am     Reply with quote

Good explanation ckielstra. Laughing

Now i understand the detailed operation of the code. Too bad I can't test the solution you suggested to me. The bluetooth module no longer with me. Anyway, thank you for knowledge sharing.
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