获取指定字符数组arduino的前n个元素

getting the first n elements of a specified char array arduino

我的目标是从串行读取一些字符串,例如 234124!3455addg#5867 如果程序看到!它应该开始将它添加到一个 char 数组,如果它看到 # 它应该 return 该 char 数组的前 4 个元素对于我的示例 return 应该是 3455。我该如何解决它?我使用 String class 做了这个,但我需要将它实现为 char 数组。 我是 arduino 的新手,所以请说清楚谢谢。 这是我的代码:

const char *s = "123123123!0037selam#aaaaSDSDa";
const char *CHAR1 = "!";
const char *CHAR2 = "#";

char *target = NULL;
char *start, *end;

void setup() {
    Serial.begin(9600);
}

void loop() {
    if ( start = strstr( s, CHAR1 ) )
    {
        start += strlen( CHAR1 );
        if ( end = strstr( start, CHAR2 ) )
        {
            target = ( char * )malloc( end - start + 1 );
            memcpy( target, start, end - start );
            target[end - start] = '[=10=]';
        }
    }

    if ( target )
    {
        for(int i=0; i<4;i++)
            Serial.print( target[i]);
    }

    free( target );
    return 0;
}

我遵循了您的代码并做了一些更改以作为您的示例。

如果你的字符串总是这样,其中 ! 总是在 # 之前,并且在它们之间总会有一些数字需要处理,那么你可以做一些循环等待那些标记。

所以,基本上:

  • 循环检查接收到一个!标记;
  • 循环以使用 isdigit() 函数继续检查有效数字;
  • 循环寻找结束标记,#

但同样,此算法适用于您提供的示例。

 #define MAXSIZE (200)

    char Tmp[MAXSIZE];

    void setup() {
        Serial.begin(9600);
        Serial.println("Enter a Message");
    }
    void loop() {
        int counter, i;
        char received;

        while (Serial.available() <= 0) {
          /* keep in the loop*/
        }

        while (Serial.read() != '!') {
            /* keep waiting the '!' */
        }

        for (i = 0; i < 4; i++) {
            if (isdigit((received = Serial.read())) == 0)
                break;
            Tmp[counter++] =  received;
            delay(10);
        }
        while (Serial.read() != '#') {
            /* keep waiting the '!' */
        }
        Tmp[counter] = 0;

        Serial.write(Tmp, strlen(Tmp));

        newPack(Tmp);

        // after you are done, make sure to clean up
        // your buffer for the next round
        counter = 0;
        memset(Tmp, 0, MAXSIZE);
    }

此外,我注意到您在 loop() 函数的末尾返回。 你不应该这样做,因为像 Arduino 这样的嵌入式系统必须有一个无限循环来保持 运行.

我认为这是一种更简单的方法。这取决于是否有未明确说明的要求。

有几点值得一提,

  1. 您想 return '!' 后的前 4 个字节,所以您 只需要缓冲4个字符
  2. 我现在手边没有所有的电缆,所以我只是 在 PC 上将一些东西拼在一起 运行。在你的情况下,而不是 return正在复制您刚刚输出的字符串缓冲区 Serial.print

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

class dummy
{
    public:
        dummy()
        {
            const char *testData = "234124!3455addg#5867";
            int dataLen = strlen(testData);
            mData = new char[dataLen+1];
            strcpy(mData, testData);
            mTotal = strlen(testData);
            mIndex = 0;
        }
        int available()
        {
            return mTotal - mIndex;
        }
        char read()
        {
            return mData[mIndex++];
        }
    private:
        char *mData;
        int mIndex;
        int mTotal;
};

char *testFunc()
{
    dummy *Serial = new dummy();
/// -------- 8< ------------ cut here until the next pair of scissors. put inside the loop function
/// your code does all of the functionality (reading and buffering) inside a single iteration of loop(). 
/// Normally, I'd expect a single character to be read each time. I'd expect loop() to be 
/// run 16 times before a result was output, since # is the 16th character of the string.
    char tmpBuffer[5] = {0};
    int bufferIndex = 0;
    bool marker1Seen = false;

    while (Serial->available() > 0)
    {
        char received = Serial->read();
        if (received == '!')
        {
            marker1Seen = true;
        }

        else if (received == '#')
        {
            return strdup(tmpBuffer);
        }

        else if (marker1Seen == true && bufferIndex < 4)
        {
            tmpBuffer[bufferIndex++] = received;
        }
    }
    // shouldn't get here if the input is well-formed
    return NULL;
/// -------- 8< ------------ cut here
}

int main()
{
    char *result = testFunc();
    cout << result;
    delete result;
}