/*
XPT2046 (pin/function compatible to ADS7843)
Resistive Touch Screen Controller module
` ` `
var touch, touchModule = require("XPT2046");
function onInit() {
// ...
// setup touchscreen
SPI2.setup({sck:B13, miso:B14, mosi:B15, baud: 2000000});
touch = tMod.connect(
// spi, cs, irq, callback, calc // landscape
SPI2, B10, B1, function(x, y, rd) { // portrait
if (x !== undefined) {
console.log(x,y);
}
}, function(yr, xr, d) { // calc function - converts raw data to x / y coordinates;
// scale and offset values calculated using markers and default calc function.
// see http://forum.espruino.com/conversations/292641 - Touchscreen
// return [ Math.round(xr / xsc + xos) // / x scale per pixel + x offset
// , Math.round(yr / ysc + yos) // / y scale per pixel + y offset
return [ Math.round(xr / -121.44 + 259.70685111989)
, Math.round(yr / 88.90357142857 + -19.78130398103)
];
});
// ...
}
` ` `
*/
exports = // XPT2046 module
{ calc: function(x, y, d) { return [x,y,d]; } // default calculation
, connect: function(spi, cs, irq, callback, calc) {
// overwrite default 'calculation': pass thru incl. raw values
if (calc) { this.calc = calc; }
// wake the controller up
spi.send([0x90,0],cs);
// look for a press
var watchFunction = function() {
var interval = setInterval(function () {
if (!digitalRead(irq)) { // touch down
var d = spi.send([0x90,0,0xD0,0,0], cs);
callback.apply(undefined, this.calc(d[1]*256+d[2], d[3]*256+d[4], d));
} else {
callback();
clearInterval(interval);
interval = undefined;
setWatch(watchFunction, irq, { repeat : false, edge: "falling" });
}
}.bind(this), 50);
}.bind(this);
setWatch(watchFunction, irq, { repeat : false, edge: "falling" });
return this;
}
};
Application using the (minified) module code from local Web IDE sandbox/modules folder. Note the touchscreen module .connect() that is supplied with the calculation function to converts the raw screen controller data into x and y for the screen.
// TFT24TRCportraitCalibr3.js - XPT2046 module test
//
// 2.4" 240x320 262K Color TFT LCD ILI9341 on SPI1 with
// Resistive Touch Screen Controller XPT2046 on SPI2
// using out of box ILI9341 and ADS7843 modules.
//
// Wiring:
// 2.4"
// DSP PICO [<---USB
// 1 VCC red 3 3.3 shared
// 2 GND blk 1 GND shared
// 3 CS blu 7 B6 CS LCD
// 4 RST brn 9 A8 reset RST LCD
// 5 D/C grn 8 B7 D/C LCD
// 6 MOSI ylw 6 B5 SPI1 MOSI LCD
// 7 SCK wht 4 B3 SPI1 SCK LCD
// 8 LED org 18 A5 LED LCD
// 9 MISO grn 5 B4 SPI1 MISO LCD
// 10 T_CLK wht 23 B13 SPI2 SCK Touch
// 11 T_CS ylw 22 B10 CS Touch
// 12 T_MOSI grn 25 B15 SPI2 MOSI Touch
// 13 T_MISO blu 24 B14 SPI2 MISO Touch
// 14 T_IRQ blk 21 B1 IRQ Touch
var dW = 240, dH = 320, dsp, dMod = require("ILI9341"),
touch, tMod = require("XPT2046");
// marker specs (lik dice face 5; top left to bottom right)
var mrks =
[{i:1, label:"topLeft ", x: 20, y: 20, xOff: 14, yOff:-6}
,{i:2, label:"topRight ", x:220, y: 20, xOff:-66, yOff:-6}
,{i:3, label:"center ", x:120, y:160, xOff:-29, yOff:14}
,{i:4, label:"bottomLeft ", x: 20, y:300, xOff: 14, yOff:-6}
,{i:5, label:"bottomRight", x:220, y:300, xOff:-74, yOff:-6}
];
var mSiz = 9; // half of marker size, (0.7 of font size)
// print marker at x/y of size s with x/y label
function mrkr(d,x,y,s,xOff,yOff) {
dsp.setColor(1,1,1);
dsp.drawRect(x-s,y-s,x+s,y+s);
dsp.drawLine(x-s,y,x+s,y);
dsp.drawLine(x,y-s,x,y+s);
dsp.setFontVector(s / 0.7);
dsp.drawString(x + " / " + y, x+xOff, y+yOff);
}
function fInt(i,l) { return (" " + i).substr(-l); }
function onInit() {
A5.set();
SPI1.setup({sck:B3, miso:B4, mosi:B5, baud: 1000000});
// spi, dc, cs, rst, callback
dsp = dMod.connect(SPI1, B7, B6, A8, function() {
dsp.clear();
// print markers like dice face of 5
mrks.forEach(function(m) {
mrkr(dsp, m.x, m.y, mSiz, m.xOff, m.yOff); });
// setup touchscreen
SPI2.setup({sck:B13, miso:B14, mosi:B15, baud: 2000000});
touch = tMod.connect(
// spi, cs, irq, callback, calc
SPI2, B10, B1, function(x, y) {
if (x !== undefined) {
console.log(fInt(x,4),fInt(y,4));
}
}, function(yr, xr, d) {
// calc function - converts raw data to x / y coordinates;
// scale and offset values calculated using calibration
// markers and default calc function. For more details see
// http://forum.espruino.com/conversations/292641 - Touchscreen
// return [ Math.round(xr / xsc + xos) // / x scale per pixel + x offset
// , Math.round(yr / ysc + yos) // / y scale per pixel + y offset
return [ Math.round(xr / -121.44 + 259.70685111989)
, Math.round(yr / 88.90357142857 + -19.78130398103)
];
});
});
}
onInit();
Related console output (tapping on markers on screen).
NOTE the last 4 lines which lay outside of the display, because the touch screen has a pretty sizable porch at the bottom.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
XPT2046.js module code:
Application using the (minified) module code from local Web IDE sandbox/modules folder. Note the touchscreen module
.connect()
that is supplied with the calculation function to converts the raw screen controller data into x and y for the screen.Related console output (tapping on markers on screen).
NOTE the last 4 lines which lay outside of the display, because the touch screen has a pretty sizable porch at the bottom.
Note: This module is used in Modular and extensible UI framework and ui elements conversation.
1 Attachment