Forum >[BLUNO] Distance Monitoring Project
General

[BLUNO] Distance Monitoring Project

userHead iShe7ata 2014-11-15 02:07:36 11363 Views18 Replies

Hey there,
First thanks for making the BLUNO chip and making BLE so easily accessible. I'm working on a project with a team now. We are trying to prototype a device that alert the mother once the child is more than 5 meters radius from her. With more than 1 million children getting lost each year, this can be handy. 

To cut to the chase, I'm using BLUNO as the central device and for now using my iPhone as the beacon to be tracked. So far I can get the BLUNO connected to my iPhone and request the RSSI in the serial monitor through AT commands. However, I'm having trouble trying to get BLUNO do this on its own by using code.

I already serached the forum before asking, so this topic is quite relevant http://www.dfrobot.com/forum/index.php?topic=18316.0
But I can't get the code there to work. I keep trying to even change the name of the BLE through the serial command, but it doesn't work. 
So in terms of concrete questions: 

Since I can't really read any data correctly in the serial monitor when Arduino is the one sending commands, Is it because the BLUNO is connected to the USB? Should it help to wire it to up LCD and display data there? Is it a must?

Is this code correct?

Code: Select allchar NAME[] = "AT+NAME=MAHMOUD"; char begin[] = "+++"; float inData= 0; void setup() {   Serial.begin(115200);   Serial.println(begin);   Serial.println(NAME);   } void loop() { while (Serial.available() > 0){   Serial.println("mahmoiud");   float inData = Serial.read();   Serial.println(inData);   delay(500);     } }



Can you share with me an example of code that's actually working to get the RSSI value and store it and use it in an arduino just like any other value?

Thanks. 
I'm waiting for your response Grey! :)

2014-11-19 17:13:51 I am running on version 1.8 by the way, and I do not bother to upgrade since I am no longer working on this anymore. Maybe that's why my version of Serial.print("+++"); works?

Anyway, I managed to bind BLUNO's CENTRAL to another beacon. Nope, negative. It does not connect to it. It can only connect to another BLUNO's PERIPHERAL as far as I know, unless otherwise stated by Grey.
userHeadPic visualxl
2014-11-19 17:13:51 I am running on version 1.8 by the way, and I do not bother to upgrade since I am no longer working on this anymore. Maybe that's why my version of Serial.print("+++"); works?

Anyway, I managed to bind BLUNO's CENTRAL to another beacon. Nope, negative. It does not connect to it. It can only connect to another BLUNO's PERIPHERAL as far as I know, unless otherwise stated by Grey.
userHeadPic visualxl
2014-11-19 17:05:28 Not sure who told you that BLUNO can only work on SLAVE mode. It definitely can work as a MASTER.

I never tried binding the BLUNO to other beacon. Hold on. Lemme try.
userHeadPic visualxl
2014-11-19 17:05:28 Not sure who told you that BLUNO can only work on SLAVE mode. It definitely can work as a MASTER.

I never tried binding the BLUNO to other beacon. Hold on. Lemme try.
userHeadPic visualxl
2014-11-19 03:10:49 Hey Grey,
Thanks for your reply. I got the thing to work completely. The code above is slightly off cuz I think it's sending to the serial port again during running
Code: Select all
Serial.println(D); //testing purpose
so this line should be commented like
Code: Select all
//Serial.println(D); //testing purpose
I've a critical question now. I've been using my iPhone as an iBeacon to test the program.
Now I want to replace the iPhone with a real small iBeacon. This means that the BLUNO will be used as a central device to communicate with the iBeacon itself.
I've been warned by lots of people that the BLUNO can only work in "slave" mode. But I read through the documentation and it clearly states that AT+ROLE can change that to Central Mode.

I'm planning on using
Code: Select all
AT+BIND=0x[MAC address of the iBeacon that I'll buy]
Will that work?
userHeadPic iShe7ata
2014-11-19 03:10:49 Hey Grey,
Thanks for your reply. I got the thing to work completely. The code above is slightly off cuz I think it's sending to the serial port again during running
Code: Select all
Serial.println(D); //testing purpose
so this line should be commented like
Code: Select all
//Serial.println(D); //testing purpose
I've a critical question now. I've been using my iPhone as an iBeacon to test the program.
Now I want to replace the iPhone with a real small iBeacon. This means that the BLUNO will be used as a central device to communicate with the iBeacon itself.
I've been warned by lots of people that the BLUNO can only work in "slave" mode. But I read through the documentation and it clearly states that AT+ROLE can change that to Central Mode.

I'm planning on using
Code: Select all
AT+BIND=0x[MAC address of the iBeacon that I'll buy]
Will that work?
userHeadPic iShe7ata
2014-11-19 02:46:38 Hello Man,

Sorry for the late. There are a lot of bothered things these days. So I only could make some fast reply.
I tested your code just now. It works. but after a few seconds, the serial port has been locked. And I tried visualxl
code, it is also stumbled.

Thank you visualxl, thank you for your understand.
I will try to write a post about Rssi value tomorrow.
userHeadPic Grey.CC
2014-11-19 02:46:38 Hello Man,

Sorry for the late. There are a lot of bothered things these days. So I only could make some fast reply.
I tested your code just now. It works. but after a few seconds, the serial port has been locked. And I tried visualxl
code, it is also stumbled.

Thank you visualxl, thank you for your understand.
I will try to write a post about Rssi value tomorrow.
userHeadPic Grey.CC
2014-11-18 21:09:33 Hey there,
from my experience in the new firmware i played with 1.8 and 1.9 in which the AT/NORM switcher is obsolete, that line of code doesn't work. It never gets you in the AT Mode.

The thing is, even for that basic way of going into the AT mode from code, they have no guide.
Look at this https://learn.sparkfun.com/tutorials/us ... mmand-mode
That's where I really learned!

userHeadPic iShe7ata
2014-11-18 21:09:33 Hey there,
from my experience in the new firmware i played with 1.8 and 1.9 in which the AT/NORM switcher is obsolete, that line of code doesn't work. It never gets you in the AT Mode.

The thing is, even for that basic way of going into the AT mode from code, they have no guide.
Look at this https://learn.sparkfun.com/tutorials/us ... mmand-mode
That's where I really learned!

userHeadPic iShe7ata
2014-11-18 19:37:28 You can send "+++" in one line. No problem. I did that before
Code: Select all
void masterConfiguration() {
  Serial.print("+++");
  delay(250);
}
I can understand your frustration since it was your first time playing with Arduino. BLUNO was my first device to play with too when I first started my Arduino journey.

But Relax. Don't be mad at them. I can assure you that DF has one of the best support as compared to other hardware providers.

By the way, you posted on Friday, after office hours. I am pretty sure DF does not operate on Weekends. So, to be fair to them, they perhaps have lots of posts to go through yesterday.

Yesterday, I was on exam leave. So, I couldn't reply to you earlier as well as I only check this forum during office hours.
userHeadPic visualxl
2014-11-18 19:37:28 You can send "+++" in one line. No problem. I did that before
Code: Select all
void masterConfiguration() {
  Serial.print("+++");
  delay(250);
}
I can understand your frustration since it was your first time playing with Arduino. BLUNO was my first device to play with too when I first started my Arduino journey.

But Relax. Don't be mad at them. I can assure you that DF has one of the best support as compared to other hardware providers.

By the way, you posted on Friday, after office hours. I am pretty sure DF does not operate on Weekends. So, to be fair to them, they perhaps have lots of posts to go through yesterday.

Yesterday, I was on exam leave. So, I couldn't reply to you earlier as well as I only check this forum during office hours.
userHeadPic visualxl
2014-11-18 18:54:53 Hey Man,
Thanks for replyin back. I already got this to work two days ago; one day after I posted this.
In fact I've tons of complaint about DF man, horrible suuport and they have bugz in the 1.9 firmware that took me too hours to get!!  >:(

Anyway, I got things to work. The problem was with the +++ thing. In 1.8 firmware you can't send Serial.print("+++");
You have to send each + on a separate line.
I didn't have LCD and it was really hard to debug this cuz either you see the data on serial monitor or get Arduino to use w/o you seeing it. It took me one and half day to get things good. First time i touch anything to do with arduino!

This is my working code with documentation and all. yet the accuracy is HORRIBLE!
I think my equation for distance suck big time! I calibrated and re calibrated. Soon I'll work on adding another beacon to get more accurate result.
Code: Select all
// while the AT connection is active, the serial port between the pc and the arduino is occuipied.
// You can manipluate the data on arduino, but to display on the serial monitor you need to exit the AT mode
char Data[100];
char RAW[3];
int INDEX;
char Value = '-';
void setup() {
  pinMode(13, OUTPUT); // This the onboard LED
  pinMode(8, OUTPUT); // This is connected to the buzzer
  Serial.begin(115200);    //Initiate the Serial comm
  Serial.print("+");
  Serial.print("+");
  Serial.print("+");  // Enter the AT mode
  delay(500); // Slow down and wait for connectin establishment
}
void loop(){
    Serial.println("AT+RSSI=?"); // Ask about the RSSI
for(int x=0 ; Serial.available() > 0 ; x++ ){    // get the Enter AT mode words
    //delay(20); // Slow down for accuracy
    Data[x] = Serial.read(); // Read and store Data Byte by Byte
    if (Data[x] == Value ) // Look for the elemnt of the array that have "-" that's the start of the RSSI value
      {
        INDEX=x;
      }
  }
    //Serial.println("AT+EXIT");  //Testing purposes 
    RAW[0] = Data[INDEX]; // Copy the RSSI value to RAW Char array
    RAW[1] = Data[INDEX**];
    RAW[2] = Data[INDEX**];
    RAW[3] = Data[INDEX+3];
    float RSSI = atoi(RAW);  //Convert the Array to an integer
    //Serial.println(RSSI); //testing pupose
    //delay(200); // Give the program time to process. Serial Comm sucks
    float D = exp(((RSSI+56.0)/-20.0)); //Calculate the distance but this is VERY inaccurate
    Serial.println(D); //testing purpose
    if (D>1.5) // If the device gets far, excute the following>>
    {
      digitalWrite(13, HIGH);
      digitalWrite(8, HIGH);
      delay(50);
      digitalWrite(13, LOW);
      digitalWrite(8, LOW);
      delay(50);
    }
    //delay(1000); //testing purposes
}
Thanks again for replying and DF you guys really disappointed me!
userHeadPic iShe7ata
2014-11-18 18:54:53 Hey Man,
Thanks for replyin back. I already got this to work two days ago; one day after I posted this.
In fact I've tons of complaint about DF man, horrible suuport and they have bugz in the 1.9 firmware that took me too hours to get!!  >:(

Anyway, I got things to work. The problem was with the +++ thing. In 1.8 firmware you can't send Serial.print("+++");
You have to send each + on a separate line.
I didn't have LCD and it was really hard to debug this cuz either you see the data on serial monitor or get Arduino to use w/o you seeing it. It took me one and half day to get things good. First time i touch anything to do with arduino!

This is my working code with documentation and all. yet the accuracy is HORRIBLE!
I think my equation for distance suck big time! I calibrated and re calibrated. Soon I'll work on adding another beacon to get more accurate result.
Code: Select all
// while the AT connection is active, the serial port between the pc and the arduino is occuipied.
// You can manipluate the data on arduino, but to display on the serial monitor you need to exit the AT mode
char Data[100];
char RAW[3];
int INDEX;
char Value = '-';
void setup() {
  pinMode(13, OUTPUT); // This the onboard LED
  pinMode(8, OUTPUT); // This is connected to the buzzer
  Serial.begin(115200);    //Initiate the Serial comm
  Serial.print("+");
  Serial.print("+");
  Serial.print("+");  // Enter the AT mode
  delay(500); // Slow down and wait for connectin establishment
}
void loop(){
    Serial.println("AT+RSSI=?"); // Ask about the RSSI
for(int x=0 ; Serial.available() > 0 ; x++ ){    // get the Enter AT mode words
    //delay(20); // Slow down for accuracy
    Data[x] = Serial.read(); // Read and store Data Byte by Byte
    if (Data[x] == Value ) // Look for the elemnt of the array that have "-" that's the start of the RSSI value
      {
        INDEX=x;
      }
  }
    //Serial.println("AT+EXIT");  //Testing purposes 
    RAW[0] = Data[INDEX]; // Copy the RSSI value to RAW Char array
    RAW[1] = Data[INDEX**];
    RAW[2] = Data[INDEX**];
    RAW[3] = Data[INDEX+3];
    float RSSI = atoi(RAW);  //Convert the Array to an integer
    //Serial.println(RSSI); //testing pupose
    //delay(200); // Give the program time to process. Serial Comm sucks
    float D = exp(((RSSI+56.0)/-20.0)); //Calculate the distance but this is VERY inaccurate
    Serial.println(D); //testing purpose
    if (D>1.5) // If the device gets far, excute the following>>
    {
      digitalWrite(13, HIGH);
      digitalWrite(8, HIGH);
      delay(50);
      digitalWrite(13, LOW);
      digitalWrite(8, LOW);
      delay(50);
    }
    //delay(1000); //testing purposes
}
Thanks again for replying and DF you guys really disappointed me!
userHeadPic iShe7ata
2014-11-18 18:16:35 And I looked at your codes.

Of course the AT commands will not get executed. As such, you won't be able to read any data.

You try the code below, and then bring up your Serial Monitor.
Code: Select all
void setup() {
  Serial.begin(115200);
  Serial.print("+++");
  Serial.println("AT+NAME=MAHMOUD");
}
I am pretty certain that the above code will work, and you shall see "OK" on your Serial Monitor.
userHeadPic visualxl
2014-11-18 18:16:35 And I looked at your codes.

Of course the AT commands will not get executed. As such, you won't be able to read any data.

You try the code below, and then bring up your Serial Monitor.
Code: Select all
void setup() {
  Serial.begin(115200);
  Serial.print("+++");
  Serial.println("AT+NAME=MAHMOUD");
}
I am pretty certain that the above code will work, and you shall see "OK" on your Serial Monitor.
userHeadPic visualxl
2014-11-18 16:30:38 Hi,

Yes!! It will greatly help if you use an LCD and don't use the Serial Monitor to want to see the expected responses!

Yes. I have some samples codes to grab the RSSI. Hold on.

I have stopped doing Arduino/Bluno projects for quite some time. So, I can't remember whether the codes below works or not. Test it out and tell me whether it works or not. If not, I still have tons of samples!
Code: Select all
/*
*  Get RSSI on 9600 Baud Rate
*  This file only get the RSSI and display it to LCD
*/
#include <LiquidCrystal.h>  //LCD library
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define MAXCHARS 50
void setup()
  Serial.begin(115200);  //RSSI only works on 115200
  Serial.print("+++");
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0,0);
  lcd.print("BLE RSSI: "); // print a simple message
}
void loop() {
  if(Serial.available() > 0)
    getRSSI();
}
/*
  Read input serial
*/
int readSerial(char result[]) {
  int i = 0;
  while(1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        result[i] = '\0';
        Serial.flush();
        return 0;
      }
      if(inChar!='\r') {
        result[i] = inChar;
        i++;
      }
    }
  }
}
void getRSSI() {
  Serial.println("AT+RSSI=?");
  delay(150);
  lcd.setCursor(0,1);
  lcd.print(Serial.peek());
  while(Serial.available() > 0) {
    char rssiString[MAXCHARS];  // RSSI string to received from BLE
    readSerial(rssiString);  //read serial and store it inside rssiString
    String responseString = "";
    int i = 1; //ignore negative
    for(i; i<4; i++)  //get RSSI from the array
      responseString += rssiString[i];
    int rssi = abs(responseString.toInt());  //parse string to int
    //lcd.setCursor(0,1);
    //lcd.print(rssi);  //responseString
  }
}
userHeadPic visualxl
2014-11-18 16:30:38 Hi,

Yes!! It will greatly help if you use an LCD and don't use the Serial Monitor to want to see the expected responses!

Yes. I have some samples codes to grab the RSSI. Hold on.

I have stopped doing Arduino/Bluno projects for quite some time. So, I can't remember whether the codes below works or not. Test it out and tell me whether it works or not. If not, I still have tons of samples!
Code: Select all
/*
*  Get RSSI on 9600 Baud Rate
*  This file only get the RSSI and display it to LCD
*/
#include <LiquidCrystal.h>  //LCD library
// select the pins used on the LCD panel
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
#define MAXCHARS 50
void setup()
  Serial.begin(115200);  //RSSI only works on 115200
  Serial.print("+++");
  lcd.begin(16, 2);              // start the library
  lcd.setCursor(0,0);
  lcd.print("BLE RSSI: "); // print a simple message
}
void loop() {
  if(Serial.available() > 0)
    getRSSI();
}
/*
  Read input serial
*/
int readSerial(char result[]) {
  int i = 0;
  while(1) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      if (inChar == '\n') {
        result[i] = '\0';
        Serial.flush();
        return 0;
      }
      if(inChar!='\r') {
        result[i] = inChar;
        i++;
      }
    }
  }
}
void getRSSI() {
  Serial.println("AT+RSSI=?");
  delay(150);
  lcd.setCursor(0,1);
  lcd.print(Serial.peek());
  while(Serial.available() > 0) {
    char rssiString[MAXCHARS];  // RSSI string to received from BLE
    readSerial(rssiString);  //read serial and store it inside rssiString
    String responseString = "";
    int i = 1; //ignore negative
    for(i; i<4; i++)  //get RSSI from the array
      responseString += rssiString[i];
    int rssi = abs(responseString.toInt());  //parse string to int
    //lcd.setCursor(0,1);
    //lcd.print(rssi);  //responseString
  }
}
userHeadPic visualxl