[SOLVED] - Trouble sending data from MitAppInv 2 App to Adafruit nRF52 via BLE UART

380 views
Skip to first unread message

Chris Wren

unread,
Jun 4, 2019, 5:06:18 PM6/4/19
to mitappinv...@googlegroups.com
I am trying to complete a project that uses an MIT App Inventor application on an android device talking to an nRF52832.

So far I have been able to get the app to connect to the nRF52. When I monitor serial data from the nRF52, I can see when the app connects to the nRF52.

Where I am having issues is transferring data from the app to the nRF52.

Here is the sketch I am using in the nRF52832:
#include <bluefruit.h>

BLEDfu  bledfu;
BLEDis  bledis;
BLEUart bleuart;
BLEBas  blebas;

uint8_t ch
;

void setup()
{
 
Serial.begin(115200);
 
while ( !Serial ) delay(10);   // for nrf52840 with native usb
 
 
Serial.println("Bluefruit52 BLEUART Example");
 
Serial.println("---------------------------\n");

 
Bluefruit.autoConnLed(true);

 
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);

 
Bluefruit.begin();
 
Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values
 
Bluefruit.setName("FettPool_Helmet");
 
Bluefruit.Periph.setConnectCallback(connect_callback);
 
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);

  bledfu
.begin();

  bledis
.setManufacturer("Adafruit Industries");
  bledis
.setModel("Bluefruit Feather52");
  bledis
.begin();

  bleuart
.begin();

  blebas
.begin();
  blebas
.write(100);;

  startAdv
();

 
Serial.println("Please use Adafruit's Bluefruit LE app to connect in UART mode");
 
Serial.println("Once connected, enter character(s) that you wish to send");
}

void startAdv(void)
{
 
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
 
Bluefruit.Advertising.addTxPower();

 
Bluefruit.Advertising.addService(bleuart);

 
Bluefruit.ScanResponse.addName();
 
 
Bluefruit.Advertising.restartOnDisconnect(true);
 
Bluefruit.Advertising.setInterval(32, 244);
 
Bluefruit.Advertising.setFastTimeout(30);
 
Bluefruit.Advertising.start(0);
}

void loop()
{
 
while ( bleuart.available() )
 
{
    ch
= (uint8_t) bleuart.read();
   
Serial.println(ch);
 
}
}

void connect_callback(uint16_t conn_handle)
{
 
BLEConnection* connection = Bluefruit.Connection(conn_handle);

 
char central_name[32] = { 0 };
  connection
->getPeerName(central_name, sizeof(central_name));

 
Serial.print("Connected to ");
 
Serial.println(central_name);
}

void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
 
(void) conn_handle;
 
(void) reason;

 
Serial.println();
 
Serial.println("Disconnected");
}


This is the bleuart.ino example modified slightly. I took out all the comments for space and removed the little bit I didn't use.

Additional information, if I connect using the Bluefruit LE app on my smart phone, I see data received from the app to the nRF52. So I know the nRF52 can receive data.

My question is, what "format" do I need to transmit the data in from the MIT App Inventor app so the nRF52 will be able to read it?

Thank you in advance for your help.

Evan Patton

unread,
Jun 4, 2019, 5:18:36 PM6/4/19
to MIT App Inventor Forum
Hi Chris,

How are you currently trying to send data to the Bluefruit? According to Adafruit's website, the service UUID for the UART is 6E400001-B5A3-F393-­E0A9-­E50E24DCCA9E, the RX (receive) characteristic is 6E400003-B5A3-F393-­E0A9-­E50E24DCCA9E and the TX (send) characteristic is 6E400002-B5A3-F393-­E0A9-­E50E24DCCA9E. At the moment the BLE extension will limit strings sent to the device to 20 bytes.

Regards,
Evan

Chris Ward

unread,
Jun 4, 2019, 5:18:55 PM6/4/19
to MIT App Inventor Forum
Hello Chris

At the moment, your Device is expecting to receive data in uint8_t format? Or is the value being received being cast into that format? 

Can we see your App Inventor Blocks?

Chris Ward

unread,
Jun 4, 2019, 5:44:36 PM6/4/19
to MIT App Inventor Forum
Also Chris, where is Adafruit in the Device equation? Is the nRF52 (Nordic Semiconductor) hosted on an Adafruit board or are you just making use of their API? 

Chris Wren

unread,
Jun 4, 2019, 5:49:00 PM6/4/19
to MIT App Inventor Forum

I don't mind sharing the blocks at all.


I have the svc UUID and the char UUID coded into a variable to make it easy.  The end run on this project (after I get this portion working) is to add a second nRF52 and send data to it as well.  But one step at a time.

As for the length limit, that isn't an issue now.  To this unit, I am sending 0, 1, 2, or 3.  That is it.  Just a number.  I am letting the nRF52 do all the work on what to do when it gets the number.


As you can see in the blocks, I have tried sending as an integer and as a string, just to see if I could see a difference.  But neither resulted in any data being "received" by the nRF52.  Let me qualify that.  I know the app sent the data, and the data was received by the nRF52, it just did not got to a place I could see it.


2019-06-04_16-43-23.png


Chris Wren

unread,
Jun 4, 2019, 5:50:41 PM6/4/19
to mitappinv...@googlegroups.com
the nRF52832 is a device made by Adafruit using the Nordic radio.   In simple terms (VERY simple terms), the Adafruit is the combination of an nRF52 BLE module and an Arduino processor (like an Uno).

Evan Patton

unread,
Jun 4, 2019, 6:01:53 PM6/4/19
to MIT App Inventor Forum
Based on the source code you provided, it should have been printed to the Serial as that's all that happens in loop(). How are you confirming that the data is actually being sent to the device if you can't see it? Also, if you write an integer it may not appears as printable characters. Another option might be to wrap the string value in a list, as there might be a bug in there where we expect a list but don't wrap the string as a list accordingly.

Regards,
Evan

Chris Ward

unread,
Jun 4, 2019, 6:04:12 PM6/4/19
to MIT App Inventor Forum
Hi Chris

We need to see all the Blocks :)

If you try to send a string, you do of course have to ensure that the device is expecting to receive a string. Strings can be a good way to send numbers. Does the nRF52832 really use UTF16 and not UTF8?

Chris Ward

unread,
Jun 4, 2019, 6:14:36 PM6/4/19
to MIT App Inventor Forum
Chris - are you using the Arduino IDE? You can use the Serial Monitor to see values received, or if you have one handy, hook-up an LCD Module.

Chris Wren

unread,
Jun 4, 2019, 6:25:03 PM6/4/19
to MIT App Inventor Forum
Evan, to answer you, yes, that is all the sketch is to do.  I have the nRF52 connected to my computer and I am running the Arduino IDE and using serial monitor to watch the data that gets received. (Chris, that should answer your last question as well).  This sketch in the end is going to have a lot of "moving parts", and I have learned to code one aspect and test.  Then move to the next.  Right now, this sketch is testing only the data transmission from the App to the nRF52.  When I get that working, I can add the next steps once I have the data.

When I send the data from "my" app, nothing happens.  The serial monitor does not update at all.  However, if I use the Adafruit Bluefruit LE app from the Play Store, if I send data via UART from the Bluefruit app, the serial monitor does update and print "stuff".  So I know the sketch can print data when it receives it, it just appears my app is not sending the data is the proper format.

Chris, for your first question, it will take me a minute but I will get the entire app block loaded so you can see it,

As for the UTF16 vs UTF8, that encoding is the exact encoding provided by Adafruit in their example code, and while I am testing this portion of the project, I tend to make as few changes as possible to make sure I'm not creating more issues.  However, I am ALWAYS open to suggestions and assistance.

Chris Wren

unread,
Jun 4, 2019, 7:58:10 PM6/4/19
to MIT App Inventor Forum
Here are the blocks surrounding this one unit.  You'll notice there is a reference to "Helmet" and "Armor".  I am working on the Helmet unit.  Once the helmet unit is working, I will be adding the "Armor" nRF52 (a second unit).

It has all my initializations, "pretties", and the push buttons.  It also shows how I am connecting to the nRF52.

2019-06-04_18-50-04.png


2019-06-04_18-50-38.png


2019-06-04_18-52-22.png


2019-06-04_18-53-08.png




Chris Wren

unread,
Jun 5, 2019, 7:34:11 AM6/5/19
to MIT App Inventor Forum
I did have one thought last night (got to love those 2am wake ups).

When I send data using the Bluefruit app from Adafruit, the line "while ( bleuart.available() )" gets triggered.  That means the data being sent triggers "bleuart".

When I send data from the MIT App, the same line does not trigger.  So the data does not trigger "bleuart", at least not in a manner the sketch recognizes.

OR

thought process #2.  The data IS in the correct format, I just don't have the UUIDs in the correct format.

Chris Wren

unread,
Jun 5, 2019, 9:12:55 AM6/5/19
to MIT App Inventor Forum
Chris, now that I am at a larger monitor and can get a better screen shot of the entire block structure, here is the entire app setup.

As you look, you'll see the "Armor" references, I know those are all messed up right now.  I was playing around trying things out.  The primary is the "Helmet" portions.  Once that is done, then I'll work on the Armor side.

As we move forward, I'd like to make sure I am correct in my understanding.  Using the Armor as a reference, I will have 2 different commands I want to send.  One will control a matrix and one will control a bar. If I understand BLE correctly, I can have the 1 service for the Armor nRF52 and then have 2 separate characteristics, one characteristic for the matrix and one for the bar.  Then I just call the SVC UUID and Matrix UUID and I will just affect that one value.  Granted I will need additional code in my nRF52 to keep an eye on each characteristic, but that shouldn't be too difficult.

OK, back on track.  Here is the entire block layout.

2019-06-05_8-04-46.png


ABG

unread,
Jun 5, 2019, 2:24:31 PM6/5/19
to MIT App Inventor Forum
You can get clearer blocks images using the right-click
menu options in the Blocks Editor workspace to ask for
a Downloaded Blocks Image, or 
block by block for individual events or procedures.

Some people prefer to use the Clean Up Blocks
option to get a vertical arrangement they can
scroll using their scroll wheel.  Do a Project->SaveAs first,
because you will lose your 2D arrangement.

ABG

Chris Wren

unread,
Jun 5, 2019, 3:06:56 PM6/5/19
to MIT App Inventor Forum
ABG, thank you.  I was not aware of that feature.  Here is the downloaded blocks.  I put some notes on the image to explain the desired results and layout.

blocks w notes.png




Chris Wren

unread,
Jun 5, 2019, 3:25:08 PM6/5/19
to MIT App Inventor Forum
Testing update.

For some reason, yesterday the MIT App gave no response when I tried to send data to the nRF52.  The nRF52 did not display any data on the serial monitor.

Today, something has changed.  I don't know what.  BUT!!! it is giving new information to assist in finding the issue.

Now when I run the app on my phone via the AI Companion, when I try to send data from the app to the nRF52, I get this error:

Invaild UUID: 6E400001-B5A3-F393-­E0A9-­E50E24DCCA9E

Unfortunately it does not give any further information.  So I am not sure if it is the app rejecting the UUID or if it is the nRF52 rejecting the UUID and the App is just reporting.

So, just as a test, I changed the UUID data from the above to 0x0001.  Same result.

So I manually entered in the UUID again and this time used lowercase.  Well good news!!!!  I am getting data.  Not the data I want or expected, but something!!!!!

ABG

unread,
Jun 5, 2019, 3:55:56 PM6/5/19
to MIT App Inventor Forum
You have a procedure half_sec_delay with a timing loop in it.

See the Waiting and timing section of FAQ
for why that's a bad idea.

ABG

Message has been deleted
Message has been deleted

Chris Wren

unread,
Jun 5, 2019, 4:52:00 PM6/5/19
to MIT App Inventor Forum

The delay timer was an older version of the app.  I don't need it now and will be deleting.  But thank you for the link.  I will look into it so I know the proper way if I do need it in the future.

Good news.  I have partially accomplished what I wanted.  Here are the blocks it took to make it work.  I tore it down to pure basics so there was nothing else.  Make it easy for those following behind me.


The only issue I am having is when I send an integer over (which is what I want), I get 4 integers.  So if I want to send "3", I get 3,0,0,0.  The upside is I was able to create an array and have the data sent into the array so i could access what I needed.  The downside, I REALLY would like to know how to access those additional spots being sent.  Part 2 of this project is connecting a 2nd nRF52 and sending 2 separate integers.  So being able to access those additional spots would REALLY come in handy.


nRF52 to MIT App blocks.png




Message has been deleted
Message has been deleted

Chris Wren

unread,
Jun 5, 2019, 4:54:14 PM6/5/19
to mitappinv...@googlegroups.com
Here is the arduino sketch:

/*********************************************************************
 based on the Adafruit bleuart.ino example


 Used in conjunction with the MIT App Inventor 2 application.


 This is the testing code.  The MIT App will send a number, and this
 will display that number on the serial monitor.


 Please note:  The MIT App sends 4 sets of data See comments below.
 Currently I do not know how to send data to the other 3 postions
 in the array from the MIT App, but I am working on it


 There may be some extra code in this sketch that is not needed, however
 I got the project functioning as this sketch is, and I do not want to
 tempt fate.
*********************************************************************/

#include <bluefruit.h>


// BLE Service
BLEDfu  bledfu;  // Over The Air Device Firmware Update service
BLEDis  bledis;  // Device Information Service
BLEUart bleuart; // uart over ble
BLEBas  blebas;  // BAttery Service


uint8_t ch
[4] = {0,0,0,0};  // creates 4 storage locations for the data from the MIT App
// The MIT App sends 4 blocks of integers.  This separates the 4 blocks into usable sections.
// Each block gets it's own spot in the array so the sketch can access the data



void setup()
{
 
Serial.begin(115200);
 
while ( !Serial ) delay(10);   // for nrf52840 with native usb
 
 
Serial.println("Bluefruit52 BLEUART Example");
 
Serial.println("---------------------------\n");



 
// Setup the BLE LED to be enabled on CONNECT
 
// Note: This is actually the default behaviour, but provided
 
// here in case you want to control this LED manually via PIN 19
 
Bluefruit.autoConnLed(true);


 
// Config the peripheral connection with maximum bandwidth
 
// more SRAM required by SoftDevice
 
// Note: All config***() function must be called before begin()

 
Bluefruit.configPrphBandwidth(BANDWIDTH_MAX);


 
Bluefruit.begin();
 
Bluefruit.setTxPower(4);    // Check bluefruit.h for supported values

 
Bluefruit.setName("Bluefruit_nRF52");
 
 
Bluefruit.Periph.setConnectCallback(connect_callback);
 
Bluefruit.Periph.setDisconnectCallback(disconnect_callback);


 
// To be consistent OTA DFU should be added first if it exists
  bledfu
.begin();


 
// Configure and Start Device Information Service

  bledis
.setManufacturer("Adafruit Industries");
  bledis
.setModel("Bluefruit Feather52");
  bledis
.begin();



 
// Configure and Start BLE Uart Service
  bleuart
.begin();


 
// Start BLE Battery Service
  blebas
.begin();
  blebas
.write(100);


 
// Set up and start advertising
  startAdv
();


 
Serial.println("nRF52 is ready.  Please activate MIT App and connect");
 
Serial.println("Data from MIT App will display here");
}


void startAdv(void)
{
 
// Advertising packet
 
Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
 
Bluefruit.Advertising.addTxPower();


 
// Include bleuart 128-bit uuid
 
Bluefruit.Advertising.addService(bleuart);


 
// Secondary Scan Response packet (optional)
 
// Since there is no room for 'Name' in Advertising packet
 
Bluefruit.ScanResponse.addName();
 
 
/* Start Advertising
   * - Enable auto advertising if disconnected
   * - Interval:  fast mode = 20 ms, slow mode = 152.5 ms
   * - Timeout for fast mode is 30 seconds
   * - Start(timeout) with timeout = 0 will advertise forever (until connected)
   *
   * For recommended advertising interval
   *
https://developer.apple.com/library/content/qa/qa1931/_index.html  
   */

 
Bluefruit.Advertising.restartOnDisconnect(true);
 
Bluefruit.Advertising.setInterval(32, 244);    // in unit of 0.625 ms
 
Bluefruit.Advertising.setFastTimeout(30);      // number of seconds in fast mode
 
Bluefruit.Advertising.start(0);                // 0 = Don't stop advertising after n seconds  
}


void loop()
{
 
/*
   *  Whatever number is sent from the MIT App will display here in this format:
   *  Value - Array Position
   *  {value} - 0
   *  0 - 1
   *  0 - 2
   *  0 - 3
   *  end of line
   *  
   */

 
while ( bleuart.available() )
 
{
   
Serial.println("Value - Array Position");
   
for (int x = 0; x < 4; x++) {
      ch
[x] = (uint8_t) bleuart.read();
     
Serial.print(ch[x]);
     
Serial.print(" - ");
     
Serial.println(x);
     
Serial.println("end of line");
     
Serial.println(" ");
   
}
 
}
}


// callback invoked when central connects
void connect_callback(uint16_t conn_handle)
{
 
// Get the reference to current connection

 
BLEConnection* connection = Bluefruit.Connection(conn_handle);


 
char central_name[32] = { 0 };
  connection
->getPeerName(central_name, sizeof(central_name));


 
Serial.print("Connected to ");
 
Serial.println(central_name);
}


/**
 * Callback invoked when a connection is dropped
 * @param conn_handle connection where this event happens
 * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
 */

Chris Wren

unread,
Jun 5, 2019, 6:26:26 PM6/5/19
to MIT App Inventor Forum
OH LORD!!!!  I am such an idiot!!!

I figured out why the 4 chunks.  The MIT App is sending 32 bits of data.  The sketch is filling an 8 bit variable.  Of course it will fill 4 times!!

So, to access the additional chunks, I just adjust the value of the integer to hit those higher bits.

Evan Patton

unread,
Jun 6, 2019, 12:49:50 PM6/6/19
to MIT App Inventor Forum
If you don't need 4 bytes, you can also use WriteBytes rather than WriteIntegers. The former will send single bytes versus 4-byte wide integers. There's also WriteShorts to send 2-byte wide numbers.

Regards,
Evan

Chris Wren

unread,
Jun 11, 2019, 4:06:40 PM6/11/19
to MIT App Inventor Forum
If anyone else is looking for help on this, here is my github where I stored the base code for both sides.

Reply all
Reply to author
Forward
0 new messages