getting the first n elements of a specified char array arduino

点点圈 提交于 2020-04-17 21:11:43

问题


My aim is reading some string from serial for example 234124!3455addg#5867 if the program sees ! 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? 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. 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;
}

回答1:


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
  2. I haven't got all the cables handy at the moment, so I've just banged-together something to run on the PC. In your case, instead of returning a copy of the string buffer you'd just output it with 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;
}



回答2:


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 ! mark;
  • loop to keep checking for valid digits with 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. You are not supposed to do that because embedded systems like Arduino must have an infinite loop to keep running.



来源:https://stackoverflow.com/questions/61120228/getting-the-first-n-elements-of-a-specified-char-array-arduino

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!