2

Using an ILI9341. I'm trying to set the rotation from within a class, but it's not working. The code is very straight forward.

If I rotate in the class, the setRotation code does not work but the text is still printed. The pointer is set properly and the text is still printed, it just doesn't get rotated.

Outside of the class, the rotation works fine.

Any help would be greatly appreciated!

#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

#define TFT_DC 5
#define TFT_CS 3

Adafruit_ILI9341 *tft;
uint8_t newRotationAngle = 0;

void drawStuff() {
    tft->setTextColor(map(rand(), 0, RAND_MAX, 0, 0xffff));
    tft->fillRect(0, 0, tft->width(), tft->height(), ILI9341_BLACK);
    tft->setCursor(0, 0);

    tft->print(F("01234567890"));
    delay(250);
}


class test {
public:
    void init(Adafruit_GFX *_p) { ptrTft = _p; };

    void inClassRotation(int newRotation) {
        ptrTft->setRotation(newRotation);
        drawStuffInClass();
    };

    void drawStuffInClass() {
        ptrTft->setTextColor(map(rand(), 0, RAND_MAX, 0, 0xffff));
        ptrTft->fillRect(0, 0, ptrTft->width(), ptrTft->height(), ILI9341_BLACK);
        ptrTft->setCursor(0, 0);

        ptrTft->print(F("01234567890"));
        delay(250);
    }

    Adafruit_GFX *ptrTft;
};

test instance;

void setup() {
    tft = new Adafruit_ILI9341(TFT_CS, TFT_DC);

    tft->begin();
    tft->setTextSize(2);

    instance.init(tft);
}


void outsideClassRotation(Adafruit_GFX *passed) {
    passed->setRotation(newRotationAngle);
    drawStuff();
}


void loop(void) {
    newRotationAngle++;

    // This works. No problems.
//    outsideClassRotation(tft);

    // This does NOT rotate but still prints the text fine.
    instance.inClassRotation(newRotationAngle);

}
1
+100

I would actually be quite surprised if outsideClassRotation() actually worked. My guess is that it does not work as is. Maybe it did work at some point, but then you made some subtle changes to your code and did not check that it is still working.

Here is the deal: there are two setRotation() methods:

  • Adafruit_GFX::setRotation(unsigned char) does very little besides storing the rotation angle... which is not used anyway.
  • Adafruit_ILI9341::setRotation(unsigned char) actually sends commands to the LCD asking it to apply the rotation; this is the method you want.

The problem is that these methods are not virtual, which means that when you call them through a pointer, as in some_pointer->setRotation(the_angle);, you get the method corresponding to the type of the pointer, not the type of the actual object. For example:

tft->setRotation(the_angle);     // calls Adafruit_ILI9341::setRotation()
ptrTft->setRotation(the_angle);  // calls Adafruit_GFX::setRotation()
passed->setRotation(the_angle);  // calls Adafruit_GFX::setRotation()

I checked this by uncommenting your call to outsideClassRotation() and disassembling the compiled binary: both times you are calling Adafruit_GFX::setRotation().

Solution: change your Adafruit_GFX * pointers to be of type Adafruit_ILI9341 *, or patch Adafruit_GFX.h to make setRotation() virtual.

  • Actually, outsideClassRotation() works regardless, but you solved my mystery. I knew it was something simple. I can only unlock bounty after 18 hours. Thanks!!! – David Jun 12 '15 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.