I’ve got the TFT working using Adafruit_TFTLCD_8bit_STM32.H but now I have problems to use the TouchScreen.
On this display the 4 wires are mpx’ed with D0, D1 and RS/CS (PA2/PA1 in my setup).
Whatever I do (TouchScreen_STM.H is the lib used) The Y-value Is something like 3500 when nothing is touched, when touched X and Y return “reasonable” values but z (pressure) remains 0.
I read the analog values on PA1 and PA2 and the XM value reads about 0, the YP readout however is 4095 when nothing is touched!
I tried different PA instead of PA2 with the same result!
I would like to try with a new board but they have not arrived yet.
Someone has an idea?
By the way, display + TS work fine on an Arduino Due.
// Touch screen library with X Y and Z (pressure) readings as well
// as oversampling to avoid 'bouncing'
// (c) ladyada / adafruit
// Code under MIT License
// Ported to STM32 by Jaret Burkett https://github.com/jaretburkett
#ifndef _ADAFRUIT_TOUCHSCREEN_STM_H_
#define _ADAFRUIT_TOUCHSCREEN_STM_H_
#include <stdint.h>
class TSPoint {
public:
TSPoint(void);
TSPoint(int16_t x, int16_t y, int16_t z);
bool operator==(TSPoint);
bool operator!=(TSPoint);
int16_t x, y, z;
};
class TouchScreen {
public:
TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym);
TouchScreen(uint8_t xp, uint8_t yp, uint8_t xm, uint8_t ym, uint16_t rx);
bool isTouching(void);
uint16_t pressure(void);
int readTouchY();
int readTouchX();
TSPoint getPoint();
int16_t pressureThreshhold;
private:
uint8_t _yp, _ym, _xm, _xp;
uint16_t _rxplate;
};
#endif
Every source (core and library) file is available on Gitub. So changes can be followed.
I also found different “releases” or the touchScreem_STM lib. They all are litterally the same.
Honestly, I suspect something more like a hardware related problem: reading out the analog inputs (with the display removed, inputs are floating at that moment) PA1 reads a near zero value whereas PA0, 2 and PA3 give a full scale 4095 reading. So, seems like PA1 is “pulled down” wher the others are “puled high”. Note that for this test the TFT and TS were disabled in software.
Use a Google site-centric search:
bluepill touch screen site:stm32duino.com
and
bluepill touchscreen site:stm32duino.com
Andy’s O’Scope project has a touch screen and has been successfully replicated.
Ray
I beleive something is wrong with the initialisation of the analog inputs. I hoped you guys knew the in’s and out’s of these little miracles.
How is the input defined? Is there any configuration bi describing the input impedance? Can the input be “inverted” by configuration?
I surely will search the ST manual on this subject, but do you really have no hint?
First thing I will do now is add some decoupling caps on the 3V3 and 5V power lines. Un fortunately the VSSA and VDDA pins are connected directly to the digital power pins. Well, that is a compromise to the cost of a multilayer PCB versu double layer.
I then ran a sketch to read out the analog value of A1 and A2.
#include <Arduino.h>
//#include <Adafruit_TFTLCD_8bit_STM32.h> // Hardware-specific library
//Adafruit_TFTLCD_8bit_STM32 tft;
// Touch screen library with X Y and Z (pressure) readings as well
// as oversampling to avoid 'bouncing'
// This demo code returns raw readings, public domain
#include <stdint.h>
#include <TouchScreen_STM.h>
#define YP PA2 // must be an analog pin
#define XM PA1 // must be an analog pin
#define YM PB8 // can be a digital pin
#define XP PB9 // can be a digital pin
// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM);
/************************** SETUP ******************************/
void setup(void) {
Serial.begin(9600);
} /* Setup */
/*************************** LOOP ********************************/
void loop(void) {
// a point object holds x y and z coordinates
// pinMode(PA3,OUTPUT);
// digitalWrite(PA3,HIGH);
/*
pinMode(PA1, INPUT_PULLDOWN);
pinMode(PA1, INPUT_ANALOG);
pinMode(PA2, INPUT_PULLUP);
pinMode(PA2, INPUT_ANALOG);
*/
TSPoint p = ts.getPoint();
// Serial.print("A0 = "); Serial.print(analogRead(PA0));
Serial.print("\tA1 = "); Serial.print(analogRead(PA1));
Serial.print("\tA2 = "); Serial.println(analogRead(PA2));
// Serial.print("\tA3 = "); Serial.println(analogRead(PA3));
// we have some minimum pressure we consider 'valid'
// pressure of 0 means no pressing!
if (p.z > ts.pressureThreshhold) {
Serial.print("X = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
}
/*
Serial.print("\tX = "); Serial.print(p.x);
Serial.print("\tY = "); Serial.print(p.y);
Serial.print("\tPressure = "); Serial.println(p.z);
*/
delay(2000);
} /* Loop */
[RikV – Tue Nov 20, 2018 7:00 pm] –
…
Just the board alone, inputs floating: A1/A2: 1962/1963 (out of 4096 I guess)
Pull-down resistor of 1 Mohm: both around 700
TFT screen in place: 0/4090!! A pull-down of 150K bring this down to only 4070
Disappointing.
Yes,
We know: https://www.stm32duino.com/viewtopic.php?t=1872
Ray
It took me a while to make everything work properly as there was a number of things that I found that stopped it working well.
First there is a slew time for the pins. I found if I set the pin to analog then read it striaght away it was influenced by the previous state of the pin so I had to add a delay of about half a ms.
Now trying to remember exactly what I did to make it work. Off memory it went like this when I wanted to read X_touch then I set Y+ to output high, Y- to output low, X+ to analog and X- to input pull-down(I found I needed X- as input pull-down to get good readings as it pulls against the output high making for good analog reading on the X+) then I wait half a ms then I take 5 reading and sort the 5 reading into order and use the median reading (reading in order 3).
See here for a bit of a demo, the first half of video I just plot the analog reading and the second half I just plot the median analog reading see https://www.youtube.com/watch?v=H51OzQl3BC8 the code is here https://github.com/OutOfTheBots/ili9341_16bit_touch
Other wise I see 2 solutions:
Buy a TFT-TS with built-in converter or move to a more expensive and less powerfull Arduino Due. First option will be the cheapest.
[RikV – Tue Nov 20, 2018 11:10 pm] –
That does’nt sound hopeful at all! I get the impression this bluePill board is useless for analog work!
…
“useless” is too strong of a word, IMO. But there is only so much one can do with a board where the uC is worth more than the price you pay for the module. The LeafLabs’ original design was a 4-layer board (separate analog & digital ground planes.)
This is a good read: https://www.stm32duino.com/viewtopic.ph … 840#p49264
Ray
I did have lots of trouble with noise on the analog pins on the STM32F407 black but after a bit I got good clean reading of the touch screen like the second half of the Video I posted on previous page. IF reading analog X+ then I set X- to digital input pull-down (to stop floating reading), I then took 5 reading but didn’t average then as any reading that r a long way off will skew the average a lot, I instead sorted the order and took the median (middle reading). This seemed to give me pretty good readings see second half of my video posted on previous page.
Fred Hamilton:
There are many possible reasons for the noise you’re seeing. It’s important to understand that an ADC has THREE inputs:
1) The input pin(s) (the one designed to be the signal input)
2) The reference input(s) (Dout = 2^n * Vin/Vref)
3) The power pins (supply + gnd)
Noise on any of those could create the noise you’re seeing, and assuming the ADC itself is not defective, the noise must be getting in through one of those three paths.
It’s possible to have decent ADC performance using the same ground for analog and digital, but you have to carefully lay out the PCB so that all the digital loop currents are isolated from the analog loops.
In this context, a loop is the entire current path a signal or power supply line (which should be considered a “noise” signal in this context) takes on the PCB. So for a power supply line it would be from where the power enters the board, along the trace until it gets to the power pin, through all the transistors in the IC, out the ground pin, then along the path of least resistance back to where the power enters the board. That’s one power supply loop.
But if you do a good job with supply bypassing, there won’t be much AC current in that loop, because you will have a much smaller, more localized loop of supply side of bypass cap to power pin to ground pin and back to ground side of bypass cap. If all your digital supplies are tightly bypassed, your power supply loop will be mostly clean and all the noisy digital constrained to short bypass cap loops.
The signal loops (including the Vref loop) work the same way – the signal comes in, winds its way to the ADC, out the ADC GND, and back to the signal ground (hopefully the same location where the signal started). If that loop crosses a digital loop, you can get noise injected. So typically a good mixed-signal design that uses one GND for analog and digital will keep the digital all on one side and the analog all on another, with GND at the end of the board right at the dividing point. It’s usually not that cut-and-dry, you have to make compromises, but that’s the idea.
Your mention “As the board consumption is minimal, below 100 mA, I think it should not cause such noise.” It’s more to do with how well the system is bypassed. A 100mA system with poor bypassing is going to have a lot more digital noise in the ground plane than a 1000mA system with good bypassing.
Results are what could be expected: exactly the same, not working at all.
As for the lib mentioned in flyboy74’s contribution: my knowledge of this “low level” programming is not good enough to find out which I/O are used and certainly not to modify it to comply with my PB8/9 PA0/1 configuration.
For the moment I deeply regret to have made the step towards STM. I know it is far more powerfull and much more power for the money, but it does not work the way it should. Is there any guarantee that it will work if I use another type of board? maybe this one:
https://www.banggood.com/Stm32f103c8t6- … rehouse=CN
or this:
https://www.banggood.com/STM32F103C8T6- … rehouse=CN
Btw, I looked carefully under the microscope and I have the inpression the BluePill boards are effectively Multi layer!!
https://www.banggood.com/nl/ARM-Cortex- … rehouse=CN
There is a separate decoupling to the VDDA (see schematic.
[RikV – Wed Nov 21, 2018 11:24 pm] –
…
For the moment I deeply regret to have made the step towards STM. I know it is far more powerfull and much more power for the money, but it does not work the way it should. Is there any guarantee that it will work if I use another type of board?
…
Btw, I looked carefully under the microscope and I have the inpression the BluePill boards are effectively Multi layer!!
Blue Pills are not multi-layer – they are 2-sided.
There are no guarantees that any “cheap” development board will satisfy your requirements. Were such decisions guaranteed, you would not see forums such as this one having an initiative to design & construct our own F4 low-noise board that is properly engineered to minimize noise on the inexpensive 2-layer commodity mail-order boards.
In this specific case, your disappointment has nothing to do with STM microcontrollers which are quality microcontrollers; rather I would suggest that the disappointment is with your original assumption/expectation that a move from 8-bit/16 MHz to 32-bit/72 MHZ would be painless. Clearly, your expectation is unrealistic… you are not the first to fall into this trap. Do not fret, there is hope, but it is a “stretch” goal and requires that you move beyond the hobby-level of uC coding knowledge.
From a software engineering prospective, hardware issues are often addressed with code. In the area of A/D noise, entire application notes are written on the subject but they are heavily mathematical in the area of digital filtering.
PDF How to get the best ADC accuracy in STM32 microcontrollers
ADC Input Noise: The Good, The Bad, and The Ugly
Good luck,
Ray
[RikV – Thu Nov 22, 2018 12:31 am] –
I finally bought this one:
https://www.banggood.com/nl/ARM-Cortex- … rehouse=CN
There is a separate decoupling to the VDDA (see schematic.
I believe that board is represented in the WiKi:
https://wiki.stm32duino.com/index.php?t … 103_boards
Remember, VddA low-pass filtering is only 1 of the 3 factors I posted about previously.
From experience over the years helping out on Arduino.cc, I recommend:
– Use a metal project box, use one point on the box to attach supply ground for shielding,
– DC to the AD reference should be through a small choke (of ferrite bead),
– when breadboarding, turn off all fluorescent lights (some LED lamps create RF hash, too),
– use only filament bulbs unless your LED lightning is known to be RF-free,
– Do not use AC wall-warts for a lab supply, buy a lab supply or use batteries,
– keep prototyping leads short, very short,
– consider putting a earth-grounded metal plate under your protyping board.
– twist all meter, o’scope leads to reduce RF AC induced voltages,
– do bypass the DC at the box entrance.
And remember, analog reference is nominally 3.3000 Volts. Ripple or noise on the reference directly affects the AD conversion!
Good luck,
Ray
i ended up drilling lots of holes till the cut section is perforated, then using a hammer and a flat head screwdriver i used it as chisel to tear out part of that then tear the rest then i used a file to file the edges so that the lcd would fit, lots of sweat, truly brute force, there has to be a better way
there are lots of ‘non electrical’ challenges trying to fit the parts in a box, and if your board don’t come with mounting holes, there’d be even more challenges that u’d need to invent ways to mount the board in the box
for drilling the holes i followed some tips from this
it helps to mark the holes well, one of those ways for boards that has mounting holes, i use a pencil to draw through the hole on the board onto the masking tape so that the hole locations would be aligned to the board. 3mm drill bits fits m3 holes just tightly enough for m3 machine screws
that’s for plastic, the threads literally makes a tight fit so much that i literally screw it (the screw) in rather than letting the screw fit through the hole
For metal, it may be too tight, search the web for the clues to the appropriate bit sizes etc
[flyboy74 – Tue Nov 20, 2018 9:04 pm] –
Ok I have successfully written a program to read a resistive touch screen on the STM32407VET.It took me a while to make everything work properly as there was a number of things that I found that stopped it working well.
First there is a slew time for the pins. I found if I set the pin to analog then read it striaght away it was influenced by the previous state of the pin so I had to add a delay of about half a ms.
Now trying to remember exactly what I did to make it work. Off memory it went like this when I wanted to read X_touch then I set Y+ to output high, Y- to output low, X+ to analog and X- to input pull-down(I found I needed X- as input pull-down to get good readings as it pulls against the output high making for good analog reading on the X+) then I wait half a ms then I take 5 reading and sort the 5 reading into order and use the median reading (reading in order 3).
See here for a bit of a demo, the first half of video I just plot the analog reading and the second half I just plot the median analog reading see https://www.youtube.com/watch?v=H51OzQl3BC8 the code is here https://github.com/OutOfTheBots/ili9341_16bit_touch
+1 this is pretty good, i did notice the adc readings from stm32f103cb (maple mini) fluctuate a bit, smoothing them out would probably help here
https://www.sparkfun.com/datasheets/LCD … 20WORK.pdf
it seemed some ITO resistive touch screens may have pretty low resistances
https://www.sigmaaldrich.com/catalog/pr … 92?lang=en
https://www.2spi.com/item/06463b-ab/
if that is true one may need different / additional circuits such as an op amp to get decent readings, doing a resistor divider with say even 1k ohm in series with an ITO resistive touch screen towards either vcc or gnd as say if that resistance is 1 ohm, u’d get at best 3 mv across the touch screen from end to end
As for the comments on this type of board: it definitely is a MULTI layer, Vbatt is connected to Vdd through a 0ohm link. Why? When one reads th STM reference manual you se that is absolutely unnecessary: th clock and backup memeory are fed by the Vbatt input untill the chip is powered on. it the automatically and internally switches to Vdd. STM suggests to connect Vbatt to Vdd through a CAPACITOR when no Battery is supplied.
I will replace the Oohm link by a .1uF cap.
Untill now I was only able to connect the 4 TS wires to the new board: the result is the same, analog inputs pulled up to Vdd.
I have problems finding a usable library for the SPI ILI9341 (yes there are plenty on the net, but one where you can decide which SPI port to use?) and also for the XPT2046 with the choise of int control or not.
One beginners question: can I put more than one SPI device on the same port, even when one or more are IRQ controlled?
The problem lies not whith noise on th A/D inputs (Vref is checked and “ripple free”) but in being pulled towards Vdd in some way or another and yes, I have some experience with analog electronics after being an electronics engineer for 40 years.
The current SPI implementations do not use IRQs as they are not so effective as DMA at high speeds.
Here you have a SPI lib where the end of DMA transaction is able to execute some user code.
[RikV – Fri Dec 07, 2018 5:08 pm] –
Sorry, but “To download. click the DOWNLOADS button in the top right corner”. There is no such button and I am signed in????
You only see the Download button on: https://github.com/stevstrong/Arduino_STM32/
You can download file-by-file, or just download the whole ZIP, unZip, and take what you want.
Example:
- RogersGithub.png (7.5 KiB) Viewed 812 times
First thing to try in the morning. It is now 1:30 am over here, time to do something more appropriate.
ILI9341, MAX31855 and XPT2046, of course each with its own Cs.
First tried everything in turn with the supplied examples: all works by the first try.
But there arises a problem: when writing to the tft while using the MAX library, thing get confused.
Commands to the tft are no longer executed (a tft.print is not executed while a Serial.print on the next line executes fine!) and artefacts appear on the screen: a green text on screen has a red “ghost” image, drawing a line creates some fragments elsewhere on the screen…
I suspect the breadboard wiring (some wires are up to 20cm long) but before I sacrifice time and resources to “clean” soldered prototype I would like to have the Insurance that this setup is likely to work. How many slaves can wone realistically handle on one SPI port?
From library point of view I suspect the MAX31855 lib as being cripled, but it is the only one I found for SM32F103 that has hardware SPI.
Any constructive suggestions?
The main issue was the library just plain stomped all over SPI, it was not designed with transactions in mind.
In the end I found some custom code to drive the 31856 directly – just implemented as function calls in my sketch, I wrapped this with the correct SPI code.
It may be worth considering going ‘simple’ and doing this yourself, have a search about.
But, even when it works it still keeps me kind of sleepless because I dont know why the hardware version doesn’t work! Knowing why would surely prevent future mistakes!
i’ll keep you all informed.
Might not be the easiest to follow, but I have SSD1306, SPI SD card, and MAX31856 all co-existing on one SPI bus – clearly this won’t help you with specific code for the 31855, but the link I previously supplied should give you the meat of the functions you need for that device.
But it is totally unclear to me how I should “connect” a MAX device (MAX31855.h) top the defined SPI2 Class.
Using SPI.setModule(2) generates a compiling error “‘SPI’ does not name a type”.
#include <SPI.h>
#include <Arduino.h>
#include <stdint.h>
#include <SPI.h>
SPIClass SPI_2(2); //Create an instance of the SPI Class called SPI_2 that uses the 2nd SPI Port
#include <string.h>
#include "streaming.h"
/****** Display stuff *******/
#include "Adafruit_GFX_AS.h"
#include "Adafruit_ILI9341_STM.h"
#define TFT_DC PB6 //Data/Command
#define TFT_CS PB7 //Chip select
#define TFT_RST PB9
/*For hardware SPI channel 1:
* PA5 SCK
* PA6 MISO
* PA7 MOSI
*/
// Create TFT display of the name tft
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST);
int w = 0;
int h = 0; //w & h of the tft to make calculations easier
/****** Touch screen stuff ******/
#include <XPT2046_Touchscreen.h>
#define TS_CS PB8
XPT2046_Touchscreen ts(TS_CS);
/****** Temp reading stuff ********/
#include <MAX31855.h>
#define MAX_CS PB12
//SPI.setModule(2);
MAX31855 thermocouple(MAX_CS);
Max31855 and XPT2046 work perfectly toghetter on the same SPI, so does ILI9341 for the first run in “LOOP”.
I placed the calls to Touchscreen and Temperature at the very beginning of “LOOP” and continued with a tft.begin() and tft works (well, I loose all settings made in setup of course). I believe this means that the TS and/or temperature routines leave the SPI in a setting that is not corrected when entering any of the functions of tft, setting SPI params is one of the thing done in “begin”.
Most logical solution would be to correct the AdaFruit_ILI9341_STM lib, not? Or, can I add a line in my prog to correct the setting of SPI only (not loosing any setups)?
I found all settings to be Mode0 an MSBfirst, frequencies 2, 4 and 48Mhz for Ts, Temp and tft resp.
Or am I -again- completely wrong?
SPI.beginTransaction(SPISettings(<frequency>, ...));
[stevestrong – Mon Dec 24, 2018 10:41 am] –
The solution suggested already in the forum is to use separate
SPI.beginTransaction(SPISettings(<frequency>, ...));
[RikV – Sun Dec 23, 2018 7:11 pm] –
I found all settings to be Mode0 an MSBfirst, frequencies 2, 4 and 48Mhz for Ts, Temp and tft resp.
[stevestrong – Mon Dec 24, 2018 11:01 am] –
Not identical, different frequencies:[RikV – Sun Dec 23, 2018 7:11 pm] –
I found all settings to be Mode0 an MSBfirst, frequencies 2, 4 and 48Mhz for Ts, Temp and tft resp.
Oops, hangovers and forums don’t mix well! Have a great Christmas
I added
tft.begin();
tft.setRotation(2); //Portrait, SD card on the right side, xy=0,0 top-left
and all seems to work fine. I can do this because MAX31855 and XPT2046 are only called once per loop. Nevertheless, this lib (Adafruit_ILI9341_STM)should be corrected I think.
Would it be an advantage if I used interrupt control on the touchScreen? Just for fun?
SPI.beginTransaction(SPISettings(48000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT));
does not work (I believe the settings are correct, but how can I retrieve the correct ones?)
This, however does work (but is no doubt more resource consuming):
tft.begin();
tft.setRotation(2); //Portrait, SD card on the right side, xy=0,0 top-left
It had been a couple of days since I last compiled the project while I was wandering arounde the WWW and have opened different .ino’s for inspiration.
Then I tried to “verify” my project after a minor modification.
Compiler errors everywhere! Why? nothing had changed? After some investigation I find that the linker complains about PID_V1.cpp.o. This lib sits in the Project directory together with its .h. Til now everything worked fine but now the linker says on all functions of PID: multiple definition of `PID::Compute()’ (as an example).
When I remove the lib from the project directory (but that is of course no solution) everythin compiles OK.
What are the rules used by the compiler to look for included libraries? How can I fix my problem?
tft.begin();
tft.setRotation(2); //Portrait, SD card on the right side, xy=0,0 top-left
takes 320ms (!!!!!) to complete. I just can’t afford to have this inside my “Main”.
SPI.beginTransaction(SPISettings(48000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT)); why does this not work? where can I find the correct parameters?
[RikV – Sun Dec 23, 2018 7:11 pm] –
…
Most logical solution would be to correct the AdaFruit_ILI9341_STM lib, not? Or, can I add a line in my prog to correct the setting of SPI only (not loosing any setups)?
…
Pull the Adafruit library (copy) into your sketch directory to encapsulate it… change #include to look like “./lib_name”
Make changes to the local sketch copy.
Never change library copies in Arduino/libraries
STM32DUINO is not Arduino.cc codebase and while much effort has gone into attempting complete compatibility, the fact is we know some issues exist and some “fixes” may have limited scope for corrective activity. So, while SPI 1&2 may work separately, there is no test plan to assure you can hang off multiple devices adhoc successfully.
What you get with STM32DUINO (Roger’s hosted core) is an advanced version of the LeafLabs original core hacked to work under the current ArduinoIDE. There simply is NO Guarantee that the ported core works, that it is compatible with any hardware, or that it meets any suitability. The end-user is ultimately responsible for adapting sketches, libraries, or core code to mitigate problems. Do not rely upon this core to be supported in any manner; things broken are your problem.
From my point-of-view, you should migrate to the Official Core ASAP:
https://github.com/stm32duino/Arduino_Core_STM32
Ray