Удаление и повторное создание массива структуры глобально из функции без знания размера массива при компиляции - PullRequest
0 голосов
/ 03 октября 2018

Полный код: Pastebin

Полный код с вашими комментариями (Google Drive): SerialGrapherV0.9

Идет выполнение кодапочти у основания.

пример YouTube для графического выполнения кода: Grapher

Справочная информация. Моя цель - написать библиотеку, позволяющую вызывающему Arduino управлять вызываемым Arduino.через последовательный порт и распечатайте на определяемом мастером графике или графиках на дисплее SSD1306 I2C (нет версии SPI для тестирования).Графический код закончен.В настоящее время я могу иметь 4 графика, которые могут обновляться синхронно или асинхронно, нет гашения и записываются только те части, которые требуют обновления.

В настоящее время оба arduinos выполняют один и тот же эскиз и определяют свою роль с помощью pullup_input, привязанного к земле, однако в более поздних версиях эскиз будет компилироваться с использованием операторов if с #defined boolean, чтобы значительно сэкономить место в программе для вызывающего arduino.

Пока что: фактический график работает и график обновляется всякий раз, когда graphAdd (graphNumber, newVal);называется.Xpos, ypos, xlength и ylength каждого графика могут быть определены на стороне вызывающего абонента следующим образом:

#define masterGraphNum 4                  //Set this to the number of Graphs you want. 

graphStruct graph[masterGraphNum] = {             //Each set of brackets is an instance of a graph, one for each specified in graphNum, set the array number on the receiver to the max number of graphs you can use.
  //Graph 1                           //Usage: {LeftX, TopY, width, height}
  {0, 0, 31, 32},
  //Graph 2
  {32, 0, 31, 32},
  //Graph 3
  {64, 0, 31, 32},
  //Graph 4
  {96, 0, 31, 32},
};

В настоящее время я пытаюсь использовать delete[] (graph);, за которым следует graphStruct *graph = new graphStruct[incomingGraphNum];, где входящийGraphNum являетсяint, посылаемый вызывающим и получаемый вызываемым, вначале кажется, что это работает, однако после короткого времени прорисовки ~ 15 секунд происходит сбой и перезапуск arduino.

FLOW:

  • Callee ожидает подключения бесконечно
  • Вызывающий отправляет готовый байт
  • Callee acks
  • Вызывающий отправляет требуемое количество графиков
  • НЕ РАБОТАЕТ: повторная инициализация графика
  • График добавляет данные через вызываемую функцию
  • NYI: отправка номера графа и нового значения через последовательный

Теперь моя проблема - создание массива структур, доступных в глобальном масштабе, из функциипоскольку я не хочу предварительно кодировать число графов в вызываемом объекте, а также назначать размер буферного массива в структуре.

Для работы функций graph [] должен быть объявлен глобально.Я хотел бы глобально объявить graph [количество графов] внутри функции во время настройки вызываемого абонента, поскольку я хочу сделать это диагностическим инструментом plug-and-play для моих будущих проектов.

Следующие шаги: Настройка пакетов для отправки данных графика.Не слишком сложно, по сути, отправка двух целых чисел, таких как (graph #, graphData) Добавление графа «заголовок» (например, «ACC» или «Интенсивность света»)

Реализовано:

  • Графическая система
  • Простая последовательная система «вызов - ответ» и система подтверждения.(Только что обнаружил потоковую функцию, включенную в Arduino IDE, в настоящее время переписываем несколько разделов для использования Serial.parseInt () вместо модифицированного serialEvent ().
  • Основная обработка ошибок
  • Loops / Secondсчетчик

1 Ответ

0 голосов
/ 04 октября 2018

Несколько идей, которые могут помочь.

Дисплей имеет 128 пикселей, поэтому вам необходим буфер размером не больше этого.Я предлагаю вам создать один глобальный буфер (вместо каждой структуры, имеющей свой собственный буфер).Это никогда не будет нуждаться в изменении размера с new/delete, независимо от того, сколько у вас графиков.

uint8_t global_graph_buffer[128];

Обратите внимание, что я изменил его с int на byte.Высота дисплея составляет всего 30 или 40 пикселей (?), Поэтому нет необходимости хранить любое число больше этого.Просто уменьшите значение, когда оно входит в порт.

graph_buffer[x] = map(incoming_data, 0, max_input, 0, height_of_graph);

См. Функцию Arduino map().

Далее, вам действительно нужен y_posа высота графиков?Планируете ли вы иметь более 1 ряда графиков?Если нет, избавьтесь от этих членов структуры.Также вы можете избавиться от полей x_pos и width.Их можно рассчитать на основе индексов.

struct graphStruct {
  uint8_t gx;  // Removed
  uint8_t gy;  // Removed
  uint8_t gw;  // Removed
  uint8_t gh;  // Removed
  int gVal;              // What is this for?
  //int graphBuffer[graphBufferSize]; This is gone
  uint8_t start_index;   // First index in the global array
  uint8_t end_index;     // Last index
  bool isReady;          // What is this for?
};

Для вычисления x_pos и ширины:

x_pos = start_index
width = end_index - start_index

Для обработки входящих данных сдвиньте только часть буфера для данного графика идобавьте значение:

int incoming_data = some_value_from_serial;
// Shift
for (byte i = graph[graphNumber].start_index+1; i < graph[graphNumber].end_index; i++) {
    global_graph_buffer[i] = global_graph_buffer[i-1]
 }
// Store
global_graph_buffer[i] = map(incoming_data, 0, graphMax, 0, 128);

И наконец, вам нужно подумать: сколько графиков вы можете реально отобразить за один раз?Установите максимум и создайте только столько структур в начале.Если вы используете глобальный буфер, как я предлагаю, вы можете повторно использовать struct несколько раз (без необходимости использовать new/delete).Просто измените поля start_index и end_index.

Не уверен, поможет ли что-нибудь из этого, но, возможно, вы сможете извлечь из него некоторые идеи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...