Skip to first unread message

ThePizzaGuy

unread,
Apr 6, 2018, 8:02:24 PM4/6/18
to MIT App Inventor Forum
Hello, I'm not sure if this question is meant for here (was directed here from StackOverflow) but I used AppInventor 2 to make a BLE remote control car, all it must do is control two motors on the car through the bluetooth packets. I used a basic guide from this link https://www.hackster.io/gerrikoiot/ble-led-controller-feather-32u4-bluefruit-le-mit-app-inv-75163d. When I first made it, I made it exactly as that guide (just for the LED) and it worked perfectly, no lag or anything. This leads me to believe the problem is with the arduino but figured id ask around here incase there is something I missed. 

I feel like if there is a problem its in one of these two blocks. I was thinking maybe there's just too much code running and it is filling up the processing power, but I also highly doubt it as the lag only happens when I disconnect the car from my pc and the serial monitor for the feather board is not connected to the serial monitor anymore.
appBlock.png
appBlocks.png

gerrikoio

unread,
Apr 8, 2018, 1:00:56 PM4/8/18
to MIT App Inventor Forum
Yes, I think you would be right in that it is quite likely to reside on the Arduino Feather side.

I did not quite follow the part with the linking via Serial Monitor. When you say "lag" are you referring to the delay between when you send a command via the app and for the motors to respond or is it the lag between when your app gets some sort of update.


ThePizzaGuy

unread,
Apr 8, 2018, 10:53:12 PM4/8/18
to MIT App Inventor Forum
So what I mean is, when it is plugged into my computer via USB, I can open up a serial monitor in the Arduino IDE which allows me to see the talking between the feather and my phone. When I unplug the feather, I can no longer see the serial monitor, and there is massive lag from when I press a button on my phone and when the motors actually move.

gerrikoio

unread,
Apr 9, 2018, 5:43:56 AM4/9/18
to MIT App Inventor Forum
I see. Please post your Arduino code, for review. In the meantime, you could use the LED (pin13) as an indicator of when the button press from the phone was received by the feather. This will work without the need for the serial monitor.

ThePizzaGuy

unread,
Apr 9, 2018, 6:07:48 PM4/9/18
to MIT App Inventor Forum
the code:



/*********************************************************************
 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
*********************************************************************/

#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"

/*=========================================================================
    APPLICATION SETTINGS

  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
                              values.
   
                            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"
/*=========================================================================*/

// Pin Configuration and Firmware Declarations

#define LED_PIN       13

const unsigned long
  BLINKTIME =         100;
  
unsigned long 
  t_blink =           0L;

int
  blinkState =        LOW;

// 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,
                      BLUEFRUIT_UART_CTS_PIN, BLUEFRUIT_UART_RTS_PIN);
*/

/* ...or hardware serial, which does not need the RTS/CTS pins. Uncomment this line */
// Adafruit_BluefruitLE_UART ble(Serial1, BLUEFRUIT_UART_MODE_PIN);

/* ...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);

/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
//Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
//                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
//                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);


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



/**************************************************************************/
/*!
    @brief  Sets up the HW an the BLE module (this function is called
            automatically on startup)
*/
/**************************************************************************/
void setup(void)
{
  pinMode(LED_PIN, OUTPUT);
  
  while (!Serial);  // required for Flora & Micro
  delay(500);

  Serial.begin(115600);
  Serial.println(F("Adafruit Bluefruit Command Mode Example"));
  Serial.println(F("---------------------------------------"));

  /* Initialise the module */
  Serial.print(F("Initialising the Bluefruit LE module: "));

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

  if ( FACTORYRESET_ENABLE )
  {
    /* 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 */
  ble.echo(false);

  Serial.println("Requesting Bluefruit info:");
  /* Print Bluefruit information */
  ble.info();

  Serial.println(F("Please use Adafruit Bluefruit LE app to connect in UART mode"));
  Serial.println(F("Then Enter characters to send to Bluefruit"));
  Serial.println();

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

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

  // LED Activity command is only supported from 0.6.6
  if ( ble.isVersionAtLeast(MINIMUM_FIRMWARE_VERSION) )
  {
    // Change Mode LED Activity
    Serial.println(F("******************************"));
    Serial.println(F("Change LED activity to " MODE_LED_BEHAVIOUR));
    ble.sendCommandCheckOK("AT+HWModeLED=" MODE_LED_BEHAVIOUR);
    Serial.println(F("******************************"));
  }
}

/**************************************************************************/
/*!
    @brief  Constantly poll for new command or response data
*/
/**************************************************************************/
void loop(void)
{
  // Now Check for incoming characters from Bluefruit
  ble.println("AT+BLEUARTRX");
  ble.readline();
  ble.waitForOK();

  String BLEbuffer = ble.buffer;

  if (BLEbuffer.length() && BLEbuffer.indexOf("OK") == -1) 
    Serial.print(F("[Recv] ")); Serial.println(BLEbuffer);
  
  
  if (BLEbuffer.indexOf("Status") >= 0) {
    Serial.println(F("Status Request Received"));
    ble.print("AT+BLEUARTTX=");
    if (t_blink) {
      ble.println("BLNK");
    }
    else {
      if (blinkState)
        ble.println("ON");
      else
        ble.println("OFF");
    }

    // check response stastus
    if (! ble.waitForOK() ) {
      Serial.println(F("Failed to get response"));
    }

    ble.println("AT+BLEUARTRX");
   
  }
  
  else if (BLEbuffer.indexOf("0") >= 0) {
    blinkState = LOW;
    digitalWrite(LED_PIN, blinkState);
    analogWrite(13, 0);
    analogWrite(11, 0);
    digitalWrite(18, LOW);
    digitalWrite(19, LOW);
    digitalWrite(20, LOW);
    digitalWrite(21, LOW);
    t_blink = 0;
    ble.print("AT+BLEUARTTX=");
    ble.println("OFF");
    //Serial.println(F("OFF Request Received"));
    ble.println("AT+BLEUARTRX");
  }
  else if (BLEbuffer.indexOf("1") >= 0) {
    //if (!t_blink) t_blink = millis();
    analogWrite(13, 100);
    analogWrite(11, 100);
    digitalWrite(18, HIGH);
    digitalWrite(19, LOW);
    digitalWrite(20, LOW);
    digitalWrite(21, HIGH);
    ble.print("AT+BLEUARTTX=");
    ble.println("FORWARD");
    //Serial.println(F("BLINK Request Received"));
    ble.println("AT+BLEUARTRX");
  }
  else if (BLEbuffer.indexOf("2") >= 0) {
    blinkState = HIGH;
    digitalWrite(LED_PIN, blinkState);
    analogWrite(13, 100);
    analogWrite(11, 100);
    digitalWrite(18, LOW);
    digitalWrite(19, HIGH);
    digitalWrite(20, HIGH);
    digitalWrite(21, LOW);
    
    t_blink = 0;
    ble.print("AT+BLEUARTTX=");
    ble.println("BACK");
    //Serial.println(F("ON Request Received"));
    ble.println("AT+BLEUARTRX");
  }
  else if (BLEbuffer.indexOf("3") >= 0) {
    analogWrite(13, 100);
    analogWrite(11, 100);
    digitalWrite(18, HIGH);
    digitalWrite(19, LOW);
    digitalWrite(20, HIGH);
    digitalWrite(21, LOW);
    ble.print("AT+BLEUARTTX=");
    ble.println("LEFT");
    //Serial.println(F("BLINK Request Received"));
    ble.println("AT+BLEUARTRX");
  }
  else if (BLEbuffer.indexOf("4") >= 0) {
    //if (!t_blink) t_blink = millis();
    analogWrite(13, 100);
    analogWrite(11, 100);
    digitalWrite(18, LOW);
    digitalWrite(19, HIGH);
    digitalWrite(20, LOW);
    digitalWrite(21, HIGH);
    
    ble.print("AT+BLEUARTTX=");
    ble.println("RIGHT");
    //Serial.println(F("BLINK Request Received"));
    ble.println("AT+BLEUARTRX");
  }
  BLEbuffer = "";
}

gerrikoio

unread,
Apr 10, 2018, 6:03:44 AM4/10/18
to mitappinv...@googlegroups.com
I have the SPI variety of that breakout board. So I am not sure I can test here. Will check.

In the meantime, maybe comment out the following lines of code as not needed if you are not using Serial Monitor.

if (BLEbuffer.length() && BLEbuffer.indexOf("OK") == -1) 
    Serial.print(F("[Recv] ")); Serial.println(BLEbuffer);

Also worth checking the Bluefruit AT command set as there may be a timeout parameter you can set if the "waitForOK" is taking too long:

  // Now Check for incoming characters from Bluefruit
  ble.println("AT+BLEUARTRX");
  ble.readline();
  ble.waitForOK();

As suggested you could use Pin13 LED as a testing tool:

  digitalWrite(13,HIGH);
  ble.println("AT+BLEUARTRX");
  ble.readline();
  ble.waitForOK();
  digitalWrite(13,LOW);

This will give an indication of the wait time.

If you wanted to test if the Serial.print function is causing a problem maybe try:

  digitalWrite(13,HIGH);
  ble.println("AT+BLEUARTRX");
  ble.readline();
  ble.waitForOK();

  String BLEbuffer = ble.buffer;

  if (BLEbuffer.length() && BLEbuffer.indexOf("OK") == -1) 
    Serial.print(F("[Recv] ")); Serial.println(BLEbuffer);
  
  digitalWrite(13,LOW);


ThePizzaGuy

unread,
Apr 11, 2018, 2:21:56 PM4/11/18
to MIT App Inventor Forum
oh my god you genius. I have tried so hard to figure this out and you did in two replies... I commented out every "serial.print" statement in my loop and the lag went from the full second-2 to less than half a second. Still a little lag there but I don't think that's avoidable given the wireless connection. Thank you so much! I think this will work to drive the course that I need to for my class. I appreciate you so much. Probably 40 hours of research and many forums posted to and now I can actually work on the real project.

Again I am very grateful for your help!
Reply all
Reply to author
Forward
0 new messages