Using Feather M0 and AI2 to transfer data from Feather to App

At the beginning of this project I couldn’t find any examples of using a Feather M0 to transfer data to the app inventor. Being a complete novice at app inventor, I had quite a time figuring it out because Bluetooth LE is more difficult than Classic Bluetooth but also the Feather M0 has its own requirements that are not well documented. I finally have a working app so I thought I would share it in case others are struggling with it. The code is definitely not efficient, it’s probably bloated and I suspect is very ugly in places - but it works!

I have to thank ChrisWard, ABG, Gerrikoio (BLE GP-O Controller | MIT App Inv + Feather M0 Bluefruit LE - Hackster.io), and electronoobs for their help and insight.

My project is designed to receive an analog signal from three pressure transducers that measure the pressure of liquids in three RV tanks and displays the percent full or gallons left in the tanks. I have only simulated the analog signals using one potentiometer and calculated offsets from it to come up with 3 data points that I can use to test the code. I present the data on two screens. The main screen shows a graph of the three data points over time with the most recent data at the right, scrolling then to the left. The day of the week is also shown on the graph. Digital values are also displayed. The other screen (not a Screen in the true sense of app inventor) shows just the digital results. All data points are stored within the device so that the app can be closed and opened at will. The Feather code simply reads the data and then concatenates the 3 values with “#” being the delimiter. I have organized the blocks in app inventor in these general categories: creating variables, initialization of the data and screens, and the main loop that waits for data along with its supporting procedures.

Here’s a few tips that were not clear to me at the beginning. One way to transfer data is to use the “Register for Strings” and “When Strings Received” blocks. The former tells the code where to look for the data and the latter waits for data to come in. Although this code determines the correct UUIDs, one must use different UUIDs for receiving and transmitting data. Both the .apk and the .aia files work, but I had trouble getting them started because I was trying to use empty strings. I think it’s resolved now, but I’m not sure.

Here’s one of the screens:

Here’s the Feather M0 code:

/*********************************************************************
 * Version 3.2 (conversion from Gerrikoio's sketch to mine
 * This sketch works with appinventor project named camper3.x and uses 
 * the Adafruit Feather M0
 * This is based on an example for Adafruit nRF51822 based Bluefruit LE modules
*  This is modified program is linked to an MIT App Inventor App to control
*  up to 6 GP-O's. See https://www.hackster.io/gerrikoiot/ble-gp-o-controller-mit-app-inv-feather-m0-bluefruit-le-4fba5e
*********************************************************************/

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

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

#include "BluefruitConfig.h"

/*=========================================================================*/

    #define MODE_LED_BEHAVIOUR          "MODE"
/*=========================================================================*/

/* Create the bluefruit object, either software serial...
......hardware SPI, using SCK/MOSI/MISO hardware SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_CS, BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);


//Inputs
int in = A0;
int fWater = 0;
int gWater = 0;
int bWater = 0;
String out = "first";

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


void setup(void)
{
 if ( !ble.begin(VERBOSE_MODE) )   //apparently needed!
  {
    error(F("Couldn't find Bluefruit, make sure it's in CoMmanD mode & check wiring?"));
  }
  
  Serial.begin(115200);
  pinMode(in,INPUT);
  Serial.println(F("MIT App Inventor Feather M0  Version 3.2"));
  Serial.println(F("------------------------------------------------"));


  /* Disable command echo from Bluefruit */
  ble.echo(false);

  /* Print Bluefruit information */
  ble.info();

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

  Serial.println(F("Waiting for connection"));

  /* Wait for connection */
  while (! ble.isConnected()) {
      delay(500);
  }

  Serial.println(F("******************************"));

  // Set module to DATA mode
  Serial.println( F("Connected. Switching to Data mode!") );
  ble.setMode(BLUEFRUIT_MODE_DATA);
  Serial.println(F("******************************"));
}
/**************************************************************************/
void loop(void)
{
 
       //Map the value from 10 bits to 8 bits:
  
  fWater = map(analogRead(in),0,679.0,0,255);    //Byte = 8 bits = 2 to the 8 = 255 
                                                 //map 3.3volts to 255 (1023*3.3/5)
   if (fWater+50>=255){
    gWater = 255;
   }
    else
    {gWater = fWater +50;
   }
   if (fWater+100>=255){
    bWater = 255;
   }
    else
    {bWater = fWater +100;
   }
   String vals = String(fWater)+"#"+String(gWater) +"#"+String(bWater);  //needed to send all data to HC-05 at once
   Serial.println(vals);   //prints to serial monitor
   ble.println(vals);
   delay(2000);                          //delay between each data send  
}

Here’s the app inventor blocks:

Here are the .aia file:
Camper3_2c.aia (220.3 KB)

Hope it helps.