использование строк в проекте и его размер

Тема в разделе "Arduino & Shields", создана пользователем gonzales, 6 авг 2018.

  1. SergeiL

    SergeiL Оракул Модератор

    Ну я так обычно и делаю. Но для Ардуино с сетупами и лупами.;)
     
  2. gonzales

    gonzales Гик

    Ничего себе тема разрослась)))
    По оптимизации удалось избавиться от float, освободилось 20% памяти. А вот перейти на char* вместо строк не получается((

    Написал простенький код для проверки, но ничего в сериал не выводит
    Код (C++):
    void setup() {
      // put your setup code here, to run once:
    Serial.begin(9600);
    byte z = 23;
    byte ost = 7;
    SendTempToNextionString(z, ost);
    }

    void loop() {
      // put your main code here, to run repeatedly:

    }

    void SendTempToNextionString(byte zeloe, byte ostatok) {
      char* c;
      if (zeloe >= 10) {
        c = StringPlus("page0.input.txt=", (char)zeloe);  
      }
      else {
        c = StringPlus("page0.input.txt=\"0", (char)zeloe);
      }
      c = StringPlus(c, ".");
      c = StringPlus(c, (char)ostatok);
      c = StringPlus(c, "\"");
      SendToNextionString(c);
    }

    char* StringPlus(char* str, char* new_str){
      char* slovo = new char[strlen(str) + strlen(new_str) + 1];
      strcat(slovo, str);
      strcat(slovo, new_str);
      return slovo;
    }

    char ByteToChar(byte byteSt, byte num)
    {
      const byte offset = 48;
     
      if (num==1) return char(offset+byteSt/10);
      if (num==2) return char(offset+byteSt-byteSt/10*10);
    }


    void SendToNextionString(char* s) {
      Serial.println(s);
    }
    Подскажите, что не так
     
  3. b707

    b707 Гуру

    зачем же так сложно-то... ужас какой

    Код (C++):


    void SendTempToNextionString(byte zeloe, byte ostatok) {
      char c[5];
      sprintf(c,"%d.%d",zeloe,ostatok);
      Serial.println(c);
    }
    добавка - если строка с будет использоваться "снаружи" функции SendTempToNextionString. она должна быть глобальной
     
    parovoZZ нравится это.
  4. SergeiL

    SergeiL Оракул Модератор

    sprintf тоже килобайта полтора притащит.:)
     
    gonzales нравится это.
  5. b707

    b707 Гуру

    точно? :) надо будет проверить...
    Ну. в принципе, написать через itoa тоже не проблема. если только itoa не тащит ту же библиотеку :)
    Иначе - вручную...
     
    SergeiL нравится это.
  6. SergeiL

    SergeiL Оракул Модератор

    Не, itoa не тянет ничего, она компактная.;)
    Я в свое время, когда в мегу8 не влезал, долго пытался оптимизироваться... Еще до ардуино,
    Потом мегу32 поставил, и все влезло, и с sprintf-ами.
     
  7. DIYMan

    DIYMan Guest

    Усложняешь. Смотри: в UART можно частями слать, в случае с Nextion признак окончания пакета - три байта 0xFF подряд. Т.е. пишешь просто:
    Код (C++):
    void Send(Stream& s, const char* data)
    {
        s.print(data);
    }

    void Send(Stream& s, byte data)
    {
        char buff[10] = {0};
        itos(data,buff,10);
     
        s.print(buff);
    }

    void setup()
    {
        Serial.begin(9600);
     
        // посылаем пакет в Nextion
        Send(Serial, "page0.input.txt=\"");  
        Send(Serial,22);  
        Send(Serial,"\"");
     
        for(byte i=0;i<3;i++)
            Serial.write(0xFF);
     
        // по итогу в UART ушла строка page0.input.txt="22" - завершающаяся тремя байтами 0xFF подряд
    }
    Навскидку так. Но! Строки в этом примере торчат в оперативе, а не в PROGMEM. Чтобы из PROGMEM читать - надо ещё чуть секаса сделать.
     
  8. parovoZZ

    parovoZZ Гуру

    Правильно__)) Поэтому цифры и надо выводить как цифры, а не символы. А строки заменить на идентификаторы.
     
  9. gonzales

    gonzales Гик

    sprintf - очень емкий, со строками дешевле работать))
    Да, уже так и сделал. Тоже пришла такая же мысль в голову.
     
  10. gonzales

    gonzales Гик

    Спрошу еще раз, может кто знает из присутствующих, есть ли какие-нить ключи для оптимизации бинарника в Ардуино IDE
     
  11. b707

    b707 Гуру

    Ардуино ИДЕ - не более чем настройка над GCC. Соответсвенно. там есть практически все режимы оптимизации. доступные в GCC
     
    Igor68 нравится это.
  12. parovoZZ

    parovoZZ Гуру

  13. DIYMan

    DIYMan Guest

    Строго говоря, в приведённом мной примере itoa юзать совершенно необязательно: Stream.print делает то же самое, т.е. пример можно сократить до:

    Код (C++):
    void Send(Stream& s, const char* data)
    {
        s.print(data);
    }

    void Send(Stream& s, byte data)
    {
        s.print(data);
    }

    void setup()
    {
        Serial.begin(9600);
     
        // посылаем пакет в Nextion
        Send(Serial, "page0.input.txt=\"");
        Send(Serial,22);
        Send(Serial,"\"");
     
        for(byte i=0;i<3;i++)
            Serial.write(0xFF);
     
        // по итогу в UART ушла строка page0.input.txt="22" - завершающаяся тремя байтами 0xFF подряд
    }
    А ещё лучше - отдать компилятору разруливание:

    Код (C++):
    template <typename T> inline Stream& operator << (Stream &s, T n) { s.print(n); return s; }

    void setup()
    {
        Serial.begin(9600);

        // посылаем пакет в Nextion
        Serial << "page0.input.txt=\"" << 22 << "\"";

        for(byte i=0;i<3;i++)
            Serial.write(0xFF);

        // по итогу в UART ушла строка page0.input.txt="22" - завершающаяся тремя байтами 0xFF подряд
    }
     
     
    SergeiL и ИгорьК нравится это.