Полное заполнение экрана цветом -около 0.2 сек, наверное...это с прескалером 2. Для 8080 нужен FSMC, а я с ним только начинаю)
С FSMC меньше гемороя с управлением, но можно и в режиме ногодрыгы. Одно могу сказать с уверенностью. Главное грамотно описать функции чтения и записи, а функции обработки графики одинаковы для любого протокола обмена.
Не могу найти таблицу регистров в даташите :( Ткните носом , пожалуйста.
Попробуйте почитать раздел Z-inversion Odd/Even Gate data input method в даташите. есть подазрение что неправильная цветопередача может связана с этим. Очевидно задать RGB или BGR можно в регистре 0х36 бит D3. Еще вопрос, когда вы заливаете экран чистым синим, красным, зеленым цветом. цвета соответствуют?
Из регистров получаю вот что - LCD driver chip: 6060
Поигравшись с командами инициализации я все-таки смог победить дисплей :) Пришлось еще повозиться с зеркалированием.
Сейчас цвет правильный и ориентация картинки тоже. В даташите ошибки. Команда выключающая инверсию на самом деле ее включает и наоборот. Вот моя инициализация дисплея:
Осталось еще побороть одну проблемку. После вызова функции 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
}
}
Исходную инициализацию я брал из библиотеки 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, спасибо большое за то, что стараетесь помочь мне. Мне пока достаточно того, что получилось. Функцию инициализации подобрал. Пусть и не совсем соответствующую даташиту, но зато работающую :) Тач работает, кард-ридер тоже. Демка с рисованием с использованием тача работает. В общем я пока доволен.
P.S. Идентификатор прочитать получается, но он не 0x9486, а 0x6060.
Проблема в таче- он работает только с одной стороны экрана . Добавил #define TOUCH_ORIENTATION PORTRAIT , все равно точно не попадает куда нажимаешь. Я где то давно видел в библиотеку добавляется , что то типа x=480 y=240 и тогда точно работает . Сам искал - ненашел .
CD не является продолжением памяти программ контроллера. Так просто не получиться отразить файл. Ошибка говорит о том что имя файла неопределено, т.е. она не видит начальный адрес массива на который ссылается функция. Для вывода изображения с CD нужно использовать функцию чтения с CD. Во втором сучае неправельное преобразование из константы одного формата в другой. Единственный способ вывести изображение это конвертировать его в дамп пикселе, сохранить во флэшь памяти контроллера и вывести как массив.
Вопрос такой мне нужно две картинки вывести одну в один момент времени вторую в другой, дисплей 3,95дюйма 480*320, ардуино Мега имеется, хотя как я понял лучше вывести одну картинку, если использовать память ардуины так как одна картинка займёт порядка 100кб? А если микро СД использовать можно несколько картинок вывести, меня интересует как проще вывести картинку? И как вывести картинку с памяти самой ардуины и с микро СД есть ли пример?
Значится так. Берем нужный файлы, преобразуем в *.bmp с нужным разрешением. Затем с помощью ImageConverter565 находящейся в папке tools библиотеки UTFT формируем массив, получаем файл типа myPicture.c. Далее можно использовать функцию myGLCD.drawBitmap(). Как вариант можно использовать flash память 25qxxx. Эта память которая работает по SPI. Выделяем в озу буфер равный длинне H выводимой картинки. Считываем дамп из внешней flash в буфер из буфера выводим в TFT. Это несколько сложнее и медленнее но экономит памть программ микроконтроллера. С SD алгоритм примерно такойже. Выбор за вами.
Да все понятно. Extern говорит что переменная находится в другом *.c файле и является глобальной, unsigned int (uint16_t) беззнаковое два байта или пол слова, кому как нравится больше, далее тоже все понятно, название массива и его размер. Суть в том что человек хотел считать массив напрямую из CD, так как буд то он находтся во flash контроллера. А это возможно только через буферный массив. Если правильно описывать переменные и функции, соблюдать правила наследования, что архиважно в C++, то проек соберется в любой IDE. При условии что сами авторы IDE и GCC не накосячили.
Дисплей нормальный оказался, теперь вопросы, мне нужно допустим выводить показания с датчиков уровня бака, когда допустим заливаю жидкость в бак, сейчас я сделал очистку дисплея функцией myGLCD.clrScr(); через каждые 2с., есть три условия if(так как три датчика) и когда одно изменяется нужно выводить на дисплей другое слово и другой прямоугольник, поэтому вывод информации на дисплей каждые 2с. потом очистка дисплея и return, но при этом же получается для глаз не приятно так как мигание дисплея. Кто как выходит с этой ситуации?
У меня точно токой дисплей 3.95" LCD touch screen ili9488 с библиотекой Adafruit , плата -Mega2560 .
Использую его с промеров программы TFTpaint2 , хочу узменив программу получть HMI .
Да что же вы все пытаетесь использовать SD как внешнюю flash с SPI. Тогда уж и используйте что то типа 25w256. Тогда можно прямо из внешней памяти читать и сразу писать в tft. C SD такое не прокатывает. Сначала надо инициализировать SD, потом открыть файл, потом в созданый заранее буфер частями перетащить его с SD в память tft.
На борту у mega2560 всего 8192 байта. Следовательно когда вы создаете unsigned intras[25000]; вы пытаетесь зарезервировать в RAM аж 50000 байт, как так, да вот так 50000 всегда больше 8192. Во втором случаи видимо массивы шрифтов и картинок в сумме с скомпелированным текстом программы превышают 256 килобайт flash памяти контроллера. Как то так. Для этого и придумали внешние устройства хранения.
Все до боли просто. Заполняем экран приятным для глаза цветом. с помощью функций линия рисуем бак, наносим нужные поясняющие надписи. Это подготовка статической части экрана. Следующим шагом пишем IF-ы.
К примеру уровень повысился рисуем прямоугольник расчитанного по высоте размера вписанный по ширене в линии рисунка бака. Затем уровень упал снова, рисуем на его месте такойже прямоугольник но его цвет равен цвету задника. Идея в том что динамичным (обновляемым) мы делаем часть изображения, т.е. только ту часть которую надо изменить
А есть тогда рабочий пример вывода картинки с микро СД?
Вот пример вывода изображения с 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;
}
Убедитесь что SD_CS определен верно, чаще для MEGA 53 pin. Посмотрите что выводится в эти переменные. зная значения байт в массиве res и видя что выводится в эти переменные можно судить о правильности работы функции. Проще говоря выведенные значения в мониторе должны быть равны содержимому файла res.
Зато когда так делал так то выводится изображение на дисплей, но разрешение очень маленькое приходится делать что -то около 50*20, то есть карта считывается(карта 4гига)
А кто за вс будет указывать где лежит массив. В тексте отсутствует "unsigned shortras[0x400];", кто за вас опишет указатель на начало массива на SD. Вобщем надо описать указатель, чтобы функция знала с кокого места начинать читать. Да и for можно упростить for(i=0;i<320*240;i++)
Не перестаю поражаться таким, как Roman2344 - мало того, что пишет не по теме, так ещё хочет, чтобы за него всё сделали, а сам не имеет ни малейшего представления о предмете. И не хочет его иметь. И удивляет долготерпение тех, кто таким объясняет такие простейшие вещи, без которых и думать нечего соваться в электронику с контроллерами.
Roman2344, Вы хоть имеете представление, какой контроллер у Вас на плате стоит? Вы хоть раз даташит на него читали? Вы пытались узнать, что такое SD-карта и как с ней работать? Нет, конечно - зачем? Проще написать сюда, чтобы за Вас всё сделали. Вы хоть раз думали о том, что люди дарят Вам своё время, объясняя то, что Вы не хотите изучать сами? Их время что, дешевле Вашего?
Не стоило, наверное, это всё писать, но порой тупость, безграмотность и наглость просто достают...
Может кому поможет. Заказывал дисплей 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 координат формирования фигур.
С FSMC меньше гемороя с управлением, но можно и в режиме ногодрыгы. Одно могу сказать с уверенностью. Главное грамотно описать функции чтения и записи, а функции обработки графики одинаковы для любого протокола обмена.
Не могу найти таблицу регистров в даташите :( Ткните носом , пожалуйста.
Попробуйте почитать раздел Z-inversion Odd/Even Gate data input method в даташите. есть подазрение что неправильная цветопередача может связана с этим. Очевидно задать RGB или BGR можно в регистре 0х36 бит D3. Еще вопрос, когда вы заливаете экран чистым синим, красным, зеленым цветом. цвета соответствуют?
http://178.130.34.198/lcd_pdf/ILI9486AN_V0.6.pdf
Из регистров получаю вот что - 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 } }Можно попробовать инвертировать значения MX и MY.
Нет, там оказалось все несколько сложнее. Вроде победил "крутилку":
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; }Нет, там оказалось все несколько сложнее. Вроде победил "крутилку":
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; }Радует. Впрочем вам проще имея на руках индикатор. Впрочем мыслили в одном направлении.
Это да :)
Спасибо за поддержку и советы.
Поковырял интернет, нашел вот такую инициализацию ili9486.
И еще, меня сильно мучает вопрос, что это за регистры F1, F2, Fn... таких в даташите нет!!!
Исходную инициализацию я брал из библиотеки UTFT. К стати в ней эти регистры отмечены знаками вопросов ))) В даташите я их тоже не нашел. Решил их пока не трогать. Бдет время попробую без них запустить. Вот исходная инициализация из библиотеки:
И все же это не совсем ili9486. Если не получается прочитать по адресу 0xD3 идентификатор .
Вот нарыл может поможет. http://178.130.34.198/adafruit/LCD_ID_Reader.zip
diger67, спасибо большое за то, что стараетесь помочь мне. Мне пока достаточно того, что получилось. Функцию инициализации подобрал. Пусть и не совсем соответствующую даташиту, но зато работающую :) Тач работает, кард-ридер тоже. Демка с рисованием с использованием тача работает. В общем я пока доволен.
P.S. Идентификатор прочитать получается, но он не 0x9486, а 0x6060.
А кто - нибудь с таким дисплеем работал, как он вообще? http://aukro.ua/sensornyj-3-95-tft-shield-dlya-arduino-mega-i5899793090.html
Или подскажите нормальный дисплей 3,5-4 дюйма для ардуино мега.
А кто - нибудь с таким дисплеем работал, как он вообще? 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
проблем у меня не было.
Вопрос такой а максимальный обьём микро СД для дисплея? А то куплю допустим микро СД на 4 или 8гиг, а картинкв не выведется.
Я со своим экраном использовал 8ГБ микро-СД или 8, или 10 класса. Все читается и выводится.
Здравствуйте помогите разобраться :
дисплей с мегой
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 и тогда точно работает . Сам искал - ненашел .
Я со своим экраном использовал 8ГБ микро-СД или 8, или 10 класса. Все читается и выводится.
Спасибо.
#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); }А текст ошибки где?
Вот ошибка на второй код
CD не является продолжением памяти программ контроллера. Так просто не получиться отразить файл. Ошибка говорит о том что имя файла неопределено, т.е. она не видит начальный адрес массива на который ссылается функция. Для вывода изображения с CD нужно использовать функцию чтения с CD. Во втором сучае неправельное преобразование из константы одного формата в другой. Единственный способ вывести изображение это конвертировать его в дамп пикселе, сохранить во флэшь памяти контроллера и вывести как массив.
А так что не так?
#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кб? А если микро СД использовать можно несколько картинок вывести, меня интересует как проще вывести картинку? И как вывести картинку с памяти самой ардуины и с микро СД есть ли пример?
Отвечу позже, надо по делам ....
Спасибо.
Значится так. Берем нужный файлы, преобразуем в *.bmp с нужным разрешением. Затем с помощью ImageConverter565 находящейся в папке tools библиотеки UTFT формируем массив, получаем файл типа myPicture.c. Далее можно использовать функцию
myGLCD.drawBitmap(). Как вариант можно использовать flash память 25qxxx. Эта память которая работает по SPI. Выделяем в озу буфер равный длинне H выводимой картинки. Считываем дамп из внешней flash в буфер из буфера выводим в TFT. Это несколько сложнее и медленнее но экономит памть программ микроконтроллера. С SD алгоритм примерно такойже. Выбор за вами.эт что за размеры? попробуйте просто unsigned int amperka[400]; , а потом усложняйте
и ещё, желательно компилить в той IDE , в которой она хорошо компилилась. Пробуйте версии 1.0 , 1.5.8
Да все понятно. Extern говорит что переменная находится в другом *.c файле и является глобальной, unsigned int (uint16_t) беззнаковое два байта или пол слова, кому как нравится больше, далее тоже все понятно, название массива и его размер. Суть в том что человек хотел считать массив напрямую из CD, так как буд то он находтся во flash контроллера. А это возможно только через буферный массив. Если правильно описывать переменные и функции, соблюдать правила наследования, что архиважно в C++, то проек соберется в любой IDE. При условии что сами авторы IDE и GCC не накосячили.
про картинку с sd http://arduino.ru/forum/apparatnye-voprosy/tft-35-i-arduino?page=18#comment-160002
У меня тоже такая проблема ...
Если найдешь решение пожалуйста сообши ...
У меня как то экран работает не полностью , и цифры тоже не на месте .
Исправил все что мог но все же .......
Дисплей нормальный оказался, теперь вопросы, мне нужно допустим выводить показания с датчиков уровня бака, когда допустим заливаю жидкость в бак, сейчас я сделал очистку дисплея функцией myGLCD.clrScr(); через каждые 2с., есть три условия if(так как три датчика) и когда одно изменяется нужно выводить на дисплей другое слово и другой прямоугольник, поэтому вывод информации на дисплей каждые 2с. потом очистка дисплея и return, но при этом же получается для глаз не приятно так как мигание дисплея. Кто как выходит с этой ситуации?
вообще то я всего несколько дней начал изучать Arduino , так что немогу помочь !!!
У меня точно токой дисплей 3.95" LCD touch screen ili9488 с библиотекой Adafruit , плата -Mega2560 .
Использую его с промеров программы TFTpaint2 , хочу узменив программу получть HMI .
Вопрос такой хочу вывести квртину с микро СД, проконвертировав картинку в 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); }Переменная для картинку в десятиричной форме, при этом такая ошибка
#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); }Вот ошибка:
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); }Вот ошибка:
Да что же вы все пытаетесь использовать SD как внешнюю flash с SPI. Тогда уж и используйте что то типа 25w256. Тогда можно прямо из внешней памяти читать и сразу писать в tft. C SD такое не прокатывает. Сначала надо инициализировать SD, потом открыть файл, потом в созданый заранее буфер частями перетащить его с SD в память tft.
На борту у mega2560 всего 8192 байта. Следовательно когда вы создаете unsigned
intras[25000];вы пытаетесь зарезервировать в RAM аж 50000 байт, как так, да вот так 50000 всегда больше 8192. Во втором случаи видимо массивы шрифтов и картинок в сумме с скомпелированным текстом программы превышают 256 килобайт flash памяти контроллера. Как то так. Для этого и придумали внешние устройства хранения.А есть тогда рабочий пример вывода картинки с микро СД?
Все до боли просто. Заполняем экран приятным для глаза цветом. с помощью функций линия рисуем бак, наносим нужные поясняющие надписи. Это подготовка статической части экрана. Следующим шагом пишем IF-ы.
К примеру уровень повысился рисуем прямоугольник расчитанного по высоте размера вписанный по ширене в линии рисунка бака. Затем уровень упал снова, рисуем на его месте такойже прямоугольник но его цвет равен цвету задника. Идея в том что динамичным (обновляемым) мы делаем часть изображения, т.е. только ту часть которую надо изменить
А есть тогда рабочий пример вывода картинки с микро СД?
Вот пример вывода изображения с 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; }Сделал так, сконвертировал картинку 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(); } }И ничего не выводится.
Вставте в код вывод в терминал:
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.
Такой вод код набросал, а в мониторе последовательного порта вообще ничего(и скоростя уменьшал)
#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); }А картинку на микро СД нужно в jpeg бросать или в С.? Я бросаю в jpeg.
Это связано с недостатком ОЗУ.
Так походу с микро СД вообще никак не вывести что ли?
Так походу с микро СД вообще никак не вывести что ли?
По идеи должно выводится.
Набросал вот так вот, теперь выводится в последовательный монитор, правда одни 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); } }А кто за вс будет указывать где лежит массив. В тексте отсутствует "unsigned
shortras[0x400];", кто за вас опишет указатель на начало массива на SD. Вобщем надо описать указатель, чтобы функция знала с кокого места начинать читать. Да и for можно упростить for(i=0;i<320*240;i++)Не перестаю поражаться таким, как Roman2344 - мало того, что пишет не по теме, так ещё хочет, чтобы за него всё сделали, а сам не имеет ни малейшего представления о предмете. И не хочет его иметь. И удивляет долготерпение тех, кто таким объясняет такие простейшие вещи, без которых и думать нечего соваться в электронику с контроллерами.
Roman2344, Вы хоть имеете представление, какой контроллер у Вас на плате стоит? Вы хоть раз даташит на него читали? Вы пытались узнать, что такое SD-карта и как с ней работать? Нет, конечно - зачем? Проще написать сюда, чтобы за Вас всё сделали. Вы хоть раз думали о том, что люди дарят Вам своё время, объясняя то, что Вы не хотите изучать сами? Их время что, дешевле Вашего?
Не стоило, наверное, это всё писать, но порой тупость, безграмотность и наглость просто достают...
Может кому поможет. Заказывал дисплей 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 координат формирования фигур.
Если у кого-то есть другие методы, напишите)