-
-
Notifications
You must be signed in to change notification settings - Fork 117
XPT2046 Driver and Example #1406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Workshopshed
wants to merge
15
commits into
nanoframework:develop
Choose a base branch
from
Workshopshed:develop
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+867
−0
Open
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
b0d1734
XPT2046 Initial Commit
cdca584
XPT2046
1ea951f
XPT2046 Driver and Example
TechyChap 3b8dcc9
XPT2046 Moved demo into subolder
TechyChap cca77ce
XPT2046 Driver and Example
9182065
Merge branch 'develop' into develop
Workshopshed 756f395
XPT2046 Fixed Typos
TechyChap 58c5fb7
Merge remote-tracking branch 'origin/develop' into develop
TechyChap 9b4d052
XPT2046 Corrected categorisation
TechyChap b538ac6
XPT2045 Corrected version case
TechyChap 367cc7c
Merge branch 'develop' of https://github.com/Workshopshed/nanoFramewo…
9403f36
XPT2046 Added StyleCop
Workshopshed bda1ee0
XPT2046 Versioning
Workshopshed 031222c
Merge branch 'develop' into develop
Ellerbach 45a1410
Merge branch 'develop' into develop
Workshopshed File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (c) .NET Foundation and Contributors | ||
// Portions Copyright (c) Microsoft Corporation. All rights reserved. | ||
// See LICENSE file in the project root for full license information. | ||
|
||
namespace Iot.Device.XPT2046 | ||
{ | ||
/// <summary> | ||
/// A touch point. | ||
/// </summary> | ||
public struct Point | ||
{ | ||
/// <summary> | ||
/// Gets or sets X. | ||
/// </summary> | ||
public int X { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets Y. | ||
/// </summary> | ||
public int Y { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the amount of pressure of the touch. | ||
/// </summary> | ||
public int Weight { get; set; } | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) .NET Foundation and Contributors | ||
// Portions Copyright (c) Microsoft Corporation. All rights reserved. | ||
// See LICENSE file in the project root for full license information. | ||
|
||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
[assembly: AssemblyTitle("Iot.Device.XPT2046")] | ||
[assembly: AssemblyDescription("XPT2046 Touch Screen Controller driver for .NET nanoFramework")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("nanoFramework Contributors")] | ||
[assembly: AssemblyProduct("Iot.Device.XPT2046")] | ||
[assembly: AssemblyCopyright("Copyright © .NET Foundation and Contributors")] | ||
[assembly: AssemblyTrademark("")] | ||
[assembly: AssemblyCulture("")] | ||
|
||
// Setting ComVisible to false makes the types in this assembly not visible | ||
// to COM components. If you need to access a type in this assembly from | ||
// COM, set the ComVisible attribute to true on that type. | ||
[assembly: ComVisible(false)] | ||
|
||
// Version information managed by Nerdbank.GitVersioning package. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# XPT2046 - Touch screen controller | ||
|
||
The XPT2046 from XPTEK is a 4-wire resistive touch screen controller that incorporates a 12-bit 125 kHz successive approximation register type A/D converter. The XPT2046 can detect the pressed screen location by performing two A/D conversions. As well as the location, the XPT2046 also measures touch screen pressure. A multiplexer allows it to measure chip temperature and battery voltage. | ||
|
||
The XPT2046 is common in a number of touch screen modules from suppliers like WaveShare and an number of ESP32 based display boards. | ||
|
||
Communication is via the SPI bus which can communicate at maximum speed of 2Mhz and uses Mode 0 for the clock polarity/phase setting. The host sends an 8 bit command and the chip responds with 16 bits of data althought the first bit and last three bits are not part of the conversion. XPT2046 needs 16 clock cycles to read a value, so this driver sends 8 bits and a padding byte between each command, and the device can be reading one result whilst sending the command for the next measurement. When reading we need to skip the first 8 bits. | ||
|
||
An additional interupt pin which is usually in a high state and goes low when a touch is detected. Note that communicating with the chip will interfere with the interupt. | ||
|
||
The chip can use an internal voltage reference or be configured to use an external reference if more accuracy is required. | ||
|
||
The XPT2046 will enter power down mode and stop communicating when the chip select pin is taken high. This is why TransferFullDuplex is used as the framework does not expose the raw SPI transaction. | ||
|
||
The driver does a best of 3 average, thanks Paul Stoffregen for the suggestion via your Arduino library. | ||
|
||
## Documentation | ||
|
||
Datasheet - https://www.waveshare.com/wiki/File:XPT2046-EN.pdf | ||
|
||
## Usage | ||
|
||
See TouchDemo for a complete example of usage based on the ESP32 and a cheap yellow display module. | ||
|
||
The driver also supports a maximum X and Y value so you can map the output to your screen size. | ||
|
||
The driver scales the output based on a maximum X and Y value so you can map it to pixels on your screen. | ||
|
||
**Important**: For the ESP32 the default pins can be remapped, do so before creating the `SPIDevice`. | ||
|
||
```csharp | ||
using nanoFramework.Hardware.ESP32; | ||
|
||
// Pin Definitions for the Cheap Yellow Display | ||
const int XPT2046_CS = Gpio.IO33; // Chip Select | ||
const int XPT2046_PenIRQ = Gpio.IO36; // Touch detected interupt | ||
const int XPT2046_COPI = Gpio.IO32; | ||
const int XPT2046_CIPO = Gpio.IO39; | ||
const int XPT2046_CLK = Gpio.IO25; | ||
|
||
// If you're using an ESP32, use nanoFramework.Hardware.Esp32 to remap the SPI pins | ||
Configuration.SetPinFunction(XPT2046_COPI, DeviceFunction.SPI1_MOSI); | ||
Configuration.SetPinFunction(XPT2046_CIPO, DeviceFunction.SPI1_CLOCK); | ||
Configuration.SetPinFunction(XPT2046_CLK, DeviceFunction.SPI1_MISO); | ||
``` | ||
|
||
```csharp | ||
using System.Device.Spi; | ||
|
||
SpiDevice spiDevice; | ||
SpiConnectionSettings connectionSettings; | ||
connectionSettings = new SpiConnectionSettings(1, XPT2046_CS); | ||
connectionSettings.ClockFrequency = 2_000_000; | ||
connectionSettings.DataBitLength = 8; | ||
connectionSettings.DataFlow = DataFlow.MsbFirst; | ||
connectionSettings.Mode = SpiMode.Mode0; | ||
|
||
// Then you create your SPI device by passing your settings | ||
spiDevice = SpiDevice.Create(connectionSettings); | ||
|
||
using GpioController gpio = new(); | ||
using Xpt2046 sensor = new(spiDevice); | ||
var ver = sensor.GetVersion(); | ||
|
||
Debug.WriteLine($"version: {ver}"); | ||
|
||
var point = sensor.GetPoint(); | ||
|
||
Debug.WriteLine($"ID: {point.TouchId}, X: {point.X}, Y: {point.Y}, Weight: {point.Weigth}, Misc: {point.Miscelaneous}"); | ||
|
||
``` | ||
|
||
Use with an interupt pin. Note that interupts that happen during conversion are not reliable. Hence setting touchDetected after calling GetPoint(); | ||
|
||
```csharp | ||
bool touchDetected = false; | ||
|
||
gpio.OpenPin(XPT2046_PenIRQ, PinMode.Input); | ||
// This will enable an event on GPIO36 on falling edge when the screen if touched | ||
gpio.RegisterCallbackForPinValueChangedEvent(XPT2046_PenIRQ, PinEventTypes.Falling, TouchInterrupCallback); | ||
|
||
while (true) | ||
{ | ||
if (touchDetected) { | ||
var point = sensor.GetPoint(); | ||
touchDetected = false; | ||
|
||
Debug.WriteLine($"ID: {point.TouchId}, X: {point.X}, Y: {point.Y}, Weight: {point.Weigth}, Misc: {point.Miscelaneous}"); | ||
|
||
Thread.Sleep(500); | ||
|
||
} | ||
|
||
Thread.Sleep(20); | ||
} | ||
|
||
void TouchInterrupCallback(object sender, PinValueChangedEventArgs pinValueChangedEventArgs) | ||
{ | ||
touchDetected = true; | ||
} | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<StyleCopSettings Version="105"> | ||
<Analyzers> | ||
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules"> | ||
<Rules> | ||
<Rule Name="FileHeaderMustContainFileName"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="FileHeaderMustHaveValidCompanyText"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="FileHeaderFileNameDocumentationMustMatchTypeName"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="PropertyDocumentationMustHaveValueText"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">True</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="DocumentationTextMustBeginWithACapitalLetter"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">True</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="DocumentationTextMustEndWithAPeriod"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">True</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="FileHeaderMustShowCopyright"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="FileHeaderMustHaveCopyrightText"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="ElementDocumentationMustBeSpelledCorrectly"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="DocumentationTextMustContainWhitespace"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
</Rules> | ||
<AnalyzerSettings> | ||
<BooleanProperty Name="IgnorePrivates">True</BooleanProperty> | ||
<BooleanProperty Name="IgnoreInternals">True</BooleanProperty> | ||
</AnalyzerSettings> | ||
</Analyzer> | ||
<Analyzer AnalyzerId="StyleCop.CSharp.ReadabilityRules"> | ||
<Rules> | ||
<Rule Name="PrefixLocalCallsWithThis"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="PrefixCallsCorrectly"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
</Rules> | ||
<AnalyzerSettings /> | ||
</Analyzer> | ||
<Analyzer AnalyzerId="StyleCop.CSharp.OrderingRules"> | ||
<Rules> | ||
<Rule Name="UsingDirectivesMustBePlacedWithinNamespace"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="ElementsMustAppearInTheCorrectOrder"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="ElementsMustBeOrderedByAccess"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
</Rules> | ||
<AnalyzerSettings /> | ||
</Analyzer> | ||
<Analyzer AnalyzerId="StyleCop.CSharp.NamingRules"> | ||
<Rules> | ||
<Rule Name="FieldNamesMustNotBeginWithUnderscore"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
<Rule Name="FieldNamesMustNotUseHungarianNotation"> | ||
<RuleSettings> | ||
<BooleanProperty Name="Enabled">False</BooleanProperty> | ||
</RuleSettings> | ||
</Rule> | ||
</Rules> | ||
<AnalyzerSettings /> | ||
</Analyzer> | ||
</Analyzers> | ||
</StyleCopSettings> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
using Iot.Device.XPT2046; | ||
using nanoFramework.Hardware.Esp32; | ||
using System; | ||
using System.Device.Gpio; | ||
using System.Device.Spi; | ||
using System.Diagnostics; | ||
using System.Threading; | ||
|
||
namespace TouchDemo | ||
{ | ||
|
||
|
||
public class Program | ||
{ | ||
static bool touchDetected = false; | ||
|
||
public static void Main() | ||
{ | ||
Debug.WriteLine("Hello from nanoFramework!"); | ||
|
||
const int XPT2046_CS = Gpio.IO33; // Chip Select | ||
const int XPT2046_PenIRQ = Gpio.IO36; // Touch detected interupt | ||
const int XPT2046_COPI = Gpio.IO32; | ||
const int XPT2046_CIPO = Gpio.IO39; | ||
const int XPT2046_CLK = Gpio.IO25; | ||
|
||
try | ||
{ | ||
//Move Display pins to correct SPI bus as the default overlaps with the XPT2046 pins | ||
Configuration.SetPinFunction(Gpio.IO13, DeviceFunction.SPI1_MOSI); | ||
Configuration.SetPinFunction(Gpio.IO14, DeviceFunction.SPI1_CLOCK); | ||
Configuration.SetPinFunction(Gpio.IO12, DeviceFunction.SPI1_MISO); | ||
|
||
// For the XPT2046 Touch controller | ||
Configuration.SetPinFunction(XPT2046_COPI, DeviceFunction.SPI2_MOSI); | ||
Configuration.SetPinFunction(XPT2046_CIPO, DeviceFunction.SPI2_MISO); | ||
Configuration.SetPinFunction(XPT2046_CLK, DeviceFunction.SPI2_CLOCK); | ||
|
||
SpiDevice spiDevice; | ||
SpiConnectionSettings connectionSettings; | ||
|
||
connectionSettings = new SpiConnectionSettings(2, XPT2046_CS); | ||
connectionSettings.ClockFrequency = 1_000_000; //Set clock speed to slowest device on bus | ||
connectionSettings.DataBitLength = 8; | ||
connectionSettings.DataFlow = DataFlow.MsbFirst; | ||
connectionSettings.Mode = SpiMode.Mode0; | ||
|
||
spiDevice = SpiDevice.Create(connectionSettings); // For XPT2046 Touch controller | ||
|
||
using GpioController gpio = new(); | ||
using Xpt2046 sensor = new(spiDevice); | ||
var ver = sensor.GetVersion(); | ||
Debug.WriteLine($"version: {ver}"); | ||
|
||
gpio.OpenPin(XPT2046_PenIRQ, PinMode.InputPullUp); | ||
// This will enable an event on GPIO36 on falling edge when the screen if touched | ||
gpio.RegisterCallbackForPinValueChangedEvent(XPT2046_PenIRQ, PinEventTypes.Falling, TouchInteruptCallback); | ||
|
||
|
||
while (true) | ||
{ | ||
if (touchDetected) | ||
{ | ||
var point = sensor.GetPoint(); | ||
Debug.WriteLine($"point: {point.X},{point.Y},{point.Weight} "); | ||
Thread.Sleep(30); | ||
touchDetected = false; | ||
} | ||
|
||
Thread.Sleep(300); | ||
} | ||
|
||
} | ||
catch (Exception ex) | ||
{ | ||
Debug.WriteLine($"Critical Exception, Terminating: {ex.Message}"); | ||
|
||
Thread.Sleep(Timeout.Infinite); | ||
} | ||
|
||
} | ||
static void TouchInteruptCallback(object sender, PinValueChangedEventArgs pinValueChangedEventArgs) | ||
{ | ||
touchDetected = true; | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please look at the how to add the linter in the project, it will point you on couple of things to adjust in the project. See: https://github.com/nanoframework/nanoFramework.IoT.Device/blob/develop/StyleCop/README.md
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Didn't seem to work as expected. But manually copied the tags into the project and the style file into the folder. And that got me all the usual recommendations. Full stops, spaces etc