Arduino .read() 函数干扰 BLE 连接

Posted

技术标签:

【中文标题】Arduino .read() 函数干扰 BLE 连接【英文标题】:Arduino .read() function interfering with BLE connection 【发布时间】:2021-10-13 20:15:14 【问题描述】:

首先,我要道歉,因为我是 BLE 连接和大部分 Arduino 编程的新手。我正忙于一个项目,该项目涉及制作一个智能咖啡秤,它可以通过 BLE 连接将数据输出到智能手机。我正在使用 Arduino nano 33 IoT 和 hx711 称重传感器放大器。

我需要创建一个程序,我可以在其中向 Arduino 和智能手机应用程序发送和接收数据。我使用了标准的 ArduinoBLE 外围库,例如“BatteryMonitor”草图和“ButtonLED”草图。通过将这两个示例草图组合在一起,我设法建立了一个可以发送和接收数据的连接。

当我尝试使用 HX711 库中的函数时出现问题,例如 scale.read();检索从 hx711 放大器输出的值。当我使用诸如 scale.read() 之类的串行读取功能时,蓝牙连接在正确建立之前失败。我想这是由于 scale.read() 函数干扰了 Arduino 发送和接收的串行数据,但我不知道如何解决这个问题。

我基本上想将电池监视器输出更改为从 hx711 称重传感器放大器读取的值的输出,但我正在努力让它工作。

#include "HX711.h"
#include <ArduinoBLE.h>

HX711 scale;

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // BLE LED Service

// BLE LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);

BLEUnsignedCharCharacteristic batteryLevelChar("2A19",  // standard 16-bit characteristic UUID
    BLERead | BLENotify); // remote clients will be able to get notifications if this characteristic changes

int oldBatteryLevel = 0;  // last battery level reading from analog input
long previousMillis = 0;  // last time the battery level was checked, in ms
const int ledPin = LED_BUILTIN; // pin to use for the LED
 double val;

void setup() 
  Serial.begin(9600);
  scale.begin(A1, A0);    //Initialized scale on these pins
  while (!Serial);

  scale.set_scale(432.f);                      // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();               // reset the scale to 0
  

  // set LED pin to output mode
  pinMode(ledPin, OUTPUT);

  // begin initialization
  if (!BLE.begin()) 
    Serial.println("starting BLE failed!");

    while (1);
  

  // set advertised local name and service UUID:
  BLE.setLocalName("COFFEE");
  BLE.setAdvertisedService(ledService);

  // add the characteristic to the service
  ledService.addCharacteristic(switchCharacteristic);
  ledService.addCharacteristic(batteryLevelChar); // add the battery level characteristic


  // add service
  BLE.addService(ledService);

  // set the initial value for the characeristic:
  switchCharacteristic.writeValue(0);

  // start advertising
  BLE.advertise();

  Serial.println("BLE LED Peripheral");


void loop() 

  // listen for BLE peripherals to connect:
  BLEDevice central = BLE.central();

  // if a central is connected to peripheral:
  if (central) 
    Serial.print("Connected to central: ");
    // print the central's MAC address:
    Serial.println(central.address());

    // while the central is still connected to peripheral:
    while (central.connected()) 
    
      
      // Battery Monitor 
      //  scale.read();
        long currentMillis = millis();
      // if 200ms have passed, check the battery level:
      if (currentMillis - previousMillis >= 200) 
         previousMillis = currentMillis;
      //  scale.read();                    // This function alone will prevent the BLE connection from establishing properly.
        updateBatteryLevel();
        
      //  outputScale();
      
      // if the remote device wrote to the characteristic,
      // use the value to control the LED:
      if (switchCharacteristic.written()) 
        if (switchCharacteristic.value())    // any value other than 0
          Serial.println("LED on");
          digitalWrite(ledPin, HIGH);         // will turn the LED on
         else                               // a 0 value
          Serial.println(F("LED off"));
          digitalWrite(ledPin, LOW);          // will turn the LED off
        
      
      
    

    // when the central disconnects, print it out:
    Serial.print(F("Disconnected from central: "));
    Serial.println(central.address());
  
  
  

void updateBatteryLevel() 



  /* Read the current voltage level on the A0 analog input pin.
     This is used here to simulate the charge level of a battery.
  */
  int battery = analogRead(A0);
  int batteryLevel = map(battery, 0, 1023, 0, 100);

  if (batteryLevel != oldBatteryLevel)       // if the battery level has changed
   // Serial.print("Battery Level % is now: "); // print it
   
    Serial.println(batteryLevel);
    batteryLevelChar.writeValue(batteryLevel);  // and update the battery level characteristic
    oldBatteryLevel = batteryLevel;           // save the level for next comparison
  


void outputScale()
 int t, i, n, T;
  double val, sum, sumsq, mean;
  float stddev;
  
  n = 20;
  t = millis();
  i = sum = sumsq = 0;
  while (i<n) 
    val = ((scale.read() - scale.get_offset()) / scale.get_scale());
    sum += val;
    sumsq += val * val;
    i++;
  
  t = millis() - t;
  mean = sum / n;
  stddev = sqrt(sumsq / n - mean * mean);
//  Serial.print("Mean, Std Dev of "); Serial.print(i); Serial.print(" readings:\t");
  Serial.print(sum / n, 3); Serial.print("\n"); // Serial.print(stddev, 3);
  // Note: 2 sigma is 95% confidence, 3 sigma is 99.7%
  //Serial.print("\nTime taken:\t"); Serial.print(float(t)/1000, 3); Serial.println("Secs\n");

  /*
  scale.power_down();             // put the ADC in sleep mode
  delay(5000);
  scale.power_up();
  */


【问题讨论】:

Arduino Nano 33 IoT 是基于 SAM21 的微控制器。他们在GitHub 中明确提到它未经测试。然而,这并不意味着它不会起作用。 scale.begin(A1, A0); 你这样初始化,然后在updateBatteryLevel 方法中有int battery = analogRead(A0);。你能详细说明一下吗? 哇。太感谢了!我不敢相信我没有注意到我的错误。问题解决了:) 我将添加此作为答案,请接受,以便关闭问题。 始终阅读文档、源代码和数据表。使用任何库而不这样做是“希望作为一种策略”。 【参考方案1】:

您在尝试从同一个 A0 引脚读取数据时初始化为 scale.begin(A1, A0)

【讨论】:

以上是关于Arduino .read() 函数干扰 BLE 连接的主要内容,如果未能解决你的问题,请参考以下文章

Arduino系列——从零开始如何自己写一个Demo-湿温度

Tuya Wi-Fi MCU SDK Arduino Library 介绍

Arduino和pyserial和ble

Arduino101学习笔记—— 蓝牙BLE

Swift 3 arduino Uno HM-10 Ble - iPhone 上的通知

AT 命令无法通过 Arduino 在 BLE HM 10 上运行