Trying once more to make Feather M0 work

Back in November, 2021 I had quite a bit of help from the community while I was trying to get the Feather M0 from Adafruit to work with app inventor. Being a noobie with AI, I was out of sorts since I couldn’t get anything to work so that I could at least muddle through learning AI. I then gave up and bought a HC-05 for my Arduino and have since been very successful in creating an app using it and AI. I now feel the need to try and make the Feather work but I’m getting ready to hang it up again! Thought I’d try one more time here.

I have successfully used Gerrikoio’s example “ BLE GP-O Controller” to produce his app on my Feather, but I am still having trouble being able to pass data from the Feather to the app. I have removed a bunch of blocks from his app in order to make it easier to follow and added a few blocks that I thought should work. The following code still works to flash the LED on the board by pressing the “pin 6” button on the app. To simplify, I’m just trying to pass any data to the app and it should show in the “pin 1” slot, but it doesn’t. I know the Feather is different from others, but I’m hoping those differences are taken care of in Gerrikoio’s app, so I just added a few blocks for the data. I only added 2 lines (lines 14 & 15 from the bottom) to his Feather code in a place where it should pass the word “test” to the app when the “pin 6” button is pressed.

 This is an example for our nRF51822 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
* This is modified program is linked to an MIT App Inventor App to control
* up to 6 GP-O's. This program only accepts data from teh App. It
* does not reply to the app in any way.
* App developed by Gerrikoio, using an example provided with the nRF51822
* library from Adafruit.
* MIT license applies.

#include <Arduino.h>
#include <SPI.h>
#if not defined (_VARIANT_ARDUINO_DUE_X_) && not defined (_VARIANT_ARDUINO_ZERO_)
  #include <SoftwareSerial.h>

#include "Adafruit_BLE.h"
#include "Adafruit_BluefruitLE_SPI.h"
#include "Adafruit_BluefruitLE_UART.h"

#include "BluefruitConfig.h"


  FACTORYRESET_ENABLE     Perform a factory reset when running this sketch
                            Enabling this will put your Bluefruit LE module
                              in a 'known good' state and clear any config
                              data set in previous sketches or projects, so
                            running this at least once is a good idea.
                            When deploying your project, however, you will
                              want to disable factory reset by setting this
                              value to 0. If you are making changes to your
                            Bluefruit LE device via AT commands, and those
                              changes aren't persisting across resets, this
                              is the reason why. Factory reset will erase
                              the non-volatile memory where config data is
                              stored, setting it back to factory default
                            Some sketches that require you to bond to a
                              central device (HID mouse, keyboard, etc.)
                              won't work at all with this feature enabled
                              since the factory reset will clear all of the
                              bonding data stored on the chip, meaning the
                              central device won't be able to reconnect.
    MINIMUM_FIRMWARE_VERSION  Minimum firmware version to have some new features
    MODE_LED_BEHAVIOUR        LED activity, valid options are
                              "DISABLE" or "MODE" or "BLEUART" or
                              "HWUART"  or "SPI"  or "MANUAL"
    #define FACTORYRESET_ENABLE         1
    #define MINIMUM_FIRMWARE_VERSION    "0.6.6"
    #define MODE_LED_BEHAVIOUR          "MODE"

// Create the bluefruit object, either software serial...uncomment these lines
SoftwareSerial bluefruitSS = SoftwareSerial(BLUEFRUIT_SWUART_TXD_PIN, BLUEFRUIT_SWUART_RXD_PIN);

Adafruit_BluefruitLE_UART ble(bluefruitSS, BLUEFRUIT_UART_MODE_PIN,

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */

/* ...hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */

/* SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

// -------------- DEMO APP GP-O PIN REFERENCE --------------------------------------------------
// These are the pin reference values (if you do not want a pin set then enter a 0 in the array) 
// MIT App button "Pin1" is 1st item in the array (refers to Feather MO pin-5), button "Pin2" is the 2nd (refers to Feather MO pin-6) etc. 
// ---------------------------------------------------------------------------------------------
const byte pinRef[6] = {5, 6, 9, 10, 11, 13};

bool cmdStr = false;        // A flag to inform which GPIO pin selected

byte pinNo = 0;

// A small helper
void error(const __FlashStringHelper*err) {
  while (1);

    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
void setup(void)

  // Configure the pin modes
  for (byte i = 0; i < 6; i++) {
    pinMode(pinRef[i], OUTPUT);
    digitalWrite(pinRef[i], HIGH);

  Serial.println(F("MIT App Inventor GPIO Control Example"));

  if ( !ble.begin(VERBOSE_MODE) )
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));

    /* Perform a factory reset to make sure everything is in a known state */
    Serial.println(F("Performing a factory reset: "));
    if ( ! ble.factoryReset() ){
      error(F("Couldn't factory reset"));

  /* Disable command echo from Bluefruit */

  /* Print Bluefruit information */;

  ble.verbose(false);  // debug info is a little annoying after this point!

  Serial.println(F("Waiting for connection"));
  for (byte i = 0; i < 6; i++) {
    digitalWrite(pinRef[i], LOW);

  /* Wait for connection */
  while (! ble.isConnected()) {


  // LED Activity command is only supported from 0.6.6
  if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
    ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);

  // Set module to DATA mode
  Serial.println( F("Connected. Switching to Data mode!") );

    @brief  Constantly poll for new command or response data
void loop(void)
  if (ble.available()) {
    byte c =;
    if (!cmdStr) {
      if (isAlpha((char)c)) {
        switch ((char)c) {
          case 'A':         // pin 1
            if (pinRef[0] != 0) {
              pinNo = pinRef[0];
              cmdStr = true;
          case 'B':         // pin 2
            if (pinRef[1] != 0) {
              pinNo = pinRef[1];
              cmdStr = true;
          case 'C':         // pin 3
            if (pinRef[2] != 0) {
              pinNo = pinRef[2];
              cmdStr = true;
          case 'D':         // pin 4
            if (pinRef[3] != 0) {
              pinNo = pinRef[3];
              cmdStr = true;
          case 'E':         // pin 5
            if (pinRef[4] != 0) {
              pinNo = pinRef[4];
              cmdStr = true;
          case 'F':         // pin 6
            if (pinRef[5] != 0) {
              pinNo = pinRef[5];
              cmdStr = true;
            Serial.println(F( " is not a valid GPIO pin reference"));
    else {
      if (isDigit((char)c)) {
        if ((char)c == '0') {
          if (pinNo) digitalWrite(pinNo, LOW);
        else if ((char)c == '1') {
          if (pinNo) digitalWrite(pinNo, HIGH);
        else {
          Serial.print(F( " is not valid for GPIO pin: "));
      cmdStr = false;


Sorry, that's hard to read. Hope this is better:

Thanks for any help.


Gerrikoio’s LED CONTROLLER has a small snippet where data is passed to the app using command structure (ble.print("AT+BLEUARTTX=") but the app doesn’t work unless the serial monitor is on - in my case, that would not be acceptable. Any other suggestions?



I’ll try to simplify my question in hopes of getting a response:

I am simply trying to transfer the word “test” from the Feather to appinventor by adding the following code to code that does transfer information from the appinventor to the Feather:

Feather code:


Appinventor code:

“Register for strings” block
“When ble strings received” block

It seems that the “When ble strings received “ block is never called since even if I put a simple set label text to “yes”, the text is never printed.

My question is:

Is my basic theory correct and therefore it should do what I want, but since it doesn’t I must have some minor error someplace.
I am not trying to transfer info correctly?

Thank you for any help you can give.


yes and no...

Register for Strings is correct
When ble Strings received is also correct

But are you using the right service UUID?
Are u using the right Characteristic UUID?
Are you getting "test" on the NRF Connect App?

I work a lot with the Adafruit BLE stuff.
But i never saw or used ble.println("test") -> What is that? A Notifiy? or Just for Read? Which UUID's?

you should check these things first

1 Like

Thanks for the reply.

I am using the code from Gerrikoio where he determines the service and Characteristic UUID automatically. I assume the UUID's that are found are correct since his part of the code works perfectly. That is, it connects and I can control the onboard LED with the code I presented above.

Yes, I do (on the Adafruit Connect App)

I wanted to transfer the easiest thing I could think of first and then modify it for the actual data once it is working. So I simply am trying to send the word "test" to the appinventor, but even that is not working - hence my problem.

When I do a "Do It", the following UUIDs are given for my register for strings block:

Service UUID: 6e400001-b5a3-f393-e0a9-e50e24dcca9e
Characteristic UUID: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E

Thanks again.


And the same Service and Charateristic UUID is displayed in Bluefruit App where you are getting the text "test" as notify?

Its hard to help you. The sketch is a very bad one. You have nothing for debugging.
You could enable Debug printing in Verbose mode. Then we could see what happend on the device side.

You are using the latest BLE Extension in AI?

1 Like


I was using the characteristic for a strings write block(6E400002) instead of the characteristic for a strings received block (6E400003).

Thanks a lot for your time and effort!


This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.