2.2" 18-bit color TFT LCD display - Landscape?

EL Wire/Tape/Panels, LEDs, pixels and strips, LCDs and TFTs, etc products from Adafruit

Moderators: adafruit_support_bill, adafruit

2.2" 18-bit color TFT LCD display - Landscape?

Postby Stephanie » Thu Apr 26, 2012 7:45 am

When I saw this new display yesterday I bought it immediately as it looked like it was the perfect fit for a project I'm working on. I'd been looking for a display that would fit inside 3" x 2" for a while, so this really seemed to fit the bill. http://www.adafruit.com/products/797

After placing the order though, I'm questioning whether this display works in landscape or portrait? All the photographs on the product page are in landscape, and the technical details tab on the product page gives the resolution in landscape - "220x176 resolution, 18-bit (262,144) color", and most of the pictures on the tutorial page show the display in landscape orientation.

But the library code on github lists the resolution in portrait -
#define HX8340B_LCDWIDTH 176
#define HX8340B_LCDHEIGHT 220

I'm planning to use this display primarily for text, and it will only work for me if I can use it in landscape orientation.

Is it possible to use the display in landscape? Or is it hardcoded in portrait?

Thanks!

p.s. FWIW if the display is hardwired to work in portrait only, I'd suggest doing all the photos in portrait (or making some kind of bold comment to that effect), otherwise it's misleading. Especially when the technical details give the resolution in landscape.
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby adafruit » Thu Apr 26, 2012 8:38 am

yes, please read the GFX library tutorial on rotation
User avatar
adafruit
 
Posts: 10485
Joined: Thu Apr 06, 2006 3:21 pm
Location: nyc

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby Stephanie » Thu Apr 26, 2012 9:40 am

Awesome! :D

Thank you so much for the quick answer too!
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

GFX setRotation() does not do anything.

Postby Stephanie » Sat May 05, 2012 8:45 pm

I received the display this week and have just got it wired up, but rotation is not working.

Using the demo sketch for an example, I have tried adding
Code: Select all
display.setRotation(1);
right below the display.begin(); line. I have tried setting rotation to 0, 1, 2, and 3 but regardless of what I do, the text still displays in its original Portrait orientation.

Looking in the library Adafruit_GFX.cpp I can see where the setRotation function is, and basically for rotations 0 and 2 all it does is set width and height to their hardware values, while for rotations 1 and 3 it sets width = height and height = width.

Edit: I realize now that the rotation function is display-dependant and I can see the latest SSD1306 library for instance does rotate as per the GFX tutorial. But the 2.2" TFT screen (with the HX8340b library downloaded as of today) does not appear to have the rotation capability.

Is it still being worked on / will be added at some point?

Thank you!
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby Stephanie » Sat May 05, 2012 11:07 pm

Sorry to keep bugging on this, I can't put things down once I get a bee in my bonnet about it.

After some playing around (and studying the latest SSD1306 library) I've managed to add the rotate function into the HX8340B.cpp file. The only thing that I have not figured out how to get working right was the GFX::fillScreen function which kept failing and I can't understand why.

I noticed there was an Adafruit_HX8340B::fillDisplay function though and changed that so it would ignore any rotation settings and just blank the display as if rotation was zero. I tested it with the example sketch (after changing all the display.fillScreen calls to display.fillDisplay) and now it seems to work with rotation set to 1.

Here's the code - the only changes were to Adafruit_HX8340B.cpp:

Code: Select all
/***************************************************
  This is a library for the Adafruit 2.2" SPI display.
  This library works with the Adafruit 2.2" TFT Breakout w/SD card
  ----> http://www.adafruit.com/products/797

  Check out the links above for our tutorials and wiring diagrams
  These displays use SPI to communicate, 3 or 4 pins are required to
  interface (RST is optional)
  Adafruit invests time and resources providing this open source code,
  please support Adafruit and open-source hardware by purchasing
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.
  banned license, all text above must be included in any redistribution
****************************************************/

#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdlib.h>
#include <SPI.h>

#include "Adafruit_GFX.h"
#include "Adafruit_HX8340B.h"

// use bitbang SPI (not suggested)
Adafruit_HX8340B::Adafruit_HX8340B(int8_t SID, int8_t SCLK, int8_t RST, int8_t CS) {
  sid = SID;
  sclk = SCLK;
  rst = RST;
  cs = CS;
  hwSPI = false;
}

// use hardware SPI
Adafruit_HX8340B::Adafruit_HX8340B(int8_t RST, int8_t CS) {
  sid = -1;
  sclk = -1;
  rst = RST;
  cs = CS;
  hwSPI = true;
}


void Adafruit_HX8340B::begin() {
  // Constructor for underlying GFX library
  constructor(HX8340B_LCDWIDTH, HX8340B_LCDHEIGHT);

  // set pin directions
  if (! hwSPI) {
    pinMode(sid, OUTPUT);
    pinMode(sclk, OUTPUT);
  }
  pinMode(rst, OUTPUT);
  pinMode(cs, OUTPUT);

  // Set pins low by default (except reset)
  if (! hwSPI) {
    digitalWrite(sid, LOW);
    digitalWrite(sclk, LOW);
  }
  digitalWrite(cs, LOW);
  digitalWrite(rst, HIGH);

  // Reset the LCD
  digitalWrite(rst, HIGH);
  delay(100);
  digitalWrite(rst, LOW);
  delay(50);
  digitalWrite(rst, HIGH);
  delay(50);


  csport    = portOutputRegister(digitalPinToPort(cs));
  cspinmask = digitalPinToBitMask(cs);

  if (! hwSPI) {
    clkport    = portOutputRegister(digitalPinToPort(sclk));
    clkpinmask = digitalPinToBitMask(sclk);
    dataport    = portOutputRegister(digitalPinToPort(sid));
    datapinmask = digitalPinToBitMask(sid);
  } else {
    clkport    = portOutputRegister(digitalPinToPort(13));
    clkpinmask = digitalPinToBitMask(13);
    dataport    = portOutputRegister(digitalPinToPort(11));
    datapinmask = digitalPinToBitMask(11);
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV8); // 4 MHz (half speed)
    SPI.setBitOrder(MSBFIRST);
    SPI.setDataMode(SPI_MODE0);
    pinMode(13, OUTPUT);
    pinMode(11, OUTPUT);
  }

  *csport &= ~cspinmask;
  HX8340B_command(HX8340B_N_SETEXTCMD);
  writeData(0xFF);
  writeData(0x83);
  writeData(0x40);

  HX8340B_command(HX8340B_N_SPLOUT);
  delay(100);

  HX8340B_command(0xCA);                  // Undocumented register?
  writeData(0x70);
  writeData(0x00);
  writeData(0xD9);
  writeData(0x01);
  writeData(0x11);
 
  HX8340B_command(0xC9);                  // Undocumented register?
  writeData(0x90);
  writeData(0x49);
  writeData(0x10);
  writeData(0x28);
  writeData(0x28);
  writeData(0x10);
  writeData(0x00);
  writeData(0x06);
  delay(20);

  HX8340B_command(HX8340B_N_SETGAMMAP);
  writeData(0x60);
  writeData(0x71);
  writeData(0x01);
  writeData(0x0E);
  writeData(0x05);
  writeData(0x02);
  writeData(0x09);
  writeData(0x31);
  writeData(0x0A);
 
  HX8340B_command(HX8340B_N_SETGAMMAN);
  writeData(0x67);
  writeData(0x30);
  writeData(0x61);
  writeData(0x17);
  writeData(0x48);
  writeData(0x07);
  writeData(0x05);
  writeData(0x33);
  delay(10);

  HX8340B_command(HX8340B_N_SETPWCTR5);
  writeData(0x35);
  writeData(0x20);
  writeData(0x45);
 
  HX8340B_command(HX8340B_N_SETPWCTR4);
  writeData(0x33);
  writeData(0x25);
  writeData(0x4c);
  delay(10);

  HX8340B_command(HX8340B_N_COLMOD);  // Color Mode
  writeData(0x05);                 // 0x05 = 16bpp, 0x06 = 18bpp

  HX8340B_command(HX8340B_N_DISPON);
  delay(10);

  HX8340B_command(HX8340B_N_CASET);
  writeData(0x00);
  writeData(0x00);
  writeData(0x00);
  writeData(0xaf);                 // 175

  HX8340B_command(HX8340B_N_PASET);
  writeData(0x00);
  writeData(0x00);
  writeData(0x00);
  writeData(0xdb);                 // 219

  HX8340B_command(HX8340B_N_RAMWR);
 
  *csport |=  cspinmask;
  //clearDisplay();
}

// clear everything
void Adafruit_HX8340B::fillDisplay(uint16_t c) {
  setWindow(0, 0, HX8340B_LCDWIDTH-1, HX8340B_LCDHEIGHT-1);
  *csport &= ~cspinmask;
  uint32_t i = HX8340B_LCDWIDTH;
  i *= HX8340B_LCDHEIGHT;
  while (i--) {
    writeData((c>>8) & 0xFF);
    writeData(c & 0xFF);
  }
  *csport |=  cspinmask;
}

void Adafruit_HX8340B::invertDisplay(uint8_t i) {
}

void Adafruit_HX8340B::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
  // check rotation, move pixel around if necessary
  switch (getRotation()) {
  case 1:
    swap(x, y);
    x = WIDTH - x - 1;
    swap(h, w);
    break;
  case 2:
    x = WIDTH - x - 1;
    y = HEIGHT - y - 1;
    break;
  case 3:
    swap(x, y);
    y = HEIGHT - y - 1;
    swap(h, w);
    break;
  } 
  setWindow(x, y, x+w-1, y+h-1);
  *csport &= ~cspinmask;
  uint32_t i = w;
  i *= h;
  while (i--) {
    writeData((color>>8) & 0xFF);
    writeData(color & 0xFF);
  }
  *csport |=  cspinmask;
}

void Adafruit_HX8340B::pushColor(uint16_t color) {
  *csport &= ~cspinmask;
  writeData((color>>8) & 0xFF);
  writeData(color & 0xFF);
  *csport |=  cspinmask;
}

// the most basic function, set a single pixel
void Adafruit_HX8340B::drawPixel(int16_t x, int16_t y, uint16_t color) {
  if ((x < 0) || (x >= width()) || (y < 0) || (y >= height()))
    return;

  // check rotation, move pixel around if necessary
  switch (getRotation()) {
  case 1:
    swap(x, y);
    x = WIDTH - x - 1;
    break;
  case 2:
    x = WIDTH - x - 1;
    y = HEIGHT - y - 1;
    break;
  case 3:
    swap(x, y);
    y = HEIGHT - y - 1;
    break;
  } 

  setWindow(x, y, x+1, y+1);
  *csport &= ~cspinmask;
  writeData((color>>8) & 0xFF);
  writeData(color & 0xFF);
  *csport |=  cspinmask;

}


void Adafruit_HX8340B::HX8340B_command(uint8_t c) {
  // Prepend leading bit instead of D/C pin

  if (hwSPI) {
    uint8_t saved_spimode = SPCR;
    SPCR = 0;

#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
    PORTB &= ~_BV(3);  // PB3 = MOSI
    PORTB |= _BV(5);  // PB5 = SCLK
    PORTB &= ~_BV(5);
    // also do mega next eh?
#else
    *dataport &=  ~datapinmask;
    *clkport |=  clkpinmask;
    *clkport &= ~clkpinmask;
#endif

    SPCR = saved_spimode;

    SPDR = c;
    while(!(SPSR & _BV(SPIF)));
  } else {
    *dataport &=  ~datapinmask;
    *clkport |=  clkpinmask;
    *clkport &= ~clkpinmask;
    for(uint8_t bit = 0x80; bit; bit >>= 1) {
      if(c & bit) *dataport |=  datapinmask;
      else        *dataport &= ~datapinmask;
      *clkport |=  clkpinmask;
      *clkport &= ~clkpinmask;
    }
  }
}


void Adafruit_HX8340B::writeData(uint8_t c) {
  // Prepend leading bit instead of D/C pin
  if (hwSPI) {
    uint8_t saved_spimode = SPCR;
    SPCR = 0;
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined(__AVR_ATmega8__)
    PORTB |= _BV(3);  // PB3 = MOSI
    PORTB |= _BV(5);  // PB5 = SCLK
    PORTB &= ~_BV(5);
    // also do mega next eh?
#else
    *dataport |=  datapinmask;
    *clkport |=  clkpinmask;
    *clkport &= ~clkpinmask;
#endif
    SPCR = saved_spimode;
    SPDR = c;
    while(!(SPSR & _BV(SPIF)));
  } else {
    *dataport |=  datapinmask;
    *clkport |=  clkpinmask;
    *clkport &= ~clkpinmask;
    for(uint8_t bit = 0x80; bit; bit >>= 1) {
      if(c & bit) *dataport |=  datapinmask;
      else        *dataport &= ~datapinmask;
      *clkport |=  clkpinmask;
      *clkport &= ~clkpinmask;
    }
  }
}

void Adafruit_HX8340B::writereg(uint8_t reg, uint8_t value) {
  *csport &= ~cspinmask;
  HX8340B_command(reg);
  HX8340B_command(value);
  *csport |=  cspinmask;
}

void Adafruit_HX8340B::setWindow(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
{
  *csport &= ~cspinmask;
  HX8340B_command(HX8340B_N_CASET);
  writeData(x0>>8);
  writeData(x0);
  writeData(x1>>8);
  writeData(x1);
 
  HX8340B_command(HX8340B_N_PASET);
  writeData(y0>>8);
  writeData(y0);
  writeData(y1>>8);
  writeData(y1);

  HX8340B_command(HX8340B_N_RAMWR);
  *csport |=  cspinmask;
}

uint16_t Adafruit_HX8340B::Color565(uint8_t r, uint8_t g, uint8_t b) {
  uint16_t c;
  c = r >> 3;
  c <<= 6;
  c |= g >> 2;
  c <<= 5;
  c |= b >> 3;

  return c;
}


Sorry I still haven't learned enough Github to make this a log or bug report or... well I don't even know the Github lingo yet.

Cheers!
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby Stephanie » Sun May 06, 2012 2:33 pm

Ok last comment on this, I promise!

I found a bug in the code I had posted above so ignore all that.

I've also figured out how to post an "issue" on Github so I have filed this as an Issue on the HX8340B library, and included my code to correct the problem in the issue:
https://github.com/adafruit/Adafruit-HX8340B/issues/1

Cheers!
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby rmm200 » Sun May 06, 2012 3:43 pm

Well github is being picky and won't let me add more than one comment.
Summarizing here:
Library maintainer don't regress my mod for Mega 2560 support please. Replace all occurrences of 11 and 13 with symbolics.
You left in a block of commented-out code in fillDisplay that should not go into the final result.
Most important, with your changes to rotation, my Mega 2560 runs the test application to completion with no errors! This is a first!
rmm200
 
Posts: 7
Joined: Sun Jan 30, 2011 5:31 pm

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby Stephanie » Sun May 06, 2012 7:42 pm

I didn't see your mod for the Mega, it might not have been there at the time I grabbed the library on Saturday morning. I should have just posted the two functions that I worked on but I wasn't sure what was the right way to do it.

I hope your mod for Mega compatibility isn't regressed but I'm sure that the maintainers will be thorough and careful when testing it all.

And I'm happy to hear that the rotation mod worked for you on the Mega - yay! :D
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby rmm200 » Sun May 06, 2012 9:50 pm

Let me just emphasize how important your fix is.
Without it, any test that called fillRect wound up blowing up. The display goes white, and eventually the Arduino resets and starts the test over.
First I thought the tests were supposed to loop - they were not.
With your fix, it runs through all tests - one time - and then prints done to the serial port.
rmm200
 
Posts: 7
Joined: Sun Jan 30, 2011 5:31 pm

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby adafruit » Mon May 07, 2012 4:25 pm

thanks for the feedback, we added Mega notes (no code requires changing, just the pin names are noted in the code) - we'll look at why rotation isnt working
User avatar
adafruit
 
Posts: 10485
Joined: Thu Apr 06, 2006 3:21 pm
Location: nyc

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby rmm200 » Mon May 07, 2012 5:29 pm

Adafruit thanks for looking at this!
Stephanie did her change based on a problem with rotation.
Please note - my problem was unrelated to rotation - just using the example in the driver library as given fails by crashing the Arduino in multiple steps.
Stephanie's change fixed that behavior. I suspect your driver was blowing an array boundary.
Personally it does not matter to me if rotation works or not - but I really don't want fillRect to blow up on a normal call.
rmm200
 
Posts: 7
Joined: Sun Jan 30, 2011 5:31 pm

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby rmm200 » Wed May 09, 2012 9:22 am

Tested Dragon's submitted library fix. My Mega 2560 change is still there, and all the example tests work. I did not specifically try rotation, but this change sure fixed my problems. Thanks again both Stephanie and Adafruit!
rmm200
 
Posts: 7
Joined: Sun Jan 30, 2011 5:31 pm

Re: 2.2" 18-bit color TFT LCD display - Landscape?

Postby Stephanie » Wed May 09, 2012 11:50 am

The library update is working great for me too. I'm using my display in landscape (rotation 1) mode and I ran through the example sketch as well as my own project sketch.

The graphics in the example felt like they ran a bit faster with the updated library. I'm only using text in my project and can't tell if its any quicker but the main thing is that it's working perfectly.

Thanks & cheers!
User avatar
Stephanie
 
Posts: 286
Joined: Sat Dec 11, 2010 12:17 am
Location: Canada


Return to Glowy things (LCD, LED, TFT, EL) purchased at Adafruit

Who is online

Users browsing this forum: No registered users and 5 guests

Stuff to buy from the Adafruit store and links to product documentation!


New Products [102]

Raspberry Pi[80]
 
FLORA[23]
 
Bunnie Studios[9]
 
FPGA[1]
 
mbed[11]
Arduino[60]
 
NETduino[14]
 
BeagleBone[24]
 
Android[6]
 
XBee[10]
More Dev Boards[30]


 
BoArduino[8]
 
SpokePOV[4]
 
TV-B-Gone[4]
 
MiniPOV[3]
 
SIM reader[3]
 
Microtouch[5]
 
Clocks & Watches[18]
 
Drawdio[4]
 
Brain Machine[1]
 
Game of Life[2]
 
MintyBoost[2]
More DIY Kits[16]


 
MaKey MaKey[3]
 
Tweet-a-Watt[5]
 
Young Engineers[33]
 
Discover Electronics[2]
 
Snap Circuits[4]
 
littleBits[3]
 
Project packs[8]


 
Breakout Boards[33]
LCDs & Displays[48]
Components & Parts[69]
Batteries & Power[49]
EL Wire/Tape/Panel[52]
LEDs[108]
 
Wireless[14]
Cables[60]
 
Lasers[6]
Sensors/Parts[145]
 
Enclosures/Cases[11]
 
Solar[11]
 
RFID / NFC[13]
Prototyping[69]
 
iDevices[13]
Tools[71]
 
Wearables[39]
 
CNC[37]
 
Robotics[29]
 
3D printing[1]
 
Materials[24]


 
Stickers[41]
 
Skill badges[55]
 
Books[25]
 
Circuit Playground[7]
 
Gift Certificates[4]