printf LCD... и вопрос и ответ

Тема в разделе "Флудилка", создана пользователем Igor68, 17 ноя 2019.

  1. Igor68

    Igor68 Гуру

    Доброго времени суток!
    Это совсем не про ардуино. С выводом строки вопросов нет, он происходит по 4-х проводному интерфейсу. Проект в кейл. Примеyяется stdio.h... но только с костылями. А это напряг.
    Сначала то что для экрана (символьного) LCD выводилось с помощью sprintf в буфер, а уж из него через GPIO на экран. Проблема сразу в том, что функция LCD_Printf требует тип данных и было так:
    Код (C++):
    int LCD_Printf(char * frm, float par)
    А применял (а мест применения много):
    Код (C++):
    LCD_Printf("Float: %f", fpar); //для float
    LCD_Printf("Int: %i", (float)ipar); //для int
    Ну так далее.
    И вот напрягло это. И вот стал курить и накурил stdarg.h. Раньше мне это было до лампочки, а вот приспичило и (работа со списком пример для ARM7 на KEIL):
    gp_print.zip
    Данный пример только для формирования в буфере без вывода на экран. У меня не получилось передавать список( не умею). Но то что вышло:
    Код (C++):
    LCD_Printf(const char * fmt, ...)
    Теперь можно так:

    Код (C++):
    LCD_Printf("string:%s char:%c ", "testing", '2');
    LCD_Printf("int: %i %d", 1234, -4678);
    LCD_Printf("unsigned int: %u %u", 1234, 4678);
    LCD_Printf("hex: %x %X", 1234, 123);
    LCD_Printf("float:%.2f %f ", 3.1459, 3.1459);
    LCD_Printf("float:%e %E ", 3.1459, 3.1459);
    Как будто просто на PC.

    Вот и вопрос может кто-то применил более стандартный вариант?
    Кстати stdout не вышло у меня, а на тему нарывался.
    Вот и китайский вариант как другой пример (только библиотека без примеров применения):
    xprintf.zip
     

    Вложения:

    • gp_print.zip
      Размер файла:
      61,3 КБ
      Просмотров:
      459
    • xprintf.zip
      Размер файла:
      4,2 КБ
      Просмотров:
      393
    Последнее редактирование: 17 ноя 2019
  2. Tomasina

    Tomasina Сушитель лампочек Модератор

    Код (C++):
    LCD << F("Temp: ") << tSensor << F("°C ");

    Serial << F("Pump state: ") << pState << F("\tLED state: ") << ledState << F("\tTime: ") << timestamp(now) << endl;
    Библиотека streaming.h
     
  3. DetSimen

    DetSimen Guest

    я отак делаю
    Код (C++):
    int srlPutChar(char c, FILE *AStream) {
        if (c == '\r') srlPutChar('\n', AStream);
        Serial.print(c);
        return 0;
    }

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

        stdout = fdevopen(srlPutChar, NULL);
        puts("Program started...\n");
    .
    .
    }

    а потом как обычно

    printf_P((const char *)(F("Unknown message:  %X, LoParam = %d, HiParam = %d\n")), Msg.Message, Msg.LoParam, Msg.HiParam);

     
     
    Andrey12 и Asper Daffy нравится это.
  4. DetSimen

    DetSimen Guest

    вместо srlPutChar() напишы свою lcdPutChar() и сё.
     
  5. Igor68

    Igor68 Гуру

    Ключевое слово: Это совсем не про ардуино
    Важно: Не должно быть отличным (кроме имени функции) от stdio.h и т.п.
     
  6. DetSimen

    DetSimen Guest

    а, понятно. я не туда влез
     
  7. Igor68

    Igor68 Гуру

    У меня не вышло подменить FILE *. Тут были примеры с GCC, там было возможно. Только вот у меня весь проект на KEIL uVision4 с компилятором по умолчанию.
    Попробую ещё, но утром.
    сейчас можно так:
    Код (C++):
    LCD_Printf("string:%s char:%c int: %i %d unsigned int:%u %u hex: %x %X float:%.2f %f  float exp:%e %E\n", "testing", '2', 1234, -4678 , 1234, 4678 , 1234, 123, 3.1459, 112.321, 9.1459/3.5, -3.1459*5.67);
    Хоть в одну строку. А если вставить '\t" то и табуляция. Короче всё, что позволяет sprintf(может какой тип упустил. Это только формирование самой строки в буфере без вывода на LCD. Всякие там "string, char, float и т.п." это просто слова, которые будут выведены в буфер вместе с парамерами в соответствующем порядке... хватило бы размера буфера. Выражения так же вставляются как и в printf, который я попытался повторить(построен на основе sprintf)... с анализом списка параметров разного типа. Надеюсь, что кто-нибудь подскажет как передавать список. Тут вот это "..." собственно список. Мне надо построить так:
    Код (C++):
    int LCD_Printf(const char * frm, ...)
    {
      char outbuf[128]; //буфер для вывода на LCD
      int size;
      int cnt = 0;
      //список: ....
      //в следующую ф-ю:
      size = sprintf(&outbuf[0], frm, <тут список ...>);
      //
      whilr(cnt < size)
    {
        //тут механизм вывода на LCD
        cnt++;
    }
    return cnt;
    }
    Сам список содержит данные разных типов через запятую. Функция sprintf в состоянии сама обработать список исходя из frm, где содердится и текст и указатели типа "%". Сейчас я обрабатываю весь список(по "%" определяю тип и вывожу все, что не тип в буфер) и вызываю sprintf для каждого типа из списка
     
  8. Asper Daffy

    Asper Daffy Иксперд

    Последнее редактирование: 17 ноя 2019
  9. Igor68

    Igor68 Гуру

    Ключевое слово: Это совсем не про ардуино
    Важно: Не должно быть отличным (кроме имени функции) от stdio.h и т.п.
    Ключевое слово: Это совсем не про ардуино
    Важно: Не должно быть отличным (кроме имени функции) от stdio.h и т.п.

    Вы тут про "присобачить" не резвитесь хвост задравши!
    ведь сказано:
    В Ваших ссылках не увидел:
    Важно: Не должно быть отличным (кроме имени функции) от stdio.h и т.п.
    потому как:
    Код (C++):
    __inline char    LCD_PrintfPS(int *nd, char * strout, const char *strin)
    {
        char    sym;
        int        cnt = 0;
        while(1)
        {
            sym = *strin++;
            switch(sym)
            {
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                case '.':
                case '-':
                    *strout++ = sym;
                    cnt++;
                    break;
                case '\n':
                case '\r':
                case ' ':
                case 0:
                    *nd = ++cnt;
                    return sym;
                default:
                    *strout++ = sym;
                    *nd = ++cnt;
                    return sym;
            }
        }
    }
    int LCD_Printf(const char* fmt, ...)
    {
        int        cnt = 0;
        int     adrplus;
        char    sym;
        char    stype[8];
        va_list    arp;
        char str[128] = {0};
        va_start(arp, fmt);
        while(1)
        {
            sym = *fmt++;
            if(sym == '%')
            {
                memset(&stype[0], 0, 8);
                stype[0] = sym;
                sym = LCD_PrintfPS(&adrplus, &stype[1], fmt);
                fmt += adrplus;
                switch(sym)
                {
                    case 's':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, char *));
                        continue;
                    case 'c':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, int));
                        continue;
                    case 'i':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, int));
                        continue;
                    case 'd':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, int));
                        continue;
                    case 'u':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, unsigned int));
                        continue;
                    case 'x':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, unsigned int));
                        continue;
                    case 'X':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, unsigned int));
                        continue;
                    case 'f':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, float));
                        continue;
                    case 'F':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, float));
                        continue;
                    case 'e':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, float));
                        continue;
                    case 'E':
                        cnt += sprintf(&str[cnt],&stype[0],va_arg(arp, float));
                        continue;
                    default:
                        break;
                }
            }
            else if(!(sym))
                goto m1;
            else
                str[cnt++] = sym;
        }
    m1:
        va_end(arp);
        return cnt;
    }


    int main(void)
    {
            LCD_Printf("string:%s char:%c ", "testing", '2');
            LCD_Printf("int: %i %d", 1234, -4678);
            LCD_Printf("unsigned int: %u %u", 1234, 4678);
            LCD_Printf("hex: %x %X", 1234, 123);
            LCD_Printf("float:%.2f %f ", 3.1459, 3.1459 * 2.5);
            LCD_Printf("float:%.e %E ", 3.1459, -3.1459/2.5);
            while(1); // это просто тесть, что бы не был выход из программы -дя отладки
        return 0;
    }
     

    только в начале объявлено:

    Код (C++):
    #include <stdio.h>
    #include <stdarg.h>
    Что есть и не arduino вовсе.
    Вы хоть к Деду(Коту) прислушивайтесь, коли остальное Вам не важно

    А на самом деле хотел инфу пр перкдачу списка из внешнего входа функции в вызываемую функцию из этой функции... только и всего.
     
    Последнее редактирование: 17 ноя 2019
  10. Asper Daffy

    Asper Daffy Иксперд

    У деда

    1) совсем не про ардуино - обще-С-шные дела
    2) нет НИКАКИХ отличий от stdio.h даже имя функции не отличается.

    Ты, правда этого не понял?
     
  11. Asper Daffy

    Asper Daffy Иксперд

    Так ты нам мозги пудрил? Тебе нужно было просто узнать как переменное количество аргументов передавать? А чего прямо не спросил? Я бы показал. А теперь, когда ты нас с дедом идиотами выставил, так даже как-то не хочется :(
     
  12. Igor68

    Igor68 Гуру

    Потому собственно и вопрос;
    - как применяя стандартное (stdin.h и др.), не прибегая к самодельному решать подобное
    - arduino не есть стандарт(общепринятый, а как только платформа для простого решения
    -идеал это не ардуино, а универсальные решения (хоть и не всегда) не взирая на разрядность архитектуры и т.п.
     
  13. Igor68

    Igor68 Гуру

    Простите пока не понял и не увидел.... (наверное виноват, но ведь там только диалоги и мало кода - курю)
     
  14. Igor68

    Igor68 Гуру

    А я разве не спросил???????????????? Именно в этом и вопрос! Простите ни Китайского и ни Индийского не знаю.
     
  15. Igor68

    Igor68 Гуру

    А деда оставь в покое и отвечай только за себя:mad:
     
  16. Igor68

    Igor68 Гуру

    вот уже и не знаю (раньше было не интересно) как сделать так):
    Код (C++):
    int func1(char * a, ...)
    {
       char * buf;
       func2(buf, a, ...);
      return 0;
    }
     
    где этот самый "..." есть список(сам я не знаю и не знаю как)
     
  17. Asper Daffy

    Asper Daffy Иксперд

    Нет. Ты сразы начал про LCD_Printf. Вот тебе про printf и отвечали. Спрсоил бы как передавать переменное количество аргументов. Был бы другой базар.
     
  18. Igor68

    Igor68 Гуру

    Прости брат, но у меня не получилоась с тем компилятором, что по умолчанию в KEIL uVison4 (rw) - там всё готово и надо изменить. А вот @Алексей.А уже показал красивость GCC, но (rw) этого не умеет. а так я бы подменил и putc и т.п.
     
  19. Igor68

    Igor68 Гуру

    Исходя из этого я придумаю и своё нестндартное. Тут нет решения. Неужели Вы думаете, что я этого не сделал, хоть и криво?
     
  20. DetSimen

    DetSimen Guest

    Ну, я примерно так и сказал. :)