Arduino Как я могу использовать char вместо String (для лучшего использования памяти) - PullRequest
0 голосов
/ 14 апреля 2020

Я тысячи раз читал, что библиотека String - не лучшее решение для оптимизации кода и памяти. Поэтому мне нужно использовать char вместо String. У меня есть несколько функций, которые возвращают строку, где я использую ее для хранения в файле (SD-карта) или публиковать в Интернете в качестве параметра. Итак, на следующем рисунке, как я могу изменить его для работы с символом. Я знаю, как сохранить в SD-файл или разместить на веб-сервере. Мне нужна только помощь для изменения строки на char.

#include <ThreeWire.h>  
#include <RtcDS1302.h>

ThreeWire myWire(7,8,6); // IO, SCLK, CE
RtcDS1302<ThreeWire> Rtc(myWire);

#define countof(a) (sizeof(a) / sizeof(a[0]))

String NowDateTime="";

void setup() {
    Serial.begin(9600);       // for debugging
    Rtc.Begin();
    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    if (!Rtc.IsDateTimeValid()) {
        Rtc.SetDateTime(compiled);
    }
    if (Rtc.GetIsWriteProtected()) {
        Rtc.SetIsWriteProtected(false);
    }
    if (!Rtc.GetIsRunning()) {
        Rtc.SetIsRunning(true);
    }
    RtcDateTime tempnow = Rtc.GetDateTime();
    if (tempnow < compiled) {
        Rtc.SetDateTime(compiled);
    }
    RtcDateTime now = Rtc.GetDateTime();
    NowDateTime = strDT(now);
    Serial.println((String)"RTC: "+NowDateTime);
}

void loop() {
    delay(1000);
    RtcDateTime now = Rtc.GetDateTime();
    NowDateTime = strDT(now); 
    Serial.println(NowDateTime);
}

//RETURN Datetime id Readeable format as stting
String strDT(const RtcDateTime& dt)
{
    char ret[30];
    snprintf_P(ret, 
            countof(ret),
            PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
            dt.Year(),
            dt.Month(),
            dt.Day(),
            dt.Hour(),
            dt.Minute(),
            dt.Second() );     
    return ret;
}

Заранее спасибо за вашу помощь !!!

Ответы [ 2 ]

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

Я знаю, что вы намерены понять, как использовать массив c вместо класса String, но в вашем коде легко избежать использования String и сохранять массив локальным внутри функции, чтобы сделать код простым и более надежный.

Вам не нужно возвращать строку, просто добавьте Serial.print в конец вашей функции.

void loop() {
  RtcDateTime now = Rtc.GetDateTime();
  printDateTime(now);
}

void printDateTime(const RtcDateTime& dt)
{
    char ret[20];
    snprintf_P(ret, 
        countof(ret),
        PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
        dt.Year(),
        dt.Month(),
        dt.Day(),
        dt.Hour(),
        dt.Minute(),
        dt.Second() 
    );
    Serial.println(ret);
}

Если вы действительно предпочитаете использовать функцию чтобы вернуть массив, содержащий отформатированную строку, вы можете объявить ret[20] как массив static внутри функции, чтобы значение массива не было освобождено после возврата из вызова функции.

void loop() {
  RtcDateTime now = Rtc.GetDateTime();
  Serial.println(strDT(now));
}

char* strDT(const RtcDateTime& dt)
{
    static char ret[20];    //local static variable
    snprintf_P(ret, 
        countof(ret),
        PSTR("%04u/%02u/%02u %02u:%02u:%02u"),
        dt.Year(),
        dt.Month(),
        dt.Day(),
        dt.Hour(),
        dt.Minute(),
        dt.Second() 
    );
    return ret;
}

Заметил, что тип возвращаемого значения из функции должен быть точкой ret (т.е. char*).

Обновлено

Класс Arduino String против cstring.h

Библиотека строк , которую вы видите в Arduino, не является частью C ++, она дает Arduino некоторые функции, такие как как python -подобная или Java -подобная конкатенация, такая как String myString = "This string " + this_var + " another string";, в которой используется динамическое c выделение памяти mallo c в динамической памяти. для новичков в Arduino это выглядит проще, однако это может привести к фрагментации кучи или утечке памяти, особенно если вы новичок в программировании и не совсем понимаете, как работает куча. Чтобы завершить замену использования класса Sting, лучше узнать, как использовать C ++ cstring.h функции для обработки строки.

0 голосов
/ 14 апреля 2020

Ваша функция strDT(const RtcDateTime& dt) возвращает символ *, а не строку, если вы не заставляете это делать.

(однако вы должны определить static char ret[30];)

...