получение первых n элементов указанного массива символов arduino - PullRequest
0 голосов
/ 09 апреля 2020

Моя цель - прочитать некоторую строку из последовательного, например, 234124! 3455addg # 5867, если программа видит! он должен начать добавлять его в массив символов и, если он увидит #, он должен вернуть первые 4 элемента этого массива символов для моего примера, возвращаемое значение должно быть 3455. Как я могу решить это? Я сделал это с помощью класса String, но мне нужно реализовать его в массив символов. Я новичок в 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] = '\0';
        }
    }

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

    free( target );
    return 0;
}

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Вот простой способ сделать это, я думаю. Это зависит от того, существуют ли требования, которые явно не указаны.

Несколько вещей, о которых стоит упомянуть,

  1. Вы хотите вернуть первые 4 байта, следующие за '!', поэтому вам нужно всего лишь 4 буфера
  2. . На данный момент у меня не все кабели под рукой, поэтому я просто собрал что-то для запуска на P C. В вашем случае вместо того, чтобы возвращать копию строкового буфера, вы просто выводите ее с помощью 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;
}
0 голосов
/ 09 апреля 2020

Я следовал вашему коду и внес некоторые изменения, чтобы вести себя как ваш пример.

Если ваша строка всегда такова, где ! всегда предшествует #, и между ними всегда будет несколько чисел для работы, тогда вы можете сделать несколько циклов для ожидания этих маркеров.

Итак, в основном:

  • l oop, чтобы продолжать проверять получение a ! mark;
  • l oop для продолжения проверки действительных цифр с помощью функции isdigit();
  • l oop для поиска метки закрытия, #

Но, опять же, этот алгоритм работает с предоставленным вами примером.

 #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, должны иметь бесконечное число l oop, чтобы продолжать работать.

...