├── library.properties ├── .github ├── workflows │ └── githubci.yml ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md ├── README.md ├── Adafruit_FT5336.h ├── examples └── CapTouchPaint │ └── CapTouchPaint.ino └── Adafruit_FT5336.cpp /library.properties: -------------------------------------------------------------------------------- 1 | name=Adafruit FT5336 2 | version=1.0.0 3 | author=Adafruit 4 | maintainer=Adafruit 5 | sentence=Arduino library for FT5336-based Capacitive touch screen 6 | paragraph=Arduino library for FT5336-based Capacitive touch screen 7 | category=Display 8 | url=https://github.com/adafruit/Adafruit_FT5336_Library 9 | architectures=* 10 | depends=Adafruit HX8357 Library, Adafruit GFX Library 11 | -------------------------------------------------------------------------------- /.github/workflows/githubci.yml: -------------------------------------------------------------------------------- 1 | name: Arduino Library CI 2 | 3 | on: [pull_request, push, repository_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/setup-python@v4 11 | with: 12 | python-version: '3.x' 13 | - uses: actions/checkout@v3 14 | - uses: actions/checkout@v3 15 | with: 16 | repository: adafruit/ci-arduino 17 | path: ci 18 | 19 | - name: pre-install 20 | run: bash ci/actions_install.sh 21 | 22 | - name: test platforms 23 | run: python3 ci/build_platform.py main_platforms 24 | 25 | - name: clang 26 | run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 27 | 28 | - name: doxygen 29 | env: 30 | GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }} 31 | PRETTYNAME : "Adafruit FT5336 Arduino Library" 32 | run: bash ci/doxy_gen_and_deploy.sh 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adafruit_FT5336 Library [![Build Status](https://github.com/adafruit/Adafruit_FT5336/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_FT5336/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit_FT5336/html/index.html) 2 | 3 | 4 | 5 | This is a library for the Adafruit FT5336-Based capacitive touch screens and displays 6 | 7 | Check out the links above for our tutorials and wiring diagrams. This chip uses I2C to communicate 8 | 9 | Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! 10 | 11 | Written by Limor Fried/Ladyada for Adafruit Industries. 12 | MIT license, all text above must be included in any redistribution 13 | 14 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for creating a pull request to contribute to Adafruit's GitHub code! 2 | Before you open the request please review the following guidelines and tips to 3 | help it be more easily integrated: 4 | 5 | - **Describe the scope of your change--i.e. what the change does and what parts 6 | of the code were modified.** This will help us understand any risks of integrating 7 | the code. 8 | 9 | - **Describe any known limitations with your change.** For example if the change 10 | doesn't apply to a supported platform of the library please mention it. 11 | 12 | - **Please run any tests or examples that can exercise your modified code.** We 13 | strive to not break users of the code and running tests/examples helps with this 14 | process. 15 | 16 | Thank you again for contributing! We will try to test and integrate the change 17 | as soon as we can, but be aware we have many GitHub repositories to manage and 18 | can't immediately respond to every request. There is no need to bump or check in 19 | on a pull request (it will clutter the discussion of the request). 20 | 21 | Also don't be worried if the request is closed or not integrated--sometimes the 22 | priorities of Adafruit's GitHub code (education, ease of use) might not match the 23 | priorities of the pull request. Don't fret, the open source community thrives on 24 | forks and GitHub makes it easy to keep your changes in a forked repo. 25 | 26 | After reviewing the guidelines above you can delete this text from the pull request. 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for opening an issue on an Adafruit Arduino library repository. To 2 | improve the speed of resolution please review the following guidelines and 3 | common troubleshooting steps below before creating the issue: 4 | 5 | - **Do not use GitHub issues for troubleshooting projects and issues.** Instead use 6 | the forums at http://forums.adafruit.com to ask questions and troubleshoot why 7 | something isn't working as expected. In many cases the problem is a common issue 8 | that you will more quickly receive help from the forum community. GitHub issues 9 | are meant for known defects in the code. If you don't know if there is a defect 10 | in the code then start with troubleshooting on the forum first. 11 | 12 | - **If following a tutorial or guide be sure you didn't miss a step.** Carefully 13 | check all of the steps and commands to run have been followed. Consult the 14 | forum if you're unsure or have questions about steps in a guide/tutorial. 15 | 16 | - **For Arduino projects check these very common issues to ensure they don't apply**: 17 | 18 | - For uploading sketches or communicating with the board make sure you're using 19 | a **USB data cable** and **not** a **USB charge-only cable**. It is sometimes 20 | very hard to tell the difference between a data and charge cable! Try using the 21 | cable with other devices or swapping to another cable to confirm it is not 22 | the problem. 23 | 24 | - **Be sure you are supplying adequate power to the board.** Check the specs of 25 | your board and plug in an external power supply. In many cases just 26 | plugging a board into your computer is not enough to power it and other 27 | peripherals. 28 | 29 | - **Double check all soldering joints and connections.** Flakey connections 30 | cause many mysterious problems. See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints. 31 | 32 | - **Ensure you are using an official Arduino or Adafruit board.** We can't 33 | guarantee a clone board will have the same functionality and work as expected 34 | with this code and don't support them. 35 | 36 | If you're sure this issue is a defect in the code and checked the steps above 37 | please fill in the following fields to provide enough troubleshooting information. 38 | You may delete the guideline and text above to just leave the following details: 39 | 40 | - Arduino board: **INSERT ARDUINO BOARD NAME/TYPE HERE** 41 | 42 | - Arduino IDE version (found in Arduino -> About Arduino menu): **INSERT ARDUINO 43 | VERSION HERE** 44 | 45 | - List the steps to reproduce the problem below (if possible attach a sketch or 46 | copy the sketch code in too): **LIST REPRO STEPS BELOW** 47 | -------------------------------------------------------------------------------- /Adafruit_FT5336.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_FT5336.h 3 | */ 4 | 5 | #ifndef ADAFRUIT_FT5336_LIBRARY 6 | #define ADAFRUIT_FT5336_LIBRARY 7 | 8 | #include "Arduino.h" 9 | #include 10 | 11 | #define FT53XX_DEFAULT_ADDR 0x38 //!< I2C address 12 | #define FT53XX_REG_VENDID 0xA3 //!< FocalTech's panel ID 13 | #define FT53XX_REG_FIRMVERS 0xA6 //!< Firmware version 14 | #define FT53XX_REG_CHIPID 0xA8 //!< Chip selecting 15 | 16 | #define FT53XX_VENDID 0x11 //!< FocalTech's panel ID 17 | #define FT5336_CHIPID 0x79 //!< Chip selecting 18 | 19 | #define FT53XX_REG_NUMTOUCHES 0x02 //!< Number of touch points 20 | 21 | #define FT5336_REG_THRESHGROUP 0x80 //!< Threshold for touch detection 22 | 23 | #define FT5336_TD_STATUS 0x02 /// http://www.adafruit.com/products/5846 5 | 6 | Check out the links above for our tutorials and wiring diagrams 7 | 8 | Adafruit invests time and resources providing this open source code, 9 | please support Adafruit and open-source hardware by purchasing 10 | products from Adafruit! 11 | 12 | Written by Limor Fried/Ladyada for Adafruit Industries. 13 | MIT license, all text above must be included in any redistribution 14 | ****************************************************/ 15 | 16 | 17 | #include 18 | #include 19 | 20 | // The FT5336 uses hardware I2C (SCL/SDA) 21 | Adafruit_FT5336 ctp = Adafruit_FT5336(); 22 | #define FT5336_MAXTOUCHES 5 23 | 24 | // The display also uses hardware SPI, plus #9 & #10 25 | #define TFT_CS 9 26 | #define TFT_RST -1 27 | #define TFT_DC 10 28 | Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC); 29 | 30 | // Size of the color selection boxes and the paintbrush size 31 | #define BOXSIZE 40 32 | #define PENRADIUS 3 33 | int oldcolor, currentcolor; 34 | 35 | void setup(void) { 36 | Serial.begin(115200); 37 | //while (!Serial) delay(10); // pause the serial port 38 | 39 | Serial.println("3.5 inch Cap Touch Paint!"); 40 | 41 | tft.begin(); 42 | 43 | if (! ctp.begin(FT53XX_DEFAULT_ADDR, &Wire)) { // pass in 'sensitivity' coefficient and I2C bus 44 | Serial.println("Couldn't start FT5336 touchscreen controller"); 45 | while (1) delay(10); 46 | } 47 | 48 | Serial.println("Capacitive touchscreen started"); 49 | 50 | tft.fillScreen(HX8357_BLACK); 51 | 52 | // make the color selection boxes 53 | tft.fillRect(0, 0, BOXSIZE, BOXSIZE, HX8357_RED); 54 | tft.fillRect(BOXSIZE, 0, BOXSIZE, BOXSIZE, HX8357_YELLOW); 55 | tft.fillRect(BOXSIZE*2, 0, BOXSIZE, BOXSIZE, HX8357_GREEN); 56 | tft.fillRect(BOXSIZE*3, 0, BOXSIZE, BOXSIZE, HX8357_CYAN); 57 | tft.fillRect(BOXSIZE*4, 0, BOXSIZE, BOXSIZE, HX8357_BLUE); 58 | tft.fillRect(BOXSIZE*5, 0, BOXSIZE, BOXSIZE, HX8357_MAGENTA); 59 | tft.fillRect(BOXSIZE*6, 0, BOXSIZE, BOXSIZE, HX8357_WHITE); 60 | tft.fillRect(BOXSIZE*7, 0, BOXSIZE, BOXSIZE, HX8357_BLACK); 61 | 62 | // select the current color 'red' 63 | tft.drawRect(0, 0, BOXSIZE, BOXSIZE, HX8357_WHITE); 64 | currentcolor = HX8357_RED; 65 | } 66 | 67 | void loop() { 68 | uint8_t touches = ctp.touched(); 69 | // Wait for a touch 70 | if (! touches) { 71 | return; 72 | } 73 | 74 | // Retrieve the points, up to 5! 75 | TS_Point ps[FT5336_MAXTOUCHES]; 76 | ctp.getPoints(ps, FT5336_MAXTOUCHES); 77 | 78 | for (int i=0; i BOXSIZE) && ((ps[i].y+PENRADIUS) < tft.height())) { 152 | tft.fillCircle(ps[i].x, ps[i].y, PENRADIUS, currentcolor); 153 | } 154 | } 155 | } -------------------------------------------------------------------------------- /Adafruit_FT5336.cpp: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file Adafruit_FT5336.cpp 3 | * 4 | * @mainpage Adafruit FT5336 Library 5 | * 6 | * @section intro_sec Introduction 7 | * 8 | * This is a library for the Adafruit Capacitive Touch Screens 9 | * 10 | * ----> http://www.adafruit.com/products/1947 11 | * 12 | * Check out the links above for our tutorials and wiring diagrams 13 | * This chipset uses I2C to communicate 14 | * 15 | * Adafruit invests time and resources providing this open source code, 16 | * please support Adafruit and open-source hardware by purchasing 17 | * products from Adafruit! 18 | * 19 | * @section author Author 20 | * 21 | * Written by Limor Fried/Ladyada for Adafruit Industries. 22 | * 23 | * @section license License 24 | 25 | * MIT license, all text above must be included in any redistribution 26 | */ 27 | 28 | #include 29 | 30 | //#define FT5336_DEBUG 31 | 32 | /**************************************************************************/ 33 | /*! 34 | @brief Instantiates a new FT5336 class 35 | */ 36 | /**************************************************************************/ 37 | // I2C, no address adjustments or pins 38 | Adafruit_FT5336::Adafruit_FT5336() { touches = 0; } 39 | 40 | /**************************************************************************/ 41 | /*! 42 | @brief Setups the I2C interface and hardware, identifies if chip is found 43 | @param i2c_addr The 7-bit address, defaults to 0x38 44 | @param theWire Which I2C bus to use, defaults to &Wire 45 | @returns True if an FT5336 is found, false on any failure 46 | */ 47 | /**************************************************************************/ 48 | bool Adafruit_FT5336::begin(uint8_t i2c_addr, TwoWire *theWire) { 49 | if (i2c_dev) 50 | delete i2c_dev; 51 | i2c_dev = new Adafruit_I2CDevice(i2c_addr, theWire); 52 | if (!i2c_dev->begin()) 53 | return false; 54 | 55 | #ifdef FT5336_DEBUG 56 | Serial.print("Vend ID: 0x"); 57 | Serial.println(readRegister8(FT53XX_REG_VENDID), HEX); 58 | Serial.print("Chip ID: 0x"); 59 | Serial.println(readRegister8(FT53XX_REG_CHIPID), HEX); 60 | Serial.print("Firm V: "); 61 | Serial.println(readRegister8(FT53XX_REG_FIRMVERS)); 62 | Serial.print("Thresh: "); 63 | Serial.println(readRegister8(FT5336_REG_THRESHGROUP)); 64 | 65 | // dump all registers 66 | for (int16_t i = 0; i < 0x10; i++) { 67 | Serial.print("I2C $"); 68 | Serial.print(i, HEX); 69 | Serial.print(" = 0x"); 70 | Serial.println(readRegister8(i), HEX); 71 | } 72 | #endif 73 | 74 | // change threshhold to be higher/lower 75 | // writeRegister8(FT53XX_REG_THRESHHOLD, thresh); 76 | 77 | if (readRegister8(FT53XX_REG_VENDID) != FT53XX_VENDID) { 78 | return false; 79 | } 80 | uint8_t id = readRegister8(FT53XX_REG_CHIPID); 81 | if (id != FT5336_CHIPID) { 82 | return false; 83 | } 84 | 85 | return true; 86 | } 87 | 88 | /**************************************************************************/ 89 | /*! 90 | @brief Determines if there are any touches detected 91 | @returns Number of touches detected, can be 0 or 1-5 for multitouch 92 | */ 93 | /**************************************************************************/ 94 | uint8_t Adafruit_FT5336::touched(void) { 95 | uint8_t n = readRegister8(FT53XX_REG_NUMTOUCHES); 96 | if (n > 5) { 97 | n = 0; 98 | } 99 | return n; 100 | } 101 | 102 | /**************************************************************************/ 103 | /*! 104 | @brief Queries the chip and retrieves a point data 105 | @param n The # index (0 to 4 inclusive) to the points we can detect. 106 | @returns {@link TS_Point} object that has the x and y coordinets set. If the 107 | z coordinate is 0 it means the point is not touched. If z is 1, it is 108 | currently touched. 109 | */ 110 | /**************************************************************************/ 111 | TS_Point Adafruit_FT5336::getPoint(uint8_t n) { 112 | readData(); 113 | if ((touches == 0) || (n > 1)) { 114 | return TS_Point(0, 0, 0); 115 | } else { 116 | return TS_Point(touchX[n], touchY[n], 1); 117 | } 118 | } 119 | 120 | /**************************************************************************/ 121 | /*! 122 | @brief Queries the chip and retrieves up to 'maxtouches' points 123 | @param points Array of {@link TS_Point} objects that will be filled with 124 | x/y/z data. z coordinate is 0 it means the point is not touched. If z is 1, 125 | it is currently touched. 126 | @param maxtouches The number of allocated points that we could fill with 127 | data. 128 | */ 129 | /**************************************************************************/ 130 | void Adafruit_FT5336::getPoints(TS_Point *points, uint8_t maxtouches) { 131 | readData(); 132 | 133 | // zero out all the points 134 | for (uint8_t i = 0; i < maxtouches; i++) { 135 | points[i].x = 0; 136 | points[i].y = 0; 137 | points[i].z = 0; 138 | } 139 | 140 | // identify all points and assign 141 | for (uint8_t i = 0; i < touches; i++) { 142 | uint8_t id = touchID[i]; 143 | if (id >= maxtouches) 144 | continue; 145 | points[id].x = touchX[i]; 146 | points[id].y = touchY[i]; 147 | points[id].z = 1; 148 | } 149 | } 150 | 151 | /************ lower level i/o **************/ 152 | 153 | /**************************************************************************/ 154 | /*! 155 | @brief Reads the bulk of data from captouch chip. Fill in {@link touches}, 156 | {@link touchX}, {@link touchY} and {@link touchID} with results 157 | */ 158 | /**************************************************************************/ 159 | void Adafruit_FT5336::readData(void) { 160 | 161 | uint8_t i2cdat[32]; 162 | uint8_t addr = 0; 163 | i2c_dev->write_then_read(&addr, 1, i2cdat, 32); 164 | 165 | touches = i2cdat[FT5336_TD_STATUS]; 166 | if ((touches > 5) || (touches == 0)) { 167 | touches = 0; 168 | } 169 | gesture = i2cdat[FT5336_GEST_ID]; 170 | #ifdef FT5336_DEBUG 171 | if (gesture) { 172 | Serial.print("Gesture #"); 173 | Serial.println(gesture); 174 | } 175 | #endif 176 | 177 | for (uint8_t i = 0; i < touches; i++) { 178 | touchX[i] = i2cdat[FT5336_TOUCH1_XH + i * 6] & 0x0F; 179 | touchX[i] <<= 8; 180 | touchX[i] |= i2cdat[FT5336_TOUCH1_XL + i * 6]; 181 | 182 | touchY[i] = i2cdat[FT5336_TOUCH1_YH + i * 6] & 0x0F; 183 | touchY[i] <<= 8; 184 | touchY[i] |= i2cdat[FT5336_TOUCH1_YL + i * 6]; 185 | 186 | touchID[i] = i2cdat[FT5336_TOUCH1_YH + i * 6] >> 4; 187 | } 188 | 189 | #ifdef FT5336_DEBUG 190 | Serial.println(); 191 | for (uint8_t i = 0; i < touches; i++) { 192 | Serial.print("ID #"); 193 | Serial.print(touchID[i]); 194 | Serial.print("\t("); 195 | Serial.print(touchX[i]); 196 | Serial.print(", "); 197 | Serial.print(touchY[i]); 198 | Serial.print(") "); 199 | } 200 | Serial.println(); 201 | #endif 202 | } 203 | 204 | uint8_t Adafruit_FT5336::readRegister8(uint8_t reg) { 205 | uint8_t buffer[1] = {reg}; 206 | i2c_dev->write_then_read(buffer, 1, buffer, 1); 207 | return buffer[0]; 208 | } 209 | 210 | void Adafruit_FT5336::writeRegister8(uint8_t reg, uint8_t val) { 211 | uint8_t buffer[2] = {reg, val}; 212 | i2c_dev->write(buffer, 2); 213 | } 214 | 215 | /**************************************************************************/ 216 | /*! 217 | @brief Instantiates a new touchpoint class with x, y and z set to 0 by 218 | default 219 | */ 220 | /**************************************************************************/ 221 | TS_Point::TS_Point(void) { x = y = z = 0; } 222 | 223 | /**************************************************************************/ 224 | /*! 225 | @brief Instantiates a new touchpoint class with x, y and z set by params. 226 | @param _x The X coordinate 227 | @param _y The Y coordinate 228 | @param _z The Z coordinate 229 | */ 230 | /**************************************************************************/ 231 | 232 | TS_Point::TS_Point(int16_t _x, int16_t _y, int16_t _z) { 233 | x = _x; 234 | y = _y; 235 | z = _z; 236 | } 237 | 238 | /**************************************************************************/ 239 | /*! 240 | @brief Simple == comparator for two TS_Point objects 241 | @param p1 The other object to compare against 242 | @returns True if x, y and z are the same for both points, False otherwise. 243 | */ 244 | /**************************************************************************/ 245 | bool TS_Point::operator==(TS_Point p1) { 246 | return ((p1.x == x) && (p1.y == y) && (p1.z == z)); 247 | } 248 | 249 | /**************************************************************************/ 250 | /*! 251 | @brief Simple != comparator for two TS_Point objects 252 | @param p1 The other object to compare against 253 | @returns False if x, y and z are the same for both points, True otherwise. 254 | */ 255 | /**************************************************************************/ 256 | bool TS_Point::operator!=(TS_Point p1) { 257 | return ((p1.x != x) || (p1.y != y) || (p1.z != z)); 258 | } 259 | --------------------------------------------------------------------------------