Более эффективный код регистрации данных

Фон:

Я использую Teensy 3.6 для регистрации данных более дюжины датчиков. Я печатаю в Serial1 для локального последовательного доступа, Serial3 для удаленного доступа (через xbee, те же данные на Serial1, что и на Serail3, только другое физическое соединение), а также журнал данных на SDCard (формат CSV). Мой код расширяется и невероятно повторяется, и я ищу более эффективный способ написания следующего. Я пытаюсь перенести большую часть остального кода в классы, используя это и этот учебник, но я не уверен, что это лучший вариант для регистрации данных, поскольку есть в этой части еще много строк.

Переменные, с которыми мы имеем дело:

  • Текущие значения датчика (eOilTempF)
  • Визуальный флажок, если датчик выходит за пределы допустимого диапазона (checkEngine)
  • Звуковой сигнал, если он выходит за пределы допустимого диапазона (eOilTempAlarm)
  • Максимальное значение, которое мы записали (engineOilStats.maximum())
  • Минимальное значение (engineOilStats.minimum())

А также все мелочи, чтобы сделать его привлекательным и удобочитаемым для сериалов.

Код:

Местный сериал:

Serial.print("Engine Oil Temp:\t");
Serial.print(eOilTempF);
Serial.print("F\t   ");
Serial.print("Flag: ");
Serial.print(checkEngine);
Serial.print("\t Alarm:");
Serial.print(eOilTempAlarm);
Serial.print("\tMAX: ");
Serial.print(engineOilStats.maximum());
Serial.print(" F");
Serial.print("\t\t\t\tAVG: ");
Serial.print(engineOilStats.average());
Serial.println(" F");

Серийный номер Xbee:

Serial3.print("Engine Oil Temp:\t");
Serial3.print(eOilTempF);
Serial3.print("F\t   ");
Serial3.print("Flag: ");
Serial3.print(checkEngine);
Serial3.print("\t Alarm:");
Serial3.print(eOilTempAlarm);
Serial3.print("\tMAX: ");
Serial3.print(engineOilStats.maximum());
Serial3.print(" F");
Serial3.print("\t\t\t\tAVG: ");
Serial3.print(engineOilStats.average());
Serial3.println(" F");

Ведение журнала SD-карты:

logfile.print(eOilTempF);
logfile.print(",");
logfile.print(checkEngine);
logfile.print(",");
logfile.print(engineOilStats.maximum());
logfile.print(",");
logfile.print(engineOilStats.average());
logfile.print(",");

tl;др

Мой раздел регистрации данных скетча состоит из 567 строк в основном повторяющегося кода, и я новичок в программировании, и мне нужны некоторые учебные пособия/термины для Google, чтобы сделать его более эффективным.

, 👍1

Обсуждение

поместите два последовательных отпечатка и журнал данных в одну функцию... вызовите функцию для каждого регистрируемого параметра... используйте массив для текста... передайте **значение параметра** и **индекс в текст** к функции ... log(1, eOilTempF); ... 1 указывает на Температура моторного масла:\t, @jsotola

IIRC есть библиотека, которая позволяет вам использовать << с Serial. Я не могу вспомнить, как это называется, и мой гугл-фу недостаточно силен., @Majenko

упростить код, используя массив для хранения значений... e[ OilTempF ] вместо eOilTempF... таким образом вы можете перебирать значения в цикле, @jsotola

@Majenko Потоковое вещание может быть тем, о чем вы говорите: https://github.com/janelia-arduino/Streaming. Это очень помогло бы удалить все Serial.print и дополнительные строки, но это все равно будет дублировать код между Serial, Serial3 и Logfile., @TheAutomator

@TheAutomator Да, это он. Это, безусловно, сделало бы каждый блок меньше, и вы могли бы использовать его с классом-оболочкой, который отражает вывод на два последовательных устройства., @Majenko


1 ответ


1

Вы можете комбинировать библиотеку Streaming с классом-оболочкой, который отправляет данные в несколько последовательных пунктов назначения.

Вот небольшой пример:

#include <Streaming.h>

class DualSerial : public Print {
    private:
        Print *_dev1;
        Print *_dev2;

    public:
        DualSerial(Print &s1, Print &s2) : _dev1(&s1), _dev2(&s2) {}

        size_t write(uint8_t c) {
            _dev1->write(c);
            _dev2->write(c);
        }      
};

DualSerial remote(Serial, Serial3);

void setup() {
    Serial.begin(115200);
    Serial3.begin(115200);
}

void loop() {
    // И Serial, и Serial3 получат это
    remote << "The time is: " << millis() << endl;
    delay(1000);
}

Класс Streaming будет работать со всем, что наследуется от класса Print, включая класс File SD-карты, поэтому вы также можете использовать его для записи на SD-карту. карта:

logfile << eOilTempF << "," 
        << checkEngine << "," 
        << engineOilStats.maximum() << ","
        << engineOilStats.average() << endl;
,

Вам не нужно использовать указатели, например. DualSerial(Print & s1, Print & s2) : _dev1(s1), _dev2(s2) {} и измените переменные-члены на Print & _dev1; Печать & _dev2;. В функции записи измените -> на .. Вы можете инициализировать ссылку в конструкторе., @Nick Gammon

@NickGammon Я знаю. Но мне *нравится* использовать указатели., @Majenko