TFT 3,5" и Ардуино

diger67
Offline
Зарегистрирован: 25.07.2015

Yarik.Yar пишет:
Полное заполнение экрана цветом -около 0.2 сек, наверное...это с прескалером 2. Для 8080 нужен FSMC, а я с ним только начинаю)

С FSMC меньше гемороя с управлением, но можно и в режиме ногодрыгы. Одно могу сказать с уверенностью. Главное грамотно описать функции чтения и записи, а функции обработки графики одинаковы для любого протокола обмена.

diger67
Offline
Зарегистрирован: 25.07.2015

thor_nsk пишет:

Не могу найти таблицу регистров в даташите :( Ткните носом , пожалуйста.

Попробуйте почитать раздел Z-inversion Odd/Even Gate data input method в даташите. есть подазрение что неправильная цветопередача может связана с этим. Очевидно задать RGB или BGR можно в регистре 0х36 бит D3. Еще вопрос, когда вы заливаете экран чистым синим, красным, зеленым цветом. цвета соответствуют?

http://178.130.34.198/lcd_pdf/ILI9486AN_V0.6.pdf

thor_nsk
Offline
Зарегистрирован: 30.01.2016

Из регистров получаю вот что - LCD driver chip: 6060
Поигравшись с командами инициализации я все-таки смог победить дисплей :) Пришлось еще повозиться с зеркалированием.
Сейчас цвет правильный и ориентация картинки тоже. В даташите ошибки. Команда выключающая инверсию на самом деле ее включает и наоборот. Вот моя инициализация дисплея:



static const uint8_t ILI9486_regValues[] PROGMEM = {
	HX8357_SWRESET, 0,
	0x11,  0,
	TFTLCD_DELAY, 100,
	0xF2,  9, 0x1C, 0xA3, 0x32, 0x02, 0xB2, 0x12, 0xFF, 0x12, 0x00,
	0xF1,  2, 0x36, 0xA4,
	0xF8,  2, 0x21, 0x04,
	0xF9,  2, 0x00, 0x08,
	0xC0,  2, 0x0D, 0x0D,
	0xC1,  2, 0x43, 0x00,
	0xC2,  1, 0x00,
	0xC5,  2, 0x00, 0x48,
	0xB6,  3, 0x00, 0x22, 0x3B,
	0xE0, 15, 0x0F, 0x24, 0x1C, 0x0A, 0x0F, 0x08, 0x43, 0x88, 0x32, 0x0F, 0x10, 0x06, 0x0F, 0x07, 0x00,
	0xE1, 15, 0x0F, 0x38, 0x30, 0x09, 0x0F, 0x0F, 0x4E, 0x77, 0x3C, 0x07, 0x10, 0x05, 0x23, 0x1B, 0x00,
	0x21,  0,
	0x36,  1, 0x08,
	0x3A,  1, 0x55,
	0x2A,  4, 0x00, 0x00, 0x01, 0xDF,
	0x2B,  4, 0x00, 0x00, 0x01, 0x3F,
	TFTLCD_DELAY, 100,
	0x29,  0,
	0x2C,  0,
};

Осталось еще побороть одну проблемку. После вызова функции setRotation с любым параметром экран становится "зеркальным". Например до вызова функции координата 0,0 была в левом верхнем углу, а после вызова уже в правом верхнем и никак обратно ее не вернуть. Видимо надо корячить эту функцию. Она с битами параметров команды 0x36 работает. Пока починить не смог.

void Adafruit_TFTLCD::setRotation(uint8_t x) {
  // Call parent rotation func first -- sets up rotation flags, etc.
  Adafruit_GFX::setRotation(x); // эта функция просто меняет местами значения _width и _height
  // Then perform hardware-specific rotation operations...
  CS_ACTIVE;
 if (driver == ID_ILI9486)  { 
   // MEME, HX8357D uses same registers as 9341 but different values
   uint16_t t;
   switch (rotation) {
   case 2:
     t = ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR;
     break;
   case 3:
     t = ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR;
     break;
  case 0:
    t = ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR;
    break;
   case 1:
     t = ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR;
     break;
  }
   writeRegister8(ILI9341_MADCTL, t); // MADCTL
   // For 9341, init default full-screen address window:
   setAddrWindow(0, 0, _width - 1, _height - 1); // CS_IDLE happens here
  }
}

 

diger67
Offline
Зарегистрирован: 25.07.2015

Можно попробовать инвертировать значения MX и MY.

thor_nsk
Offline
Зарегистрирован: 30.01.2016

Нет, там оказалось все несколько сложнее. Вроде победил "крутилку":

   switch (rotation) {
   case 2:
     t = ILI9341_MADCTL_MH | ILI9341_MADCTL_ML | ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR;
     break;
   case 3:
     t = ILI9341_MADCTL_ML | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR;
     break;
  case 0:
    t = ILI9341_MADCTL_BGR;
    break;
   case 1:
     t = ILI9341_MADCTL_MX | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR;
     break;
  }

 

diger67
Offline
Зарегистрирован: 25.07.2015

thor_nsk пишет:

Нет, там оказалось все несколько сложнее. Вроде победил "крутилку":

   switch (rotation) {
   case 2:
     t = ILI9341_MADCTL_MH | ILI9341_MADCTL_ML | ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR;
     break;
   case 3:
     t = ILI9341_MADCTL_ML | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR;
     break;
  case 0:
    t = ILI9341_MADCTL_BGR;
    break;
   case 1:
     t = ILI9341_MADCTL_MX | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR;
     break;
  }

 

Радует. Впрочем вам проще имея на руках индикатор. Впрочем мыслили в одном направлении.

thor_nsk
Offline
Зарегистрирован: 30.01.2016

diger67 пишет:
Впрочем мыслили в одном направлении.

Это да :)

Спасибо за поддержку и советы.

diger67
Offline
Зарегистрирован: 25.07.2015

Поковырял интернет, нашел вот такую инициализацию ili9486.


  LCD_WR_REG(0xB0);
  LCD_WR_DATA(0x00);
  LCD_WR_REG(0x11);
  Delay(2000);


  LCD_WR_REG(0xB3);
  LCD_WR_DATA(0x02);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x00);


  LCD_WR_REG(0xC0);
  LCD_WR_DATA(0x10);//13
  LCD_WR_DATA(0x3B);//480
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x02);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x01);
  LCD_WR_DATA(0x00);//NW
  LCD_WR_DATA(0x43);


  LCD_WR_REG(0xC1);
  LCD_WR_DATA(0x10);//LCD_WR_DATA(0x08);
  LCD_WR_DATA(0x10);//LCD_WR_DATA(0x16);//CLOCK
  LCD_WR_DATA(0x08);
  LCD_WR_DATA(0x08);


  LCD_WR_REG(0xC4);
  LCD_WR_DATA(0x11);
  LCD_WR_DATA(0x07);
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x03);


  LCD_WR_REG(0xC6);
  LCD_WR_DATA(0x00);


  LCD_WR_REG(0xC8);//GAMMA
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x13);
  LCD_WR_DATA(0x5C);
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x07);
  LCD_WR_DATA(0x14);
  LCD_WR_DATA(0x08);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x21);
  LCD_WR_DATA(0x08);
  LCD_WR_DATA(0x14);
  LCD_WR_DATA(0x07);
  LCD_WR_DATA(0x53);
  LCD_WR_DATA(0x0C);
  LCD_WR_DATA(0x13);
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x21);
  LCD_WR_DATA(0x00);


  LCD_WR_REG(0x35);
  LCD_WR_DATA(0x00);


  LCD_WR_REG(0x36);  
  LCD_WR_DATA(0x08);


  LCD_WR_REG(0x3A);
  LCD_WR_DATA(0x55);


  LCD_WR_REG(0x44);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x01);


  LCD_WR_REG(0xB6);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x22);//0 GS SS SM ISC[3:0]
  LCD_WR_DATA(0x3B);


  LCD_WR_REG(0xD0);
  LCD_WR_DATA(0x07);
  LCD_WR_DATA(0x07);//VCI1
  LCD_WR_DATA(0x1D);//VRH


  LCD_WR_REG(0xD1);
  LCD_WR_DATA(0x00);
  LCD_WR_DATA(0x03);//VCM
  LCD_WR_DATA(0x00);//VDV


  LCD_WR_REG(0xD2);
  LCD_WR_DATA(0x03);
  LCD_WR_DATA(0x14);
  LCD_WR_DATA(0x04);


  LCD_WR_REG(0x29);
  Delay(2000);


  LCD_WR_REG(0xB4);
  LCD_WR_DATA(0x00);
  Delay(2000);
  LCD_WR_REG(0x2C);

 

И еще, меня сильно мучает вопрос, что это за регистры F1, F2, Fn... таких в даташите нет!!!

thor_nsk
Offline
Зарегистрирован: 30.01.2016

Исходную инициализацию я брал из библиотеки UTFT. К стати в ней эти регистры отмечены знаками вопросов ))) В даташите я их тоже не нашел. Решил их пока не трогать. Бдет время попробую без них запустить. Вот исходная инициализация из библиотеки:

	LCD_Write_COM(0x11);		// Sleep OUT
	delay(50);
 
	LCD_Write_COM(0xF2);		// ?????
	LCD_Write_DATA(0x1C);
	LCD_Write_DATA(0xA3);
	LCD_Write_DATA(0x32);
	LCD_Write_DATA(0x02);
	LCD_Write_DATA(0xb2);
	LCD_Write_DATA(0x12);
	LCD_Write_DATA(0xFF);
	LCD_Write_DATA(0x12);
	LCD_Write_DATA(0x00);

	LCD_Write_COM(0xF1);		// ?????
	LCD_Write_DATA(0x36);
	LCD_Write_DATA(0xA4);

	LCD_Write_COM(0xF8);		// ?????
	LCD_Write_DATA(0x21);
	LCD_Write_DATA(0x04);

	LCD_Write_COM(0xF9);		// ?????
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x08);

	LCD_Write_COM(0xC0);		// Power Control 1
	LCD_Write_DATA(0x0d);
	LCD_Write_DATA(0x0d);

	LCD_Write_COM(0xC1);		// Power Control 2
	LCD_Write_DATA(0x43);
	LCD_Write_DATA(0x00);

	LCD_Write_COM(0xC2);		// Power Control 3
	LCD_Write_DATA(0x00);

	LCD_Write_COM(0xC5);		// VCOM Control
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x48);

	LCD_Write_COM(0xB6);		// Display Function Control
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x22);		// 0x42 = Rotate display 180 deg.
	LCD_Write_DATA(0x3B);

	LCD_Write_COM(0xE0);		// PGAMCTRL (Positive Gamma Control)
	LCD_Write_DATA(0x0f);
	LCD_Write_DATA(0x24);
	LCD_Write_DATA(0x1c);
	LCD_Write_DATA(0x0a);
	LCD_Write_DATA(0x0f);
	LCD_Write_DATA(0x08);
	LCD_Write_DATA(0x43);
	LCD_Write_DATA(0x88);
	LCD_Write_DATA(0x32);
	LCD_Write_DATA(0x0f);
	LCD_Write_DATA(0x10);
	LCD_Write_DATA(0x06);
	LCD_Write_DATA(0x0f);
	LCD_Write_DATA(0x07);
	LCD_Write_DATA(0x00);

	LCD_Write_COM(0xE1);		// NGAMCTRL (Negative Gamma Control)
	LCD_Write_DATA(0x0F);
	LCD_Write_DATA(0x38);
	LCD_Write_DATA(0x30);
	LCD_Write_DATA(0x09);
	LCD_Write_DATA(0x0f);
	LCD_Write_DATA(0x0f);
	LCD_Write_DATA(0x4e);
	LCD_Write_DATA(0x77);
	LCD_Write_DATA(0x3c);
	LCD_Write_DATA(0x07);
	LCD_Write_DATA(0x10);
	LCD_Write_DATA(0x05);
	LCD_Write_DATA(0x23);
	LCD_Write_DATA(0x1b);
	LCD_Write_DATA(0x00); 

	LCD_Write_COM(0x20);		// Display Inversion OFF
	LCD_Write_DATA(0x00);//C8 	 

	LCD_Write_COM(0x36);		// Memory Access Control
	LCD_Write_DATA(0x0A);

	LCD_Write_COM(0x3A);		// Interface Pixel Format
	LCD_Write_DATA(0x55); 

	LCD_Write_COM(0x2A);		// Column Addess Set
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x01);
	LCD_Write_DATA(0xDF);

	LCD_Write_COM(0x002B);		// Page Address Set
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x00);
	LCD_Write_DATA(0x01);
	LCD_Write_DATA(0x3f);	 
	delay(50);
	LCD_Write_COM(0x0029);		// Display ON
	LCD_Write_COM(0x002C);		// Memory Write

 

diger67
Offline
Зарегистрирован: 25.07.2015

И все же это не совсем ili9486. Если не получается прочитать по адресу 0xD3 идентификатор .

Вот нарыл может поможет.  http://178.130.34.198/adafruit/LCD_ID_Reader.zip

 

thor_nsk
Offline
Зарегистрирован: 30.01.2016

diger67, спасибо большое за то, что стараетесь помочь мне. Мне пока достаточно того, что получилось. Функцию инициализации подобрал. Пусть и не совсем соответствующую даташиту, но зато работающую :) Тач работает, кард-ридер тоже. Демка с рисованием с использованием тача работает. В общем я пока доволен.

P.S. Идентификатор прочитать получается, но он не 0x9486, а 0x6060.

Roman2344
Offline
Зарегистрирован: 09.09.2015

А кто - нибудь с таким дисплеем работал, как он вообще? http://aukro.ua/sensornyj-3-95-tft-shield-dlya-arduino-mega-i5899793090.html

Или подскажите нормальный дисплей 3,5-4 дюйма для ардуино мега.

diger67
Offline
Зарегистрирован: 25.07.2015

Roman2344 пишет:

А кто - нибудь с таким дисплеем работал, как он вообще? http://aukro.ua/sensornyj-3-95-tft-shield-dlya-arduino-mega-i5899793090.html

Или подскажите нормальный дисплей 3,5-4 дюйма для ардуино мега.

Зайдите на aliexspress наберите tft 3.5 arduino смотрите по списку. Конечно есть вероятность получить кота в мешке т.е. не тот чип на борту или косяк в самом шилде. Но все эти вопросы сдесь похоже обсосаны до нельзя. Потому как за последний месяц криков Help не слышно в теме. Если устроит шина 8bit с таким http://ru.aliexpress.com/item/Free-shipping-LCD-Display-Module-TFT-3-5-inch-TFT-LCD-screen-for-Arduino-UNO-R3/1995671772.html?spm=2114.14010208.99999999.327.iQeiLc

проблем у меня не было.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Вопрос такой а максимальный обьём микро СД для дисплея? А то куплю допустим микро СД на 4 или 8гиг, а картинкв не выведется.

thor_nsk
Offline
Зарегистрирован: 30.01.2016

Я со своим экраном использовал 8ГБ микро-СД или 8, или 10 класса. Все читается и выводится.

victorv
Offline
Зарегистрирован: 31.07.2015

Здравствуйте помогите разобраться :

дисплей с мегой

http://ru.aliexpress.com/item/MEGA-2560-ATmega2560-16AU-Board-For-Arduin...

 в скетче инициализация :

UTFT myGLCD(CTE40,38,39,40,41);

UTouch        myTouch(6, 5, 4, 3, 2);

бтблиотеки -

#include <UTFT.h>

#include <UTouch.h>
#include <UTFT_Buttons.h>
 

Проблема в таче- он работает только с одной стороны экрана . Добавил  #define TOUCH_ORIENTATION  PORTRAIT , все равно точно не попадает куда нажимаешь. Я где то давно видел в библиотеку добавляется , что то типа x=480 y=240  и тогда точно работает . Сам искал - ненашел .

 

 

 

 

Roman2344
Offline
Зарегистрирован: 09.09.2015

thor_nsk пишет:

Я со своим экраном использовал 8ГБ микро-СД или 8, или 10 класса. Все читается и выводится.

Спасибо.

Roman2344
Offline
Зарегистрирован: 09.09.2015
Не могу скомпилировать код в ардуино ИДЕ для вывода картинки с микро СД
Вот такой код пишу, а ардуино ошибку выбрасывает, что не так помогите пожалуйста.
#include <UTFT.h>
 
// создаём объект класса UTFT
// и передаём идентификатор модели дисплея и номера пинов
// к которым подключаются линии SCK, SDI (MOSI), D/C, RESET, CS
UTFT myGLCD(ILI9486,38,39,40,41);
 
// объявления встроенного шрифта
extern uint8_t BigFont[];
 
// объявления двух массив изображений
extern unsigned int amperka[0x400];
extern unsigned int raspberry[0x400];
 
void setup()
{
  // инициализируем дисплей с горизонтальной ориентацией
  myGLCD.InitLCD();
}
 
void loop()
{


    myGLCD.drawBitmap(20, 20, 32, 32, amperka);
 delay(5000);
 myGLCD.clrScr();

    myGLCD.drawBitmap(20, 20, 32, 32, raspberry);

 
  delay(5000);
 myGLCD.clrScr();
}





И такой:
#include <UTFT.h>

 #include <memorysaver.h>
// создаём объект класса UTFT
// и передаём идентификатор модели дисплея и номера пинов
// к которым подключаются линии SCK, SDI (MOSI), D/C, RESET, CS
#include <SPI.h>
#include <SD.h>
#define SD_CS  22//вывод CS, связанный с разъемом SD-карты.
 UTFT myGLCD(ILI9486,38,39,40,41);
// объявления встроенного шрифта
extern uint8_t BigFont[];
 extern unsigned short background[0x400];


 
void setup()
{
  // инициализируем дисплей с горизонтальной ориентацией
  myGLCD.InitLCD();
  myGLCD.clrScr();// очистка дисплея
}
 
void loop()
{
 myGLCD.drawBitmap (0,0, 240, 160, background,2);
   
  
}

 

 

thor_nsk
Offline
Зарегистрирован: 30.01.2016

А текст ошибки где?

Roman2344
Offline
Зарегистрирован: 09.09.2015
Вот: Arduino: 1.6.5 Hourly Build 2015/05/24 09:48 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
 
Изменена опция сборки, пересобираем все
 
Arduino: 1.6.5 Hourly Build 2015/05/24 09:48 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
 
Изменена опция сборки, пересобираем все
 
sketch_feb16d.cpp.o: In function `loop':
D:\Новая папка/sketch_feb16d.ino:25: undefined reference to `amperka'
D:\Новая папка/sketch_feb16d.ino:25: undefined reference to `amperka'
D:\Новая папка/sketch_feb16d.ino:29: undefined reference to `raspberry'
D:\Новая папка/sketch_feb16d.ino:29: undefined reference to `raspberry'
collect2.exe: error: ld returned 1 exit status
Ошибка компиляции.
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
 
Roman2344
Offline
Зарегистрирован: 09.09.2015

Вот ошибка на второй код

Arduino: 1.6.5 Hourly Build 2015/05/24 09:48 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
 
Изменена опция сборки, пересобираем все
 
sketch_feb16e.ino: In function 'void loop()':
sketch_feb16e:26: error: invalid conversion from 'short unsigned int*' to 'unsigned int*' [-fpermissive]
In file included from sketch_feb16e.ino:1:0:
D:\Новая папка\libraries\UTFT/UTFT.h:223:8: error:   initializing argument 5 of 'void UTFT::drawBitmap(int, int, int, int, unsigned int*, int)' [-fpermissive]
   void drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int scale=1);
        ^
invalid conversion from 'short unsigned int*' to 'unsigned int*' [-fpermissive]
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
diger67
Offline
Зарегистрирован: 25.07.2015

CD не является продолжением памяти программ контроллера. Так просто не получиться отразить файл. Ошибка говорит о том что имя файла неопределено, т.е. она не видит начальный адрес массива на который ссылается функция. Для вывода изображения с CD нужно использовать функцию чтения с CD. Во втором сучае неправельное преобразование из константы одного формата в другой. Единственный способ вывести изображение это конвертировать его в дамп пикселе, сохранить во флэшь памяти контроллера и вывести как массив.

Roman2344
Offline
Зарегистрирован: 09.09.2015

А так что не так?



#include <UTFT.h>
#include <SD.h>
#include <Wire.h>
 #include <SPI.h>
#define SD_CS 22
extern unsigned int ras[0x400];

 UTFT myGLCD(ILI9486,38,39,40,41);

 

 
void setup()
{
  myGLCD.InitLCD();
    myGLCD.clrScr();
 SD.begin(SD_CS);
      File inFile;
      inFile = SD.open("ras",FILE_READ);
       myGLCD.drawBitmap(20, 20, 20, 20,inFile);
}
 
void loop(){}

 

Примеры брал отсюда:http://wiki.amperka.ru/%D0%BF%D1%80%D0%BE%D0%B4%D1%83%D0%BA%D1%82%D1%8B:tft-lcd-240x320

И отсюда: http://blog.lincomatic.com/?p=1074

Вопрос такой мне нужно две картинки вывести одну в один момент времени вторую в другой, дисплей 3,95дюйма 480*320, ардуино Мега имеется, хотя как я понял лучше вывести одну картинку, если использовать память ардуины так как одна картинка займёт порядка 100кб? А если микро СД использовать можно несколько картинок вывести, меня интересует как проще вывести картинку? И как вывести картинку с памяти самой ардуины и с микро СД есть ли пример?

diger67
Offline
Зарегистрирован: 25.07.2015

Отвечу позже, надо по делам ....

Roman2344
Offline
Зарегистрирован: 09.09.2015

Спасибо.

diger67
Offline
Зарегистрирован: 25.07.2015

Значится так. Берем нужный файлы, преобразуем в *.bmp с нужным разрешением. Затем с помощью ImageConverter565 находящейся в папке tools библиотеки UTFT формируем массив, получаем файл типа myPicture.c. Далее можно использовать функцию  myGLCD.drawBitmap(). Как вариант можно использовать flash память 25qxxx. Эта память которая работает по SPI. Выделяем в озу буфер равный длинне H выводимой картинки. Считываем дамп из внешней flash в буфер из буфера выводим в TFT. Это несколько сложнее и медленнее но экономит памть программ микроконтроллера. С SD алгоритм примерно такойже. Выбор за вами.

slider
Offline
Зарегистрирован: 17.06.2014

Roman2344 пишет:

Не могу скомпилировать код в ардуино ИДЕ для вывода картинки с микро СД
 
extern unsigned int amperka[0x400];
extern unsigned int raspberry[0x400];

эт что за размеры? попробуйте просто unsigned int amperka[400]; , а потом усложняйте

и ещё, желательно компилить в той IDE , в которой она хорошо компилилась. Пробуйте версии 1.0 , 1.5.8

diger67
Offline
Зарегистрирован: 25.07.2015

Да все понятно. Extern говорит что переменная находится в другом *.c файле и является глобальной, unsigned int (uint16_t) беззнаковое два байта или пол слова, кому как нравится больше, далее тоже все понятно, название массива и его размер. Суть в том что человек хотел считать массив напрямую из CD, так как буд то он находтся во flash контроллера. А это возможно только через буферный массив. Если правильно описывать переменные и функции, соблюдать правила наследования, что архиважно в C++, то проек соберется в любой IDE. При условии что сами авторы IDE и GCC не накосячили.

smoki
Offline
Зарегистрирован: 24.10.2015
davoi-mail94
Offline
Зарегистрирован: 10.02.2016

У меня тоже такая проблема ...
Если найдешь решение пожалуйста сообши ... 

davoi-mail94
Offline
Зарегистрирован: 10.02.2016

У меня как то экран работает не полностью , и цифры тоже не на месте .

Исправил все что мог но все же .......
 

 

Roman2344
Offline
Зарегистрирован: 09.09.2015

Дисплей нормальный оказался, теперь вопросы, мне нужно допустим выводить показания с датчиков уровня бака, когда допустим заливаю жидкость в бак, сейчас я сделал очистку дисплея функцией myGLCD.clrScr(); через каждые 2с., есть три условия if(так как три датчика) и когда одно изменяется нужно выводить на дисплей другое слово и другой прямоугольник, поэтому вывод информации на дисплей каждые 2с. потом очистка дисплея и return, но при этом же получается для глаз не приятно так как мигание дисплея. Кто как выходит с этой ситуации?

 

davoi-mail94
Offline
Зарегистрирован: 10.02.2016

вообще то я  всего несколько дней начал изучать Arduino  , так что немогу помочь !!!
 

davoi-mail94
Offline
Зарегистрирован: 10.02.2016

У меня точно токой дисплей 3.95" LCD touch screen ili9488  с библиотекой Adafruit ,  плата -Mega2560 .
Использую его с промеров программы TFTpaint2 , хочу узменив программу получть HMI . 

 
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <TouchScreen.h>
 
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4
 
 
#define YP A1  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 7   // can be a digital pin
#define XP 6   // can be a digital pin
 
#define TS_MINX 150
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
 
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 
// Assign human-readable names to some common 16-bit color values:
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define ROZ     0xFBE0
#define GRI     0xBDF7
 
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);;
 
#define BOXSIZE 40
#define PENRADIUS 3
int oldcolor, currentcolor;
int ics;
 
void setup(void) {
#ifdef DEBUG
  Serial.begin(9600);
  Serial.println(F("Paint!"));
#endif //DEBUG
  tft.reset();
 
  uint16_t identifier = tft.readID();
 
if(identifier == 0x9325) {
#ifdef DEBUG
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if(identifier == 0x9328) {
 
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if(identifier == 0x7575) {
 
    Serial.println(F("Found HX8347G LCD driver"));
  } else if(identifier == 0x9341) {
 
    Serial.println(F("Found ILI9341 LCD driver"));
  } else if(identifier == 0x8357) {
 
    Serial.println(F("Found HX8357D LCD driver"));
#endif // DEBUG
    } else {
    #ifdef DEBUG
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.print(F("I try use ILI9341 LCD driver "));
    Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    #endif // DEBUG
    identifier = 0x9341;
  }
 
 
  tft.begin(identifier);
  tft.fillScreen(GREEN);
  tft.fillRect(0, 0, 480, 320, GREEN);
  tft.setRotation(3);
  tft.setCursor(100, 60);
  tft.setTextColor(RED);  tft.setTextSize(3);
  tft.println("HELLO");
  
 
delay(1500);
tft.fillRect(0, 0, 480, 320, BLACK);
 
tft.setRotation(0);
  
  tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
  tft.fillRect(0, BOXSIZE, BOXSIZE, BOXSIZE, YELLOW);
  tft.fillRect(0, BOXSIZE*2, BOXSIZE, BOXSIZE, GREEN);
  tft.fillRect(0, BOXSIZE*3, BOXSIZE, BOXSIZE, CYAN);
  tft.fillRect(0, BOXSIZE*4, BOXSIZE, BOXSIZE, BLUE);
  tft.fillRect(0, BOXSIZE*5, BOXSIZE, BOXSIZE, MAGENTA);
  tft.fillRect(0, BOXSIZE*6, BOXSIZE, BOXSIZE, GRI);
  tft.fillRect(0, BOXSIZE*7, BOXSIZE, BOXSIZE,  WHITE);
  
 
  currentcolor = RED;
 
 
 cifre (WHITE);
  pinMode(80, OUTPUT);
}
 
#define MINPRESSURE 0
#define MAXPRESSURE 1000
 
void loop()
{
  digitalWrite(40, HIGH);
  // Recently Point was renamed TSPoint in the TouchScreen library
  // If you are using an older version of the library, use the
  // commented definition instead.
  // Point p = ts.getPoint();
  TSPoint p = ts.getPoint();
  digitalWrite(40, LOW);
 
  // if sharing pins, you'll need to fix the directions of the touchscreen pins
  //pinMode(XP, OUTPUT);
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);
  //pinMode(YM, OUTPUT);
 
  // we have some minimum pressure we consider 'valid'
  // pressure of 0 means no pressing!
 
  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {
   
#ifdef DEBUG
    Serial.print(); Serial.print(p.x);
    Serial.print(); Serial.print(p.y);
    Serial.print(); Serial.println(p.z);
#endif // DEBUG
if (p.y < (TS_MINY-5)) stergere();
    // scale from 0->1023 to tft.width
    p.x = tft.width()-(map(p.x, TS_MINX, TS_MAXX, tft.width(), 0));
    p.y = tft.height()-(map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));
#ifdef DEBUG
    Serial.print("("); Serial.print(p.x);
    Serial.print(", "); Serial.print(p.y);
    Serial.println(")");
#endif // DEBUG
    if (p.x < BOXSIZE) {
       oldcolor = currentcolor;
 
       if (p.y < BOXSIZE) {
         currentcolor = RED;
         tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*2) {
         currentcolor = YELLOW;
         tft.drawRect(0, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*3) {
         currentcolor = GREEN;
         tft.drawRect(0, BOXSIZE*2, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*4) {
         currentcolor = CYAN;
         tft.drawRect(0, BOXSIZE*3, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*5) {
         currentcolor = BLUE;
         tft.drawRect(0, BOXSIZE*4, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*6) {
         currentcolor = MAGENTA;
         tft.drawRect(0,BOXSIZE*5, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*7) {
         currentcolor = GRI;
         tft.drawRect(0,BOXSIZE*6, BOXSIZE, BOXSIZE, WHITE);
//         text (currentcolor);
       } else if (p.y < BOXSIZE*8) {
         currentcolor = ROZ;
         tft.drawRect(0,BOXSIZE*7, BOXSIZE, BOXSIZE, WHITE);
         stergere();
       }
 
//text (currentcolor);
//cifre (currentcolor);
       if (oldcolor != currentcolor) {
          if (oldcolor == RED) tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
          if (oldcolor == YELLOW) tft.fillRect(0, BOXSIZE, BOXSIZE, BOXSIZE, YELLOW);
          if (oldcolor == GREEN) tft.fillRect(0, BOXSIZE*2, BOXSIZE, BOXSIZE, GREEN);
          if (oldcolor == CYAN) tft.fillRect(0, BOXSIZE*3, BOXSIZE, BOXSIZE, CYAN);
          if (oldcolor == BLUE) tft.fillRect(0, BOXSIZE*4, BOXSIZE, BOXSIZE, BLUE);
          if (oldcolor == MAGENTA) tft.fillRect(0, BOXSIZE*5, BOXSIZE, BOXSIZE, MAGENTA);
          if (oldcolor == GRI) tft.fillRect(0, BOXSIZE*6, BOXSIZE, BOXSIZE, GRI);
          if (oldcolor == ROZ) tft.fillRect(0, BOXSIZE*7, BOXSIZE, BOXSIZE, ROZ);
     cifre (currentcolor);
     }
 
    }
   // if (((p.y-PENRADIUS) > BOXSIZE) && ((p.y+PENRADIUS) < tft.height())) {
/*
if (((p.y-PENRADIUS) > 5) && ((p.y+PENRADIUS) < tft.height())) {
   tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
    }
*/
if (((p.x-PENRADIUS) > BOXSIZE) && ((p.x+PENRADIUS) < tft.width())) {
   tft.fillCircle(p.x, p.y, PENRADIUS, currentcolor);
    }
 
  }
}
 
void text (int culoare)
{
tft.setRotation(3);
 
          tft.setCursor(5, 220);
          tft.setTextSize(2);
          tft.println("BUHOSOFT");
tft.setRotation(0);
}
 
void cifre (int culoare)
{
// number for "buttons"
 tft.setRotation(3);
 tft.setTextColor(culoare);
 tft.setTextSize(3);
 tft.drawLine(0, 0, 40, 40, culoare);
 tft.drawLine(0, 40, 40, 0, culoare);
// tft.setCursor(15, 10);
// tft.println("1");
 tft.setCursor(170, 10);
 tft.println("0");
 tft.setCursor(210, 10);
 tft.println("1");
 tft.setCursor(250, 10);
 tft.println("2");
 tft.setCursor(290, 10);
 tft.println("3");
 tft.setCursor(330, 10);
 tft.println("4");
 tft.setCursor(370, 10);
 tft.println("5");
 tft.setCursor(410, 10);
 tft.println("6");
 tft.setCursor(450, 10);
 tft.println("7");
 
 tft.setRotation(0);
}
 
void stergere ()
{
    #ifdef DEBUG
      Serial.println("erase");
    #endif // DEBUG
      // press the bottom of the screen to erase
 //     tft.fillRect(0, BOXSIZE, tft.width(), tft.height()-BOXSIZE, BLACK);
   tft.fillRect(0, 0, 480, 320, BLACK);
   tft.setRotation(0);
  tft.fillRect(0, 0, BOXSIZE, BOXSIZE, RED);
  tft.fillRect(0, BOXSIZE, BOXSIZE, BOXSIZE, YELLOW);
  tft.fillRect(0, BOXSIZE*2, BOXSIZE, BOXSIZE, GREEN);
  tft.fillRect(0, BOXSIZE*3, BOXSIZE, BOXSIZE, CYAN);
  tft.fillRect(0, BOXSIZE*4, BOXSIZE, BOXSIZE, BLUE);
  tft.fillRect(0, BOXSIZE*5, BOXSIZE, BOXSIZE, MAGENTA);
  tft.fillRect(0, BOXSIZE*6, BOXSIZE, BOXSIZE, GRI);
  tft.fillRect(0, BOXSIZE*7, BOXSIZE, BOXSIZE,  ROZ);
//tft.fillRect(BOXSIZE, BOXSIZE, BOXSIZE, BOXSIZE, WHITE);
 
  tft.drawRect(0, 0, BOXSIZE, BOXSIZE, WHITE);
  currentcolor = RED;
     cifre (WHITE);
     
    }
 
Можно рисавать на всем экране но кагда хочу стирать не все исчезает  
 
 
 
 
 
 
 
 
 
Поможете исправить  ????????
Roman2344
Offline
Зарегистрирован: 09.09.2015

Вопрос такой хочу вывести квртину с микро СД, проконвертировав картинку в 200на125, загрузил её на микро СД, и написал такой скетч

#include <UTFT.h>



UTFT myGLCD(ILI9486, 38, 39, 40, 41);

extern uint8_t BigFont[];//переменная размера шрифта
extern uint8_t SmallFont[];


#include <SPI.h>
#include <SD.h>
#define SD_CS  53//вывод CS, связанный с разъемом SD-карты.
 unsigned int ras[25000];
void setup() {
  myGLCD.InitLCD();// инициализация LCD
  myGLCD.clrScr();// очистка дисплея


}

void loop() {
 
      File inFile;
      inFile = SD.open("ras",FILE_READ);

  myGLCD.drawBitmap(0, 0, 200, 125, ras, 2);

}

Переменная для картинку в десятиричной форме, при этом такая ошибка

Arduino: 1.6.5 Hourly Build 2015/05/24 09:48 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
 
Изменена опция сборки, пересобираем все
 
sketch_feb19a:15: error: size of array 'ras' is too large
sketch_feb19a.ino: In function 'void loop()':
sketch_feb19a:28: error: 'ras' was not declared in this scope
size of array 'ras' is too large
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
 
Делаю тоже самое только переменная для картинки в шестнадцатиричной форме
#include <SPI.h>
#include <SD.h>
#define SD_CS  53//вывод CS, связанный с разъемом SD-карты.
 unsigned int ras[0x61A8];
void setup() {
  myGLCD.InitLCD();// инициализация LCD
  myGLCD.clrScr();// очистка дисплея


}

void loop() {
 
      File inFile;
      inFile = SD.open("ras",FILE_READ);

  myGLCD.drawBitmap(0, 0, 200, 125, ras, 2);

}

 

Вот ошибка:

Arduino: 1.6.5 Hourly Build 2015/05/24 09:48 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
 
Изменена опция сборки, пересобираем все
 
sketch_feb19a:15: error: size of array 'ras' is too large
sketch_feb19a.ino: In function 'void loop()':
sketch_feb19a:28: error: 'ras' was not declared in this scope
size of array 'ras' is too large
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
Далее беру эту картинку и с помощью Image convertr делаю файл C., и в папку проекта бросаю, и пытаюсь с памяти процессора вывести и опять ошибки 
 
UTFT myGLCD(ILI9486, 38, 39, 40, 41);
 
extern uint8_t BigFont[];//переменная размера шрифта
extern uint8_t SmallFont[];
 
 
#include <SPI.h>
#include <SD.h>
#define SD_CS  53//вывод CS, связанный с разъемом SD-карты.
 extern unsigned int ras[
25000];
void setup() {
  myGLCD.InitLCD();// инициализация LCD
  myGLCD.clrScr();// очистка дисплея
 
 
}
 
void loop() {
 
  myGLCD.drawBitmap(0, 0, 200, 125, ras, 2);
 
}

Вот ошибка:

Arduino: 1.6.5 Hourly Build 2015/05/24 09:48 (Windows 7), Плата"Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"
 
Изменена опция сборки, пересобираем все
 
ras.c:16: error: size of array 'ras' is too large
 const unsigned short ras[25000] PROGMEM={
                      ^
size of array 'ras' is too large
 
  Это сообщение будет содержать больше информации чем
  "Отображать вывод во время компиляции"
  включено в Файл > Настройки
 
Ошибки связяны типа с превышением памяти но как так?
 
diger67
Offline
Зарегистрирован: 25.07.2015

Да что же вы все пытаетесь использовать SD как внешнюю flash с  SPI. Тогда уж и используйте что то типа 25w256. Тогда можно прямо из внешней памяти читать и сразу писать в tft. C SD такое не прокатывает. Сначала надо инициализировать SD, потом открыть файл, потом в созданый заранее буфер частями перетащить его с SD в память tft.

На борту у mega2560 всего 8192 байта. Следовательно когда вы создаете unsigned int ras[25000]; вы пытаетесь зарезервировать в RAM аж 50000 байт, как так, да вот так 50000 всегда больше 8192. Во втором случаи видимо массивы шрифтов и картинок в сумме с скомпелированным текстом программы превышают 256 килобайт flash памяти контроллера. Как то так. Для этого и придумали внешние устройства хранения.

Roman2344
Offline
Зарегистрирован: 09.09.2015

А есть тогда рабочий пример вывода картинки с микро СД?

diger67
Offline
Зарегистрирован: 25.07.2015

Все до боли просто. Заполняем экран приятным для глаза цветом. с помощью функций линия рисуем бак, наносим нужные поясняющие надписи. Это подготовка статической части экрана. Следующим шагом пишем IF-ы.

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

diger67
Offline
Зарегистрирован: 25.07.2015

Roman2344 пишет:

А есть тогда рабочий пример вывода картинки с микро СД?

Вот пример вывода изображения с SD для Adafruit. По аналогии можно понять как сделать для UTFT.


// This sketch has been Refurbished by BUHOSOFT
// BMP-loading example specifically for the TFTLCD breakout board.
// If using the Arduino shield, use the tftbmp_shield.pde sketch instead!
// If using an Arduino Mega make sure to use its hardware SPI pins, OR make
// sure the SD library is configured for 'soft' SPI in the file Sd2Card.h.
//No DEBUG Mode: Sketch uses 30.070 bytes (93%) of program storage space. Maximum is 32.256 bytes.
//DEBUG Mode: Sketch uses 31.046 bytes (96%) of program storage space. Maximum is 32.256 bytes.

#define DEBUG
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPI.h>
#include <SD.h>

// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// For Arduino Uno/Duemilanove, etc
//  connect the SD card with DI going to pin 11, DO going to pin 12 and SCK going to pin 13 (standard)
//  Then pin 10 goes to CS (or whatever you have set up)
#if defined __AVR_ATmega2560__
#define SD_SCK 13
#define SD_MISO 12
#define SD_MOSI 11

#endif
#define SD_CS 10     // Set the chip select line to whatever you use (10 doesnt conflict with the library)

// In the SD card, place 24 bit color BMP files (be sure they are 24-bit!)
// There are examples in the sketch folder

// our TFT wiring
Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);

void setup()
{
  tft.reset();
//this sketch force the  ILI9341 LCD driver chage the next code line to chage the driver
//0x9325  ILI9325 LCD driver
//0x9328  ILI9328 LCD driver
//0x7575  HX8347G LCD driver
//0x9341  ILI9341 LCD driver
//0x8357  HX8357D LCD driver
  tft.begin(0x9341);
  tft.setTextSize(2);
  tft.fillScreen(0);
  tft.setRotation(1);
  tft.println(F("Initializing SD card..."));
  #if defined __AVR_ATmega2560__
  if (!SD.begin(SD_CS, SD_MOSI, SD_MISO, SD_SCK )) {
    tft.println(F("failed!"));
    return;
  }
  #else
  if (!SD.begin(SD_CS)) {
    tft.println(F("failed!"));
    return;
  }
  #endif
  delay(500);

  bmpDraw("Test.bmp", 0, 0);

}

void loop()
{
    delay(2000);
    bmpDraw("arduinoW.bmp", 0, 0);
    delay(2000);
    bmpDraw("AUnoR3.bmp", 0, 0);
    delay(2000);
    bmpDraw("arduinoG.bmp", 0, 0);
    delay(1000);
#ifndef DEBUG
  for(int i = 0; i<4; i++) {
    delay(1000);
    tft.setRotation(i);
    tft.fillScreen(0);
    for(int j=0; j <= 200; j += 50) {
      bmpDraw("miniardu.bmp", j, j);
    }

  }
#endif
}

// This function opens a Windows Bitmap (BMP) file and
// displays it at the given coordinates.  It's sped up
// by reading many pixels worth of data at a time
// (rather than pixel by pixel).  Increasing the buffer
// size takes more of the Arduino's precious RAM but
// makes loading a little faster.  20 pixels seems a
// good balance.

#define BUFFPIXEL 20

void bmpDraw(char *filename, int x, int y) {

  File     bmpFile;
  int      bmpWidth, bmpHeight;   // W+H in pixels
  uint8_t  bmpDepth;              // Bit depth (currently must be 24)
  uint32_t bmpImageoffset;        // Start of image data in file
  uint32_t rowSize;               // Not always = bmpWidth; may have padding
  uint8_t  sdbuffer[3*BUFFPIXEL]; // pixel in buffer (R+G+B per pixel)
  uint16_t lcdbuffer[BUFFPIXEL];  // pixel out buffer (16-bit per pixel)
  uint8_t  buffidx = sizeof(sdbuffer); // Current position in sdbuffer
  boolean  goodBmp = false;       // Set to true on valid header parse
  boolean  flip    = true;        // BMP is stored bottom-to-top
  int      w, h, row, col;
  uint8_t  r, g, b;
  uint32_t pos = 0, startTime = millis();
  uint8_t  lcdidx = 0;
  boolean  first = true;

  if((x >= tft.width()) || (y >= tft.height())) return;

#ifdef DEBUG
  tft.fillScreen(0);
  tft.setCursor(0,0);
  tft.print(F("Loading image '"));
  tft.print(filename);
  tft.println('\'');
#endif
  // Open requested file on SD card
  if ((bmpFile = SD.open(filename)) == NULL) {
    #ifdef DEBUG
    tft.println(F("File not found"));
    #endif
    return;
  }

  // Parse BMP header
  if(read16(bmpFile) == 0x4D42) {
      // BMP signature
    #ifdef DEBUG
    tft.println(F("File size: ")); tft.println(read32(bmpFile));
    #else
        read32(bmpFile);
    #endif
    (void)read32(bmpFile); // Read & ignore creator bytes
    bmpImageoffset = read32(bmpFile); // Start of image data
    #ifdef DEBUG
    tft.print(F("Image Offset: ")); tft.println(bmpImageoffset, DEC);
    // Read DIB header
    tft.print(F("Header size: ")); tft.println(read32(bmpFile));
    #else
    read32(bmpFile);
    #endif

    bmpWidth  = read32(bmpFile);
    bmpHeight = read32(bmpFile);
    if(read16(bmpFile) == 1) { // # planes -- must be '1'
      bmpDepth = read16(bmpFile); // bits per pixel
      #ifdef DEBUG
      Serial.print(F("Bit Depth: ")); Serial.println(bmpDepth);
      #endif
      if((bmpDepth == 24) && (read32(bmpFile) == 0)) { // 0 = uncompressed

        goodBmp = true; // Supported BMP format -- proceed!
        #ifdef DEBUG
        tft.print(F("Image size: "));
        tft.print(bmpWidth);
        tft.print('x');
        tft.println(bmpHeight);
        delay(3000);
        #endif
        // BMP rows are padded (if needed) to 4-byte boundary
        rowSize = (bmpWidth * 3 + 3) & ~3;

        // If bmpHeight is negative, image is in top-down order.
        // This is not canon but has been observed in the wild.
        if(bmpHeight < 0) {
          bmpHeight = -bmpHeight;
          flip      = false;
        }

        // Crop area to be loaded
        w = bmpWidth;
        h = bmpHeight;
        if((x+w-1) >= tft.width())  w = tft.width()  - x;
        if((y+h-1) >= tft.height()) h = tft.height() - y;

        // Set TFT address window to clipped image bounds
        tft.setAddrWindow(x, y, x+w-1, y+h-1);

        for (row=0; row<h; row++) { // For each scanline...
          // Seek to start of scan line.  It might seem labor-
          // intensive to be doing this on every line, but this
          // method covers a lot of gritty details like cropping
          // and scanline padding.  Also, the seek only takes
          // place if the file position actually needs to change
          // (avoids a lot of cluster math in SD library).
          if(flip) // Bitmap is stored bottom-to-top order (normal BMP)
            pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
          else     // Bitmap is stored top-to-bottom
            pos = bmpImageoffset + row * rowSize;
          if(bmpFile.position() != pos) { // Need seek?
            bmpFile.seek(pos);
            buffidx = sizeof(sdbuffer); // Force buffer reload
          }

          for (col=0; col<w; col++) { // For each column...
            // Time to read more pixel data?
            if (buffidx >= sizeof(sdbuffer)) { // Indeed
              // Push LCD buffer to the display first
              if(lcdidx > 0) {
                tft.pushColors(lcdbuffer, lcdidx, first);
                lcdidx = 0;
                first  = false;
              }
              bmpFile.read(sdbuffer, sizeof(sdbuffer));
              buffidx = 0; // Set index to beginning
            }

            // Convert pixel from BMP to TFT format
            b = sdbuffer[buffidx++];
            g = sdbuffer[buffidx++];
            r = sdbuffer[buffidx++];
            lcdbuffer[lcdidx++] = tft.color565(r,g,b);
          } // end pixel
        } // end scanline
        // Write any remaining data to LCD
        if(lcdidx > 0) {
          tft.pushColors(lcdbuffer, lcdidx, first);
        }

      } // end goodBmp
    }
  }

  bmpFile.close();
  if(!goodBmp) tft.println(F("BMP format not recognized."));
}

// These read 16- and 32-bit types from the SD card file.
// BMP data is stored little-endian, Arduino is little-endian too.
// May need to reverse subscript order if porting elsewhere.

uint16_t read16(File f) {
  uint16_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read(); // MSB
  return result;
}

uint32_t read32(File f) {
  uint32_t result;
  ((uint8_t *)&result)[0] = f.read(); // LSB
  ((uint8_t *)&result)[1] = f.read();
  ((uint8_t *)&result)[2] = f.read();
  ((uint8_t *)&result)[3] = f.read(); // MSB
  return result;
}

 

Roman2344
Offline
Зарегистрирован: 09.09.2015

Сделал так, сконвертировал картинку 370*278, забросил на микро СД, и такой код с нета взял

#include <SPI.h>

#include <UTFT.h>
#include <SD.h>
#include <Wire.h>
 
#define SD_CS 53
 
UTFT myGLCD(ILI9486,38,39,40,41);
 
void dispRaw(UTFT *utft,File inFile)
{
  char VH,VL;
  int i,j = 0;
  cbi(utft->P_CS, utft->B_CS);
  for(i = 0; i < 370; i++)
    for(j = 0; j < 278; j++) {
    VL = inFile.read();
    VH = inFile.read();
    utft->LCD_Write_DATA(VL,VH);
      }
  sbi(utft->P_CS, utft->B_CS);
  utft->clrXY();
}
 
void setup()
{
  myGLCD.InitLCD();
 
}
 
void loop(){
   if (SD.begin(SD_CS))
    {
      char VH,VL;
      File inFile;
      inFile = SD.open("ras",FILE_READ);
      if (! inFile)
    {
      while (1);  //if file does not exsit, stop here.
    }
      dispRaw(&myGLCD,inFile);
      inFile.close();
    }
  }

И ничего не выводится.

diger67
Offline
Зарегистрирован: 25.07.2015

Вставте в код вывод в терминал:

void setup()
{
    myGLCD.InitLSD();
    Serial.begin(115200);
}




void dispRaw(UTFT *utft,File inFile) 
{ 
  char VH,VL; 
  int i,j = 0; 
  cbi(utft->P_CS, utft->B_CS); 
  for(i = 0; i < 370; i++) 
    for(j = 0; j < 278; j++) { 
    VL = inFile.read(); 
    Serial.Print(VL, HEX);
    VH = inFile.read(); 
    Serial.Print(VH, HEX);
    utft->LCD_Write_DATA(VL,VH); 
      } 
  sbi(utft->P_CS, utft->B_CS); 
  utft->clrXY(); 
} 

 

Убедитесь что SD_CS определен верно, чаще для MEGA 53 pin. Посмотрите что выводится в эти переменные. зная значения байт в массиве res и видя что выводится в эти переменные можно судить о правильности работы функции. Проще говоря выведенные значения в мониторе должны быть равны содержимому файла res.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Такой вод код набросал, а в мониторе последовательного порта вообще ничего(и скоростя уменьшал)

#include <SPI.h>

#include <UTFT.h>
#include <SD.h>
#include <Wire.h>
 
#define SD_CS 53
 
UTFT myGLCD(ILI9486,38,39,40,41);



void setup()
{
    myGLCD.InitLCD();
    Serial.begin(115200);
}




void dispRaw(UTFT *utft,File inFile) 
{ 
  char VH,VL; 
  int i,j = 0; 
  cbi(utft->P_CS, utft->B_CS); 
  for(i = 0; i < 370; i++) 
    for(j = 0; j < 278; j++) { 
    VL = inFile.read(); 
    Serial.print(VL, HEX);
    VH = inFile.read(); 
    Serial.print(VH, HEX);
    utft->LCD_Write_DATA(VL,VH); 
      } 
  sbi(utft->P_CS, utft->B_CS); 
  utft->clrXY(); 
} 



void loop(){
   if (SD.begin(SD_CS))
    {
      char VH,VL;
      File inFile;
      inFile = SD.open("ras",FILE_READ);
      if (! inFile)
    {
      while (1);  //if file does not exsit, stop here.
    }
      dispRaw(&myGLCD,inFile);
      inFile.close();
    }
  }

 

Зато когда так делал так то выводится изображение на дисплей, но разрешение очень маленькое приходится делать что -то около 50*20, то есть карта считывается(карта 4гига)

#include <memorysaver.h>
#include <UTFT.h>
UTFT myGLCD(ILI9486,38,39,40,41);

extern uint8_t BigFont[];//переменная размера шрифта
extern uint8_t SmallFont[];


#include <SPI.h>
#include <SD.h>
#define SD_CS  53//вывод CS, связанный с разъемом SD-карты.
unsigned short ras[0x400];
void setup() {
  myGLCD.InitLCD();// инициализация LCD 
myGLCD.clrScr();// очистка дисплея


}

void loop() {
SD.begin(SD_CS);
      File inFile;
      inFile = SD.open("ras",FILE_READ);
       myGLCD.drawBitmap(20, 20, 50, 20,ras,4);

}

 

Roman2344
Offline
Зарегистрирован: 09.09.2015

А картинку на микро СД нужно в jpeg бросать или в С.? Я бросаю в jpeg.

diger67
Offline
Зарегистрирован: 25.07.2015

Это связано с недостатком ОЗУ.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Так походу с микро СД вообще никак не вывести что ли?

diger67
Offline
Зарегистрирован: 25.07.2015

Roman2344 пишет:

Так походу с микро СД вообще никак не вывести что ли?

По идеи должно выводится.

Roman2344
Offline
Зарегистрирован: 09.09.2015

Набросал вот так вот, теперь выводится в последовательный монитор, правда одни F, картинки на дисплее так и нету

#include <SPI.h>
#include <UTFT.h>
#include <SD.h>
#include <Wire.h>
 
#define SD_CS 53
 
UTFT myGLCD(ILI9486,38,39,40,41);



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

}





void loop(){
     SD.begin(SD_CS);
  
      char VH,VL;
      File inFile;
      inFile = SD.open("ras",FILE_READ);

  int i,j = 0; 

  for(i = 0; i < 370; i++) 
    for(j = 0; j < 278; j++) { 
    VL = inFile.read(); 
  Serial.print(VL, HEX);

    VH = inFile.read(); 
   Serial.print(VH, HEX);

    
      } 
  

  
  }

 

diger67
Offline
Зарегистрирован: 25.07.2015

А кто за вс будет указывать где лежит массив. В тексте отсутствует "unsigned short ras[0x400];", кто за вас опишет указатель на начало массива на SD. Вобщем надо описать указатель, чтобы функция знала с кокого места начинать читать. Да и for можно упростить for(i=0;i<320*240;i++)

AlexBel
AlexBel аватар
Offline
Зарегистрирован: 14.10.2014

Не перестаю поражаться таким, как Roman2344 - мало того, что пишет не по теме, так ещё хочет, чтобы за него всё сделали, а сам не имеет ни малейшего представления о предмете. И не хочет его иметь. И удивляет долготерпение тех, кто таким объясняет такие простейшие вещи, без которых и думать нечего соваться в электронику с контроллерами.

Roman2344, Вы хоть имеете представление, какой контроллер у Вас на плате стоит? Вы хоть раз даташит на него читали? Вы пытались узнать, что такое SD-карта и как с ней работать? Нет, конечно - зачем? Проще написать сюда, чтобы за Вас всё сделали.  Вы хоть раз думали о том, что люди дарят Вам своё время, объясняя то, что Вы не хотите изучать сами? Их время что, дешевле Вашего?

Не стоило, наверное, это всё писать, но порой тупость, безграмотность и наглость просто достают...

makc014
makc014 аватар
Offline
Зарегистрирован: 18.01.2016

Может кому поможет. Заказывал дисплей 3.2" 320х240 ILI9341. 

Подключил к Arduino DUE по схеме (только без резисторов) как указано в теме

В библиотеке UTFT работает с ILI9141 только с serial, а это нам не подходит. Перебором определил, что подойдет  ILI9327 = ITDB32WC (ILI9481=CTE32HR, R61581=CTE35IPS, ILI9486=CTE40 с "зеркалом", лечится в инициализации), НО картинка смещена:

Чтобы устанить сдвиг (самый простой метод) необходимо отредактировать UTFT.cpp,  изменить disp_y_size = dsy[model]; на disp_y_size = dsy[model]-80; Это применительно только для примера 320х240!

ИМХО: Другие способы сводяться к корректировке скетча с +80 или в UTFT.cpp координат формирования фигур.

Если у кого-то есть другие методы, напишите)