In my project, i need to read position of a steel ball. For that purpose i am using a 4 wire touchscreen. To read a data of x and y coordinations from a 4 wire touchscreen its necessary to alternately change pins from INPUT to OUTPUT and so on, in a loop(). Here is my code:
const int XP = A0; // zelená
const int XM = A1; // červená
const int YP = A2; // biela
const int YM = A3; // čierna
//rozlíšenie 1024*768 pixelov.... nejde floating nastavenie inputu - trvala 1 na vstupe -> teda nemozem citat analog. vstup
int readX() {
pinMode(YP, INPUT);
pinMode(YM, INPUT);
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
digitalWrite(XP, HIGH);
digitalWrite(XM, LOW);
delay(50); // stabilizácia
int value = analogRead(YP);
return value;
}
int readY() {
pinMode(XP, INPUT);
pinMode(XM, INPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
digitalWrite(YP, HIGH);
digitalWrite(YM, LOW);
delay(50); // stabilizácia
int value = analogRead(XP);
// Otočíme hodnoty Y (invertujeme)
value = 1023 - value; // Hodnota Y bude inverzná
return value;
}
void setup() {
Serial.begin(9600);
}
void loop() {
// Zoberieme hodnotu pre Y ako X a pre X ako Y
int x = readY(); // X teraz čítame z Y
int y = readX(); // Y teraz čítame z X
Serial.print("X: ");
Serial.print(x);
Serial.print("\tY: ");
Serial.println(y);
delay(200);
}
This code properly works on my UNO, NANO and also a MEGA boards and i am reading coordinates of x and y very properly. Unfortunately, for my project i needed a more "better" board, so i bought a new Arduino Giga R1 Wi-Fi board (from original arduino store...). And now this is where my problem starts. This code is not working on my GIGA board. After some debugging and tryings i figured out that the problem is with dynamical change of pin states from INPUT to OUTPUT and so on, because when i am reading only one coordinate x or y (so i dont need to change GPIO states in loop()) it works. I was trying to find something on internet or someone who had a similar problem, but i found nothing which could really explain the problem, so i decided to write here. I would really appreciate any advice or maybe some explanation what is going on in here... Maybe it has something to do with "dual-core STM32 proccessor" is using a different architecture and it is not possible at all to dynamically change those pin states? (maybe its some safe protocol to not "fight" pin access between the cores?) or is it just mine problem? I am an amateur, so i dont know exactly how this works, but i was hoping maybe you have experienced something similar? Thanks, for every answer, have a nice day!
Please post your full sketch, using code tags when you do
Posting your code using code tags prevents parts of it being interpreted as HTML coding and makes it easier to copy for examination
In my experience the easiest way to tidy up the code and add the code tags is as follows
Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.
It is also helpful to post error messages in code tags as it makes it easier to scroll through them and copy them for examination
You might want to post a link to the technical information for the one you are using. With the information I could only take a guess which would probably be wrong. Is it compatible with 3V3?
Sorry, i dont have exact documentation because i ordered it from China, but yes it is 100% compatible with 3.3V, because as i said, when i read only one coordination it works on GIGA (the fact that i read only one instead of both coordinates doesnt mind, because it would read only one coordinate at a time anyway...). The problem is 100% with OUTPUT/INPUT changing... I am just curious why it doesnt change and if it is a typical feature of STM32xx, or if there is a way of how to potentially solve it. Thank you for answer!
You have provided no evidence supporting this dubious statement. For help, describe in detail what you expect to happen and what happens instead, posting example output (copy and paste, using code tags).
So the touchscreen has 4 wires connected to 2 layers of resistive. X+, X-, Y+, Y- every from other side of screen (left, right, up, down)... (horizontal layer; vertical layer). When a touch occurs, these layers come into contact, and the touchscreen behaves like a voltage divider. The principle of measuring is to apply a known voltage across one layer and read the voltage from the other layer, which will vary depending on where the screen is touched.
For exaple lets say i want to measure a x coordinate:
I set the X+ and X- as OUTPUT and write HIGH (5V) on X+ and LOW (GND) on X-
I set the Y+ and Y- as INPUT and read analog value of Y+ (dont really need Y- as INPUT)
The value i measure divided by 5V is equal to 0-1023/1024
Code example:
int readX() {
pinMode(X_PLUS, OUTPUT);
pinMode(X_MINUS, OUTPUT);
digitalWrite(X_PLUS, HIGH);
digitalWrite(X_MINUS, LOW);
pinMode(Y_PLUS, INPUT);
pinMode(Y_MINUS, INPUT);
return analogRead(Y_PLUS); // Value proportional to X coordinate
}
This code above measure only one X coordination. To measure Y coordination, i need to do the same but with swapped pin mods, so Y+ and Y- set as OUTPUT for HIGH and LOW, and X+ and X- set as INPUT and analog reading X+ to get the Y coordinates.
Thats the principle of measuring.
Now what happens? When I use either UNO, NANO or MEGA everything works as expected, i touch the screen and get the coordinate. Exactly like this: (Serial monitor when i swipe from bottom left corner to top right corner)
Looks OK, so we can say that touchscreen works, and code also (at least for ATmega328p in Arduino UNO). Now, the exact same code uploaded to an Arduino GIGA, looks like this:
This is after i swipe, so as you can see it doesnt react. Values mean there is a constant 1 (HIGH) in analog reading. I explain why: 930 and 127 are not 1023 and 0 but this is because it is not calibrated... (On Arduino UNO it was also the maximum values i got in the edges of touch, so it is a maximum possible value)... Y with value 127 is also a logical 1 because in my code i have inverted the value to the opposite because i wanted to have 0 on the other side of screen as it really is. There is the invertion:
value = 1023 - value;
This means there are logical 1 on the both analog readings and it was not because of real value but because somehow there was a internal PULL-UP. (Also when i unplugged the touchscreen values stayed same - which is really unlogical, there should be pure 1023, but it was really also the edge values of Arduino UNO...)
That was all probably i didnt set pin state in void setup(). When I did that, like this:
const int XP = A0;
const int XM = A1;
const int YP = A2;
const int YM = A3;
int readY() {
digitalWrite(YP, HIGH);
digitalWrite(YM, LOW);
delay(50);
int value = analogRead(XP);
value = 1023 - value;
return value;
}
void setup() {
Serial.begin(9600);
pinMode(XP, INPUT);
pinMode(XM, INPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
}
void loop() {
int x = readY();
Serial.print("\nX: ");
Serial.print(x);
delay(200);
}
I readed a X value, but not Y value...It somehow has a problem when i am setting pinMode to INPUT/OUTPUT anywhere else outside the void loop() section. Heres a proof: (I just defined pinMode in a other section and not in the voidsetup(), just like this)
const int XP = A0;
const int XM = A1;
const int YP = A2;
const int YM = A3;
int readY() {
digitalWrite(YP, HIGH);
digitalWrite(YM, LOW);
delay(50);
int value = analogRead(XP);
value = 1023 - value;
return value;
}
void setup() {
Serial.begin(9600);
}
void loop() {
pinMode(XP, INPUT);
pinMode(XM, INPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
int x = readY();
Serial.print("\nX: ");
Serial.print(x);
delay(200);
}
So as you can see, this is a problem... So i think for 99% its the problem of pinMode settings, i just dont know if i am doing something wrong, or my board is somehow dont working properly or what is going on in here? I really dont understand this behavior and havent ever heard about something similar... Does something come in to your mind, or would you need some more detailed informations? Thanks for your anwer, appreciate it!
Hi @martin5152855. The Arduino developers are tracking the bug here:
I was able to work around the bug by adding this code before the analogRead call:
delete analogPinToAdcObj(XP);
new mbed::AnalogIn(analogPinToPinName(XP));
You must also add the following #include directives to get the declarations:
#include <mbed.h>
#include <pinDefinitions.h>
(the one for mbed.h is not absolutely required since it is provided transitively via pinDefinitions.h, but it is best to avoid unnecessary reliance on such things)
#include <mbed.h>
#include <pinDefinitions.h>
const int XP = A0; // zelená
const int XM = A1; // červená
const int YP = A2; // biela
const int YM = A3; // čierna
//rozlíšenie 1024*768 pixelov.... nejde floating nastavenie inputu - trvala 1 na vstupe -> teda nemozem citat analog. vstup
int readX() {
pinMode(YP, INPUT);
pinMode(YM, INPUT);
pinMode(XP, OUTPUT);
pinMode(XM, OUTPUT);
digitalWrite(XP, HIGH);
digitalWrite(XM, LOW);
delay(50); // stabilizácia
int value = analogRead(YP);
return value;
}
int readY() {
pinMode(XP, INPUT);
pinMode(XM, INPUT);
pinMode(YP, OUTPUT);
pinMode(YM, OUTPUT);
digitalWrite(YP, HIGH);
digitalWrite(YM, LOW);
delete analogPinToAdcObj(XP);
new mbed::AnalogIn(analogPinToPinName(XP));
delay(50); // stabilizácia
int value = analogRead(XP);
// Otočíme hodnoty Y (invertujeme)
value = 1023 - value; // Hodnota Y bude inverzná
return value;
}
void setup() {
Serial.begin(9600);
}
void loop() {
// Zoberieme hodnotu pre Y ako X a pre X ako Y
int x = readY(); // X teraz čítame z Y
int y = readX(); // Y teraz čítame z X
Serial.print("X: ");
Serial.print(x);
Serial.print("\tY: ");
Serial.println(y);
delay(200);
}
I'm not very knowledgeable in this area, so it is possible there is a better/correct approach than the one I fumbled together. If so, hopefully one of the other forum helpers will provide it.
Hi @ptillisch,
I tried it and it works...
Now when i think about it, it kinda makes a sense and i understand what the problem was. However i am sure i would never ever be able to find out the bug by myself... This way I would like to thank you very very much, really appreciate your help!