Project goal is to detect nearby bluetooth devices and do certain actions (control lights mainly), connection to and from the cloud is used to also manually control those actions.
The code I’m using:
// Serial1 is RN42 connected to TX/RX on Spark Core, also tried Serial2 with the same results.
// 3,3v and gnd is connected to the Spark as well.
char cellPhone[] = "123456789ABC,12345A";
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
Serial1.println("---"); // make sure the device is not in command mode
}
void loop()
{
Serial1.print("$$$");
//Wait a bit for the module to respond
delay(200);
Serial1.println("IN,2");
delay(5000);
int h = Serial1.available();
if (h >= 42) { // we know there is a bluetooth device
char *id = readSerial(h);
char *str;
while ((str = strtok_r(id, "\n", &id)) != NULL) {
Serial.println(str);
Serial.print("Retry count: ");
Serial.println(retryLockCount);
if(strncmp(str, cellPhone,19) == 0) {
Serial.println(str);
}
}
}
//Exit command mode
Serial1.println("---");
}
char* readSerial(int h) {
char input;
char buffer[1000];
if (Serial1.available() > 0) {
int j = 0;
for (int i = 0; i < h; i++) { // the id's start at char 21, se we copy from there
input = (char)Serial1.read();
if (i >= 21) {
buffer[j] = input;
buffer[j + 1] = '\0';
j++;
}
}
return buffer;
}
else {
return "No Data";
}
}
It works and prints everything to the Serial interface like expected however when it reaches the data reading part(int h = Serial1.available() it turns off the connection to the cloud and the onboard Spark led will turn from breathing cyan to breathing blue which is no wi-fi according to docs.
Also it seems to happen after about 2 to 3 loops, it will still output everything bluetooth related just fine but I can’t send it commands via the cloud or ping it on my network.
Is there any way to debug this and check why this occurs?
Any suggestions on this would be much appreciated
@RickDB, the problem may be that readSerial() is returning a pointer to the local variable buffer[] which is de-allocated when the function returns! The buffer should either be global or allocated in loop() and its pointer passed to readSerial().
Thanks!
Corrected the error however it still turns to a breathing blue led once I connect the bluetooth module and reach the readSerial1 code
Current sketch:
char cellPhone[] = "123456789ABC,12345A";
char buffer[1000];
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
Serial1.println("---"); // make sure the device is not in command mode
}
void loop()
{
Serial1.print("$$$");
//Wait a bit for the module to respond
delay(200);
Serial1.println("IN,2");
delay(5000);
int h = Serial1.available();
if (h >= 42) { // we know there is a bluetooth device
char *id = readSerial(h);
char *str;
while ((str = strtok_r(id, "\n", &id)) != NULL) {
Serial.println(str);
if(strncmp(str, cellPhone,19) == 0) {
Serial.println(str);
}
}
}
//Exit command mode
Serial1.println("---");
}
char* readSerial(int h) {
char input;
if (Serial1.available() > 0) {
int j = 0;
for (int i = 0; i < h; i++) { // the id's start at char 21, se we copy from there
input = (char)Serial1.read();
if (i >= 21) {
buffer[j] = input;
buffer[j + 1] = '\0';
j++;
}
}
return buffer;
}
else {
return "No Data";
}
}
/edit: for some reason that sketch takes forever to apply on my Spark Core (via Spark Build online), seems to be running the old code when it finishes (does report success).
@RickDB, you need to rethink your readSerial() function. You should pass it the pointer to the buffer you want to write to and the function should simply exit. So it becomes a void function, something like this:
in loop()
readSerial(h, buffer);
void readSerial(int h, char* buff) {
char input;
if (Serial1.available() > 0) {
int j = 0;
for (int i = 0; i < h; i++) { // the id's start at char 21, se we copy from there
input = (char)Serial1.read();
if (i >= 21) {
buff[j] = input;
buff[j + 1] = '\0';
j++;
}
}
return;
}
else {
strcpy(buff, "No Data");
}
}
Applied that function but still get the breathing blue led for an unknown reason, everything will still remain running (reports found BT devices) however the Wi-Fi / cloud part is just dead.
It does seem to come back to breathing cyan for a few seconds now and again like it has reconnected to Wi-Fi but reverts to blue afterwards, all while still outputting the expected data to my serial connection.
Checked the power requirements for this BT module but it should be enough to power it off the Spark Core alone afaik.
Thanks again and really appreciate any help
/edit: even when commenting out the readSerial function call it will revert to breathing blue, very odd bug this one
Current sketch:
char cellPhone[] = "123456789ABC,12345A";
char buffer[500];
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
Serial1.println("---"); // make sure the device is not in command mode
}
void loop()
{
Serial1.print("$$$");
//Wait a bit for the module to respond
delay(200);
Serial1.println("IN,2");
delay(5000);
int h = Serial1.available();
Serial.println(h);
if (h >= 42) { // we know there is a bluetooth device
readSerial(h, buffer);
char *id = buffer;
char *str;
while ((str = strtok_r(id, "\n", &id)) != NULL) {
Serial.println(str);
if(strncmp(str, cellPhone,19) == 0) {
Serial.println(str);
}
}
}
//Exit command mode
Serial1.println("---");
delay(5000);
}
void readSerial(int h, char* buff) {
char input;
if (Serial1.available() > 0) {
int j = 0;
for (int i = 0; i < h; i++) { // the id's start at char 21, se we copy from there
input = (char)Serial1.read();
if (i >= 21) {
buff[j] = input;
buff[j + 1] = '\0';
j++;
}
}
return;
}
else {
strcpy(buff, "No Data");
}
}
Reduced sketch with only Serial available which has the same problem, there must be something incompatible but considering it’s basic uart I can’t figure out why:
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
Serial1.println("---"); // make sure the device is not in command mode
}
void loop()
{
Serial1.print("$$$");
//Wait a bit for the module to respond
delay(200);
Serial1.println("IN,2");
delay(5000);
int h = Serial1.available();
//Exit command mode
Serial1.println("---");
delay(5000);
}
@RickDB, you have a couple of delay(5000) statements which should not stall the cloud connection but you may want to convert these to millis() delays, something like this:
unsigned long wait = millis();
while ((millis() - wait) < 5000UL)
SPARK_WLAN_Loop();
This causes the background task (normally called every time loop() ends) to be called during the wait.
Same result sadly , seems the moment I call int h = Serial1.available() it turns to breathing blue.
Gonna try a few things to see where it fails exactly.
/edit: If I trigger bluetooth discovery via Serial1.println(“IN,2”); it will turn to breathing blue so gonna check if I did something wrong there.
Only thing that comes to mind is that during the scan it might halt any other operations just not sure how to fix that.
/edit2: is it possible with the spark to make a function threaded (background process)?
Current sketch:
char cellPhone[] = "123456789ABC,12345A";
char buffer[1000];
unsigned long wait = millis();
void setup()
{
Serial.begin(115200);
Serial1.begin(115200);
Serial1.println("---"); // make sure the device is not in command mode
}
void loop()
{
Serial.println("Started");
Serial1.print("$$$");
//Wait a bit for the module to respond
wait = millis();
while ((millis() - wait) < 200UL)
SPARK_WLAN_Loop();
Serial1.println("IN,2");
wait = millis();
while ((millis() - wait) < 5000UL)
SPARK_WLAN_Loop();
int h = Serial1.available();
if (h >= 42) { // we know there is a bluetooth device
readSerial(h, buffer);
char *id = buffer;
char *str;
while ((str = strtok_r(id, "\n", &id)) != NULL) {
Serial.println(str);
if(strncmp(str, cellPhone,19) == 0) {
Serial.println(str);
}
}
}
//Exit command mode
Serial1.println("---");
wait = millis();
while ((millis() - wait) < 5000UL)
SPARK_WLAN_Loop();
}
void readSerial(int h, char* buff) {
char input;
if (Serial1.available() > 0) {
int j = 0;
for (int i = 0; i < h; i++) { // the id's start at char 21, se we copy from there
input = (char)Serial1.read();
if (i >= 21) {
buff[j] = input;
buff[j + 1] = '\0';
j++;
}
}
return;
}
else {
strcpy(buff, "No Data");
}
}
@RickDB, the firmware sets the Serial1 circular buffer to 64 chars. So if the module puts out more than 64 bytes then a call to Serial1.available() my show less than 42 chars due to the circular buffer wrapping around.
One way to fix this is read all characters as they are received into your main buffer and then parse that. Here is the general idea:
h = 0;
If (Serial.available()) {
while (Serial1.available)
buffer[h++]=Serial1.read();
buffer[h] = “\0”;
}
if (h > 42) { // start parsing from the 21st char
while ((str = strtok_r(id, "\n", &buffer[21])) != NULL) {
Serial.println(str);
if(strncmp(str, cellPhone,19) == 0) {
Serial.println(str);
}
}
Thanks, even without the serial reading it reverts to the breathing blue state.
The moment I put the Bluetooth device in discovery mode (“IN,2”) it kills Wi-Fi on the Spark Core, not sure why though
Also ordered the Adafruit Bluetooth devices (BLE breakout / BL2) as those are much nicer to work with (auto baud rate / accepts 3,3v-16v / external power supply) just hoped that this one would work but still want to figure out why this one doesn’t though.
BT (and BLE) broadcast on the same frequency as the Cc3000. The two can coexist as long as they are not broadcasting at the same time. Probably you will need to disconnect from the cloud during the BT discovery period and reconnect once discovery is completed.
I have used a Rn42 and the Spark ( TCP no cloud) successfully together abiding by this “one at a time rule”
Extended cables of Bluetooth module (2 meters apart from Spark Core)
This was to rule out local interference due to the shared signal frequency of BT/WiFi as they were sitting right next to each other before.
Even then it still lost WiFi instantly when discovery started, added WiFi.off / on switches before and after the discovery like you suggested which does seem to resolve it, however reconnection takes about 15s total which is still a bit too long and during the discovery it would be unreachable so flashing it remotely would be hit and miss
Not yet, haven’t got any 3,3v power adapter at the moment (only 5/12v) to connect the Bluetooth module directly.
Could order one to rule that out and it might come in handy for other projects.
Putting the unit near the router won’t stop interference (if that is one cause of your problems.) You should try attempting to just use one at a time, as suggested by @pra above.
As for the 3.3V supply, I’d rather order a bunch of 3V3 regulators - they will always become useful, especially if you want to create several projects and don’t want to fork out for a 3V3 adapter for each of them.
Unless you are going for a propper lab supply It’s always good to have one of these
And for a quick test to rule out power issues, you may even get away with a voltage divider - not nice but quickly done
If you can leave the wifi on but the cloud disconnected it should be ok during discovery, as there should be no wifi transmissions. That way reestablishiing the cloud connection may be a bit quicker when BT discovery is finished. It the cloud handshaking back and forth during the 30 seconds or so it takes the RN42 to do discovery that’s causing the problem IMHO
Tried that but reconnecting to the cloud can take some time and during discovery it will be unreachable for flashing or API calls, remotely you can't tell whats its doing as well so for instance remote flashing would be cumbersome to say the least.
Nice, much better than having to buy multiple adapters
Also found the power requirements of the Bluetooth module:
Low power: 26 uA sleep, 3 mA connected, 30 mA transmit
Think the Spark Core should be able to give that at least so not 100% sure if the loss of Wi-Fi is related to the Bluetooth module asking too much.
Thanks, will try with Spark.connect / disconnect and see if I can get some faster reconnects.
The reliable current supply of the Core via the 3V3 pin is the matter of some threads here, but there are a few key figures to do your own estimations.
Max current via the 3V3 regulator is 500mA.
The Core needs 25 to 50 mA (avg. w/o sourcing on output pins)
Each pin of the Core could source up to 20mA (max. Ivdd 150 mA (!))
The CC3000 may use up to 350mA when active
So you might get your 30mA or you might not - it all depends on your usage and some luck
But given your experience, you might not be too lucky
Given my own experiance with an 32x32 RGB LED matrix, I experianced the blue flashing very reproducable due to power issues.
Although sucking current in a diffetent league (5V 2A), the blue flashing was definetly triggered when the power supply got near its limits (>80% LEDs bright white) and disappeared when current consumption decreased.
This might not apply to your case, but just as side info.