Результат функции строка.

sadman41
Offline
Зарегистрирован: 19.10.2016

Чем strcpy_P не подходят в 03 и 04 строках?

AsNik
Offline
Зарегистрирован: 24.10.2020

sadman41 пишет:
Чем strcpy_P не подходят в 03 и 04 строках?

Да не то что не подходит. Просто я не знаю что это такое.... Сейчас поищу...

Яндекс-поиск по strcpy_P первым выдал страницу гайвера :) Боюсь уже туда заходить....

 

sadman41
Offline
Зарегистрирован: 19.10.2016

https://m.habr.com/ru/post/311874/
Например.
Или https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html - самый источниковый источник по библиотечным функциям С для AVR.

AsNik
Offline
Зарегистрирован: 24.10.2020

sadman41 пишет:
https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html - самый источниковый источник по библиотечным функциям С для AVR.

Ага вот тут и читаю.... первую ссылку тоже видел.

Правильно я понял, что нужно так return strcpy_P (_str, PSTR("Text"));?

Просто я уже боюсь лишний раз ардуину загружать.... Хоть она у меня специально для тестов и отладок, но... За последние пару дней ей тяжко пришлось)

sadman41
Offline
Зарегистрирован: 19.10.2016

Нет, не так и на Хабре написано почему это не будет работать.
У меня одна ардуина уже лет 5 трудится на ниве тестов и отладок, не жалуется.

PS, а с PSTR - правильно.

AsNik
Offline
Зарегистрирован: 24.10.2020

sadman41 пишет:
Нет, не так и на Хабре написано почему это не будет работать. У меня одна ардуина уже лет 5 трудится на ниве тестов и отладок, не жалуется. PS, а с PSTR - правильно.

Ясно. Но я тоже проверил и вроде работает:

char * myStr(const float x, char *_str) {
  const size_t len = strlen(dtostrf(x, 1, 1, _str));
  strcpy(_str + len, len <= 5 ? " C" : "C");
  return  strcpy_P (_str, PSTR("Text")); //_str;
}

void setup() {
  char str[7];
  float f = -99.89;
  Serial.begin(9600); while (!Serial);
  Serial.print(">"); Serial.print(myStr(f, str)); Serial.print("<");
}void loop() {
}

Результат:

>Text<

Не обращайте внимания данный код чисто для теста.

AsNik
Offline
Зарегистрирован: 24.10.2020

sadman41 пишет:
PS, а с PSTR - правильно.

Тогда как лучше и правильней: (char*) или strcpy_P ?

Или в моем случае (char*) - вообще не в тему? (Хоть и работает)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

AsNik пишет:

sadman41 пишет:
https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html - самый источниковый источник по библиотечным функциям С для AVR.

Ага вот тут и читаю.... первую ссылку тоже видел.

Правильно я понял, что нужно так return strcpy_P (_str, PSTR("Text"));?

Просто я уже боюсь лишний раз ардуину загружать.... Хоть она у меня специально для тестов и отладок, но... За последние пару дней ей тяжко пришлось)

Не бойся. У мня ардуина с 2014 года на отладке работает. Каждый день, в среднем, до 10 раз прошивается

AsNik
Offline
Зарегистрирован: 24.10.2020

Спасибо. Успокоили по поводу ардуины)

sadman41
Offline
Зарегистрирован: 19.10.2016

AsNik пишет:

sadman41 пишет:
PS, а с PSTR - правильно.

Тогда как лучше и правильней: (char*) или strcpy_P ?

Или в моем случае (char*) - вообще не в тему? (Хоть и работает)


Прямым возвратом строки я никогда не баловался и даже не возникало мысли об этом, поэтому не могу в деталях о последствиях рассказать.

С указателями все просто: звёздочка при объявлении переменной говорит, что это указатель. Далее - переменной можно присвоить адрес области памяти (само по себе объявление указателя память не резервирует), а по имени переменной, записанной с лидирующей звёздочкой, оперировать ее содержимым.

int a=32;
int * b=&a;
..print(*b);
*b = 45;
...print(*b);

Как-то так. С телефона сильно не попишешь.

AsNik
Offline
Зарегистрирован: 24.10.2020

Вернулся в данную тему с вопросом. Но увидев последнее сообщение.

sadman41 пишет:

int a=32;
int * b=&a;
..print(*b);
*b = 45;
...print(*b);

Прокрутив это в голове не проверяя результат выполнения, сделал вывод, что если последней строчкой вывести ...print(а); - выведет 45. Верно? (Хотя подозреваю, что в #60 sadman41 последней строчкой и хотел написать ...print(а);) Сейчас проверю себя) Ок. А вопрос вот в чем.

Можно ли как-то малой кровью имея вот такой код:

char * myStr(const float x, bool _isT, bool _isCur, char *_str) {
  if (_isCur && dhts[idDHT].f_DHTError) {
    if (_isT) return strcpy_P (_str, PSTR("TErr  "));
    else return strcpy_P (_str, PSTR("HErr  "));
  }
  if (isnan(x)) return strcpy_P (_str, PSTR("-nd-"));

  const size_t len = strlen(dtostrf(x, 1, 1, _str));
  if (_isT) strcpy(_str + len, len <= 5 ? " C" : "C");
  else strcpy(_str + len, len <= 5 ? " %" : "%");
  return _str;
}


вызываем:
....
          char str[9];
          lcd.setCursor(6, 2); lcd.print(myStr(dhts[idDHT].t, 1, 1, str));
...

сделать так, что когда пробел перед символом 'C' выводится, заменить его на знак градуса?

Малой кровью - это минимум изменений. Сам символ я создал и он у меня в char(0).

b707
Онлайн
Зарегистрирован: 26.05.2017

В строчку 9 вместо пробела вставьте свой символ да и все

AsNik
Offline
Зарегистрирован: 24.10.2020

Так в том и проблема, что в кодовой таблице LCD2004 нет этого символа градуса. Я его создал и загрузил lcd.createChar(0, gradus); Его вывод на экран lcd.print(char(0)); - т.е. тут даже не gradus...

А как совместить в одной строке и "то" и "это" не знаю... Я уже подумываю, что малой кровью не получится(

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А откуда информация об отсутствии символа градуса в кодовой таблице?

AsNik
Offline
Зарегистрирован: 24.10.2020

Н-да.... Пересмотрел много картинок с кодовыми таблицами этих дисплеев... не видел там этого градуса

но после #64

сделал

void loop() {
  // put your main code here, to run repeatedly:
  for (int n = 0; n < 256; n++) {
    lcd.setCursor(0, 0);
    lcd.write(n);
    lcd.setCursor(0, 1);
    lcd.print(n); lcd.print(" ");
    delay(50);
  }
  lcd.setCursor(8, 2);
  lcd.write(8); lcd.print("C");  
}

Так, теперь нужно как-то 0x08 вставить вместо пробела (не в этом коде, а выше в моей myStr).... Буду думать

sadman41
Offline
Зарегистрирован: 19.10.2016

Не знаю, зачем эти упражнения со строкой, но в строку символ по ASCII-коду вставляется как-то так: "\x08 Other text".

AsNik
Offline
Зарегистрирован: 24.10.2020

Т.е. это было бы так:

char * myStr(const float x, bool _isT, bool _isCur, char *_str) {
  if (_isCur && dhts[idDHT].f_DHTError) {
    if (_isT) return strcpy_P (_str, PSTR("TErr  "));
    else return strcpy_P (_str, PSTR("HErr  "));
  }
  if (isnan(x)) return strcpy_P (_str, PSTR("-nd-"));

  const size_t len = strlen(dtostrf(x, 1, 1, _str));
  if (_isT) strcpy(_str + len, len <= 5 ? "\x08C" : "C");   // < 0x08
  else strcpy(_str + len, len <= 5 ? " %" : "%");
  return _str;
}

Если бы не..... В общем не знаю как он(градус) там (в 0x08)оказался (сам я не под градусом если что:)) Но после перезагрузки по питанию LCD этот градус оттуда исчез..... И получается нет в моем LCD градуса :(

sadman41
Offline
Зарегистрирован: 19.10.2016

Что же тут удивительного? Все пользовательские символы формируются в RAM контроллера дисплея. А RAM - это не ROM и не EEPROM.

sadman41
Offline
Зарегистрирован: 19.10.2016

https://www.letscontrolit.com/forum/viewtopic.php?t=2368 в конце, на последней строке таблицы вполне себе "градусный" квадратик.

AsNik
Offline
Зарегистрирован: 24.10.2020

sadman41 пишет:
Что же тут удивительного?

Удивительно то, что свой градус я создавал в (0)

И код, который я выше для просмотра символов в LCD показывал первым (нулевым) символом именно градус. Я и подумал, что это мой созданный, но потом когда на очередном шаге показался еще один градус, я и грешным делом решил, что он все таки присутствует в таблице моего LCD....

А по ссылке - этот квадратик я видел.... Да ну... не красив) Вот был бы он хотя бы к правому краю прижат еще куда не шло.... Лучше, уж, если ничего не придумаю, без него пусть будет) (в смысле как сейчас - пробел)