Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Teensy version of Adafruit_ST7735 needs updating

  1. #1
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,259

    Teensy version of Adafruit_ST7735 needs updating

    It was reported in the adafruit forums (https://forums.adafruit.com/viewtopic.php?f=8&t=81387) that the uncanny eyes tutorial does not build on the current teensyduino.

    As a matter of coincidence, I had become interested in the same project, and I had just received two 1.44" 128x128 screens from an ebay seller (http://www.ebay.com/itm/122005165823...%3AMEBIDX%3AIT).

    I haven't gotten to the point of wiring up the displays, but I did verify that the tutorial does not build, due to INITR_144GREENTAB not being defined in the Teensy ST7735 source (but it is in the current Adafruit source). Here are the errors, including a typo in the uncanny eyes source:

    Code:
     /home/meissner/Arduino/teensy-eyes/uncannyEyes/uncannyEyes.ino:460:17: warning: extra tokens at end of #ifdef directive [enabled by default]
     #ifdef IRIS_PIN && (IRIS_PIN >= 0) // Interactive iris
                     ^
    uncannyEyes: In function 'void setup()':
    uncannyEyes:105: error: 'INITR_144GREENTAB' was not declared in this scope
         eye[e].display.initR(INITR_144GREENTAB);
                              ^
    If I fix line 460 to be:

    Code:
     #if defined(IRIS_PIN) && (IRIS_PIN >= 0) // Interactive iris
    and replace hardware/teensy/avr/libraries/Adafruit_ST7735 with a link to the current Adafruit libraries, it now compiles, but it has some warnings in the library:

    Code:
    WARNING: Spurious .github folder in 'Adafruit ST7735 Library' library
    uncannyEyes: In function 'void frame(uint16_t)':
    uncannyEyes:327: warning: comparison between signed and unsigned integer expressions 
         if((t - eye[eyeIndex].blink.startTime) >= eye[eyeIndex].blink.duration) {
                                                                       ^
    uncannyEyes:404: warning: comparison between signed and unsigned integer expressions 
         if(s >= eye[eyeIndex].blink.duration) s = 255;   // At or past blink end
                                     ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawChar(int16_t, int16_t, unsigned char, uint16_t, uint16_t, uint8_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:566:14: warning: unused variable 'xa' [-Wunused-variable]
                  xa = pgm_read_byte(&glyph->xAdvance);
                  ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawBitmap(int16_t, int16_t, const uint8_t*, int16_t, int16_t, uint16_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:392:27: warning: 'byte' may be used uninitialized in this function [-Wmaybe-uninitialized]
           if(i & 7) byte <<= 1;
                               ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawBitmap(int16_t, int16_t, const uint8_t*, int16_t, int16_t, uint16_t, uint16_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:410:27: warning: 'byte' may be used uninitialized in this function [-Wmaybe-uninitialized]
           if(i & 7) byte <<= 1;
                               ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawBitmap(int16_t, int16_t, uint8_t*, int16_t, int16_t, uint16_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:427:27: warning: 'byte' may be used uninitialized in this function [-Wmaybe-uninitialized]
           if(i & 7) byte <<= 1;
                               ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawBitmap(int16_t, int16_t, uint8_t*, int16_t, int16_t, uint16_t, uint16_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:443:27: warning: 'byte' may be used uninitialized in this function [-Wmaybe-uninitialized]
           if(i & 7) byte <<= 1;
                               ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawXBitmap(int16_t, int16_t, const uint8_t*, int16_t, int16_t, uint16_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:462:27: warning: 'byte' may be used uninitialized in this function [-Wmaybe-uninitialized]
           if(i & 7) byte >>= 1;
                               ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp: In member function 'void Adafruit_GFX::drawChar(int16_t, int16_t, unsigned char, uint16_t, uint16_t, uint8_t)':
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:600:9: warning: 'bits' may be used uninitialized in this function [-Wmaybe-uninitialized]
             if(bits & 0x80) {
             ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:604:47: warning: 'yo16' may be used uninitialized in this function [-Wmaybe-uninitialized]
                 fillRect(x+(xo16+xx)*size, y+(yo16+yy)*size, size, size, color);
                                                   ^
    /rock/shared/arduino/teensy-1.30-beta1-1.6.8/hardware/teensy/avr/libraries/Adafruit_GFX/Adafruit_GFX.cpp:570:14: warning: 'xo16' may be used uninitialized in this function [-Wmaybe-uninitialized]
         int16_t  xo16, yo16;
                  ^
    
    Sketch uses 186,216 bytes (71%) of program storage space. Maximum is 262,144 bytes.
    Global variables use 4,896 bytes (7%) of dynamic memory, leaving 60,640 bytes for local variables. Maximum is 65,536 bytes.
    Unfortunately, the source is too large too post inside of {code} and {/code} tags. I have added uncannyEyes.ino as an attachment, but you will need to load defaultEye.h from the uncanny eyes tutorial.
    Attached Files Attached Files

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,259
    Since this is more about the 128x128 support and not the basic Teensy 3.6 support (which Paul has updated the missing #if defined to treat the 3.5/3.6 like the 3.1/3.2), I am moving it back to this thread. Here is the thread, I posted the patch in:


    I attempted to merge in the 128x128 support from Adafruit and it does not seem to work. I don't have the standard 128x64 display to test it.

    On both the 3.1 and 3.6 static is displayed on the screens rather than the eyes. If I fall back to the Adafruit libraries the 3.6 can display both eyes, while the 3.1 can only display 1 eye. Note, in looking at the sketch, the sketch does all of the heavy lifting itself, and once setup, only does SPI.beginTransaction and SPI.endTransation in the main loop. So, I imagine it is dependent on something in the Adafruit initialization.

    Here is the basic configuration for pins that I used:

    Code:
    #define DISPLAY_DC     A1  // Data/command pin for BOTH displays
    #define DISPLAY_RESET   8 // Reset pin for BOTH displays
    #define SELECT_L_PIN    9 // LEFT eye chip select pin
    #define SELECT_R_PIN   10 // RIGHT eye chip select pin
    
    // INPUT CONFIG (for eye motion -- enable or comment out as needed) --------
    
    //#define JOYSTICK_X_PIN A0 // Analog pin for eye horiz pos (else auto)
    //#define JOYSTICK_Y_PIN A1 // Analog pin for eye vert position (")
    //#define JOYSTICK_X_FLIP   // If set, reverse stick X axis
    //#define JOYSTICK_Y_FLIP   // If set, reverse stick Y axis
    //#define TRACKING          // If enabled, eyelid tracks pupil
    //#define IRIS_PIN       A2 // Photocell or potentiometer (else auto iris)
    //#define IRIS_PIN_FLIP     // If set, reverse reading from dial/photocell
    #define IRIS_SMOOTH       // If enabled, filter input from IRIS_PIN
    #define IRIS_MIN      120 // Clip lower analogRead() range from IRIS_PIN
    #define IRIS_MAX      720 // Clip upper "
    #define WINK_L_PIN      0 // Pin for LEFT eye wink button
    #define BLINK_PIN       3 // Pin for blink button (BOTH eyes)
    #define WINK_R_PIN      1 // Pin for RIGHT eye wink button
    #define AUTOBLINK         // If enabled, eyes blink autonomously
    Here is the display that I got:


    I soon will be switching to the Adafruit OLED displays. Given mostly the same code is used for the OLED, I don't know if I will have similar issues.

    For reference, here is the patch I mentioned in the previous thread:
    Code:
    Index: Adafruit_ST7735.cpp
    ===================================================================
    --- Adafruit_ST7735.cpp (revision 61)
    +++ Adafruit_ST7735.cpp (working copy)
    @@ -1,10 +1,15 @@
    -/*************************************************** 
    +/***************************************************
       This is a library for the Adafruit 1.8" SPI display.
    -  This library works with the Adafruit 1.8" TFT Breakout w/SD card
    +
    +This library works with the Adafruit 1.8" TFT Breakout w/SD card
       ----> http://www.adafruit.com/products/358
    -  as well as Adafruit raw 1.8" TFT display
    +The 1.8" TFT shield
    +  ----> https://www.adafruit.com/product/802
    +The 1.44" TFT breakout
    +  ----> https://www.adafruit.com/product/2088
    +as well as Adafruit raw 1.8" TFT display
       ----> http://www.adafruit.com/products/618
    - 
    +
       Check out the links above for our tutorials and wiring diagrams
       These displays use SPI to communicate, 4 or 5 pins are required to
       interface (RST is optional)
    @@ -25,7 +30,7 @@
     
     // Constructor when using software SPI.  All output pins are configurable.
     Adafruit_ST7735::Adafruit_ST7735(uint8_t cs, uint8_t rs, uint8_t sid,
    - uint8_t sclk, uint8_t rst) : Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT)
    + uint8_t sclk, uint8_t rst) : Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT_18)
     {
            _cs   = cs;
            _rs   = rs;
    @@ -39,7 +44,7 @@
     // Constructor when using hardware SPI.  Faster, but must use SPI pins
     // specific to each board type (e.g. 11,13 for Uno, 51,52 for Mega, etc.)
     Adafruit_ST7735::Adafruit_ST7735(uint8_t cs, uint8_t rs, uint8_t rst) :
    -  Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT) {
    +  Adafruit_GFX(ST7735_TFTWIDTH, ST7735_TFTHEIGHT_18) {
            _cs   = cs;
            _rs   = rs;
            _rst  = rst;
    @@ -233,6 +238,8 @@
            if (pin == 2 || pin == 6 || pin == 9) return true;
            if (pin == 10 || pin == 15) return true;
            if (pin >= 20 && pin <= 23) return true;
    +       Serial.print ("spi_pin_is_cs failed, ");
    +       Serial.println (pin);
            return false;
     }
     
    @@ -249,6 +256,8 @@
                     case 22: CORE_PIN22_CONFIG = PORT_PCR_MUX(2); return 0x08; // PTC1
                     case 15: CORE_PIN15_CONFIG = PORT_PCR_MUX(2); return 0x10; // PTC0
             }
    +       Serial.print ("spi_configure_cs_pin failed, ");
    +       Serial.println (pin);
             return 0;
     }
     
    @@ -467,6 +476,15 @@
           0x00, 0x00,             //     XSTART = 0
           0x00, 0x9F },           //     XEND = 159
     
    +  Rcmd2green144[] = {              // Init for 7735R, part 2 (green 1.44 tab)
    +    2,                        //  2 commands in list:
    +    ST7735_CASET  , 4      ,  //  1: Column addr set, 4 args, no delay:
    +      0x00, 0x00,             //     XSTART = 0
    +      0x00, 0x7F,             //     XEND = 127
    +    ST7735_RASET  , 4      ,  //  2: Row addr set, 4 args, no delay:
    +      0x00, 0x00,             //     XSTART = 0
    +      0x00, 0x7F },           //     XEND = 127
    +
       Rcmd3[] = {                 // Init for 7735R, part 3 (red or green tab)
         4,                        //  4 commands in list:
         ST7735_GMCTRP1, 16      , //  1: Magical unicorn dust, 16 args, no delay:
    @@ -701,6 +719,11 @@
                    commandList(Rcmd2green);
                    colstart = 2;
                    rowstart = 1;
    +       } else if(options == INITR_144GREENTAB) {
    +               _height = ST7735_TFTHEIGHT_144;
    +               commandList(Rcmd2green144);
    +               colstart = 2;
    +               rowstart = 3;
            } else {
                    // colstart, rowstart left at default '0' values
                    commandList(Rcmd2red);
    @@ -811,7 +834,12 @@
                            writedata(MADCTL_MX | MADCTL_MY | MADCTL_BGR);
                    }
                    _width  = ST7735_TFTWIDTH;
    -               _height = ST7735_TFTHEIGHT;
    +
    +               if (tabcolor == INITR_144GREENTAB) 
    +                 _height = ST7735_TFTHEIGHT_144;
    +               else
    +                 _height = ST7735_TFTHEIGHT_18;
    +
                    break;
            case 1:
                    if (tabcolor == INITR_BLACKTAB) {
    @@ -819,7 +847,12 @@
                    } else {
                            writedata(MADCTL_MY | MADCTL_MV | MADCTL_BGR);
                    }
    -               _width  = ST7735_TFTHEIGHT;
    +
    +               if (tabcolor == INITR_144GREENTAB) 
    +                 _width = ST7735_TFTHEIGHT_144;
    +               else
    +                 _width = ST7735_TFTHEIGHT_18;
    +
                    _height = ST7735_TFTWIDTH;
                    break;
            case 2:
    @@ -829,7 +862,11 @@
                            writedata(MADCTL_BGR);
                    }
                    _width  = ST7735_TFTWIDTH;
    -               _height = ST7735_TFTHEIGHT;
    +               if (tabcolor == INITR_144GREENTAB) 
    +                 _height = ST7735_TFTHEIGHT_144;
    +               else
    +                 _height = ST7735_TFTHEIGHT_18;
    +
                    break;
            case 3:
                    if (tabcolor == INITR_BLACKTAB) {
    @@ -837,7 +874,11 @@
                    } else {
                            writedata(MADCTL_MX | MADCTL_MV | MADCTL_BGR);
                    }
    -               _width  = ST7735_TFTHEIGHT;
    +               if (tabcolor == INITR_144GREENTAB) 
    +                 _width = ST7735_TFTHEIGHT_144;
    +               else
    +                 _width = ST7735_TFTHEIGHT_18;
    +
                    _height = ST7735_TFTWIDTH;
                    break;
            }
    Index: Adafruit_ST7735.h
    ===================================================================
    --- Adafruit_ST7735.h   (revision 61)
    +++ Adafruit_ST7735.h   (working copy)
    @@ -1,10 +1,15 @@
     /***************************************************
       This is a library for the Adafruit 1.8" SPI display.
    -  This library works with the Adafruit 1.8" TFT Breakout w/SD card
    +
    +This library works with the Adafruit 1.8" TFT Breakout w/SD card
       ----> http://www.adafruit.com/products/358
    -  as well as Adafruit raw 1.8" TFT display
    +The 1.8" TFT shield
    +  ----> https://www.adafruit.com/product/802
    +The 1.44" TFT breakout
    +  ----> https://www.adafruit.com/product/2088
    +as well as Adafruit raw 1.8" TFT display
       ----> http://www.adafruit.com/products/618
    - 
    +
       Check out the links above for our tutorials and wiring diagrams
       These displays use SPI to communicate, 4 or 5 pins are required to
       interface (RST is optional)
    @@ -44,8 +49,16 @@
     #define INITR_REDTAB   0x1
     #define INITR_BLACKTAB   0x2
     
    +#define INITR_18GREENTAB    INITR_GREENTAB
    +#define INITR_18REDTAB      INITR_REDTAB
    +#define INITR_18BLACKTAB    INITR_BLACKTAB
    +#define INITR_144GREENTAB   0x1
    +
     #define ST7735_TFTWIDTH  128
    -#define ST7735_TFTHEIGHT 160
    +// for 1.44" display
    +#define ST7735_TFTHEIGHT_144 128
    +// for 1.8" display
    +#define ST7735_TFTHEIGHT_18  160
     
     #define ST7735_NOP     0x00
     #define ST7735_SWRESET 0x01
    @@ -100,7 +113,7 @@
     #define        ST7735_GREEN   0x07E0
     #define ST7735_CYAN    0x07FF
     #define ST7735_MAGENTA 0xF81F
    -#define ST7735_YELLOW  0xFFE0  
    +#define ST7735_YELLOW  0xFFE0
     #define ST7735_WHITE   0xFFFF
    Here is the code to draw an eye from the source:

    Code:
    void drawEye( // Renders one eye.  Inputs must be pre-clipped & valid.
      uint8_t  e,       // Eye array index; 0 or 1 for left/right
      uint32_t iScale,  // Scale factor for iris
      uint8_t  scleraX, // First pixel X offset into sclera image
      uint8_t  scleraY, // First pixel Y offset into sclera image
      uint8_t  uT,      // Upper eyelid threshold value
      uint8_t  lT) {    // Lower eyelid threshold value
    
      uint8_t  screenX, screenY, scleraXsave;
      int16_t  irisX, irisY;
      uint16_t p, a;
      uint32_t d;
    
      // Set up raw pixel dump to entire screen.  Although such writes can wrap
      // around automatically from end of rect back to beginning, the region is
      // reset on each frame here in case of an SPI glitch.
      SPI.beginTransaction(settings);
    #ifdef _ADAFRUIT_ST7735H_ // TFT
      eye[e].display.setAddrWindow(0, 0, 127, 127);
    #else // OLED
      eye[e].display.writeCommand(SSD1351_CMD_SETROW);    // Y range
      eye[e].display.writeData(0); eye[e].display.writeData(SCREEN_HEIGHT - 1);
      eye[e].display.writeCommand(SSD1351_CMD_SETCOLUMN); // X range
      eye[e].display.writeData(0); eye[e].display.writeData(SCREEN_WIDTH  - 1);
      eye[e].display.writeCommand(SSD1351_CMD_WRITERAM);  // Begin write
    #endif
      digitalWrite(eye[e].cs, LOW);                       // Chip select
      digitalWrite(DISPLAY_DC, HIGH);                     // Data mode
      // Now just issue raw 16-bit values for every pixel...
    
      scleraXsave = scleraX; // Save initial X value to reset on each line
      irisY       = scleraY - (SCLERA_HEIGHT - IRIS_HEIGHT) / 2;
      for(screenY=0; screenY<SCREEN_HEIGHT; screenY++, scleraY++, irisY++) {
        scleraX = scleraXsave;
        irisX   = scleraXsave - (SCLERA_WIDTH - IRIS_WIDTH) / 2;
        for(screenX=0; screenX<SCREEN_WIDTH; screenX++, scleraX++, irisX++) {
          if((lower[screenY][screenX] <= lT) ||
             (upper[screenY][screenX] <= uT)) {             // Covered by eyelid
            p = 0;
          } else if((irisY < 0) || (irisY >= IRIS_HEIGHT) ||
                    (irisX < 0) || (irisX >= IRIS_WIDTH)) { // In sclera
            p = sclera[scleraY][scleraX];
          } else {                                          // Maybe iris...
            p = polar[irisY][irisX];                        // Polar angle/dist
            d = (iScale * (p & 0x7F)) / 128;                // Distance (Y)
            if(d < IRIS_MAP_HEIGHT) {                       // Within iris area
              a = (IRIS_MAP_WIDTH * (p >> 7)) / 512;        // Angle (X)
              p = iris[d][a];                               // Pixel = iris
            } else {                                        // Not in iris
              p = sclera[scleraY][scleraX];                 // Pixel = sclera
            }
          }
          // SPI FIFO technique from Paul Stoffregen's ILI9341_t3 library:
          while(KINETISK_SPI0.SR & 0xC000); // Wait for space in FIFO
          KINETISK_SPI0.PUSHR = p | SPI_PUSHR_CTAS(1) | SPI_PUSHR_CONT;
        }
      }
    
      KINETISK_SPI0.SR |= SPI_SR_TCF;         // Clear transfer flag
      while((KINETISK_SPI0.SR & 0xF000) ||    // Wait for SPI FIFO to drain
           !(KINETISK_SPI0.SR & SPI_SR_TCF)); // Wait for last bit out
      digitalWrite(eye[e].cs, HIGH);          // Deselect
      SPI.endTransaction();
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •