Go Down

Topic: Problem in receiving the data from Bluetooth module (Read 5561 times) previous topic - next topic

PaulS

I see some repeating data in that stream of data:
00:12:39:00:34:35,"RLMobile"
00:13:45:46:99:23,"Jeny"
00:12:39:00:34:35,"RLMobile"
00:13:45:46:99:23,"Jerry"

I see that between each repeating pattern of data that there is a delimiter, the comma. That will make parsing easy.

I see that there is non-repeating data:
\r\n +INQ: (at the start)
\r\n (at the end)

So, what I would see as the start of the packet is the + (SOP), and the \r is the end of the packet (EOP). After the start of the packet, then, there is a token that can be ignored (INQ:) and after the end of the packet, before the start of the next, there is some other stuff that can be ignored (\n, \r, \n) (assuming that the next packet looks just like this one).

elan_arr

Code: [Select]
void readatinq()
{
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP1)
    {  Serial.println("SOP detected");
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP1)
    { Serial.println("EOP1 detected");
      count=count+1;
      if(count>=3)
      {
       Serial.print("EOP2 detected");
       ended = true;
       break;
    }}
    else
    {
      if(index < 199)
      {
        inData[index] = inChar;
        Serial.print(inData[index]);
        index++;
        inData[index] = '\0';
      }
    }
  }

  if(started && ended)
  {
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
   }
}


here SOP is + and the EOP i used is comma ,
I did not use \r because the code begins with a \r the code is not processed at all. Since there are more than one commas I used a variable "count" to and entered a code to exit the loop when "count" value is greater than 3. I've used the "EOP1 detected" and "EOP2 detected" to find out which part of the code is being executed. Even now  my output is

===
OK
LLL
OK
AT+INQ
OK
SOP detected
INQ:00:12:39:00:34:35 EOP1 DETECTED
"RLMobile"
00:13:45:46:99:23 EOP1 DETECTED
"Je


2nd iteration continues

I still don't understand why I am not able to receive the complete output! Please help

PaulS

Quote
I still don't understand why I am not able to receive the complete output

The key is right here:
Quote
here SOP is + and the EOP i used is comma ,

So, the code starts storing the message when the + arrives, which is good, and stops when the comma arrives. Since the comma is NOT the end of packet, storing terminates prematurely.

Quote
I did not use \r because the code begins with a \r the code is not processed at all.

This doesn't make sense. The stream of data may well contain a \r before the +, but that doesn't matter. Nothing happens with the bytes in the stream until the + arrives. 47 \r could arrive before the + does, and they would all be ignored.

Like my advice. You can continue to ignore it, or not. Your choice.

elan_arr

Oh no. I never meant to ignore your inputs sir. I did try out + as the SOP and \r as the EOP. I still did not get an output. I'll post the entire code here, I guess i made a mistake in the read and print process for I did not quite understand your instructions on them, a few posts back. Kindly check the code for me.
Code: [Select]
#define SOP '+'
#define EOP '\r'
#include <avr/wdt.h>
int count=0;
int i;

bool started = false;
bool ended = false;

char inData[200];
byte index;

void setup()
{
   Serial.begin(9600);
   // Other stuff...
}
void readprocess()
{
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 199)
      {
        inData[index] = inChar;
        Serial.print(inData[index]);
        index++;
        inData[index] = '\0';
      }
    }
  }

   Serial.println('\n'); 

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
   }
}
void readatinq()
{
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       Serial.print("SOP detected");
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {  Serial.print("EOP detected");
       ended = true;
       break;
    }
    else
    {
      if(index < 199)
      {
        inData[index] = inChar;
        Serial.print(inData[index]);
        index++;
        inData[index] = '\0';
      }
    }
  }

   Serial.println('\n'); 

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
   }
}

void loop()
{

  Serial.write("===");
  delay(100);
  readprocess();
  delay(2000);
  Serial.write("LLL");
  delay(100);
  readprocess();
   delay(2000);
  Serial.write("\r\nAT+INQ\r\n");
  delay(1000);
  readprocess();
  delay(30000);
  readatinq();
  delay(2000);
  wdt_enable(WDTO_15MS);
  wdt_reset();
}


The output I got is this
===
OK
LLL
OK
AT+INQ
OK
EOP DETECTED

2nd iteration continues

PaulS

Quote
Even now  my output is

===
OK
LLL
OK
AT+INQ
OK
SOP detected
INQ:00:12:39:00:34:35 EOP1 DETECTED
"RLMobile"
00:13:45:46:99:23 EOP1 DETECTED
"Je

was what you were getting, when SOP was + and EOP was ,.

You said that you changed just the EOP value, and now all you get is this:
Quote
The output I got is this
===
OK
LLL
OK
AT+INQ
OK
EOP DETECTED

I find it a little difficult to believe that you changed just one character, unless something happened to your phone.

elan_arr

#20
Mar 03, 2012, 05:57 pm Last Edit: Mar 03, 2012, 08:42 pm by elan_arr Reason: 1
Sorry, I forgot that I removed the "count" stuff that I included when the EOP was a comma..Now again when I introduce that piece of code with the SOP as + and EOP as \r I get pretty much the same output I got when the EOP was , .

===
OK
LLL
OK
AT+INQ
OK
SOP detected
INQ:00:12:39:00:34:35 EOP1 DETECTED
"RLMobile"
00:13:45:46:99:23 EOP1 DETECTED
"Je


The code is (i have posted the correct code that I have used unlike the previous time)
Code: [Select]
#define SOP '+'
#define EOP '\r'
#include <avr/wdt.h>
int count=0;
int i;

bool started = false;
bool ended = false;

char inData[200];
byte index;

void setup()
{
  Serial.begin(9600);
  // Other stuff...
}
void readprocess()
{
 while(Serial.available() > 0)
 {
   char inChar = Serial.read();
   if(inChar == SOP)
   {
      index = 0;
      inData[index] = '\0';
      started = true;
      ended = false;
   }
   else if(inChar == EOP)
   {
      ended = true;
      break;
   }
   else
   {
     if(index < 199)
     {
       inData[index] = inChar;
       Serial.print(inData[index]);
       index++;
       inData[index] = '\0';
     }
   }
 }

  Serial.println('\n');  

 // We are here either because all pending serial
 // data has been read OR because an end of
 // packet marker arrived. Which is it?
 if(started && ended)
 {
   // The end of packet marker arrived. Process the packet

   // Reset for the next packet
   started = false;
   ended = false;
   index = 0;
   inData[index] = '\0';
  }
}
void readatinq()
{
 while(Serial.available() > 0)
 {
   char inChar = Serial.read();
   if(inChar == SOP)
   {
      Serial.print("SOP detected");
      index = 0;
      inData[index] = '\0';
      started = true;
      ended = false;
   }
   else if(inChar == EOP)
   {  Serial.print("EOP detected");
      count=count+1;
      if(count>=4)
      {
      ended = true;
      break;
   }}
   else
   {
     if(index < 199)
     {
       inData[index] = inChar;
       Serial.print(inData[index]);
       index++;
       inData[index] = '\0';
     }
   }
 }

  Serial.println('\n');  

 // We are here either because all pending serial
 // data has been read OR because an end of
 // packet marker arrived. Which is it?
 if(started && ended)
 {
   // The end of packet marker arrived. Process the packet

   // Reset for the next packet
   started = false;
   ended = false;
   index = 0;
   inData[index] = '\0';
  }
}

void loop()
{

 Serial.write("===");
 delay(100);
 readprocess();
 delay(2000);
 Serial.write("LLL");
 delay(100);
 readprocess();
  delay(2000);
 Serial.write("\r\nAT+INQ\r\n");
 delay(1000);
 readprocess();
 delay(30000);
 readatinq();
 delay(2000);
 wdt_enable(WDTO_15MS);
 wdt_reset();
}


PaulS

I'm becoming convinced that you are beyond help. That code does not produce that output!. Nowhere in that code is that anything that write EOP1 to the serial port.

elan_arr

Sir, that is just a print statement I made an error. I could not select all the output from my com port and since the output was same as the previous one, i just copied the output I had posted in the previous post. Just an error of EOP1 and EOP, the code is the same. Please help me.

PaulS

Quote
I could not select all the output from my com port

Why not? That is such a trivial thing to do.

elan_arr

No sir, i don't get any options n the com port window when i right click and even ctrl+C , ctrl+V doesnt work. I have even attached a screen recording of the process. It really isn't working sir.

elan_arr

Quote
It expects that you will not try to print the data in the array until the end of packet marker has arrived. The modifications you've made no longer buffer (and ignore) data until the end of packet marker arrives.

You should revise loop to not call printprocess() unless ended is true. Of course, you will have a problem even then, since readprocess() clears the ended flag when the end of packet marker has been received, because it (still) expects to process the packet and get ready for the next one.

I'm not sure how you want to go about fixing the issues. If it were me, I'd remove the code from readprocess() that clears the started and ended flags and resets the index and array, and revise loop() to only call printprocess() is started and ended are true. In that if() block, I'd put the stuff I removed from readprocess().


I was not clear how to go about regarding the concepts you mentioned in the above quote. Is my code still erroneous on those concepts??

PaulS

Quote
Is my code still erroneous on those concepts??

Yes, it is. Look at the functions called in loop.
Code: [Select]
void loop()
{
  Serial.write("===");
  delay(100);
  readprocess();
  delay(2000);
  Serial.write("LLL");
  delay(100);
  readprocess();
   delay(2000);
  Serial.write("\r\nAT+INQ\r\n");
  delay(1000);
  readprocess();
  delay(30000);
  readatinq();
  delay(2000);
  wdt_enable(WDTO_15MS);
  wdt_reset();
}

You are still using Serial.write() to send ASCII data, even though you've been advised that that is not the correct function to use.

You write "===" to the Serial port, then call readprocess() to get whatever response arrives within the 1/10th second delay.

Code: [Select]
void readprocess()
{
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 199)
      {
        inData[index] = inChar;
        Serial.print(inData[index]);
        index++;
        inData[index] = '\0';
      }
    }
  }

   Serial.println('\n'); 

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
   }
}

Data gets collected in an array. There is an area where processing should occur, but you have elected to do no processing in that area.

After the processing is complete, the data that was processed is discarded, and the code resets for the next time it is called.

Since no processing actually occurred, that data is simply discarded.

Notice, also that this code is reading from, and writing to the same port. Since that appears to be the one connected to the serial monitor, it seems quite unlikely that this code will receive any data from your phone. So, calling it was a waste of time.

So, now you diddle around some more, then write (not print) "LLL" to the serial monitor, diddle around some more, and then try to read whatever was sent from the serial monitor, discarding the data again without doing anything with it.

You diddle around some more, and then write (not print) "\r\nAT+INQ\r\n" to the serial monitor, diddle around some more, and then try to read whatever was sent from the serial monitor, discarding the data again without doing anything with it.

Finally, after a whole bunch of diddling around, you call readatinq().
Code: [Select]
void readatinq()
{
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       Serial.print("SOP detected");
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {  Serial.print("EOP detected");
       count=count+1;
       if(count>=4)
       {
       ended = true;
       break;
    }}
    else
    {
      if(index < 199)
      {
        inData[index] = inChar;
        Serial.print(inData[index]);
        index++;
        inData[index] = '\0';
      }
    }
  }

   Serial.println('\n'); 

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
   }
}

Here again you read incoming data from the serial monitor, discarding the data without processing it. In this case, though, you expect one start of packet marker, and FOUR end of packet markers.

Now, I'm confused about several things. You have two very similar blocks of code - one that reasonably expects a single end of packet marker to match the start of packet marker sent. In this code, you discard with using any data received. Why?

The other block of code expects one start of packet marker and 4 end of packet markers. Since the phone is going to send one start of packet marker and one end of packet marker, why are you expecting 4 end of packet markers? In this code, you discard with using any data received. Why?

Now, the next thing that confuses me is whether the serial monitor or the phone is on the other end of the serial port. You can't have both of them there without confusing the hell out of one or the other. So, what is on the end of the serial port?

Now, for the serial monitor issue. Turn off the auto scrolling. When there is data present in the serial monitor, drag the mouse across an area of the monitor. When the characters highlight, if they do, press ctrl-c. Open notepad, and press ctrl-v. What happens? It certainly appears as though you are running windows, so, you should be able to highlight text in any text-based window and copy that text, and paste it anywhere else.

And, finally, why are you not printing some really simple diagnostic stuff, like:
Code: [Select]
void readatinq()
{
   Serial.println("readatinq ==>");
   // some code here
   Serial.println("readatinq <==");
}

If you were to do so, we'd KNOW what code was being called to read what data, don't you think?

elan_arr

Quote
whether the serial monitor or the phone is on the other end of the serial port.

My bluetooth module (not a phone) has Txd and Rxd pins. I have connected the Txd of the module to the Rxd of the arduino and have connected the Rxd of the Module to the Txd of the arduino.  I open the Com port to view the data that has been sent by the module.

Quote
You are still using Serial.write()

Done, I've changed to Serial.print()

Quote
There is an area where processing should occur, but you have elected to do no processing in that area.

If I am not wrong, processing corresponds to printing the data that was received right? In that case
Code: [Select]
Serial.print(inData[index]); should be placed here??
Code: [Select]
if(started && ended)
  {
    // The end of packet marker arrived. Process the packet
//At this point???
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
   }


If yes then I should include a for loop to print the data from the "inData" array right?

And one more thing that I noticed is that the manual of the Bluetooth module( i have attached) specifies that for the AT+INQ command, the result will be in the form of
Quote
\r\n +INQ:00:12:39:00:34:35,"Device1",00:13:45:46:99:23,"Device 2"\r\n

But when I connect my module directly to the serial port and give the input commands manually in order to check the output, i get a response for the AT+INQ like
Code: [Select]

+INQ:00:12:39:00:34:35,"Device1"
00:13:45:46:99:23,"Device 2"


The comma between Device 1 and device 2 has disappeared and also the two devices appear in two different lines. Does it mean that a \r\n is present between Devices 1 and 2??
Just because I thought it did, I tried to detect 4 EOP's and yeah I have changed that too.

Quote
You have two very similar blocks of code

Because AT+INQ command will initiate a searching process on the device that lasts upto 30 seconds before a device is detected and a response is sent. In order to accommodate that I have used a separate function just for the sake of isolation.






PaulS

Quote
If I am not wrong, processing corresponds to printing the data that was received right?

I don't think so. Presumably, there is some reason that you want to get data from the bluetooth module, and that the reason involves more than just printing it.

Quote
In that case
Code: [Select]
Serial.print(inData[index]);
should be placed here??

At that point, inData[index] is the terminating NULL, so, no.
Code: [Select]
Serial.print(inData);
maybe.

Quote
If yes then I should include a for loop to print the data from the "inData" array right?

No. It is a NULL terminated array of characters. The print() method already knows how to print it. There is no reason for you to print it one character at a time.

Having the bluetooth device connected to the same serial port that you use for debugging is clearly not working for you. I think that you need to address that issue. Either by using SoftwareSerial/NewSoftSerial or by using a board with multiple hardware serial ports.

Quote
But when I connect my module directly to the serial port and give the input commands manually in order to check the output, i get a response for the AT+INQ like

You can't enter commands directly to the serial port. You need to use some application that can talk to the serial port. Generally, those programs have options to define how the incoming data is displayed. Pick ASCII one time and capture a screen shot. Then, pick HEX, and repeat the test, and take another screen shot. Looking at an ASCII table, you should be able to match up at least some of the characters. The ones that don't match up are non-printing characters, and are the one that are of real interest.

Quote
The comma between Device 1 and device 2 has disappeared and also the two devices appear in two different lines. Does it mean that a \r\n is present between Devices 1 and 2??

It looks like that is the case. In which case capturing the incoming data is going to be a little more of a challenge, since the device is not playing by the rules.

Quote
Just because I thought it did, I tried to detect 4 EOP's and yeah I have changed that too.

If there is indeed a \r and \n between records, there are still only 2 \r characters between the SOP (+) and the end of the packet, not 4.

Quote
Because AT+INQ command will initiate a searching process on the device that lasts upto 30 seconds before a device is detected and a response is sent. In order to accommodate that I have used a separate function just for the sake of isolation.

Now, this I disagree with. You might prefer to use two functions, and that is fine with me. But, aside from node query, what else are you going to eventually do? Will you build a separate receive function for each command that you send?

Anyway, I'd be interested in what is actually received from the device in response to the INQ command. if you can convince your application to display HEX output.

elan_arr

#29
Mar 05, 2012, 06:24 pm Last Edit: Mar 05, 2012, 06:26 pm by elan_arr Reason: 1
Quote
there is some reason that you want to get data from the bluetooth module

Yes, I need to store the MAC ID (the INQ stuff..) in an SD card along with the time of detection. I have separately written programs for SD card and the timing part(using RTC chip).

Quote
Having the bluetooth device connected to the same serial port that you use for debugging is clearly not working for you.

So I should use another way of viewing the incoming data other than the Serial monitor on arduino? I'm currently have  software named Flash magic and Realterm that helps in monitoring the serial port. So I should connect the Rxd of my device to the Txd of the arduino and the Txd of the device to the Rxd of the arduino and use another USB to UART converter and connect the txd, rxd pins of the module to it and
view the data separately on the software aforementioned.correct?

Quote
if you can convince your application to display HEX output.


Only the realterm software has the option to view data in HEX but that currently doesn't seems to work. I'm working on it and I'll post as soon as i get the hex values.

Please tell me if I have interpreted the following codes right.

Code: [Select]
void readprocess()
{
 while(Serial.available() > 0)
 {
   char inChar = Serial.read();
   if(inChar == SOP)
   {
      index = 0;
      inData[index] = '\0';
      started = true;
      ended = false;
   }
   else if(inChar == EOP)
   {
      ended = true;
      break;
   }
   else
   {
     if(index < 199)
     {
       inData[index] = inChar;
       index++;
       inData[index] = '\0';
     }
   }
 }

  Serial.println('\n');  

 // We are here either because all pending serial
 // data has been read OR because an end of
 // packet marker arrived. Which is it?
 if(started && ended)
 {
   // The end of packet marker arrived. Process the packet

   // Reset for the next packet
   started = false;
   ended = false;
   index = 0;
   inData[index] = '\0';
  }
}


If some data is available at the receiving terminal, the very first character that is read is stored in "inchar" (this is capable of storing only a single character right?). if the first character is the SOP, it sets index as 0 and clears the first element of array "inData" and sets the started and ended stuffs as true and false.

If it is an EOP, ended is made as true and loop is exited.

After detecting the SOP, and if data is still available, it again stores the value in "inchar" this time it is not an SOP and hence it checks for the "index" value. The index value was initialized wen the SOP was detected and hence now it'll be <199(in my case) and it stores the value in inData[0], then index is incremented and inData[1] is cleared to store the next new character.
Finally if started and ended flags are true, it resets all the values.
Am I right?

And I guess this reading process doesn't change in my case too. So, after detecting the SOP, all data are read and after reading the EOP it comes to the processing stage. So here is where I should include my processing program in this case, storing in an SD card.
Code: [Select]
File dataFile = SD.open("log.txt", FILE_WRITE);
 if (dataFile)
 {
   dataFile.print(inData);
   dataFile.close();
     }
 else
 {
   Serial.println("Couldn't open log file");
 }
}

This is the code for storing in an SD. dtafile.print(inData) will store the data that was read initially right?
Quote

Code: [Select]
Serial.print(inData);
maybe.
or should I make some changes?

Go Up