CelliesProjects / aquacontrol32

5 channel aquarium LED controller with web interface for ESP32 boards. Supports DS18B20, SSD1306, ILI9341, XPT2046 and SmartConfig. Arduino IDE.
MIT License
62 stars 20 forks source link

Problem with Touchscreen #5

Closed Odaller closed 6 years ago

Odaller commented 6 years ago

I have tested 2 different ILI9341 screens, both with XPT2046 touch controller and wired correctly (I assume). Screen works fine with the has_no_mosi option, but I cant get the touch function working. Is there a touch example I could try? I tried the examples in the librarie without succes.

CelliesProjects commented 6 years ago

You could try my mapTouch Gist. Don't forget the pull-ups on the mosi, irq and cs lines.

The example does not use interrupts, but the Aquacontrol code does.

/* Map XPT2046 input to ILI9341 320x240 raster */
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <XPT2046_Touchscreen.h> /* https://github.com/PaulStoffregen/XPT2046_Touchscreen */

#define TFT_DC             27
#define _sclk              25
#define _mosi              32 /* 10K pull-up */
#define _miso              39
#define TFT_CS              4 /* 10K pull-up */
#define TFT_RST            12
#define TFT_BACKLIGHT_PIN   2 /* -via transistor- */
#define TOUCH_CS_PIN       33 /* 10K pull-up */
#define TOUCH_IRQ_PIN      35 /* 10K pull-up */

#define TFT_NORMAL          1
#define TFT_UPSIDEDOWN      3

const uint8_t TFT_ORIENTATION = TFT_NORMAL;

Adafruit_ILI9341 tft = Adafruit_ILI9341( TFT_CS, TFT_DC, TFT_RST );

XPT2046_Touchscreen touch( TOUCH_CS_PIN, TOUCH_IRQ_PIN );

void setup() {
  Serial.begin( 115200 );
  SPI.begin( _sclk, _miso, _mosi );
  SPI.setFrequency( 60000000 );

  tft.begin( 10000000, SPI );

  tft.setRotation( TFT_ORIENTATION );
  tft.fillScreen( ILI9341_BLACK );
  tft.setTextColor( ILI9341_GREEN, ILI9341_BLACK );

  pinMode( TFT_BACKLIGHT_PIN, OUTPUT );
  digitalWrite( TFT_BACKLIGHT_PIN, HIGH );

  touch.begin();
  Serial.println( "Touch screen ready." );
}

TS_Point rawLocation;

void loop() {
  //if ( touch.touched() )
    while ( touch.touched() )
    {
      rawLocation = touch.getPoint();
      /*
        tft.setCursor( 100, 150 );
        tft.print( "X = " );
        tft.print( rawLocation.x );
        tft.setCursor(100, 180);
        tft.print( "Y = " );
        tft.print( rawLocation.y );
        Serial.print("x = ");
        Serial.print(rawLocation.x);
        Serial.print(", y = ");
        Serial.print(rawLocation.y);
        Serial.print(", z = ");
        Serial.println(rawLocation.z);
      */
      if ( TFT_ORIENTATION == TFT_UPSIDEDOWN )
      {
        tft.drawPixel( mapFloat( rawLocation.x, 340, 3900, 0, 320 ),
                       mapFloat( rawLocation.y, 200, 3850, 0, 240 ),
                       ILI9341_GREEN );
      }
      if ( TFT_ORIENTATION == TFT_NORMAL )
      {
        tft.drawPixel( mapFloat( rawLocation.x, 340, 3900, 320, 0 ),
                       mapFloat( rawLocation.y, 200, 3850, 240, 0 ),
                       ILI9341_GREEN );
      }
    }
  //tft.fillScreen(ILI9341_BLACK);
}

static inline __attribute__((always_inline)) float mapFloat( float x, const float in_min, const float in_max, const float out_min, const float out_max)
{
  return ( x - in_min ) * ( out_max - out_min ) / ( in_max - in_min ) + out_min;
}

Just tested here, should work fine.

Odaller commented 6 years ago

Thanks, I got it working now, well, kind of (see below). The fault was mine.

I just have to figure out why everything is reversed: Touch: I touch the left bottom corner, the screen registers the right top corner... etcetera. Backlight: the higher I put the slider, the lower the backlight intensity gets. 100% is almost completely dark, 0% is superbright.

CelliesProjects commented 6 years ago

Ah, I have one of those here too.

I just thought it was a one-off. Seems that it is rather common. Will include an option to reverse the input from the touch screen.

CelliesProjects commented 6 years ago

Just commited 2d5d97224b41eeef8cb680e41b40cf89a35b7bcb which is a simple fix for reversed touch coordinates. Set TOUCH_IS_INVERTED to 1 in aquacontrol32.ino to use these displays.

CelliesProjects commented 6 years ago

@Odaller Does that commit work?

Odaller commented 6 years ago

Yes this fix did the trick for the inverted coördinates. Thank you!