蓝牙低能量慢反应时间

时间:2018-04-06 03:16:17

标签: arduino bluetooth-lowenergy app-inventor

我目前正在尝试使用Adafruit Feather 32u4来控制带有Android应用程序的2个电机(小型遥控车)。这是我正在使用的:

应用程序的MitAppInventor 2,显然是汽车的Arduino IDE。

App Inventor没有一种愉快的方式来共享代码,但基本上我已经通过了配对,并且只能按下按钮。它们完美地工作,使汽车向前,向后,向左和向右前进。我遇到的问题是,当我从计算机上拔下羽毛时,按钮按下和电机移动之间的时间大约为1.5秒,这绝对不适合驾驶。

所有Arduino都会从手机接收阵列,这将是状态,0,1,2,3或4.根据该号码,它会按所需方向打开电机。

我使用的代码只修改了this指南

中的代码

这是我的Arduino IDE代码:

/*********************************************************************
 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 = "";
}

所有这一切应该是每个循环都在读取一行,挑出字符,并运行该字符的代码块。我没有看到它滞后的原因,因为数据量似乎非常小。如果插入并运行串行监视器,也几乎没有延迟。一旦我拔掉它,它就会保持连接状态,除了大规模的延迟外,一切都还能正常工作。

我最初的想法是,缓冲区太满了&#34;空白&#34;命令,并且它必须在真正的命令之前处理所有这些命令,但如果是这种情况那么它将在串行监视器打开时滞后。

到目前为止,我已经尝试将BAUD率更改为更低的数字,认为300是最小的,如果问题是堆栈得到太多的命令来排序300将是一个很小的数量相比我有115600它在之前,但没有产生任何结果。我也试过削减代码,这似乎是我可以使用的最小代码,使它仍然可以工作。

我确实读过它可能有助于应用onSerialEvent()方法,但是当我尝试它时会陷入困境:

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("******************************"));
      }

可能是它的布线?例如,我可能需要在电机之前使用一个电容器,以防止它们不得不提升电流。实际开始移动所需的功率?我不太了解电器,但这只是一个想法。

1 个答案:

答案 0 :(得分:3)

因此解决方案非常简单,我不认为它只是一个BLE解决方案,因为它只与串行命令(I.E. serial.print())有关。在设备不再连接到计算机之后在代码中使用这些命令将导致电路板不响应它们或者在最终放弃之前花费额外的时间来尝试处理它们(我猜测实际发生了什么)。 / p>

解决方案是在上传到设备之前简单地注释掉所有的Serial命令,意图在没有插入的情况下运行代码。或者你显然可以将它们全部删除但是下次你可能会妨碍你的调试体验正在尝试编辑代码。

我认为不是删除这个问题,而是用我发现的问题回答它可能会帮助其他人。