You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中BLE设备0-59内存地址循环读写回调执行异常问题

Solution for Serial BLE Read/Write Loop (Addresses 0-59)

The root issue here is that BLE write and read operations are asynchronous. If you tried a plain for loop, it would fire all 60 write requests at once, overwhelming the device and causing read callbacks to fail or execute out of order. We need to run these operations serially — finish one full "write → read → increment" cycle before starting the next.

Here are two robust solutions depending on your JavaScript environment:


Option 1: Using Async/Await (Cleanest & Most Readable)

If your environment supports ES2017+ (most modern Node.js versions, Electron, etc.), async/await makes this logic straightforward. First, we'll wrap the callback-based BLE methods in Promises, then use a standard loop with await to enforce sequential execution:

// Wrap BLE write/read into Promises for async/await compatibility
function writeCharacteristic(data) {
  return new Promise((resolve, reject) => {
    SensorCharacteristic.write(data, false, (error) => {
      error ? reject(error) : resolve();
    });
  });
}

function readCharacteristic() {
  return new Promise((resolve, reject) => {
    SensorCharacteristic.read((error, data) => {
      error ? reject(error) : resolve(data);
    });
  });
}

// Main function to read all addresses from 0 to 59
async function readAllMemoryAddresses(startAddr = 0, endAddr = 59) {
  for (let addr = startAddr; addr <= endAddr; addr++) {
    // Build the command string: AAAD00 + 2-digit hex address (padded with zero if needed)
    const hexAddr = addr.toString(16).padStart(2, '0').toUpperCase();
    const mydata = `AAAD00${hexAddr}`;
    console.log(`Processing address 0x${hexAddr}, command: ${mydata}`);

    try {
      // Step 1: Write the command to the characteristic
      await writeCharacteristic(Buffer.from(mydata, 'hex'));
      console.log('Writing command SUCCESSFUL', mydata);

      // Step 2: Read the response from the characteristic
      const data = await readCharacteristic();
      console.log("Entered read callback");
      
      const hexData = data.toString('hex');
      if (hexData !== '0000') {
        console.log(`Temperature History (0x${hexAddr}):`, hexData);
      } else {
        console.log(`Address 0x${hexAddr} contains null value`);
      }

      // Optional: Add a small delay to avoid overwhelming the device
      await new Promise(resolve => setTimeout(resolve, 100));
    } catch (error) {
      console.error(`Failed to process address 0x${hexAddr}:`, error);
      // Continue to next address even if current one fails
      continue;
    }
  }
  console.log('All memory addresses processed successfully!');
}

// Start the loop
readAllMemoryAddresses();

Key Benefits:

  • Synchronous-style code that's easy to follow and debug
  • Automatic sequential execution (no race conditions)
  • Proper error handling to prevent a single failure from breaking the entire loop
  • Ensures the address is always 2 hex digits (e.g., address 9 becomes 09, address 10 becomes 0A)

Option 2: Using Recursion (Compatible with Older Environments)

If you can't use async/await, a recursive function will achieve the same sequential flow. Each iteration calls itself only after the previous read/write cycle completes:

// Recursive function to process addresses one by one
function readNextAddress(currentAddr = 0, endAddr = 59) {
  // Exit condition: we've processed all addresses
  if (currentAddr > endAddr) {
    console.log('All memory addresses processed successfully!');
    return;
  }

  // Build the command string with 2-digit hex address
  const hexAddr = currentAddr.toString(16).padStart(2, '0').toUpperCase();
  const mydata = `AAAD00${hexAddr}`;
  console.log(`Processing address 0x${hexAddr}, command: ${mydata}`);

  const buff2 = Buffer.from(mydata, 'hex');
  SensorCharacteristic.write(buff2, false, function(error) {
    if (error) {
      console.error(`Failed to write to 0x${hexAddr}:`, error);
      // Move to next address even if write fails
      readNextAddress(currentAddr + 1, endAddr);
      return;
    }
    console.log('Writing command SUCCESSFUL', mydata);

    SensorCharacteristic.read((error, data) => {
      if (error) {
        console.error(`Failed to read from 0x${hexAddr}:`, error);
        readNextAddress(currentAddr + 1, endAddr);
        return;
      }
      console.log("Entered read callback");

      const hexData = data.toString('hex');
      if (hexData !== '0000') {
        console.log(`Temperature History (0x${hexAddr}):`, hexData);
      } else {
        console.log(`Address 0x${hexAddr} contains null value`);
      }

      // Optional delay before next iteration
      setTimeout(() => {
        readNextAddress(currentAddr + 1, endAddr);
      }, 100);
    });
  });
}

// Start the recursive loop
readNextAddress();

Key Notes:

  • Recursion ensures we never send concurrent requests to the device
  • Error handling keeps the loop running even if one address fails
  • The optional setTimeout gives the device time to process each request (adjust the delay based on your device's responsiveness)

Critical Things to Remember:

  1. Always pad the address to 2 hex digits: Using padStart(2, '0') ensures your command stays in the AAAD00xx format — no invalid commands like AAAD00A for address 10.
  2. Respect device limits: Some BLE devices can't handle back-to-back operations immediately, so the optional delay is a good safety measure.
  3. Error handling: Don't skip this! A single failed read/write shouldn't stop your entire data collection.

内容的提问来源于stack exchange,提问作者APARNA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:26:05