1

我们有一个控制 80 条 LED 灯条的项目,通过移动应用程序连接。我们使用的组件如下:

  • Arduino纳米板
  • HM-10蓝牙模块
  • WS2812b 灯带

在应用程序上,用户可以选择颜色(最多 5 种)、动画(可选)、动画速度和亮度。选择的配置通过一定的节流和去抖动传输到 BLE 模块。颜色(在应用程序的色轮上选择)和亮度传输良好,没有任何问题。

我们遇到的问题是,当某些动画处于活动状态时,如果用户通过应用程序更改动画速度,arduino 部分会自行锁定,不再接受任何命令。

要使用动画激活配置,我们将数据从应用程序发送到 arduino,如下所示:

<l255180200,240135068:089;04200>

格式为:< [mode] [colors(with ',')] : [brightness] ; [动画代码(2位)] [动画速度] >

起初,我们对连续数据有一些不一致的地方,所以我们实现了以下数据采集:

void loop()
{
  // Read all serial data available, as fast as possible
  while (bleSerial.available() > 0)
  {
    char inChar = bleSerial.read();
    if (inChar == SOP)
    {
      index = 0;
      inData[index] = '\0';
      started = true;
      ended = false;
    }
    else if (inChar == EOP)
    {
      ended = true;
      break;
    }
    else
    {
      if (index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if (started && ended)
  {
    // The end of packet marker arrived. Process the packet

    Serial.println(inData);
    Serial.println(inData[0]);
    char mode = inData[0];

    if (mode == 'p')
    {
      togglePower(inData);
      finalizeRead();
      return;
    }

    if (mode == 'b')
    {
      changeBrightness(inData);
      finalizeRead();
      return;
    }
    if (mode == 't')
    {
      char *themeNo = strtok(NULL, ";");
      int themeCode = valueFromString(themeNo, 0, 2);
      theme(themeCode);
    }

    //    if (mode == 'e') {
    //      sound();
    //      return;
    //    }

    char *colorsWithBrightness = strtok(inData, ";");
    char *animation = strtok(NULL, ";");

    char *colors = strtok(colorsWithBrightness, ":");
    char *brightness = strtok(NULL, ":");

    custom(colors, brightness, animation);

    finalizeRead();
  }
}

void finalizeRead()
{
  // Reset for the next packet
  started = false;
  ended = false;
  index = 0;
  inData[index] = '\0';
}

int valueFromString(char *string, int start, int width)
{
  int value = 0;
  for (int n = 0; n < width; n++)
    value = value * 10 + string[start + n] - '0';

  return value;
}

所以当模式=='l'时调用自定义函数。在自定义函数中,我们执行如下:

void custom(char *colors, char *brightness, char *animation)
{
  char *trueColors = strtok(colors, "l");
  char *colorsSplit = strtok(trueColors, ",");
  int colorCount = 0;
  uint32_t colorArray[5] = {};
  while (colorsSplit != NULL)
  {
    int r = valueFromString(colorsSplit, 0, 3);
    int g = valueFromString(colorsSplit, 3, 3);
    int b = valueFromString(colorsSplit, 6, 3);

    colorArray[colorCount] = strip.Color(r, g, b);
    colorCount++;
    colorsSplit = strtok(NULL, ",");
  }

  int ledsPerSegment = ledCount / colorCount;

  for (int n = 0; n < colorCount; n++)
  {
    int currentSegment = (n + 1) * ledsPerSegment;
    Serial.println(currentSegment);
    for (int z = n * ledsPerSegment; z < (n + 1) * ledsPerSegment; z++)
    {
      strip.setPixelColor(z, colorArray[n]);
    }
  }

  strip.setBrightness(atoi(brightness));
  strip.show();
  Serial.println("Done");

  if (animation)
  {
    int animationCode = valueFromString(animation, 0, 2);
    int animationSpeed = valueFromString(animation, 2, 3);
    Serial.println(animationSpeed);
    if (animationCode == 1)
      breath(animationSpeed, atoi(brightness));
    else if (animationCode == 7)
      pulse(animationSpeed, colorArray, colorCount);
  }
}

问题出现在脉冲动画中,是这样的:

void pulse(int wait, uint32_t colorArray[], int colorCount)
{
  black();
  while (bleSerial.available() <= 0)
  {
    for (i = 0; i < colorCount && bleSerial.available() <= 0; i++)
    {
      for (j = 0; j < ledCount / 2 && bleSerial.available() <= 0; j++)
      {
        strip.setPixelColor(39 - j, colorArray[i]);
        strip.setPixelColor(40 + j, colorArray[i]);
        strip.show();
        delay(wait);
      }
      black();
    }
  }
}

我们使用以下方法初始化动画,没有任何问题:

<l255180200,240135068:089;04200>

一旦我们从应用程序调整动画速度,我们每秒发送大约 2 个新配置,这与上面相同,只是速度不同('>' 之前的最后 3 个字符)。arduino部分随机接收数据不正确,丢失2-3个字符,如<l2551800,240135068:089;04200>

字符丢失通常发生在字符串的不同部分,但每次都会发生连续字符被误读的情况。此外,有时我们会得到一个倒退的问号。我们不确定我们在哪里实施了错误,因此对于解决此问题的任何帮助表示赞赏。

谢谢!

4

0 回答 0