简体   繁体   English

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

[英]getting the first n elements of a specified char array arduino

My aim is reading some string from serial for example 234124.3455addg#5867 if the program sees?如果程序看到,我的目标是从串行中读取一些字符串,例如 234124.3455addg#5867? it should start to add it to a char array and if it sees # it should return the first 4 elements of that char array for my example the return should be 3455. How can I solve it.它应该开始将它添加到一个 char 数组中,如果它看到 # 它应该返回该 char 数组的前 4 个元素,对于我的示例,返回应该是 3455。我该如何解决它。 I made this using String class but I need to implement it to char array: I am quite new on arduino so please be clear thank you.我使用 String class 制作了这个,但我需要将它实现到 char 数组:我对 arduino 很陌生,所以请清楚谢谢。 Here is my code:这是我的代码:

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] = '\0';
        }
    }

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

    free( target );
    return 0;
}

Here's a simpler way of going about it, I think.我认为这是一种更简单的方法。 It depends on whether or not there are requirements that aren't explicitly stated.这取决于是否有未明确说明的要求。

A few things worth mentioning,有几点值得一提,

  1. You'd like to return the first 4 bytes that follow a ',', so you only need to buffer 4 chars您想返回 ',' 之后的前 4 个字节,因此您只需要缓冲 4 个字符
  2. I haven't got all the cables handy at the moment, so I've just banged-together something to run on the PC.目前我还没有准备好所有的电缆,所以我只是拼凑了一些可以在 PC 上运行的东西。 In your case, instead of returning a copy of the string buffer you'd just output it with Serial.print在你的情况下,而不是返回字符串缓冲区的副本,你只需 output 它与 Serial.print

Code:代码:

#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;
}

I followed your code and I did some changes to behave as your example.我遵循了您的代码,并做了一些更改以作为您的示例。

If your string is always such that, where the !如果你的字符串总是这样,那么! always come before the # and, in between them there will always be some numbers to work on, then you can do some loops to wait for those markers.总是出现在#之前,并且在它们之间总会有一些数字需要处理,然后你可以做一些循环来等待这些标记。

So, basically:所以,基本上:

  • loop to keep checking the receiving of a !循环以继续检查 a 的接收情况! mark;标记;
  • loop to keep checking for valid digits with isdigit() function;循环使用isdigit() function 继续检查有效数字;
  • loop to look for the closing mark, the #循环查找结束标记, #

But again, this algorithm works with the example you provided.但同样,此算法适用于您提供的示例。

 #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);
    }

Also, I noticed you are returning at the end of the loop() function.另外,我注意到您在loop() function 结束时返回。 You are not supposed to do that because embedded systems like Arduino must have an infinite loop to keep running.你不应该这样做,因为像 Arduino 这样的嵌入式系统必须有一个无限循环才能继续运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM