Ардуино - Извлечение нескольких строк из последовательного чтения

Я пытаюсь написать код Arduino, который читает длинную строку, например <11,22,33>, через последовательный монитор, а затем сохраняет 11,22 и 33 в отдельные ячейки матричного массива.

Таким образом, пользователь может ввести: <11,22,33> И код будет хранить три записи в матрице строк:

matrix[0]=11;

matrix[1]=22;

matrix[2]=33;

Всякий раз, когда я пытаюсь запустить код, выводится только один результат

matrix[0]=33;

matrix[1]=33;

matrix[2]=33;

Но странная часть заключается в том, что когда я ставлю команды печати после матрицы[i]=строка данных в коде, вывод показывает правильные цифры! Я не уверен, где проблема, и если каким-то образом я сделал все записи последней записи. Любая помощь приветствуется!

// Пример 3 - Получение с маркерами начала и конца

const byte numChars = 32;
char data[numChars]; //запись данных для добавления последовательных данных
char *matrix[numChars]; //матрица записей данных
static byte i=0;  //индекс матрицы

boolean newData = false;

void setup() {
    Serial.begin(9600);
    Serial.println("<Arduino is ready>");
}

void loop() {
    recvWithStartEndMarkers();
    showNewData();
    Serial.println(matrix[1]);
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ind = 0;  //индекс данных
    char startMarker = '<';
    char midMarker = ',';
    char endMarker = '>';
    char rc;    //Последовательный символ чтения


    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (rc == startMarker) {
            recvInProgress = true;  //если прибывает startMarker, то введите secondary if ниже
        }

        else if (recvInProgress) {  //begin appending characters if startMarker activated switch

            if (rc == midMarker) {  //если достигнут midMarker...
                matrix[i]=data;     //добавить данные к i-й записи в матрице
                i++;                //добавить в индекс матрицы
                data[0] = '\0';     //очистить данные
                ind = 0;            //сброс индекса данных
            }
            else if (rc == endMarker) {     //если достигнут endMarker
                matrix[i]=data;             //добавление данных к последней записи в матрице (гарантирует добавление последних данных)
                data[ind] = '\0';           // завершение строки
                recvInProgress = false;     
                ind = 0;                    //reset counters for data and matrix
                i = 0;
                newData = true;
            }
            else {
                data[ind] = rc;           //eppend Serial character into data
                ind++;                    //add to data index
                if (ind >= numChars) {
                    ind = numChars - 1;
                }
            }  
        }
    }
}

void showNewData() {
    if (newData == true) {
        Serial.print("This just in ... ");
        Serial.println(matrix[0]);
        Serial.println(matrix[1]);
        Serial.println(matrix[2]);
        newData = false;
    }
}

, 👍-1


1 ответ


0

Вы определяете указатели для каждого значения следующим образом :

char *matrix[numChars]; //матрица записей данных

Однако во всех случаях вы позволяете ему указывать на данные:

matrix[i]=data; 

Затем вы устанавливаете значение, начиная с этого адреса. Итак, что происходит после того, как вы прочитали первое значение (11), и матрица[0] содержит "11", чем матрица[1] указывает на те же данные, в которые вы записываете значение 22. И вы делаете то же самое для 33. Таким образом, вы получаете 3 указателя на один и тот же адрес (данные), содержащие/перезаписывающие последнее значение (33). Таким образом, вы получаете трижды 33.

Вам следует либо продолжить запись строки в данные, либо обратиться к правильной части внутри строковых данных. Если вы хотите создать Serial.println, вы должны заканчивать строки символом \0, поэтому строковые данные и ссылки на матрицу должны быть:

index:    0   1  2  3  4  5  6  7  8
data:     1   1 \0  2  2 \0  3  3 \0
matrix:  [0]       [1]      [2]
i:        0         1        2

Это поможет, если вы измените

matrix[i]=data; 

чтобы

matrix[i]=&(data[ind]); 
,

Я не уверен, что понимаю ваши исправления. Если я изменю матрицу[i]=данные на матрицу[i]=&(данные[ind]), то напечатанное будет пустым., @mojojojo

Я не пробовал эту программу, так что это немного сложно проверить из моей головы. Я думаю, вам следует изменить строку в конце моего ответа в обоих случаях (если (rc == мидМаркер) и (rc == эндМаркер). Также в случае с midMarker я думаю, что вы должны поставить i++ перед назначением матрицы[i]. Однако я предлагаю вам протестировать эту функцию не на Arduino, а, например, в VisualStudio на ПК. Вызовите функцию и пройдите с отладчиком через код, чтобы сразу увидеть, что не так., @Michel Keijzers