Thanks for the input; the support files for the touchscreen library state that it is for SPI2 - but I am not convinced.
I've tried your suggestions but didnt get very far.
I then tried another touch library which you initialise with an SPI instance whereby you specify SPI2 - it's called Serasidis_XPT2046_touch and is in the STM32-master repository.
It doesnt use interrupts but seems to work fine. I've managed to get the software doing what I want (touch screen band selection for a ham radio RF amplifier). The TFT is on SPI1 and the Touch on SPI2 and its all working now.
I found that the touchscreen x,y coordinates are not the same as the TFT x,y so I have had to do some jiggery pokery to map the touch onto the graphics - but its all OK now. I have concerns my code is very inefficient, so I'll stick it down below if anyone would be kind enough to comment.
I'm new to STM32 and a struggling a little understanding what is and isnt compatible with the board.
Code: Select all
#include "SPI.h"
#include ".\Adafruit_GFX_AS.h"
#include ".\Adafruit_ILI9341_STM.h"
#include "XPT2046_touch.h"
// true for serial3 debug comms
const boolean debug = true;
// TFT Pins plus SPI1
const int TFT_CS = PA0;
const int TFT_DC = PA2;
const int TFT_RST = PA1;
// define the band switch pins
const int Band160M = PA9;
const int Band80M = PA10;
const int Band60M = PA13;
const int Band40M = PA14;
const int Band30M = PA15;
const int Band20M = PB3;
const int Band17M = PB4;
const int Band15M = PB5;
const int Band12M = PB6;
const int Band10M = PB7;
const int Band6M = PB8;
const int Band4M = PB9;
// define the analoge inputs for
// the forward and reflected
// power readings
const int ForwardPwr = PB0;
const int ReflectedPwr = PB1;
// touch screen is on SPI2
const int CS_PIN = PA8;
const int KeyPadStarty = 110;
const int ButtonDepth = 53;
const int ButtonWidth = 50;
// global variables (always a bad idea)
boolean wastouched = true;
uint16_t xy[2];
int BandSelection = 20; // default band selection is 20M
int OldBandSelection = 160;
float Forward_Watts = 0.0;
float Reflected_Watts = 0.0;
float Calculated_SWR = 1.0;
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI
SPIClass mySPI(2); //Create an SPI instance on SPI2 port.
XPT2046_touch ts(CS_PIN, mySPI); // Chip Select pin, SPI port
void DisplayScreen()
{
int BandList[12] = {160, 80, 60, 40, 30, 20, 17, 15, 12, 10, 6, 4};
tft.setRotation(1);
tft.fillScreen(ILI9341_BLACK);
// fill rect startx, starty, width, depth, colour
tft.fillRect(0, KeyPadStarty, 320, 140, ILI9341_RED);
tft.setCursor(20, 10);
tft.setTextColor(ILI9341_RED);
tft.setTextSize(4);
tft.print("G0MGX LINEAR");
tft.setTextColor(ILI9341_GREEN);
tft.setCursor(35, 50);
tft.setTextSize(3);
tft.print("FWD: REF:");
tft.setCursor(110, 80);
tft.setTextSize (2);
tft.setTextColor(ILI9341_YELLOW);
tft.print("SWR:");
for (int Bands = 0; Bands <= 11; Bands++)
{
DisplayButton(ILI9341_WHITE, BandList[Bands], ILI9341_BLACK);
}
}
void DisplayButton(int textcolour, int band, int boxcolour)
{
int textxcoord; int textycoord; int boxxcoord; int boxycoord;
switch (band)
{
case 160:
textxcoord = 10;
textycoord = 140;
boxxcoord = 3;
boxycoord = KeyPadStarty+10;
break;
case 80:
textxcoord = 70;
textycoord = 140;
boxxcoord = 56;
boxycoord = KeyPadStarty+10;
break;
case 60:
textxcoord = 123;
textycoord = 140;
boxxcoord = 109;
boxycoord = KeyPadStarty+10;
break;
case 40:
textxcoord = 175;
textycoord = 140;
boxxcoord = 162;
boxycoord = KeyPadStarty+10;
break;
case 30:
textxcoord = 230;
textycoord = 140;
boxxcoord = 215;
boxycoord = KeyPadStarty+10;
break;
case 20:
textxcoord = 280;
textycoord = 140;
boxxcoord = 268;
boxycoord = KeyPadStarty+10;
break;
case 17:
textxcoord = 15;
textycoord = 195;
boxxcoord = 3;
boxycoord = KeyPadStarty+66;
break;
case 15:
textxcoord = 70;
textycoord = 195;
boxxcoord = 56;
boxycoord = KeyPadStarty+66;
break;
case 12:
textxcoord = 123;
textycoord = 195;
boxxcoord = 109;
boxycoord = KeyPadStarty+66;
break;
case 10:
textxcoord = 175;
textycoord = 195;
boxxcoord = 162;
boxycoord = KeyPadStarty+66;
break;
case 6:
textxcoord = 235;
textycoord = 195;
boxxcoord = 215;
boxycoord = KeyPadStarty+66;
break;
case 4:
textxcoord = 287;
textycoord = 195;
boxxcoord = 268;
boxycoord = KeyPadStarty+66;
break;
default:
break;
}
tft.fillRect(boxxcoord, boxycoord, ButtonWidth, ButtonDepth, boxcolour);
tft.setTextColor(textcolour);
tft.setTextSize(2);
tft.setCursor(textxcoord, textycoord);
tft.print(band);
}
void setup()
{
if (debug)
{
Serial3.begin(9600);
Serial3.println("Starting");
}
tft.begin();
tft.fillScreen(ILI9341_BLACK);
ts.begin(); //Begin TouchScreen.
// initialise digital outputs
pinMode (Band160M, OUTPUT);
digitalWrite (Band160M, LOW);
pinMode (Band80M, OUTPUT);
digitalWrite (Band80M, LOW);
pinMode (Band60M, OUTPUT);
digitalWrite (Band60M, LOW);
pinMode (Band40M, OUTPUT);
digitalWrite (Band40M, LOW);
pinMode (Band30M, OUTPUT);
digitalWrite (Band30M, LOW);
pinMode (Band20M, OUTPUT);
digitalWrite (Band20M, LOW);
pinMode (Band17M, OUTPUT);
digitalWrite (Band17M, LOW);
pinMode (Band15M, OUTPUT);
digitalWrite (Band15M, LOW);
pinMode (Band12M, OUTPUT);
digitalWrite (Band12M, LOW);
pinMode (Band10M, OUTPUT);
digitalWrite (Band10M, LOW);
pinMode (Band6M, OUTPUT);
digitalWrite (Band6M, LOW);
pinMode (Band4M, OUTPUT);
digitalWrite (Band4M, LOW);
// Declare the inputs as INPUT_ANALOG:
pinMode(ForwardPwr, INPUT_ANALOG);
pinMode(ReflectedPwr, INPUT_ANALOG);
}
void ReadADCValues()
{
int ForwardPower;
int ReflectedPower;
double Forward_dBm;
double Reflected_dBm;
float Pref_over_Pfwd = 0.0;
float Root_Pref_over_Pfwd = 0.0;
const float Forward_Alpha = 0.0948;
const float Forward_Beta = -37.658;
const float Reflected_Alpha = 0.0931;
const float Reflected_Beta = -35.413;
ForwardPower = analogRead(ForwardPwr);
ReflectedPower = analogRead(ReflectedPwr);
// We use the constants defined before to solve the equation
// dbM = Alpha ADC + Beta (where ADC = ADC value and Alpha and Beta are constants)
// We originally determine the values of Alpha and Beta from the spreadsheet
// First lets do the Forward Power Channel
Forward_dBm = ( ForwardPower * Forward_Alpha ) + Forward_Beta;
Forward_Watts = (pow(10,(Forward_dBm/10)) / 1000);
// Now let's do it again but for the reflected power values
Reflected_dBm = ( ReflectedPower * Reflected_Alpha ) + Reflected_Beta;
Reflected_Watts = (pow(10,(Reflected_dBm/10)) / 1000);
if (Reflected_Watts < 0.01) // if the reflected power is small dont bother calculating the SWR
{
Pref_over_Pfwd = 0.0;
Calculated_SWR = 1.0;
}
else
{
Pref_over_Pfwd = Reflected_Watts / Forward_Watts;
Root_Pref_over_Pfwd = sqrt(Pref_over_Pfwd);
Calculated_SWR = ((1 + Root_Pref_over_Pfwd) / ( 1 - Root_Pref_over_Pfwd));
}
}
void SetLPF (int BandSelection)
{
int OutputPins[12] = {Band160M, Band80M, Band60M, Band40M, Band30M, Band20M, Band17M, Band15M, Band12M, Band10M, Band6M, Band4M};
int OutputValues[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
switch (BandSelection)
{
case 160:
OutputValues[0] = 1;
break;
case 80:
OutputValues[1] = 1;
break;
case 60:
OutputValues[2] = 1;
break;
case 40:
OutputValues[3] = 1;
break;
case 30:
OutputValues[4] = 1;
break;
case 20:
OutputValues[5] = 1;
break;
case 17:
OutputValues[6] = 1;
break;
case 15:
OutputValues[7] = 1;
break;
case 12:
OutputValues[8] = 1;
break;
case 10:
OutputValues[9] = 1;
break;
case 6:
OutputValues[10] = 1;
break;
case 4:
OutputValues[11] = 1;
break;
}
for (int writeOutputs = 0; writeOutputs <=11; writeOutputs++)
{
if (debug)
{
Serial3.print("Writing to Pin: ");
Serial3.print(OutputPins[writeOutputs]);
Serial3.print(" value ");
Serial3.println(OutputValues[writeOutputs]);
}
digitalWrite(OutputPins[writeOutputs],OutputValues[writeOutputs]);
}
}
void CheckTouchScreen()
{
int TFTWidth = 320;
int TFTDepth = 240;
// the touch x and y coordinates are on a different
// scale to the TFT
// so we need to convert between them
// these are my cal factors and are the left most x coordinate and top most y
int CalFactorx = 258;
int TouchScreenWidth = 3650 - CalFactorx;
int CalFactory = 426;
int TouchScreenDepth = 3740 - CalFactory;
int XFactor = TouchScreenWidth / TFTWidth;
int YFactor = TouchScreenDepth / TFTDepth;
int TouchButtonWidth = ButtonWidth * XFactor;
int TouchButtonDepth = ButtonDepth * YFactor;
// define my box x y start coords
// the TFT is 320 accross and 250 deep
// these numbers are relative to that baseline
// row 1
int Box160M[2] = {3 * XFactor + CalFactorx, 120 * YFactor + CalFactory};
int Box80M[2] = {56 * XFactor + CalFactorx, 120 * YFactor + CalFactory};
int Box60M[2] = {109 * XFactor + CalFactorx, 120 * YFactor + CalFactory};
int Box40M[2] = {162 * XFactor + CalFactorx, 120 * YFactor + CalFactory};
int Box30M[2] = {215 * XFactor + CalFactorx, 120 * YFactor + CalFactory};
int Box20M[2] = {268 * XFactor + CalFactorx, 120 * YFactor + CalFactory};
// row 2
int Box17M[2] = {3 * XFactor + CalFactorx, 176 * YFactor + CalFactory};
int Box15M[2] = {56 * XFactor + CalFactorx, 176 * YFactor + CalFactory};
int Box12M[2] = {109 * XFactor + CalFactorx, 176 * YFactor + CalFactory};
int Box10M[2] = {162 * XFactor + CalFactorx, 176 * YFactor + CalFactory};
int Box6M[2] = {215 * XFactor + CalFactorx, 176 * YFactor + CalFactory};
int Box4M[2] = {268 * XFactor + CalFactorx, 176 * YFactor + CalFactory};
static uint16_t xy[2];
boolean istouched = ts.read_XY(xy);
if (istouched)
{
// this is a crude debounce to only act once per touch
if (!wastouched)
{
// determine if the x-coordinate is inside a button
// this feels very messy and there must be a better way....
if ((xy[0] >= Box160M[0]) && (xy[0] <= Box160M[0] + TouchButtonWidth) &&
(xy[1] >= Box160M[1]) && (xy[1] <= Box160M[1] + TouchButtonDepth))
{
BandSelection = 160;
}
else if ((xy[0] >= Box80M[0]) && (xy[0] <= Box80M[0] + TouchButtonWidth) &&
(xy[1] >= Box80M[1]) && (xy[1] <= Box80M[1] + TouchButtonDepth))
{
BandSelection = 80;
}
else if ((xy[0] >= Box60M[0]) && (xy[0] <= Box60M[0] + TouchButtonWidth) &&
(xy[1] >= Box60M[1]) && (xy[1] <= Box60M[1] + TouchButtonDepth))
{
BandSelection = 60;
}
else if ((xy[0] >= Box40M[0]) && (xy[0] <= Box40M[0] + TouchButtonWidth) &&
(xy[1] >= Box40M[1]) && (xy[1] <= Box40M[1] + TouchButtonDepth))
{
BandSelection = 40;
}
else if ((xy[0] >= Box30M[0]) && (xy[0] <= Box30M[0] + TouchButtonWidth) &&
(xy[1] >= Box30M[1]) && (xy[1] <= Box30M[1] + TouchButtonDepth))
{
BandSelection = 30;
}
else if ((xy[0] >= Box20M[0]) && (xy[0] <= Box20M[0] + TouchButtonWidth) &&
(xy[1] >= Box20M[1]) && (xy[1] <= Box20M[1] + TouchButtonDepth))
{
BandSelection = 20;
}
else if ((xy[0] >= Box17M[0]) && (xy[0] <= Box17M[0] + TouchButtonWidth) &&
(xy[1] >= Box17M[1]) && (xy[1] <= Box17M[1] + TouchButtonDepth))
{
BandSelection = 17;
}
else if ((xy[0] >= Box15M[0]) && (xy[0] <= Box15M[0] + TouchButtonWidth) &&
(xy[1] >= Box15M[1]) && (xy[1] <= Box15M[1] + TouchButtonDepth))
{
BandSelection = 15;
}
else if ((xy[0] >= Box12M[0]) && (xy[0] <= Box12M[0] + TouchButtonWidth) &&
(xy[1] >= Box12M[1]) && (xy[1] <= Box12M[1] + TouchButtonDepth))
{
BandSelection = 12;
}
else if ((xy[0] >= Box10M[0]) && (xy[0] <= Box10M[0] + TouchButtonWidth) &&
(xy[1] >= Box10M[1]) && (xy[1] <= Box10M[1] + TouchButtonDepth))
{
BandSelection = 10;
}
else if ((xy[0] >= Box6M[0]) && (xy[0] <= Box6M[0] + TouchButtonWidth) &&
(xy[1] >= Box6M[1]) && (xy[1] <= Box6M[1] + TouchButtonDepth))
{
BandSelection = 6;
}
else if ((xy[0] >= Box4M[0]) && (xy[0] <= Box4M[0] + TouchButtonWidth) &&
(xy[1] >= Box4M[1]) && (xy[1] <= Box4M[1] + TouchButtonDepth))
{
BandSelection = 4;
}
}
}
// if the band selection has changed act accordingly
if (OldBandSelection != BandSelection)
{
DisplayButton(ILI9341_RED, BandSelection, ILI9341_WHITE);
DisplayButton(ILI9341_WHITE, OldBandSelection, ILI9341_BLACK);
SetLPF(BandSelection);
OldBandSelection = BandSelection;
// as we dont want to keep switching lets hold the boat a while here
delay (500);
}
wastouched = istouched;
}
void UpdatePowerDisplay()
{
int Forward_Watts_Int;
int Reflected_Watts_Int;
// this is the SWR reading
tft.fillRect(160, 80, 60, 20, ILI9341_BLACK);
tft.setCursor(160, 80);
tft.setTextSize (2);
tft.setTextColor(ILI9341_YELLOW);
if ((Calculated_SWR > 5.0) || (Calculated_SWR < 0.0))
tft.print("Huge");
else
tft.print(Calculated_SWR,2);
// this is the power
tft.fillRect(110, 50, 50, 22, ILI9341_BLACK);
tft.setCursor(110, 50);
tft.setTextSize(3);
Forward_Watts_Int = round(Forward_Watts);
if (Forward_Watts_Int > 10)
tft.print("10");
else
tft.print(Forward_Watts_Int);
tft.fillRect(240, 50, 50, 22, ILI9341_BLACK);
tft.setCursor(240, 50);
tft.setTextSize(3);
Reflected_Watts_Int = round(Reflected_Watts);
if (Reflected_Watts_Int > 10)
tft.print("10");
else
tft.print(Reflected_Watts_Int);
}
void MaintainPowerDisplay()
{
static const unsigned long TimeInterval = 1000; // ms
static unsigned long lastRefreshTime = 0;
if(millis() - lastRefreshTime >= TimeInterval)
{
lastRefreshTime += TimeInterval;
UpdatePowerDisplay();
}
}
void loop()
{
boolean TimetoUpdate = false;
// we need to setup the screen once
DisplayScreen();
while (true)
{
// then loop forever reading the power, checking the touch screen and
// acting accordingly
ReadADCValues();
CheckTouchScreen();
delay(100);
MaintainPowerDisplay();
}
}