Go Down

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

elan_arr

My current code
Code: [Select]
void readatinq()
{
  while(mySerial.available() > 0)
  {
   char inChar = mySerial.read();
    if(inChar == SOP)
    {
       Serial.println("SOP MARKER READ");
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP && started)
    {  Serial.println("EOP MARKER READ");
       count=count+1;
       Serial.print("count: ");
       Serial.println(count);
       if (count>=3)
       {
       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
Serial.println(inData);
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    count=0;
    inData[index] = '\0';
   }


and its output
Quote
Initializing
===
OK


LLL
OK



AT+INQ

OK


SOP MARKER READ
EOP MARKER READ
count: 1


Initializing
===
OK


LLL
OK



AT+INQ

OK


EOP MARKER READ
count: 2
SOP MARKER READ
EOP MARKER READ
count: 3


INQ:00:1C:A4:14:7D:AA,"Sony Ericsson"
Initializing
===
D4:C1:FC:3A:56:7C,"C1
OK


LLL
OK



AT+INQ

OK

and so on...


Multiple id's are separated by a \r\n .
I need to print the MAC ID once the EOP is detected and again check the receive buffer and print the next ID..that logic is missing in my code!

PaulS

Quote
My current code

Is missing a whole lot of stuff, like setup() and loop().

elan_arr

Quote
Is missing a whole lot of stuff, like setup() and loop().

I just posted the part of my code that had changes.

Anyways, I removed the "count" part from the program and my current code is this one
Code: [Select]
#define rxPin 2
#define txPin 3
#define SOP '+'
#define EOP '\r'
#include <SoftwareSerial.h>
#include <avr/wdt.h>
#include <SD.h>
int CS_pin=10;
int pow_pin=8;
int count=0;
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

int i;

bool started = false;
bool ended = false;

char inData[200];
char inData1[200];
byte index;

void setup()
{  // define pin modes for tx, rx, led pins:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  pinMode(CS_pin, OUTPUT);
  pinMode(pow_pin, OUTPUT);
  mySerial.begin(9600);
  Serial.begin(9600);
 
   if (!SD.begin(CS_pin))
   {
     Serial.println("Card Failure");
     return;
   }
Serial.println("Card Ready"); 

   // Other stuff...
}
void readprocess()
{
  while(mySerial.available() > 0)
  {
    char inChar = mySerial.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(mySerial.available() > 0)
  {
   char inChar = mySerial.read();
    if(inChar == SOP)
    {
       Serial.println("SOP MARKER READ");
       index = 0;
       inData1[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP && started)
    {  Serial.println("EOP MARKER READ");
       ended = true;
       break;
    }
    else
    {
     if(index < 199)
      {
        inData1[index] = inChar;
        index++;
        inData1[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

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

void store()
{
  File dataFile = SD.open("log.txt", FILE_WRITE);
  if (dataFile)
  {
    dataFile.println(inData1);
    dataFile.close();
    Serial.println(inData1);
  }
  else
  {
    Serial.println("Couldn't open log file");
  }
}
void loop()
{
  Serial.println("Initializing");
  Serial.print("===");
  mySerial.print("===");
  delay(100);
  readprocess();
  delay(2000); 
  Serial.print("LLL");
  mySerial.print("LLL");
  delay(100);
  readprocess();
  delay(2000);
  Serial.print("\r\nAT+INQ\r\n");
  mySerial.print("\r\nAT+INQ\r\n");
  delay(100);
  readprocess();
  delay(25000);
  readatinq();
  delay(2000);

}


And my output is
Quote
Card Ready
Initializing
===
OK


LLL
OK



AT+INQ

OK


SOP MARKER READ
EOP MARKER READ


INQ:D4:C1:FC:3A:56:7C,"C1-01"
Initializing
===
00:1C:A4:14:7D:AA,"Sony Ericsson"

OK


LLL00:25:48:7B:55:2F,"Nokia 5130c-2"
DONE

OK


All the devices are getting detected and being printed. But they should be printed in one go. Further, only   

Quote
INQ:D4:C1:FC:3A:56:7C,"C1-01"
gets stored on the SD card. The remaining two ID's aren't stored.

PaulS

Code: [Select]
   Serial.println('\n'); 
Useful. Not!

Quote
All the devices are getting detected and being printed. But they should be printed in one go. Further, only   

The problem is that the data is not all arriving at once. So, on one pass through loop, you get some data in response to the INQ command, and on the next pass through loop, you get some more data, and on the next pass, you get some more.

There is clearly a start of packet marker (+INQ:), and field delimiters (\r\n), but I don't see any kind of end of packet marker, unless that DONE part is the end of the data.

What I would try is putting the code to send data to the device in setup, along with the calls to readprocess(). Leave just the call to readatinq() in loop.

In readatinq(), PRINT EVERY CHARACTER READ!!!

Remove the useless Serial.println('\n') calls.

Load the sketch to the Arduino, and show the output.

If it turns out that +INQ: and DONE bound the data stream, then you can modify readatinq() to store data until the array ends with DONE.

elan_arr

Quote
Load the sketch to the Arduino, and show the output.

If it turns out that +INQ: and DONE bound the data stream, then you can modify readatinq() to store data until the array ends with DONE.


Yes the ID's that are detected begin with +INQ and once all devices are detected and displayed, a DONE followed by an OK are displayed.




PaulS

So, you need to set started to true when the + arrives. After each character is added (including the \r and \n) to the array, test if the last 4 characters are 'D', 'O', 'N', and 'E'. If so, set ended to true.

Then, in the started and ended section, use strtok() with \n as the delimiter, to extract each token and print/store the token, after making sure that the \n and \r are stripped from the token.

You can then move all the code back to loop, but sending the INQ command should not happen unless there is a trigger event - a switch press or something.

elan_arr

Quote
So, you need to set started to true when the + arrives. After each character is added (including the \r and \n) to the array, test if the last 4 characters are 'D', 'O', 'N', and 'E'. If so, set ended to true.


Before implementing this concept, I have a query. I just set the EOP marker as 'D' so so that the stuff that is read from the module can be displayed once the 'D' from the 'DONE' is detected. So logically the output should be similar to
INQ: MAC ID 1,"name 1", \r\n MAC ID 2,"name 2" D

I just included a statement to visualize every character that is stored in the array. So the readatinq function and the loop function of my program are,
Code: [Select]
void readatinq()
{
  while(mySerial.available() >0)
  {
   char inChar = mySerial.read();
    if(inChar == SOP)
    {
       Serial.println("SOP MARKER READ");
       index = 0;
       inData1[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP && started)
    {  Serial.println("EOP MARKER READ");
       ended = true;
       break;
    }
    else
    {
     if(index < 199)
      {
        inData1[index] = inChar;
        Serial.print("index[");
        Serial.print(index);
        Serial.print("]: ");
        Serial.println(inData1[index]);
        index++;
        inData1[index] = '\0';
      }
    }
  }
   

  // 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)

  { i++;
    Serial.print("Loop executed : ");
    Serial.println(i);
    // The end of packet marker arrived. Process the packet
Serial.println(inData1);
   
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    count=0;
    inData[index] = '\0';
   }
}

void loop()
{
  Serial.println("Initializing");
  Serial.println("===");
  mySerial.print("===");
  delay(100);
  readprocess();
  delay(500); 
  Serial.println("LLL");
  mySerial.print("LLL");
  delay(100);
  readprocess();
  delay(500);
  Serial.print("\r\nAT+INQ\r\n");
  mySerial.print("\r\nAT+INQ\r\n");
  delay(100);
  readprocess();
  delay(25000);
  readatinq();
  delay(1000);

}


The output that I get is

Quote
Initializing
===

OK
LLL

OK

AT+INQ

OK
index[85]:

index[86]:

SOP MARKER READ
index[0]: I
index[1]: N
index[2]: Q
index[3]: :
index[4]: 0
index[5]: 0
index[6]: :
index[7]: 1
index[8]: C
index[9]: :
index[10]: A
index[11]: 4
index[12]: :
index[13]: 1
index[14]: 4
index[15]: :
index[16]: 7
index[17]: D
index[18]: :
index[19]: A
index[20]: A
index[21]: ,
index[22]: "
index[23]: S
index[24]: o
index[25]: n
index[26]: y
index[27]: 
index[28]: E
index[29]: r
index[30]: i
index[31]: c
index[32]: s
index[33]: s
index[34]: o
index[35]: n
index[36]: "
index[37]:

index[38]:

index[39]: D
index[40]: 4
index[41]: :
index[42]: C
index[43]: 1
index[44]: :
index[45]: F
index[46]: C
index[47]: :
index[48]: 3
index[49]: A
index[50]: :
index[51]: 5
index[52]: 6
index[53]: :
index[54]: 7
index[55]: C
index[56]: ,
index[57]: "
index[58]: C
index[59]: 1


The loop has been terminated even without the EOP marker being detected and as the EOP wasn't detected, the elements of the array weren't printed. and there are still a few characters left. the loop has stopped at index[59] abruptly.
I guess that for a split second there is no element available at the receive buffer and as the code contains
Quote
while(mySerial.available() >0)

the loop has been terminated. could that be the reason? If yes, how to resolve it?

PaulS

Quote
index[17]: D
index[39]: D

Clearly, you did NOT set EOP to 'D' correctly.

elan_arr

Quote
Clearly, you did NOT set EOP to 'D' correctly.

Sorry, made a mistake while posting. The EOP was Capital letter 'O' .

elan_arr

Quote
Sorry, made a mistake while posting. The EOP was Capital letter 'O' .


Quote
===

OK
LLL

OK

AT+INQ

OK


These 'OK' s are a result of a separate read function(readprocess) for which the SOP and EOP are different. I do not have any problem until this. The problem starts only in the "readatinq" function.

PaulS

Quote
I guess that for a split second there is no element available at the receive buffer and as the code contains
Code: [Select]
while(mySerial.available() >0)
the loop has been terminated.

Yes, this happens sooner or later (later, in your case because of all the serial output you are sending).

Quote
could that be the reason?

Yes. Normally, the read function would be called over and over again, on each pass through loop, so eventually all the data gets read. Then, it can be processed.

elan_arr

Quote
Normally, the read function would be called over and over again, on each pass through loop, so eventually all the data gets read. Then, it can be processed.


So what alterations should I do to the program to make it process only after ensuring that all the data from the receive buffer has been read? Anything like making the function to wait for a moment when the receive buffer is empty so as to read the data that might arrive a bit late?

PaulS

Quote
So what alterations should I do to the program to make it process only after ensuring that all the data from the receive buffer has been read?

Code: [Select]
while(strcmp(lastFourCharacters, "DONE") != 0)
{
  // Keep reading...
}

elan_arr

Quote
test if the last 4 characters are 'D', 'O', 'N', and 'E'. If so, set ended to true.


After the "DONE" there is still a \r\n and an OK followed by another \r\n is present.

So should I still look out for "DONE" ?

If yes, I'm using
Code: [Select]
f(index < 199)
      {
        inData1[index] = inChar;
        for(int i=index ;i>=(index-3);i--)
        {
          if(inData1[i]=='E')
          {
            if(inData1[i-1]=='N')
            {
              if(inData1[i-2]=='O')
              {
                   if(inData1[i-3]=='D')
                     {
                        Serial.println("DETECTED");
                        break;
                      }
               }
            }
          }

to detect DONE. Is this feasible?

PaulS

Quote
Is this feasible?

Why are the if tests in a for loop? The if tests are right, but for only one value of i.

Go Up