0

I am using an Adafruit HUZZAH32 Feather with the ESP WROOM32 module and an Adafruit 2,8" cap touch Display. When trying my code I encountered a strange problem: one specific line of code lets the controller freeze, even though everything compiles fine. By freeze I mean the displayed image stays the same as before the upload and nothing moves any more. The output is

Couldn't start FT6206 touchscreen controller

so it stops there in the while(1);

#include <Adafruit_GFX.h>    // Core graphics library
#include <SPI.h>       // this is needed for display
#include <Adafruit_ILI9341.h>
#include <Wire.h>      // this is needed for FT6206
#include <Adafruit_FT6206.h>


// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ctp = Adafruit_FT6206();

// The display also uses hardware SPI, plus #9 & #10
#define TFT_CS 21
#define TFT_DC 14
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

#define BOXSIDE 100
#define LBLUE     0x0479
#define BLACK     0x0000
#define RED       0xD802
#define LGREEN    0x7DE4
#define BACKGROUNDCOLOR BLACK

TS_Point lastPoint;
bool continuedTouch = false;

typedef struct box box;

/**
 * Struct to define boxes for the graphical interface
 */
struct box {
   int posx; /**< Start position on x-axis*/
   int posy; /**< Start position on y-axos*/
   int sidex; /**< Length of side in x direction*/
   int sidey; /**< Length of side in y direction*/
};

box leftBox ;
box middleBox ;
box rightBox ;

void setup() {
  while (!Serial);     // used for leonardo debugging

  Serial.begin(115200);

  tft.begin();
  tft.setRotation(1);
  // Initialization here because of rotation
  leftBox = {0, tft.height()/2 - BOXSIDE/2,  BOXSIDE, BOXSIDE};
  middleBox = {tft.width()/2 - BOXSIDE/2, tft.height()/2 - BOXSIDE/2, BOXSIDE, BOXSIDE};
  rightBox = {tft.width() - BOXSIDE, tft.height()/2 - BOXSIDE/2,  BOXSIDE, BOXSIDE};
  if (! ctp.begin(40)) {  // pass in 'sensitivity' coefficient
    Serial.println("Couldn't start FT6206 touchscreen controller");
    while (1);
  }
  tft.fillScreen(BACKGROUNDCOLOR);
  showMainScreen();
}

void loop() {
    // Wait for a touch
  if (! ctp.touched()) {
    continuedTouch = false;
    return;
  }
  int buf = 0;

  // Retrieve a point  
  TS_Point p = ctp.getPoint();
  p.x = map(p.x, 0, 240, 320, 0);
  p.y = map(p.y, 0, 320, 240, 0);
  buf = p.y;
  p.y = p.x;
  p.x = buf;
  if (continuedTouch == false){
    lastPoint = p;
    continuedTouch = true;
    Serial.println("in if");
  }

  int overlap = 0;
  int diff = 0;

  if (lastPoint.x < p.x){
    diff = p.x-lastPoint.x;

    if (leftBox.posx > (tft.width() - leftBox.sidex )){
      overlap = leftBox.posx + leftBox.sidex  - tft.width() - 10; 
      tft.fillRect(0, leftBox.posy, overlap, leftBox.sidey, RED);
      if (leftBox.posx > tft.width()){
        //Serial.println(""); // If this is commented out...
        leftBox.posx = leftBox.posx - tft.width() -10; // ...this line causes problems
      }
    } 
    tft.fillRect(leftBox.posx, leftBox.posy, diff, leftBox.sidey, BLACK);
    tft.fillRect(leftBox.posx+leftBox.sidex, leftBox.posy, diff, leftBox.sidey, RED);
    leftBox.posx = leftBox.posx + diff;


    if (middleBox.posx > (tft.width() - middleBox.sidex )){
      overlap = middleBox.posx + middleBox.sidex  - tft.width() - 10;
      tft.fillRect(0, middleBox.posy, overlap, middleBox.sidey, LGREEN);
      if (middleBox.posx > tft.width()){
        middleBox.posx = middleBox.posx - tft.width() - 10; // Here the same line does not make problems
      }
    } 
    tft.fillRect(middleBox.posx, middleBox.posy, diff, middleBox.sidey, BLACK);
    tft.fillRect(middleBox.posx+middleBox.sidex, middleBox.posy, diff, middleBox.sidey, LGREEN);
    middleBox.posx = middleBox.posx + diff;


    if (rightBox.posx > (tft.width() - rightBox.sidex )){
      overlap = rightBox.posx + rightBox.sidex - tft.width() - 10;
      tft.fillRect(0, rightBox.posy, overlap, rightBox.sidey, LBLUE);
      if (rightBox.posx > tft.width()){
        rightBox.posx = rightBox.posx - tft.width()-10; // Here neither
      }
    } 
    tft.fillRect(rightBox.posx, rightBox.posy, diff, rightBox.sidey, BLACK);
    tft.fillRect(rightBox.posx+rightBox.sidex, rightBox.posy, diff, rightBox.sidey, LBLUE);
    rightBox.posx = rightBox.posx + diff;
  }  

  lastPoint = p;
}


void showMainScreen(){
  tft.fillRect(middleBox.posx, middleBox.posy, middleBox.sidex,middleBox.sidey, LGREEN); //middle
  tft.fillRect(leftBox.posx, leftBox.posy, leftBox.sidex,leftBox.sidey, RED); // left
  tft.fillRect(rightBox.posx, rightBox.posy, rightBox.sidex,rightBox.sidey, LBLUE); // right
}

The program draws 3 boxes, that scroll when the finger is moved to the right on the touch screen. They repeat themselves when moved out of the display. My question is why does the touchscreen controller fail to start when I comment out the Serial.println("");? Initially leftBox.posx is zero so with this line it would be negative, is this the problem? But the part of code is inside an if, so I would not suspect it to be executed upon start. Could anyone please explain this behaviour?

The wiring looks like this (sorry for my crappy paint job)Wiring

P.S. I am not sure if this is the right SE forum, if not please let me know. Also I asked this question on Electrical Engineering and was advised to ask here, so I deleted it there.


I came to the solution that it has something to do with a kind of magic...After trying a lot more I encountered the touchscreen controller failure in several different occasions: Once when I changed the colors of the boxes, (when all are LGREENthe controller starts, when they are RED, LGREEN and LBLUEnot), when I tried another tft.fillRect it didn't work...It seems that seemingly random code changes sometimes let the controller fail. If I add a Serial.prinln() directly above one of those statements the controller starts. Why on earth would something happening in the loop cause the touchscreen controller to not start?

Additional info: As stated in the comments I have two Feather boards and two displays. One of those displays is the one shown in the picture, the other one is the breakout board version. Both displays work fine with the examples provided by Adafruit. They also work well most of the time (although sometimes when the touch input is fast the picture gets messed up...probably because my algorithm is crap or the drawing is not fast enough but that's another issue) with what I wrote, except when they don't as explained above. I soldered the I2C pads on the display and the Adafruit tutorial states that the display has indeed I2C as touch interface. I should also mention that it is pretty obvious a problem caused by the code, as when I change it back to when it worked all works fine again.

  • Can you show your wirings? Did you connect the I2C pins to SDA and SCL (if you used A4 and A5 you need to solder these jumpers. Can you double check that the touchscreen has a I2C controller rather than a SPI? Do you have an oscilloscope to see what is going on on the SCL and SDA lines? – frarugi87 Dec 12 '17 at 10:39
  • @frarugi87 I soldered the jumpers and tried it with both the Uno header version as well as the breakout board version of the display. Both work well with the examples provided by Adafruit. I can see if I get access to an oscilloscope and will update the answer. – Lehue Dec 12 '17 at 10:42
  • So the cap touch is working on the uno, but not with the feather? I just noted, moreover, that the feather has 3.3V I/Os. So I suggest you to try powering the board at 3.3V instead of 5V. you will probably lose part of the backlight, but this is just to check if the I2C communication works on the featherù – frarugi87 Dec 12 '17 at 10:50
  • @frarugi87 No, it's working on the feather with provided examples but not with the code written by me. With my code it works if the Serial.println(""); is not commented out. As the feather only has 3V output I am already powering the display this way. I will upload a picture to make it clear – Lehue Dec 12 '17 at 11:25

Your Answer

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

Browse other questions tagged or ask your own question.