Считывание с SD карты и вывод на экран

Lictor
Offline
Зарегистрирован: 01.10.2015

Доброго времени суток.

У меня такая задача: считать слова из текстового файла с SD карты (список в строчку из 12 слов с пробелами, без знаков препинания) и вывести их на экран. Все бы ничего, но согласно библиотеки на экран можно выводить целые числа, с точкой и char*. Т.к. у меня слова, то мне нужно выводить char*. Напрямую считывать в массива такого типа не получается, компиллятор выдает ошибку. Поэтому читаю в массив типа int. но конвертировать в числа в буквы ASCII у меня не получается. Хотя цифры на экран выводятся корректные. Пробовал через функцию atoi не получилось. Подскжите, плиз, что делать.

 

пример кода:

#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h>  //подключение библиотек экрана и работы с SD для экрана

#include <SPI.h>
#include <SD.h> //работа с SD

File myFile;

int zamok[85];  //массив для считывания данных с SD
char* pol[85];   // массив для вывода на экран
int w,e, r = 0;  //переменные для перебора значений массива

extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];   //объявление встроенных шрифтов

UTFT myGLCD(R61581, 38, 39, 40, 41);  //инициализация экрана
UTFT_tinyFAT myFiles(&myGLCD);        //создание объекта экрана

void setup() {
   Serial.begin(115200); //запустим серийный порт
    SD.begin(53);        //активируем SD карту
  myGLCD.InitLCD(LANDSCAPE);  //ориентация экрана
  myGLCD.clrScr(); //очистка экрана
  file.initFAT();  
  
  myGLCD.setBackColor(0, 0, 0);  //цвет фона
  myGLCD.setColor(255, 255, 255); //цвет символов
  myGLCD.setFont(BigFont);    //выбранный размер и тип шрифта
  
   myFile = SD.open("zamok.txt"); //откроем файл
  if (myFile) {  //если открылся, то 
    byte q = 0;
    while (myFile.available()) {  //читаем, пока есть что читать
      zamok[q] = myFile.read();
      Serial.print(zamok[q]);
      Serial.print(" ");
      q++;
    }
    myFile.close();  //закроем файл
  }


  Serial.println("test");

  while (1) {
  //  itoa(zamok[w], pol[w], DEC);  //преобразуем числа в символы????
//myGLCD.print(pol[w], 2+32*e , 10+r );
  //  Serial.print(pol[w]);
  myGLCD.printNumI(zamok[w], 2+50*e , 10+r );
    Serial.print(zamok[w], DEC);
     Serial.print(" ");
     w++;
    e++;
    if (e == 6) {
      e = 0;
      r = r + 20;
    }
       if (w == 85) break;
  }

}

void loop() {
  }

 

negavoid
Offline
Зарегистрирован: 09.07.2016
Serial.print( char( zamok[w] ) );

 

Lictor
Offline
Зарегистрирован: 01.10.2015

Не... это я знаю. Я не могу вывести на экран дисплея

myGLCD.print(pol[w], 2+32*e , 10+r );

 

negavoid
Offline
Зарегистрирован: 09.07.2016

типа так?

myGLCD.print( char( zamok[w] ), 2+32*e , 10+r );

 

Lictor
Offline
Зарегистрирован: 01.10.2015

negavoid пишет:

типа так?

myGLCD.print( char( zamok[w] ), 2+32*e , 10+r );

 

типа так, но я же говорил, что это вызывает ошибку компиляции: 

SD.ino: In function 'void setup()':
SD.ino:50:54: error: invalid conversion from 'char' to 'char*' [-fpermissive]
In file included from SD.ino:2:0:
C:\Program Files (x86)\Arduino\libraries\UTFT/UTFT.h:215:8: error:   initializing argument 1 of 'void UTFT::print(char*, int, int, int)' [-fpermissive]
   void print(char *st, int x, int y, int deg=0);
        ^
Ошибка компиляции.

а вызов 

myGLCD.printNumI(char(zamok[w]), 2 + 75 * e , 10 + r );

хоть ошибку не вызывает, но выводит цифры и числа вместо символов.

 

Этоя уже пробовал. Мне кажется тут именно конвертация нужна.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Lictor пишет:

но конвертировать в числа в буквы ASCII у меня не получается. Хотя цифры на экран выводятся корректные. Пробовал через функцию atoi не получилось. 

atoi конвертирует символу в числа. Если Вам надо числа в символы, то используйте itoa

Lictor
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП пишет:

Lictor пишет:

но конвертировать в числа в буквы ASCII у меня не получается. Хотя цифры на экран выводятся корректные. Пробовал через функцию atoi не получилось. 

atoi конвертирует символу в числа. Если Вам надо числа в символы, то используйте itoa

Пардон, описАлся, itoa и использую (в первом посте в коде видно).

Lictor
Offline
Зарегистрирован: 01.10.2015

итоговый код такой, но на экран ничего не выводится

#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h>  //подключение библиотек экрана и работы с SD для экрана

#include <SPI.h>
#include <SD.h> //работа с SD

File myFile;

int zamok[85];  //массив для считывания данных с SD
char* pol[85];   // массив для вывода на экран
int w, e, r = 0; //переменные для перебора значений массива

extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];   //объявление встроенных шрифтов

UTFT myGLCD(R61581, 38, 39, 40, 41);  //инициализация экрана
UTFT_tinyFAT myFiles(&myGLCD);        //создание объекта экрана

void setup() {
  Serial.begin(115200); //запустим серийный порт
  SD.begin(53);        //активируем SD карту
  myGLCD.InitLCD(LANDSCAPE);  //ориентация экрана
  myGLCD.clrScr(); //очистка экрана
  file.initFAT();

  myGLCD.setBackColor(0, 0, 0);  //цвет фона
  myGLCD.setColor(255, 255, 255); //цвет символов
  myGLCD.setFont(BigFont);    //выбранный размер и тип шрифта

  myFile = SD.open("zamok.txt"); //откроем файл
  if (myFile) {  //если открылся, то
    byte q = 0;
    while (myFile.available()) {  //читаем, пока есть что читать
      zamok[q] = myFile.read();
      Serial.print(zamok[q]);
      Serial.print(" ");
      q++;
    }
    myFile.close();  //закроем файл
  }

  Serial.println("test");

  while (1) {
      itoa(zamok[w], pol[w], DEC);  //преобразуем числа в символы????
    myGLCD.print(pol[w], 2 + 75 * e , 10 + r );
//    Serial.print(char(zamok[w]));
    w++;
    e++;
    if (e == 6) {
      e = 0;
      r = r + 20;
    }
    if (w == 85) break;
  }
}

void loop() {
}

 

negavoid
Offline
Зарегистрирован: 09.07.2016

Да не нужен этот второй массив pol )) ох уж эта glcd :) я с ней никогда не работал, но у меня ещё много весёлых идей:

myGLCD.print( (char) zamok[w], 2+32*e , 10+r );

// или 

myGLCD.print( (char*) zamok[w], 2+32*e , 10+r );

 

Lictor
Offline
Зарегистрирован: 01.10.2015

negavoid пишет:

Да не нужен этот второй массив pol )) ох уж эта glcd :) я с ней никогда не работал, но у меня ещё много весёлых идей:

myGLCD.print( (char) zamok[w], 2+32*e , 10+r );

// или 

myGLCD.print( (char*) zamok[w], 2+32*e , 10+r );

 

 

Месье любит извращения? Я тоже. 

первый вариант разумеется не работает, т.к. не соответсвует тип переменной, второй выводит абракадабру. Уже лучше, но все еще плохо.

Logik
Offline
Зарегистрирован: 05.08.2014

агоспадзи..

itoa(zamok[w], pol, DEC);  //преобразуем числа в символы???? 

myGLCD.print(pol, 2 + 75 * e , 10 + r );

ПС. Мое пиво доверяю выпить Вам в день программиста

Lictor
Offline
Зарегистрирован: 01.10.2015

Logik пишет:

агоспадзи..

itoa(zamok[w], pol, DEC);  //преобразуем числа в символы???? 

myGLCD.print(pol, 2 + 75 * e , 10 + r );

ПС. Мое пиво доверяю выпить Вам в день программиста

Постараюсь оправдать Ваше доверие) Да только не работает. pol типа char*? Т.е. не массив, а просто переменная? Все равно не работает (сам по себе скетч рабочий, экран работает, надписи выводит). Проблема именно с itoa. После преобразования pol не получается даже в сериал порт вывести.

Lictor
Offline
Зарегистрирован: 01.10.2015

немного поменял код

#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h>  //подключение библиотек экрана и работы с SD для экрана

#include <SPI.h>
#include <SD.h> //работа с SD

File myFile;

int zamok[85];  //массив для считывания данных с SD
char* pol = {" "};   // массив для вывода на экран
int w, e, r = 0; //переменные для перебора значений массива

extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];   //объявление встроенных шрифтов

UTFT myGLCD(R61581, 38, 39, 40, 41);  //инициализация экрана
UTFT_tinyFAT myFiles(&myGLCD);        //создание объекта экрана

void setup() {
  Serial.begin(115200); //запустим серийный порт
  SD.begin(53);        //активируем SD карту
  myGLCD.InitLCD(LANDSCAPE);  //ориентация экрана
  myGLCD.clrScr(); //очистка экрана
  file.initFAT();

  myGLCD.setBackColor(60, 60, 60);  //цвет фона
  myGLCD.setColor(255, 255, 255); //цвет символов
  myGLCD.setFont(SmallFont);    //выбранный размер и тип шрифта

  myFile = SD.open("zamok.txt"); //откроем файл
  if (myFile) {  //если открылся, то
    byte q = 0;
    while (myFile.available()) {  //читаем, пока есть что читать
      zamok[q] = myFile.read();
      Serial.print(zamok[q]);
      Serial.print(" ");
      q++;
    }
    myFile.close();  //закроем файл
  }

  Serial.println("test");

  while (1) {
      itoa(zamok[w], pol, DEC);  //преобразуем числа в символы????
    myGLCD.print(pol, 2 + 75 * e , 10 + r );
   Serial.print(char(zamok[w]));
    w++;
    e++;
    if (e == 7) {
      e = 0;
      r = r + 20;
    }
    if (w == 85) break;
  }
}

void loop() {
}

изменил задание переменной на такое

char* pol = {" "};   // массив для вывода на экран

начало выводить на экран, но только цифры, а не буквы. Уже лучше.

Lictor
Offline
Зарегистрирован: 01.10.2015

Господа, ну может еще хоть какие-нибудь идеи?

пробовал таую конструкцию

#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h>  //подключение библиотек экрана и работы с SD для экрана

#include <SPI.h>
#include <SD.h> //работа с SD

File myFile;

int zamok[85];  //массив для считывания данных с SD
char* pol = {" "};   // массив для вывода на экран
int w, e, r = 0; //переменные для перебора значений массива
char* p[85] ={"q"};
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];   //объявление встроенных шрифтов

UTFT myGLCD(R61581, 38, 39, 40, 41);  //инициализация экрана
UTFT_tinyFAT myFiles(&myGLCD);        //создание объекта экрана

void setup() {
  Serial.begin(115200); //запустим серийный порт
  SD.begin(53);        //активируем SD карту
  myGLCD.InitLCD(LANDSCAPE);  //ориентация экрана
  myGLCD.clrScr(); //очистка экрана
  file.initFAT();

  myGLCD.setBackColor(60, 60, 60);  //цвет фона
  myGLCD.setColor(255, 255, 255); //цвет символов
  myGLCD.setFont(BigFont);    //выбранный размер и тип шрифта

  myFile = SD.open("zamok.txt"); //откроем файл
  if (myFile) {  //если открылся, то
    byte q = 0;
    while (myFile.available()) {  //читаем, пока есть что читать
      p[q] = (char*) myFile.read();
      Serial.print(zamok[q]);
      Serial.print(" ");
      q++;
    }
    myFile.close();  //закроем файл
  }
  
Serial.println();
  Serial.println("test");
  while (1) {
  myGLCD.print(p[w], 2 + 70 * e , 10 + r );
    w++;
    e++;
    if (e == 7) {
      e = 0;
      r = r + 20;
    }
    if (w == 85) break;
  }
}

void loop() {
}

На экранчик выдает какие-то артефакты, причем довольно рандомно.

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

Опишите p как массив символов.

Logik
Offline
Зарегистрирован: 05.08.2014

Lictor пишет:

 pol типа char*? Т.е. не массив, а просто переменная? 

pol  - массив char. 

 

Lictor
Offline
Зарегистрирован: 01.10.2015

Если описываю pol как массив char, тоя его не могу вывести на экран, т.к. можно выводить только char*

если написать такую строчку, то вообще ничего не выводится, или выводятся артефакты.

myGLCD.print( (char*) p[w], 2 + 70 * e , 10 + r );

Может сама идея порочна? И я выбрал не тот путь? По сути, мне нужно вывести слово из файла на SD карте на экран. Возможно есть способ без танцев с бубнами, точно ведь кто-то до меня это уже делал.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Lictor пишет:

Если описываю pol как массив char, тоя его не могу вывести на экран, т.к. можно выводить только char*

если написать такую строчку, то вообще ничего не выводится, или выводятся артефакты.

myGLCD.print( (char*) p[w], 2 + 70 * e , 10 + r );

Может сама идея порочна? И я выбрал не тот путь? По сути, мне нужно вывести слово из файла на SD карте на экран. Возможно есть способ без танцев с бубнами, точно ведь кто-то до меня это уже делал.

Массив char - это и есть char * (по большому - гамбургскому счёту)

Что до примера, Вы не написали как описан p. Как char p[N] ? Если так, то Вашу строчку нужно писать вот так

myGLCD.print( (char*) (& (p[0])), 2 + 70 * e , 10 + r );

 

Logik
Offline
Зарегистрирован: 05.08.2014

Ниче не порочно. Цитата из рабочего проекта

  char s[10];
  ltoa(CountOneWireDev,s,10);
  myOLED.drawString(7,3,s);

Если выдает ошибки - пишите их сюда.

Проблема в вашем уровне знаний С. Запись  (char*) p[w] - бред при обявлении char p[85], а при char* p[85] - просто нет обявления строки а есть неинициализированый массив указателей на символы.

 

Lictor
Offline
Зарегистрирован: 01.10.2015

ЕвгенийП, Logik, благодарю за помощь! ̶Ф̶и̶л̶о̶с̶о̶ф̶с̶к̶и̶й̶ ̶к̶а̶м̶е̶н̶ь̶  Рабочий код таки получен.

#include <tinyFAT.h>
#include <UTFT.h>
#include <UTFT_tinyFAT.h>  //подключение библиотек экрана и работы с SD для экрана

#include <SPI.h>
#include <SD.h> //работа с SD

File myFile;

byte zamok[85];  //массив для считывания данных с SD
char pol[3] = {"a"};   // массив для вывода на экран
int w, e, r = 0; //переменные для перебора значений массива

extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];   //объявление встроенных шрифтов

UTFT myGLCD(R61581, 38, 39, 40, 41);  //инициализация экрана
UTFT_tinyFAT myFiles(&myGLCD);        //создание объекта экрана

void setup() {
  Serial.begin(115200); //запустим серийный порт
  SD.begin(53);        //активируем SD карту
  myGLCD.InitLCD(LANDSCAPE);  //ориентация экрана
  myGLCD.clrScr(); //очистка экрана
  file.initFAT();

  myGLCD.setBackColor(60, 60, 60);  //цвет фона
  myGLCD.setColor(255, 255, 255); //цвет символов
  myGLCD.setFont(BigFont);    //выбранный размер и тип шрифта

  myFile = SD.open("zamok.txt"); //откроем файл
  if (myFile) {  //если открылся, то
    byte q = 0;
    while (myFile.available()) {  //читаем, пока есть что читать
      zamok[q] = myFile.read();
      Serial.print(zamok[q]);
      Serial.print(" ");
      q++;
    }
    myFile.close();  //закроем файл
  }

  Serial.println();
  Serial.println("test");

  while (1) {
    // itoa(zamok[w], pol[0], DEC);  //преобразуем числа в символы????
    pol[0] =char(zamok[w]);
      myGLCD.print((char*) (&(pol[0])), 2 + 70 * e , 10 + r );
    Serial.print(pol[0]);
    Serial.print("x");
    w++;
    e++;
    if (e == 7) {
      e = 0;
      r = r + 20;
    }
    if (w == 85) break;
  }
}

void loop() {
}

Осталось разобраться как ОНО работает.