IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

URTouch en hardware SPI au lieu du bitbanging [edit : problème matériel ?]


Sujet :

Arduino

  1. #1
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut URTouch en hardware SPI au lieu du bitbanging [edit : problème matériel ?]
    Bonjour,

    Toujours sur mon projet Arduino UNI / Shield Ethernet / Ecran TFT tactile

    La dalle tactile est SPI mais la bibliothèque URTouch que j'utilise n'utilise que du bitbanging (software SPI).

    Je souhaite utiliser le SPI hardware, qui est déjà utilisé avec succès pour le shield Ethernet et l'écran TFT, pour les raisons suivantes :
    - libérer des broches I/O
    - code plus compact
    - mon code ne communique jamais en même temps avec l'écran TFT, la dalle tactile et le shield Ethernet.

    J'ai trouvé unce message intéressant mais ancien, et je m'en suis inspiré pour modifier la librairie URTouch

    Ancien fichier .h de la librairie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    /*
      URTouch.h - Arduino/chipKit library support for Color TFT LCD Touch screens 
      Copyright (C)2018 Rinky-Dink Electronics, Henning Karlsen. All right reserved
      
      Basic functionality of this library are based on the demo-code provided by
      ITead studio.
     
      You can find the latest version of the library at 
      http://www.RinkyDinkElectronics.com/
     
      This library is free software; you can redistribute it and/or
      modify it under the terms of the CC BY-NC-SA 3.0 license.
      Please see the included documents for further information.
     
      Commercial use of this library requires you to buy a license that
      will allow commercial use. This includes using the library,
      modified or not, as a tool to sell products.
     
      The license applies to all part of the library including the 
      examples and tools supplied with the library.
    */
     
    #ifndef URTouch_h
    #define URTouch_h
     
    #define URTOUCH_VERSION	202
     
    #if defined(__AVR__)
    	#include "Arduino.h"
    	#include "HW_AVR_defines.h"
    #elif defined(__PIC32MX__)
    	#include "WProgram.h"
    	#include "hardware/pic32/HW_PIC32_defines.h"
    #elif defined(__arm__)
    	#include "Arduino.h"
    	#include "hardware/arm/HW_ARM_defines.h"
    #endif
     
    #define PORTRAIT			0
    #define LANDSCAPE			1
     
    #define PREC_LOW			1
    #define PREC_MEDIUM			2
    #define PREC_HI				3
    #define PREC_EXTREME		4
     
    class URTouch
    {
    	public:
    		int16_t	TP_X ,TP_Y;
     
    				URTouch(byte tclk, byte tcs, byte tdin, byte dout, byte irq);
     
    		void	InitTouch(byte orientation = LANDSCAPE);
    		void	read();
    		bool	dataAvailable();
    		int16_t	getX();
    		int16_t	getY();
    		void	setPrecision(byte precision);
     
    		void	calibrateRead();
     
        private:
    		regtype *P_CLK, *P_CS, *P_DIN, *P_DOUT, *P_IRQ;
    		regsize B_CLK, B_CS, B_DIN, B_DOUT, B_IRQ;
    		byte	T_CLK, T_CS, T_DIN, T_DOUT, T_IRQ;
    		long	_default_orientation;
    		byte	orient;
    		byte	prec;
    		byte	display_model;
    		long	disp_x_size, disp_y_size, default_orientation;
    		long	touch_x_left, touch_x_right, touch_y_top, touch_y_bottom;
     
    		void	touch_WriteData(byte data);
    		word	touch_ReadData();
     
    #if defined(ENERGIA)
    		volatile uint32_t* portOutputRegister(int value);
    		volatile uint32_t* portInputRegister(int value);
    #endif
    };
     
    #endif
    Ancien fichier .cpp de la librairie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    /*
      URTouch.cpp - Arduino/chipKit library support for Color TFT LCD Touch screens 
      Copyright (C)2018 Rinky-Dink Electronics, Henning Karlsen. All right reserved
      
      Basic functionality of this library are based on the demo-code provided by
      ITead studio.
     
      You can find the latest version of the library at 
      http://www.RinkyDinkElectronics.com/
     
      This library is free software; you can redistribute it and/or
      modify it under the terms of the CC BY-NC-SA 3.0 license.
      Please see the included documents for further information.
     
      Commercial use of this library requires you to buy a license that
      will allow commercial use. This includes using the library,
      modified or not, as a tool to sell products.
     
      The license applies to all part of the library including the 
      examples and tools supplied with the library.
    */
     
    #include "RLucas_TFT_Touch.h"
    #include "RLucas_TFT_TouchCD.h"
     
    void URTouch::touch_WriteData(byte data)
    {
    	byte temp;
     
    	temp=data;
    	cbi(P_CLK, B_CLK);
     
    	for(byte count=0; count<8; count++)
    	{
    		if(temp & 0x80)
    			sbi(P_DIN, B_DIN);
    		else
    			cbi(P_DIN, B_DIN);
    		temp = temp << 1; 
    		cbi(P_CLK, B_CLK);                
    		sbi(P_CLK, B_CLK);
    	}
    }
     
    word URTouch::touch_ReadData()
    {
    	word data = 0;
     
    	for(byte count=0; count<12; count++)
    	{
    		data <<= 1;
    		sbi(P_CLK, B_CLK);
    		cbi(P_CLK, B_CLK);                
    		if (rbi(P_DOUT, B_DOUT))
    			data++;
    	}
    	return(data);
    }
     
     
    URTouch::URTouch(byte tclk, byte tcs, byte din, byte dout, byte irq)
    {
    	T_CLK	= tclk;
    	T_CS	= tcs;
    	T_DIN	= din;
    	T_DOUT	= dout;
    	T_IRQ	= irq;
    }
     
    void URTouch::InitTouch(byte orientation)
    {
    	orient					= orientation;
    	_default_orientation	= CAL_S>>31;
    	touch_x_left			= (CAL_X>>14) & 0x3FFF;
    	touch_x_right			= CAL_X & 0x3FFF;
    	touch_y_top				= (CAL_Y>>14) & 0x3FFF;
    	touch_y_bottom			= CAL_Y & 0x3FFF;
    	disp_x_size				= (CAL_S>>12) & 0x0FFF;
    	disp_y_size				= CAL_S & 0x0FFF;
    	prec					= 10;
     
    	P_CLK	= portOutputRegister(digitalPinToPort(T_CLK));
    	B_CLK	= digitalPinToBitMask(T_CLK);
    	P_CS	= portOutputRegister(digitalPinToPort(T_CS));
    	B_CS	= digitalPinToBitMask(T_CS);
    	P_DIN	= portOutputRegister(digitalPinToPort(T_DIN));
    	B_DIN	= digitalPinToBitMask(T_DIN);
    	P_DOUT	= portInputRegister(digitalPinToPort(T_DOUT));
    	B_DOUT	= digitalPinToBitMask(T_DOUT);
    	P_IRQ	= portInputRegister(digitalPinToPort(T_IRQ));
    	B_IRQ	= digitalPinToBitMask(T_IRQ);
     
    	pinMode(T_CLK,  OUTPUT);
        pinMode(T_CS,   OUTPUT);
        pinMode(T_DIN,  OUTPUT);
        pinMode(T_DOUT, INPUT);
        pinMode(T_IRQ,  OUTPUT);
     
    	sbi(P_CS, B_CS);
    	sbi(P_CLK, B_CLK);
    	sbi(P_DIN, B_DIN);
    	sbi(P_IRQ, B_IRQ);
    }
     
    void URTouch::read()
    {
    	unsigned long tx=0, temp_x=0;
    	unsigned long ty=0, temp_y=0;
    	unsigned long minx=99999, maxx=0;
    	unsigned long miny=99999, maxy=0;
    	int datacount=0;
     
    	cbi(P_CS, B_CS);                    
     
    	pinMode(T_IRQ,  INPUT);
    	for (int i=0; i<prec; i++)
    	{
    		if (!rbi(P_IRQ, B_IRQ))
    		{
    			touch_WriteData(0x90);        
    			pulse_high(P_CLK, B_CLK);
    			temp_x=touch_ReadData();
     
    			if (!rbi(P_IRQ, B_IRQ))
    			{
    				touch_WriteData(0xD0);      
    				pulse_high(P_CLK, B_CLK);
    				temp_y=touch_ReadData();
     
    				if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096))
    				{
    					tx+=temp_x;
    					ty+=temp_y;
    					if (prec>5)
    					{
    						if (temp_x<minx)
    							minx=temp_x;
    						if (temp_x>maxx)
    							maxx=temp_x;
    						if (temp_y<miny)
    							miny=temp_y;
    						if (temp_y>maxy)
    							maxy=temp_y;
    					}
    					datacount++;
    				}
    			}
    		}
    	}
    	pinMode(T_IRQ,  OUTPUT);
     
    	if (prec>5)
    	{
    		tx = tx-(minx+maxx);
    		ty = ty-(miny+maxy);
    		datacount -= 2;
    	}
     
    	sbi(P_CS, B_CS);                    
    	if ((datacount==(prec-2)) or (datacount==PREC_LOW))
    	{
    		if (orient == _default_orientation)
    		{
    			TP_X=ty/datacount;
    			TP_Y=tx/datacount;
    		}
    		else
    		{
    			TP_X=tx/datacount;
    			TP_Y=ty/datacount;
    		}
    	}
    	else
    	{
    		TP_X=-1;
    		TP_Y=-1;
    	}
    }
     
    bool URTouch::dataAvailable()
    {
    	bool avail;
    	pinMode(T_IRQ,  INPUT);
    	avail = !(rbi(P_IRQ, B_IRQ));
    	pinMode(T_IRQ,  OUTPUT);
    	return avail;
    }
     
    int16_t URTouch::getX()
    {
    	long c;
     
    	if ((TP_X==-1) or (TP_Y==-1))
    		return -1;
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	else
    	{
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
    		else
    			c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
    	return c;
    }
     
    int16_t URTouch::getY()
    {
    	int c;
     
    	if ((TP_X==-1) or (TP_Y==-1))
    		return -1;
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
    	else
    	{
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		else
    			c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	return c;
    }
     
    void URTouch::setPrecision(byte precision)
    {
    	switch (precision)
    	{
    		case PREC_LOW:
    			prec=1;		// DO NOT CHANGE!
    			break;
    		case PREC_MEDIUM:
    			prec=12;	// Iterations + 2
    			break;
    		case PREC_HI:
    			prec=27;	// Iterations + 2
    			break;
    		case PREC_EXTREME:
    			prec=102;	// Iterations + 2
    			break;
    		default:
    			prec=12;	// Iterations + 2
    			break;
    	}
    }
     
    void URTouch::calibrateRead()
    {
    	unsigned long tx=0;
    	unsigned long ty=0;
     
    	cbi(P_CS, B_CS);                    
     
    	touch_WriteData(0x90);        
    	pulse_high(P_CLK, B_CLK);
    	tx=touch_ReadData();
     
    	touch_WriteData(0xD0);      
    	pulse_high(P_CLK, B_CLK);
    	ty=touch_ReadData();
     
    	sbi(P_CS, B_CS);                    
     
    	TP_X=ty;
    	TP_Y=tx;
    }
    Nouvelle version du fichier .h de la librairie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #define PORTRAIT			0
    #define LANDSCAPE			1
     
    #define PREC_LOW			1
    #define PREC_MEDIUM			2
    #define PREC_HI				3
    #define PREC_EXTREME		4
     
    class URTouch
    {
    	public:
    		int	TP_X ,TP_Y;
     
    		URTouch(byte tcs, byte irq);
     
    		void	InitTouch(byte orientation = LANDSCAPE);
    		void	read();
    		bool	dataAvailable();
    		int	getX();
    		int	getY();
    		void	setPrecision(byte precision);
     
    		//void	calibrateRead();
     
        private:
    		//byte	T_CLK, T_CS, T_DIN, T_DOUT, T_IRQ;
    		byte	T_CS, T_IRQ;
    		long	_default_orientation;
    		byte	orient;
    		byte	prec;
    		byte	display_model;
    		long	disp_x_size, disp_y_size, default_orientation;
    		long	touch_x_left, touch_x_right, touch_y_top, touch_y_bottom;
     
    		word	touch_ReadData(byte data);
    };
    Nouvelle version du fichier .cpp de la librairie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    //https://forum.arduino.cc/index.php?topic=313633.0
     
    #include "SPI.h"
    #include "RLucas_TFT_Touch.h"
    #include "RLucas_TFT_TouchCD.h"
     
    URTouch::URTouch(byte tcs, byte irq)
    {
        T_CS = tcs;
        T_IRQ = irq;
    }
     
    void URTouch::InitTouch(byte orientation)
    {
    	//On ne communique pas avec l'afficheur à ce stade
    	orient					= orientation;
    	_default_orientation	= CAL_S>>31;
    	touch_x_left			= (CAL_X>>14) & 0x3FFF;
    	touch_x_right			= CAL_X & 0x3FFF;
    	touch_y_top				= (CAL_Y>>14) & 0x3FFF;
    	touch_y_bottom			= CAL_Y & 0x3FFF;
    	disp_x_size				= (CAL_S>>12) & 0x0FFF;
    	disp_y_size				= CAL_S & 0x0FFF;
    	prec					= 10;
     
        //pinMode(T_IRQ, OUTPUT);
        //pinMode(T_CS, OUTPUT);
    	digitalWrite(T_CS,  HIGH);
     
    /*
    	SPI.begin();
    	SPI.setDataMode(SPI_MODE3);
        SPI.setClockDivider(SPI_CLOCK_DIV4);
        SPI.setBitOrder(MSBFIRST);
    */
    }
     
    void URTouch::setPrecision(byte precision)
    {
    	//On ne communique pas avec l'afficheur à ce stade
    	switch (precision)
    	{
    		case PREC_LOW:
    			prec=1;		// DO NOT CHANGE!
    			break;
    		case PREC_MEDIUM:
    			prec=12;	// Iterations + 2
    			break;
    		case PREC_HI:
    			prec=27;	// Iterations + 2
    			break;
    		case PREC_EXTREME:
    			prec=102;	// Iterations + 2
    			break;
    		default:
    			prec=12;	// Iterations + 2
    			break;
    	}
    }
     
    bool URTouch::dataAvailable()
    {
    	//On ne communique pas avec l'afficheur à ce stade, on regarde juste l'état de la broche :
    	bool avail;
    	//pinMode(T_IRQ,  INPUT);
    	avail = !digitalRead(T_IRQ);
    	//pinMode(T_IRQ,  OUTPUT);
    	return avail;
    }
     
    void URTouch::read()
    {
    	unsigned long tx=0, temp_x=0;
    	unsigned long ty=0, temp_y=0;
    	int datacount=0;
     
    	//With most SPI devices
    	//after SPI.beginTransaction() you will write the slave select pin LOW
    	//call SPI.transfer() any number of times to transfer data
    	//then write the SS pin HIGH
    	//and finally call SPI.endTransaction().
     
    	//SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE3));
    	SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE3)); // Test avec une vitesse SPI plus faible
    	digitalWrite(T_CS,LOW);
     
    	for (int i=0; i<prec; i++)
    	{
            //added param command - RB 6/4/15
    		temp_x = touch_ReadData(0x90);
    		temp_y = touch_ReadData(0xD0);
     
    		if (!((temp_x>max(touch_x_left, touch_x_right)) or (temp_x==0) or (temp_y>max(touch_y_top, touch_y_bottom)) or (temp_y==0)))
    		{
    			ty+=temp_x;
    			tx+=temp_y;
    			datacount++;
    		}
    	}
     
    	digitalWrite(T_CS,HIGH);
    	SPI.endTransaction();
    	if (datacount>0)
    	{
    		if (orient == _default_orientation)
    		{
    			TP_X=tx/datacount;
    			TP_Y=ty/datacount;
    		}
    		else
    		{
    			TP_X=ty/datacount;
    			TP_Y=tx/datacount;
    		}
    	}
    	else
    	{
    		TP_X=-1;
    		TP_Y=-1;
    	}
    }
    //combined the write data method into the read seeing as HW SPI does both at the same time - RB 06/04/15
    word URTouch::touch_ReadData(byte command)
    {
    	//first send the command, this will not return anything useful so disregard the return byte
    	SPI.transfer(command);
     
    	//next we need to send 12 bits of nothing to get the 12 bits we need back
    	//we can only send in batches of 8, ie 1 byte so do this twice
    	byte f1 = SPI.transfer(0x00);
    	byte f2 = SPI.transfer(0x00);
     
    	//combine the 16 bits into a word
    	word w = word(f1, f2);
     
    	//the word is organised with MSB leftmost, shift right by 3 to make 12 bits
    	w = w >> 3;
     
    	//and return the result
    	return w;
    }
     
    int URTouch::getX()
    {
    	long c;
     
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	} else {
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
    		else
    			c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
     
    	return c;
    }
     
    int URTouch::getY()
    {
    	int c;
     
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	} else {
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		else
    			c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	return c;
    }
     
    /*
    void URTouch::calibrateRead()
    {
    	unsigned long tx=0;
    	unsigned long ty=0;
     
    	SPI.begin();
    	digitalWrite(T_CS,LOW);
     
    	tx=touch_ReadData(0x90);
        ty=touch_ReadData(0xD0);
     
    	digitalWrite(T_CS,HIGH);
    	SPI.end();
     
    	TP_X=ty;
    	TP_Y=tx;
    }
    */
    A noter : le fichier RLucas_TFT_TouchCD.h est inchangé, ce sont les données de calibration.

    Voici mon sketch :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    //Ethernet plus rapide ?
    //https://forum.arduino.cc/index.php?topic=217183.0
     
    #include <SPI.h>
     
    // DALLE TACTILE ************************************************************************************************************************************************
    // Calibration à faire avec 003_TFT_Touch_Calibrate_OK
    #include "RLucas_TFT_Touch.h"
    #define t_IRQ 5
    #define t_MISO 7 // ROUGE (TFT OUT) // La broche 4 est utilisée pour le lecteur SD de l'ethernet Shield
    #define t_MOSI 3 // VERT (TFT IN)
    #define t_CS 2  // JAUNE
    #define t_SCK 1 // BLEU
    //URTouch ts(t_SCK, t_CS, t_MOSI, t_MISO, t_IRQ);
    URTouch ts(t_CS, t_IRQ);
     
    // ECRAN TFT ****************************************************************************************************************************************************
    #include "RLucas_TFT_GFX.h"
    #include "RLucas_TFT_ILI9341_config.h" // C'est dans le fichier PDQ_ILI9341_config.h qu'on définit les broches CS, DC et RST :
    //#define ILI9341_CS_PIN    0   // <= /CS pin (chip-select, LOW to get attention of ILI9341, HIGH and it ignores SPI bus)
    //#define ILI9341_DC_PIN    9   // <= DC pin (1=data or 0=command indicator line) also called RS
    //#define ILI9341_RST_PIN   8   // <= RST pin (optional)
    //#define  ILI9341_SAVE_SPCR 0     // <= 0/1 with 1 to save/restore AVR SPI control register (to "play nice" when other SPI use) => prend plus de code et non nécessaire !
    #include "RLucas_TFT_ILI9341.h"      // PDQ: Hardware-specific driver library
    PDQ_ILI9341 tft;      
    #define TFT_PWM_LED 6 // Un transistor PNP permet de piloter le rétroéclairage 
     
    // ETHERNET *****************************************************************************************************************************************************
    #include "RLucas_Ethernet.h"
    // Ethernet Shield 2 : communicates with both the W5500 and SD card using the SPI bus (through the ICSP header).
    // This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega.
    // On both boards, pin 10 is used to select the W5500 and pin 4 for the SD card. These pins cannot be used for general I/O.
    // On the Mega, the hardware SS pin, 53, is not used to select either the W5500 or the SD card, but it must be kept as an output or the SPI interface won't work.
    byte mac[] = {
      0xA8, 0x61, 0x0A, 0xAE, 0x75, 0xCA //Voir étiquette collée sous le Shield
    };
    IPAddress ip(192, 168, 123, 177); //Choisir une IP fixe compatible avec le réseau local ou bien utiliser DHCP
    //IPAddress myDns(212, 27, 40, 240);
    //IPAddress myDns(192, 168, 123, 254); //DNS ou adresse du routeur  - Indispensable si IP Fixe (sans DHCP) et si on souhaite aller sur INTERNET (mais pas en local)
    //IPAddress gateway(192, 168, 123, 254); //Adresse du routeur - Indispensable si IP Fixe (sans DHCP) et si on souhaite aller sur INTERNET (mais pas en local)
    EthernetClient client;
    byte serverIP[] = { 192, 168, 123, 32 }; // Adresse IP du PC Fixe
    #define NetworkTimeout 2000
     
    // To open a port in the Windows 7 Firewall
    // On the Start menu, click Control Panel
    // Click on the System and Security category, then Windows Firewall. If you are not viewing by category, you can simply click on the Window Firewall item.
    // Click on the Advanced Settings link on the left hand side. This will open the Windows Firewall with Advanced Security Management Console application.
    // Click on Inbound Rules on the left hand menu. Under the Actions on the right hand side, click on New Rule. This opens the New Inbound Rule Wizard.
    // Select the Port option and click Next.
    // Select TCP and Specific local ports (80), then enter a comma-separated list of port numbers you want to open and click Next.
    // Select Allow the connection and click Next.
    // Check the boxes next to the desired network types and click Next.
    // Enter a name for your rule - and optionally a description - and click Finish.
    // Your inbound rule should now be displayed on the Inbound Rules list. To remove this rule, simply delete it from the list when you are done.
     
    // VARIABLES GLOBALES *******************************************************************************************************************************************
    // Buffer qui contient les requêtes et les réponses HTTP :
    #define Buffer_HTTP_Len 512
    char Buffer_HTTP[Buffer_HTTP_Len];
    int Buffer_HTTP_Stop; // Les données à traiter sont les octers de Buffer_HTTP de [0] à [Buffer_HTTP_Stop-1]
    int Buffi;
     
    // Variables "RAM" pouvant être écrites par le serveur et conservées :
    #define Buffer_RAM_Len 512
    char Buffer_RAM[Buffer_RAM_Len];
    int R1;
    int R2;
    int W1;
    int H1;
    int W2;
    int H2;
    unsigned int Couleur[14];
    int Palette; // Palette peut valoir 0 ou 7; la couleur à utiliser est définie par Couleur[index+Palette] avec index=0...6
     
    //Variables globales :
    int Status;
    int Touch_X;
    int Touch_Y;
    unsigned long debut;
    unsigned long duree;
    unsigned long duree2;
    int X1;
    int Y1;
    int X2;
    int Y2;
    int X3;
    int Y3;
    #define LIRE_X1_Y1 1
    #define LIRE_X2_Y2 2
    #define LIRE_X3_Y3 3
    #define LIRE_W1_H1 4
    #define LIRE_W2_H2 5
    uint8_t C1R;
    uint8_t C1G;
    uint8_t C1B;
    uint8_t C2R;
    uint8_t C2G;
    uint8_t C2B;
    int L;
     
    #define LireEntreeAnalogique 1
    #define LireEntreeNumerique 2
    #define LireEntreeLumiere 3
    const int MaxReadedPin = 10;
    byte ReadedPin[MaxReadedPin];
    int ReadedPinValue[MaxReadedPin];
    int ReadedPinIndex;
     
    #define PING_SERVEUR A5
    boolean pinPingServeur;
     
    #define AMBIANT_LIGHT A4
     
    /*
    #define AfficherBmpSansBG 1
    #define AfficherBmpAvecBG 2
    #define AfficherBmpBicolor 3
    */
     
    //char Buffer[20];
     
     
    // SETUP ********************************************************************************************************************************************************
    void setup() {
      Ajuster_Lumiere();
      //duree2=millis();
     
      tft.begin();
      tft.setRotation(0);
     
      ts.InitTouch(PORTRAIT);
      ts.setPrecision(PREC_EXTREME);
    /*
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
      tft.setTextSize(1);
    */
      // You can use Ethernet.init(CSpin) to configure the CS pin
      //Ethernet.begin(mac, ip, myDns, gateway); 
      Ethernet.begin(mac, ip);
      pinPingServeur = digitalRead(PING_SERVEUR);
     
      Status=0; // Démarrage
      Network_Contacter_Serveur();
    }
     
    // LOOP *********************************************************************************************************************************************************
    void loop() {
      // Gestion du rétroéclairage :
      Ajuster_Lumiere();
      //duree2=millis();
      // On demande à l'écran tactile s'il y a eu un appui :
      if (ts.dataAvailable()) {
        ts.read();
        Touch_X = ts.getX();
        Touch_Y = ts.getY();
        if ((Touch_X != -1) && (Touch_Y != -1)) {
          //analogWrite(TFT_PWM_LED,128);// Juste pour indiquer la détection d'une touche
          Network_Contacter_Serveur();
        }
      }
      // On surveille la broche permettant au serveur de solliciter une requête :
      if (pinPingServeur != digitalRead(PING_SERVEUR)) {
        pinPingServeur = !pinPingServeur;
        Status = 2; //Requête à la demande du serveur
        Network_Contacter_Serveur();
      }
    }
     
    void Ajuster_Lumiere() {
      analogWrite(TFT_PWM_LED, 205 - min(analogRead(AMBIANT_LIGHT) / 3, 205));
    }
     
    // REQUETTE *****************************************************************************************************************************************************
     
    void Network_Contacter_Serveur() {
      do {
        duree2=millis();
        Network_Construire_Requete_Traiter_Reponse();
      } while(Status > 2); // Fonction Force Another Request !
    }
     
    int Network_Envoyer_Requete_Pretraiter_Reponse() {
      int nb;
      char c;
      int i;
      //int j;
      //int nb_deja_lu;
      int RAM_pos;
      byte RAM_len;
      unsigned int longueur;
      byte crc;
      int err_RAM_Ecrite;
     
      duree=millis();
      // Connection au serveur web :
      // client.stop(); // L'arrêt du client prend beaucoup de temps, à faire après
      if (client.connect(serverIP, 80)) {
        client.print(Buffer_HTTP);
     
        //Attente de la réponse du serveur
        debut = millis();
        nb=0;
        while(nb==0){ 
          nb = client.available();
          if (millis()-debut>NetworkTimeout) {break;}
        }
     
        //Lecture de la réponse du serveur :
        if (nb==0) {
          return 1; // ERREUR : Le serveur met trop de temps à répondre
        } else {
          //On élimine l'entête, en cherchant le caractère '<' qui marque le début des données utiles :
          do {
            if (nb==0){
              return 3; // ERREUR : Le début des données n'a pas été trouvé
            }
            c=client.read();
            nb--;
          } while(c!='<');
     
          longueur = nb;
          crc = 0;
     
          if (nb==0){
            // Le serveur ne donne aucune instruction :
            Buffer_HTTP_Stop=0;
        return 9; // ERREUR : Manque Longueur + CRC
          }else{
            // Le serveur donne une ou plusieurs instructions :
            c=client.read();
            crc^=c;
            nb--;
     
            if (c==1) { // Network Resend data again
              // Le serveur demande à renvoyer les données, parce qu'il a mal reçu la requête :
              return 8; // ERREUR : Requête à recommencer
            }
     
            err_RAM_Ecrite = 0; // IMPORTANT : il peut se produire une erreur, alors qu'on a déjà écrit dans Buffer_RAM. Si oui le serveur devra en tenir compte lors du traitement de l'erreur.
     
            while(c==8) {
              // Ecriture dans le RAM buffer - Ces instructions d'écriture dans le RAM buffer ne peuvent être que les premières
              // ce qui permet d'éviter de stocker bêtement ces données en double dans le Buffer HTTP :
              nb-=2;
              if (nb<0){
                return 4 + err_RAM_Ecrite; // ERREUR : Données manquantes 
              }
              c=client.read();
              crc^=c;
              RAM_pos=(byte)c; //client.read();
              if (RAM_pos==255) {
                c=client.read();
                crc^=c;
                RAM_pos+=(byte)c; //client.read();
                nb--;
              }
              c=client.read();
              crc^=c;
              RAM_len=(byte)c; //client.read();
              nb-=RAM_len;
              if (nb<0){
                return 5 + err_RAM_Ecrite; // ERREUR : Données manquantes 
              }
              if (RAM_pos+RAM_len>=Buffer_RAM_Len){
                return 6 + err_RAM_Ecrite; // ERREUR : La position et la longeur d'écriture en RAM dépassent la limite
              }
              err_RAM_Ecrite = 32; // IMPORTANT : il peut se produire une erreur, alors qu'on a déjà écrit dans Buffer_RAM. Si oui le serveur devra en tenir compte lors du traitement de l'erreur.
              for (i=0;i<RAM_len;i++) {
                c=client.read(); // UTILISER PLUTOT : int EthernetClient::read(uint8_t *buf, size_t size) ? puis calculer le CRC ensuite ?
                crc^=c;
                Buffer_RAM[i+RAM_pos]=c; //client.read();
              }
              if (nb==0){
                // Le serveur ne donne aucune autre instruction :
                Buffer_HTTP_Stop=0;
                return 9 + err_RAM_Ecrite; // ERREUR : Manque Longueur + CRC
              }else{
                c=client.read();
                crc^=c;
                nb--;
              }
            }
     
            // Quand on arrive ici, le caractère 'c' qui a été lu auparavent est le premier caractère des instructions :
            Buffer_HTTP[0]=c;
            // Il reste 'nb' caractères à lire :
            if (nb>Buffer_HTTP_Len-2) {
              return 7 + err_RAM_Ecrite; // ERREUR : Trop de données envoyées par le serveur
            } 
            for (i=1;i<nb;i++) { //i<nb au lieu de i<=nb car le CRC ne doit pas être calculé sur lui-même
              c=client.read(); // UTILISER PLUTOT : int EthernetClient::read(uint8_t *buf, size_t size) ? puis calculer le CRC ensuite ?
              crc^=c;
              Buffer_HTTP[i]=c; //client.read();
            }
            c=client.read();
            Buffer_HTTP[i]=c; //=client.read();
            Buffer_HTTP_Stop=i+1;
          }
     
          // Il faut vérifier la longueur et le CRC :
          if (Buffer_HTTP_Stop<3) {
            return 9 + err_RAM_Ecrite; // ERREUR : Manque Longueur + CRC
          }
          Buffi=Buffer_HTTP_Stop-4; // Voir code de LireUInt16()
          if (longueur!=LireUInt16()) {
            return 10 + err_RAM_Ecrite; // ERREUR : Longueur incorrecte
          }
          if (crc!=(byte)Buffer_HTTP[Buffer_HTTP_Stop-1]) {
            return 11 + err_RAM_Ecrite; // ERREUR : CRC incorrect
          }
    /*
          tft.fillScreen(0);
          tft.setCursor(0, 0);
          tft.print("L=");   //263 OK vu avec Wireshark
          tft.print(longueur);
          tft.print(" CRC="); //87 OK !
          tft.print(crc);
          tft.print(" nb=");  //200
          tft.print(nb);
          tft.print(" BHS="); //201
          tft.print(Buffer_HTTP_Stop);
          tft.print(" LD=");  //263 OK !
          Buffi=Buffer_HTTP_Stop-4;
          tft.print(LireUInt16());
          tft.print(" C=");   //87 OK !
          tft.println((byte)Buffer_HTTP[Buffer_HTTP_Stop-1]);
          tft.println();
          j=0;
          for (i=0;i<Buffer_HTTP_Stop;i++) {
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%02x"), (byte)Buffer_HTTP[i]);
            tft.print(Buffer);
            tft.print(F(" "));
            j++;
            if (j>9) {
              j=0;
              tft.println();
            }
          }
          return 11;
    */
          // IMPORTANT : la longueur et le CRC ne doivent pas être exécutés !!!
          Buffer_HTTP_Stop-=3;
     
          return 0; // SUCCES
        }
      } else {
          return 2; // ERREUR : Pas de connection
      }
    }
     
    void Network_Construire_Requete_Traiter_Reponse() {
      int err_code;
      int i;
      int j;
      byte instr;
      int s;
      byte coul_index;
      int pos;
      int pin;
      int value;
      int valueoff;
      int w;
      int crc;
      unsigned int couleur1;
      unsigned int couleur2;
     
      //uint8_t *pointeur;
    /*
      int nb_ai;
      byte ai[50];
      int ai_ind[50];
      nb_ai=0;
    */
      err_code=0;
      do {
        // On construit la requête au serveur ici :
        //snprintf_P(Buffer_HTTP, sizeof(Buffer_HTTP), PSTR("GET /?E=%d&S=%d&X=%d&Y=%d HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"), err_code, Status, Touch_X, Touch_Y);
     
        /*
        strncpy_P(Buffer_HTTP, sizeof(Buffer_HTTP), PSTR("GET /?"));
        i=snprintf_P(Buffer_HTTP+6, sizeof(Buffer_HTTP)-6, PSTR("E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
        strncpy_P(Buffer_HTTP+i+6, sizeof(Buffer_HTTP), PSTR(" HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"));
        */
        /*
        strcpy_P(Buffer_HTTP, PSTR("GET /?"));
        i=6;
        i=sprintf_P(Buffer_HTTP+i, PSTR("E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
        */
        crc = err_code ^ Status ^ Touch_X ^ Touch_Y;
        i=sprintf_P(Buffer_HTTP, PSTR("GET /?E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
         if (Status==4) {
          for (j=0;j<ReadedPinIndex;j++) {
            i+=sprintf_P(Buffer_HTTP+i, PSTR("&I%d=%d"), ReadedPin[j], ReadedPinValue[j]);
            crc^=ReadedPinValue[j];
          }
        }
        i+=sprintf_P(Buffer_HTTP+i, PSTR("&C=%d"), crc);
        strcpy_P(Buffer_HTTP+i, PSTR(" HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"));
     
        // Le serveur connait :
        //
        //- Status
        //   0 : Le client démarre les variables et Buffer_RAM sont vides
        //   1 : Fonctionnement normal
        //   2 : Le client fait une requête à la demande du serveur (fil "interruption")
        //   3 : Le client dit au serveur qu'il est prêt a recevoir la suite de la réponse que le serveur avait demandé
        //   4 : Le client envoit la lecture des broches d'entrées que le serveur a demandé
        //
        //- err_code : le client a rencontré une erreur et demande au serveur une nouvelle requête
        //   err_code                  Le serveur a bien eu la requête précédente ?
        //   0 : SUCCES                OUI => traiter la requête normalement
        //   1 : Timeout               NON => traiter la requête normalement
        //   2 : Pas de connection     NON => traiter la requête normalement
        //   3 : Début non trouvé      OUI => juste renvoyer la réponse précédente
        //   4 : Données manquantes    OUI => juste renvoyer la réponse précédente
        //   5 : Données manquantes    OUI => juste renvoyer la réponse précédente
        //   6 : RAM overflow          OUI => juste renvoyer la réponse précédente
        //   7 : Trop de données       OUI => juste renvoyer la réponse précédente
        //   8 : Requête à recommencer OUI mais le serveur a rencontré une erreur et redemande la requete au client => traiter la requête normalement
        //   9 : CRC manquant          OUI => juste renvoyer la réponse précédente
        //   10: Longueur incorrecte   OUI => juste renvoyer la réponse précédente
        //   11: CRC incorrect         OUI => juste renvoyer la réponse précédente
        //
        //   IMPORTANT : err_code est augmenté de 32 si Buffer_RAM a été possiblement corrompu par des données incorrectes.
        //               dans ce cas de figure le serveur devra renvoyer les données pour remplir Buffer_RAM avec des données sûres.
        //
        //   "traiter la requête normalement" :
        //   - Si Status = 0 => le serveur doit envoyer les données d'initialisation
        //   - Si Status = 1 => le serveur doit executer l'action correspondant à la frappe sur le pavé tactile X et Y
        //   - Si Status = 2 => le serveur doit envoyer les données qu'il souhaite (requête client faite à la demande du serveur)
        //   - Si Status = 3 => le serveur doit envoyer la suite des données si il y a une suite disponible 
        //   - Si Status = 4 => le serveur doit lire les données lues, et envoyer la suite des données si il y a une suite disponible 
     
        err_code = Network_Envoyer_Requete_Pretraiter_Reponse();
        duree = millis()-duree;
     
        tft.tftSpiBegin();
        if (err_code==0) {
          // On traite la réponse ici :
          // Les instructions et les données à traiter sont comprises entre Buffer_HTTP[0] et Buffer_HTTP[Buffer_HTTP_Stop-1]
     
          Status=1; // On réinitialise le statut à la valeur "normale"
          ReadedPinIndex = 0;
          Buffi=-1;
     
          while(Buffi<Buffer_HTTP_Stop-1) {
            instr = LireUByte();
            if (instr>31) {
              // Il faut récupérer l'index de la couleur et remettre le numéro de l'instruction de base :
              coul_index = (instr - 32) % 7;
              instr -= coul_index;
              coul_index += Palette;
              if (instr>52 && instr<228) {
                LireXY(LIRE_X1_Y1); // Eviter de copier cette instruction de multiples fois (cases vertes dans le tableau Excel)
              }
            }else{
              if (instr>15 && instr<20) {
                // Dégradés
                LireXY(LIRE_X1_Y1); // Eviter de copier cette instruction de multiples fois (cases vertes dans le tableau Excel)
                LireXY(LIRE_X2_Y2); // Eviter de copier cette instruction de multiples fois (cases bleues dans le tableau Excel)
                if (instr>17) {
                  couleur1 = LireUInt16();                      
                  couleur2 = LireUInt16();
                  instr-=2;
                }else{
                  couleur1 = Couleur[LireUInt8()];                      
                  couleur2 = Couleur[LireUInt8()]; 
                }
                C1R = ((couleur1 >> 11) & 0x1F);
                C1G = ((couleur1 >> 5) & 0x3F);
                C1B = (couleur1 & 0x1F);
                C2R = ((couleur2 >> 11) & 0x1F);
                C2G = ((couleur2 >> 5) & 0x3F);
                C2B = (couleur2 & 0x1F);
              }else{
                if (instr>20 && instr<25) {
                  // Il faut récupérer la taille du texte et remettre le numéro de l'instruction de base :
                  s = instr-20;    
                  instr = 21;
                }
              }
            }
    /*
            ai[nb_ai]=instr;
            ai_ind[nb_ai]=Buffi;
            nb_ai++;
    */
            switch (instr) {
              case 0: // 
                // A FAIRE
                break;
              // case 1: Network Resend data => Traité dans la procédure Network_Faire_Requete();
              case 2: // Network Force other request
                if (Status<3) {Status = 3;} // Force other request (demande la suite) - Il faut laisser le Status à 4 s'il y est déjà
                break;
              case 3: // Write pin
                pin = LireUInt8();
                value = LireUInt8();
                //pinMode(pin, OUTPUT); //déjà dans analogWrite
                analogWrite(pin,value);
                break;
              case 4: // Write pin pulse
                pin = LireUInt8();
                w = LireUInt9();
                value = LireUInt8();
                valueoff = LireUInt8();
                //pinMode(pin, OUTPUT); //déjà dans analogWrite
                analogWrite(pin,value);
                delay(w);
                analogWrite(pin,valueoff);
                break;
              case 5: // Read digital pin
                LireEntree(LireEntreeNumerique);
                break;
              case 6: // Read analog pin
                LireEntree(LireEntreeAnalogique);
                break;
              case 7: // Read Ambiant light
                LireEntree(LireEntreeLumiere);
                break;
              case 9: // Set R1
                R1 = LireUInt9();
                break;
              case 10: // Set R2
                R2 = LireUInt9();
                break;
              case 11: // Set W1 H1
                LireXY(LIRE_W1_H1);
                break;
              case 12: // Set W2 H2
                LireXY(LIRE_W2_H2);
                break;
              case 13: // Set color
                i = LireUInt8();
                Couleur[i] = LireUInt16();
                break;
              case 14: // Set color index 0...6
                Palette=0;
                break;
              case 15: // Set color index 7...13
                Palette=7;
                break;
     
              case 16: // TFT Fill Rect Colormorph H
                L = X2-1;
                for (i=0;i<X2;i++) {
                  tft.drawFastVLine(i+X1, Y1, Y2, CouleurDegrade(i));
                }
                break;
              case 17: // TFT Fill Rect Colormorph V
                L = Y2-1;
                for (i=0;i<Y2;i++) {
                  tft.drawFastHLine(X1, i+Y1, X2, CouleurDegrade(i));
                }
                break;
     
              case 20: // TFT Set text cursor 
                LireXY(LIRE_X1_Y1);
                tft.setCursor(X1, Y1);
                break;
              case 21: // TFT Set text size 
                tft.setTextSize(s);
                break;
              case 25: // TFT Set text wrap off 
                tft.setTextWrap(false);
                break;
              case 26: // TFT Set text wrap on 
                tft.setTextWrap(true);
                break;
              case 27: // TFT Set text color
                  tft.setTextColor(Couleur[LireUInt8()]);
                break;
              case 28: // TFT Set text color & BG color
                  i=LireUInt8();
                  tft.setTextColor(Couleur[i],Couleur[LireUInt8()]);
                break;
              case 29: // TFT Print @RAM
                pos=LireUInt9();
                tft.print((char*)(Buffer_RAM + pos));
                break;
              case 30: // TFT Print
                PrintString();
                break;
              case 31: // TFT Print char
                Buffi++;
                tft.print(Buffer_HTTP[Buffi]);
                break;
     
              case 46: // TFT Fill Screen
                tft.fillScreen(Couleur[coul_index]);
                break;
     
              case 32: // TFT Draw Rect Button
                w = PrintString();
                // A FAIRE
                break;
              case 39: // TFT Draw Circle Button
                w = PrintString();
                // A FAIRE
                break;
     
              case 53: // TFT Draw Line
                LireXY(LIRE_X2_Y2);
                tft.drawLine(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 60: // TFT Draw H Line
                tft.drawFastHLine(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 67: // TFT Draw V Line
                tft.drawFastVLine(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
     
              case 74: // TFT Draw Rect
                LireXY(LIRE_X2_Y2);
                tft.drawRect(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 88: // TFT Draw Rect Size1
                tft.drawRect(X1, Y1, W1, H1, Couleur[coul_index]);
                break;
              case 102: // TFT Draw Rect Size2
                tft.drawRect(X1, Y1, W2, H2, Couleur[coul_index]);
                break;
     
              case 81: // TFT Draw Round Rect
                LireXY(LIRE_X2_Y2);
                tft.drawRoundRect(X1, Y1, X2, Y2, LireUInt9(), Couleur[coul_index]);
                break;
              case 95: // TFT Draw Round Rect Size1 R1
                tft.drawRoundRect(X1, Y1, W1, H1, R1, Couleur[coul_index]);
                break;
              case 109: // TFT Draw Round Rect Size2 R2
                tft.drawRoundRect(X1, Y1, W2, H2, R2, Couleur[coul_index]);
                break;
     
              case 116: // TFT Draw Circle
                tft.drawCircle(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 123: // TFT Draw Circle R1
                tft.drawCircle(X1, Y1, R1, Couleur[coul_index]);
                break;
              case 130: // TFT Draw Circle R2
                tft.drawCircle(X1, Y1, R2, Couleur[coul_index]);
                break;
     
              case 137: // TFT Draw Triangle
                LireXY(LIRE_X2_Y2);
                LireXY(LIRE_X3_Y3);
                tft.drawTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
              case 144: // TFT Draw Triangle
                X2 = X1 + W1;
                Y2 = Y1 + H1;
                X3 = X1 + W2;
                Y3 = Y1 + H2;
                tft.drawTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
     
              case 151: // TFT Fill Rect
                LireXY(LIRE_X2_Y2);
                tft.fillRect(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 165: // TFT Fill Rect Size1
                tft.fillRect(X1, Y1, W1, H1, Couleur[coul_index]);
                break;
              case 179: // TFT Fill Rect Size2
                tft.fillRect(X1, Y1, W2, H2, Couleur[coul_index]);
                break;
     
              case 158: // TFT Fill Round Rect
                LireXY(LIRE_X2_Y2);
                tft.fillRoundRect(X1, Y1, X2, Y2, LireUInt9(), Couleur[coul_index]);
                break;
              case 172: // TFT Fill Round Rect Size1 R1
                tft.fillRoundRect(X1, Y1, W1, H1, R1, Couleur[coul_index]);
                break;
              case 186: // TFT Fill Round Rect Size2 R2
                tft.fillRoundRect(X1, Y1, W2, H2, R2, Couleur[coul_index]);
                break;
     
              case 193: // TFT Fill Circle
                tft.fillCircle(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 200: // TFT Fill Circle R1
                tft.fillCircle(X1, Y1, R1, Couleur[coul_index]);
                break;
              case 207: // TFT Fill Circle R2
                tft.fillCircle(X1, Y1, R2, Couleur[coul_index]);
                break;
     
              case 214: // TFT Fill Triangle
                LireXY(LIRE_X2_Y2);
                LireXY(LIRE_X3_Y3);
                tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
              case 221: // TFT Fill Triangle
                X2 = X1 + W1;
                Y2 = Y1 + H1;
                X3 = X1 + W2;
                Y3 = Y1 + H2;
                tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
     
              case 228: // 
     
                break;
              case 235: // TFT Draw Bitmap RAM
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                //tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], 0, false, LireUInt8());
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], 0, LireUInt8());
                break;
              case 242: // TFT Draw Bitmap RAM + Bicolor
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                j = LireUInt8();
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], Couleur[j], LireUInt8());
                break;
              case 249: // TFT Draw Bitmap RAM + BG
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], Couleur[Palette], LireUInt8());
                break;
     
              default:
                break;
            }
     
          } 
     
     
          // Affichage de debug : -----------------------------------------------------------------------------
          //tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
          tft.setCursor(0, 0);
          tft.print(duree); // Temps pris pour envoyer la requête au serveur et recevoir la réponse
          tft.print(F("ms "));
          tft.print(millis()-duree2-duree);  // Temps pris pour gérer l'appui sur l'écran tactile et l'affichage
          tft.print(F("ms "));
          tft.println(Buffer_HTTP_Stop);
    /*
          tft.println();
          for (i=0;i<8;i++){
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%d %04x"), i, Couleur[i]);
            tft.println(Buffer);
          }
          tft.println();
     
          j=0;
          for (i=0;i<Buffer_HTTP_Stop;i++) {
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%02x"), (byte)Buffer_HTTP[i]);
            tft.print(Buffer);
            tft.print(F(" "));
            j++;
            if (j>9) {
              j=0;
              tft.println();
            }
          }
          tft.println();
          tft.println();
          tft.print(F("Buffer_HTTP_Stop = "));
          tft.println(Buffer_HTTP_Stop);
     
          if (nb_ai>0) {
            tft.print(F("Appels :"));
            tft.println(nb_ai);
          }
          j=0;
          for (i=0;i<nb_ai;i++) {
            tft.print(ai_ind[i]);
            tft.print(F(":"));
            tft.print(ai[i]);
            j++;
            if (j>4) {
              j=0;
              tft.println();
            }else{
                tft.print(F("  "));
            }
          }
    */
          // --------------------------------------------------------------------------------------------------
     
        } else {
          // En cas d'erreur, on affiche et on recommence :
          tft.fillScreen(0);
          tft.setCursor(0, 0);
          tft.print(F("Erreur "));
          tft.print(err_code);
          delay(250);
        }
      tft.tftSpiEnd();
      } while(err_code!=0);
    }
     
    /*
    void AfficherBMP (byte mode) {
      int i;
      unsigned int CoulBG;
      i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
      LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
      if (mode == AfficherBmpBicolor) {
        CoulBG = Couleur[LireUInt8()];
      }else{
        CoulBG = Couleur[Palette];
      }
      tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], CoulBG, mode!=AfficherBmpSansBG, LireUInt8());
    }
    */
     
    void LireEntree(byte mode) {
      int pin;
      Status = 4;
      if (ReadedPinIndex<MaxReadedPin) {
        if (mode==LireEntreeLumiere) {
          pin = AMBIANT_LIGHT;
        }else{
          pin = LireUInt8();
        }
        pinMode(pin, INPUT);
        ReadedPin[ReadedPinIndex] = pin;
        if (mode==LireEntreeNumerique) {
          ReadedPinValue[ReadedPinIndex] = digitalRead(pin);
        }else{
          ReadedPinValue[ReadedPinIndex] = analogRead(pin);
        }
        ReadedPinIndex++;
      }
    }
     
    unsigned int CouleurDegrade(int i) {
      int R;
      int G;
      int B;
      R = int(C2R * i/L + C1R * (L-i)/L);
      G = int(C2G * i/L + C1G * (L-i)/L);
      B = int(C2B * i/L + C1B * (L-i)/L);
      /*
      if (R>31) {R=31;}
      if (G>63) {R=63;}
      if (B>31) {B=31;}
      */
      return (R << 11) | (G << 5) | B;
    }
     
    int PrintString() {
      int i;
      int j;
      Buffi++;
      tft.print(Buffer_HTTP + Buffi);
      for (i=Buffi;i<Buffer_HTTP_Stop;i++) {
        if (Buffer_HTTP[i]==0) {
          j = i - Buffi;
          Buffi = i;
          return j;
        }
      }
      return -1;
    }
     
    byte LireUByte() {
      Buffi++;
      return Buffer_HTTP[Buffi]; 
    }
     
    int LireUInt8() {
      Buffi++;
      return (byte)Buffer_HTTP[Buffi];
    }
     
    int LireUInt9() {
      // Entier compris entre 0 et 510 - Occupe un octet si inférieur à 255
      int tmp;
      Buffi++;
      tmp = (byte)Buffer_HTTP[Buffi];
      if (tmp==255) {
        Buffi++;
        tmp += (byte)Buffer_HTTP[Buffi];
      }
      return tmp;  
    }
     
    /*
    int LireUInt9_RAM() {
      // Entier compris entre 0 et 510 - Occupe un octet si inférieur à 255
      int tmp;
      tmp = (byte)Buffer_RAM[Buffiram];
      Buffiram++;
      if (tmp==255) {
        tmp += (byte)Buffer_RAM[Buffiram];
        Buffiram++;
      }
      return tmp;  
    }
    */
     
    unsigned int LireUInt16() {
      byte MSB;
      byte LSB;
      Buffi+=2;
      MSB = Buffer_HTTP[Buffi-1];
      LSB = Buffer_HTTP[Buffi];
      return (MSB<<8) + LSB;
    }
     
    void LireXY(int num) {
      int tmpX;
      int tmpY;
      tmpX = LireUInt9();
      tmpY = LireUInt9() ;
      switch(num) {
      case LIRE_X1_Y1:
        X1=tmpX;
        Y1=tmpY;
        break;
      case LIRE_X2_Y2:
        X2=tmpX;
        Y2=tmpY;
        break;
      case LIRE_X3_Y3:
        X3=tmpX;
        Y3=tmpY;
        break;
      case LIRE_W1_H1:
        W1=tmpX;
        H1=tmpY;
        break;
      case LIRE_W2_H2:
        W2=tmpX;
        H2=tmpY;
        break;
      }    
    }
    Alors ça ne fonctionne pas bien et je sèche un peu...

    J'arrive à détecter une touche sur l'écran via la broche IRQ, mais mon serveur ne reçoit à chaque frappe sur l'écran les valeurs X=0 et Y=319 quel que soit l'endroit où on a touché l'écran tactile...

    Tout le reste fonctionne (affichage, shield Ethernet, ...)

    S'agissant des branchements, j'ai simplement :
    - laissé la broche IRQ de la dalle tactile câblée comme avant
    - laissé la broche CS de la dalle tactile câblée comme avant
    - câblé la broche MOSI de la dalle tactile en parallèle sur la broche MOSI de l'écran TFT
    - câblé la broche MISO de la dalle tactile en parallèle sur la broche MISO de l'écran TFT
    - câblé la broche CK de la dalle tactile en parallèle sur la broche CK de l'écran TFT

    Je ne comprend pas ce qui cloche... J'ai essayé de baisser la vitesse du bus SPI pour la dalle tactile sans succès.

    Je ne dois pas être loin de la solution car tout le reste fonctionne, y compris l'écran TFT et le shield Ethernet qui utilisent le hardware SPI

    Ce passage au hardware SPI est plus "propre" et fait économiser 746 octets de ROM ainsi que 3 broches I/O, ce n'est pas négligeable.

    A bientôt

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  2. #2
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    J'ai essayé avec une autre variante du fichier .cpp de la librairie mais le résultat est le même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    #include "SPI.h"
    #include "RLucas_TFT_Touch.h"
    #include "RLucas_TFT_TouchCD.h"
     
    URTouch::URTouch(byte tcs, byte irq)
    {
        //T_CLK        = tclk;
        T_CS         = tcs;
        //T_DIN        = din;
        //T_DOUT       = dout;
        T_IRQ        = irq;
    }
     
    void URTouch::InitTouch(byte orientation)
    {
    	orient					= orientation;
    	_default_orientation	= CAL_S>>31;
    	touch_x_left			= (CAL_X>>14) & 0x3FFF;
    	touch_x_right			= CAL_X & 0x3FFF;
    	touch_y_top				= (CAL_Y>>14) & 0x3FFF;
    	touch_y_bottom			= CAL_Y & 0x3FFF;
    	disp_x_size				= (CAL_S>>12) & 0x0FFF;
    	disp_y_size				= CAL_S & 0x0FFF;
    	prec					= 10;
     
    	//pinMode(T_CLK,  OUTPUT);
        pinMode(T_CS,   OUTPUT);
        //pinMode(T_DIN,  OUTPUT);
        //pinMode(T_DOUT, INPUT);
        pinMode(T_IRQ,  OUTPUT);
     
    	digitalWrite(T_CS,  HIGH);
    	//digitalWrite(T_CLK, HIGH);
    	//digitalWrite(T_DIN, HIGH);
    	//digitalWrite(T_CLK, HIGH);
    }
     
    // transmit byte serially, MSB first
    /*
    void URTouch::touch_WriteData(byte data)
    {
    	byte temp;
    	byte nop;
     
    	temp=data;
    	digitalWrite(T_CLK,LOW);
     
    	// send bits 7..0
    	for(byte count=0; count<8; count++)
    	{
    		// consider leftmost bit
            // set line high if bit is 1, low if bit is 0
    		if(temp & 0x80)
    			digitalWrite(T_DIN, HIGH);
    		else
    			digitalWrite(T_DIN, LOW);
     
    		// shift byte left so next bit will be leftmost
    		temp = temp << 1;
     
    		// pulse clock to indicate that bit value should be read
    		digitalWrite(T_CLK, LOW);
    		nop++;
    		digitalWrite(T_CLK, HIGH);
    		nop++;
    	}
    }
    */
    word URTouch::touch_ReadData(byte b)
    {
    	//the d_out will return 12 bits of data for every 8 bit command ?
    	//so we need to send the 8 bit command plus some garbage ?
    	return word(SPI.transfer(b), SPI.transfer(0x00));
     
    	/*
    	byte nop;
    	word data = 0;
     
    	// read bits 11..0
    	for(byte count=0; count<12; count++)
    	{
    		// shift byte left so next bit will be leftmost
    		data <<= 1;
     
    		// pulse clock to indicate that bit value should be read
    		digitalWrite(T_CLK, HIGH);
    		nop++;
    		digitalWrite(T_CLK, LOW);
    		nop++;
     
    		//if T_DOUT is high, this position in data will be 1, else it will be 0
    		if (digitalRead(T_DOUT))
    			data++;
    	}
     
    	return(data);
    	*/
     
     
    }
     
    void URTouch::read()
    {
    	unsigned long tx=0, temp_x=0;
    	unsigned long ty=0, temp_y=0;
    	int datacount=0;
     
    	//With most SPI devices
    	//after SPI.beginTransaction() you will write the slave select pin LOW
    	//call SPI.transfer() any number of times to transfer data
    	//then write the SS pin HIGH
    	//and finally call SPI.endTransaction().
    	SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE3)); // Test avec une vitesse SPI plus faible
    	digitalWrite(T_CS,LOW);
     
    	for (int i=0; i<prec; i++)
    	{
    		//touch_WriteData(0x90);
    		//digitalWrite(T_CLK,HIGH);
    		//digitalWrite(T_CLK,LOW);
    		//temp_x=touch_ReadData();
    		temp_x=touch_ReadData(0x90);
     
    		//touch_WriteData(0xD0);
    		//digitalWrite(T_CLK,HIGH);
    		//digitalWrite(T_CLK,LOW);
    		//temp_y=touch_ReadData(0x90, 0xD0);
    		temp_y=touch_ReadData(0xD0);
     
    		if (!((temp_x>max(touch_x_left, touch_x_right)) or (temp_x==0) or (temp_y>max(touch_y_top, touch_y_bottom)) or (temp_y==0)))
    		{
    			ty+=temp_x;
    			tx+=temp_y;
    			datacount++;
    		}
    	}
     
    	digitalWrite(T_CS,HIGH);
    	SPI.endTransaction();
     
    	if (datacount>0)
    	{
    		if (orient == _default_orientation)
    		{
    			TP_X=tx/datacount;
    			TP_Y=ty/datacount;
    		}
    		else
    		{
    			TP_X=ty/datacount;
    			TP_Y=tx/datacount;
    		}
    	}
    	else
    	{
    		TP_X=-1;
    		TP_Y=-1;
    	}
    }
     
    bool URTouch::dataAvailable()
    {
    	bool avail;
    	pinMode(T_IRQ,  INPUT);
    	avail = !digitalRead(T_IRQ);
    	pinMode(T_IRQ,  OUTPUT);
    	return avail;
    }
     
    int URTouch::getX()
    {
    	long c;
     
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	else
    	{
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
    		else
    			c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
    	return c;
    }
     
    int URTouch::getY()
    {
    	int c;
     
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
    	else
    	{
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		else
    			c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	return c;
    }
     
    void URTouch::setPrecision(byte precision)
    {
    	switch (precision)
    	{
    		case PREC_LOW:
    			prec=1;
    			break;
    		case PREC_MEDIUM:
    			prec=10;
    			break;
    		case PREC_HI:
    			prec=25;
    			break;
    		case PREC_EXTREME:
    			prec=100;
    			break;
    		default:
    			prec=10;
    			break;
    	}
    }
    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  3. #3
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    J'ai constaté pas mal de différence entre la bibliothèque proposée par les gens sur le forums et la bibliothèque originale...

    J'ai refait une version plus proche de l'original mais le problème est exactement le même :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    #include "SPI.h"
    #include "RLucas_TFT_Touch.h"
    #include "RLucas_TFT_TouchCD.h"
     
    URTouch::URTouch(byte tcs, byte irq)
    {
        //T_CLK        = tclk;
        T_CS         = tcs;
        //T_DIN        = din;
        //T_DOUT       = dout;
        T_IRQ        = irq;
    }
     
    void URTouch::InitTouch(byte orientation)
    {
    	orient					= orientation;
    	_default_orientation	= CAL_S>>31;
    	touch_x_left			= (CAL_X>>14) & 0x3FFF;
    	touch_x_right			= CAL_X & 0x3FFF;
    	touch_y_top				= (CAL_Y>>14) & 0x3FFF;
    	touch_y_bottom			= CAL_Y & 0x3FFF;
    	disp_x_size				= (CAL_S>>12) & 0x0FFF;
    	disp_y_size				= CAL_S & 0x0FFF;
    	prec					= 10;
     
    	//pinMode(T_CLK,  OUTPUT);
        pinMode(T_CS,   OUTPUT);
        //pinMode(T_DIN,  OUTPUT);
        //pinMode(T_DOUT, INPUT);
        pinMode(T_IRQ,  OUTPUT);
     
    	digitalWrite(T_CS,  HIGH);
    	//digitalWrite(T_CLK, HIGH);
    	//digitalWrite(T_DIN, HIGH);
    	//digitalWrite(T_CLK, HIGH);
    }
     
    // transmit byte serially, MSB first
    /*
    void URTouch::touch_WriteData(byte data)
    {
    	byte temp;
    	byte nop;
     
    	temp=data;
    	digitalWrite(T_CLK,LOW);
     
    	// send bits 7..0
    	for(byte count=0; count<8; count++)
    	{
    		// consider leftmost bit
            // set line high if bit is 1, low if bit is 0
    		if(temp & 0x80)
    			digitalWrite(T_DIN, HIGH);
    		else
    			digitalWrite(T_DIN, LOW);
     
    		// shift byte left so next bit will be leftmost
    		temp = temp << 1;
     
    		// pulse clock to indicate that bit value should be read
    		digitalWrite(T_CLK, LOW);
    		nop++;
    		digitalWrite(T_CLK, HIGH);
    		nop++;
    	}
    }
    */
    word URTouch::touch_ReadData(byte b)
    {
    	//the d_out will return 12 bits of data for every 8 bit command ?
    	//so we need to send the 8 bit command plus some garbage ?
    	return word(SPI.transfer(b), SPI.transfer(0x00));
     
    	/*
    	byte nop;
    	word data = 0;
     
    	// read bits 11..0
    	for(byte count=0; count<12; count++)
    	{
    		// shift byte left so next bit will be leftmost
    		data <<= 1;
     
    		// pulse clock to indicate that bit value should be read
    		digitalWrite(T_CLK, HIGH);
    		nop++;
    		digitalWrite(T_CLK, LOW);
    		nop++;
     
    		//if T_DOUT is high, this position in data will be 1, else it will be 0
    		if (digitalRead(T_DOUT))
    			data++;
    	}
     
    	return(data);
    	*/
     
     
    }
     
    void URTouch::read()
    {
    	unsigned long tx=0, temp_x=0;
    	unsigned long ty=0, temp_y=0;
    	unsigned long minx=99999, maxx=0;
    	unsigned long miny=99999, maxy=0;
    	int datacount=0;
     
    	//cbi(P_CS, B_CS);     
    	SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE3)); // Test avec une vitesse SPI plus faible
    	digitalWrite(T_CS,LOW);
     
     
    	pinMode(T_IRQ,  INPUT);
    	for (int i=0; i<prec; i++)
    	{
    		if (!digitalRead(T_IRQ))
    		{
    			//touch_WriteData(0x90);        
    			//pulse_high(P_CLK, B_CLK);
    			//temp_x=touch_ReadData();
    			temp_x=touch_ReadData(0x90);
     
    			if (!digitalRead(T_IRQ))
    			{
    				//touch_WriteData(0xD0);      
    				//pulse_high(P_CLK, B_CLK);
    				//temp_y=touch_ReadData();
    				temp_y=touch_ReadData(0xD0);
     
    				if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096))
    				{
    					tx+=temp_x;
    					ty+=temp_y;
    					if (prec>5)
    					{
    						if (temp_x<minx)
    							minx=temp_x;
    						if (temp_x>maxx)
    							maxx=temp_x;
    						if (temp_y<miny)
    							miny=temp_y;
    						if (temp_y>maxy)
    							maxy=temp_y;
    					}
    					datacount++;
    				}
    			}
    		}
    	}
    	pinMode(T_IRQ,  OUTPUT);
     
    	if (prec>5)
    	{
    		tx = tx-(minx+maxx);
    		ty = ty-(miny+maxy);
    		datacount -= 2;
    	}
     
    	//sbi(P_CS, B_CS);   
    	digitalWrite(T_CS,HIGH);
    	SPI.endTransaction();
     
    	if ((datacount==(prec-2)) or (datacount==PREC_LOW))
    	{
    		if (orient == _default_orientation)
    		{
    			TP_X=ty/datacount;
    			TP_Y=tx/datacount;
    		}
    		else
    		{
    			TP_X=tx/datacount;
    			TP_Y=ty/datacount;
    		}
    	}
    	else
    	{
    		TP_X=-1;
    		TP_Y=-1;
    	}
    }
     
     
    /*
    void URTouch::read()
    {
    	unsigned long tx=0, temp_x=0;
    	unsigned long ty=0, temp_y=0;
    	int datacount=0;
     
    	//With most SPI devices
    	//after SPI.beginTransaction() you will write the slave select pin LOW
    	//call SPI.transfer() any number of times to transfer data
    	//then write the SS pin HIGH
    	//and finally call SPI.endTransaction().
    	SPI.beginTransaction(SPISettings(400000, MSBFIRST, SPI_MODE3)); // Test avec une vitesse SPI plus faible
    	digitalWrite(T_CS,LOW);
     
    	for (int i=0; i<prec; i++)
    	{
    		//touch_WriteData(0x90);
    		//digitalWrite(T_CLK,HIGH);
    		//digitalWrite(T_CLK,LOW);
    		//temp_x=touch_ReadData();
    		temp_x=touch_ReadData(0x90);
     
    		//touch_WriteData(0xD0);
    		//digitalWrite(T_CLK,HIGH);
    		//digitalWrite(T_CLK,LOW);
    		//temp_y=touch_ReadData(0x90, 0xD0);
    		temp_y=touch_ReadData(0xD0);
     
    		if (!((temp_x>max(touch_x_left, touch_x_right)) or (temp_x==0) or (temp_y>max(touch_y_top, touch_y_bottom)) or (temp_y==0)))
    		{
    			ty+=temp_x;
    			tx+=temp_y;
    			datacount++;
    		}
    	}
     
    	digitalWrite(T_CS,HIGH);
    	SPI.endTransaction();
     
    	if (datacount>0)
    	{
    		if (orient == _default_orientation)
    		{
    			TP_X=tx/datacount;
    			TP_Y=ty/datacount;
    		}
    		else
    		{
    			TP_X=ty/datacount;
    			TP_Y=tx/datacount;
    		}
    	}
    	else
    	{
    		TP_X=-1;
    		TP_Y=-1;
    	}
    }
    */
     
    bool URTouch::dataAvailable()
    {
    	bool avail;
    	pinMode(T_IRQ,  INPUT);
    	avail = !digitalRead(T_IRQ);
    	pinMode(T_IRQ,  OUTPUT);
    	return avail;
    }
     
    int URTouch::getX()
    {
    	long c;
     
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_X - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	else
    	{
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_X - touch_y_top) * (-disp_y_size)) / long(touch_y_bottom - touch_y_top) + long(disp_y_size);
    		else
    			c = long(long(TP_X - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
    	return c;
    }
     
    int URTouch::getY()
    {
    	int c;
     
    	if (orient == _default_orientation)
    	{
    		c = long(long(TP_Y - touch_y_top) * (disp_y_size)) / long(touch_y_bottom - touch_y_top);
    		if (c<0)
    			c = 0;
    		if (c>disp_y_size)
    			c = disp_y_size;
    	}
    	else
    	{
    		if (_default_orientation == PORTRAIT)
    			c = long(long(TP_Y - touch_x_left) * (disp_x_size)) / long(touch_x_right - touch_x_left);
    		else
    			c = long(long(TP_Y - touch_x_left) * (-disp_x_size)) / long(touch_x_right - touch_x_left) + long(disp_x_size);
    		if (c<0)
    			c = 0;
    		if (c>disp_x_size)
    			c = disp_x_size;
    	}
    	return c;
    }
     
    void URTouch::setPrecision(byte precision)
    {
    	switch (precision)
    	{
    		case PREC_LOW:
    			prec=1;
    			break;
    		case PREC_MEDIUM:
    			prec=10;
    			break;
    		case PREC_HI:
    			prec=25;
    			break;
    		case PREC_EXTREME:
    			prec=100;
    			break;
    		default:
    			prec=10;
    			break;
    	}
    }
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  4. #4
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Bonjour,

    J'ai trouvé un autre librairie qui a trois avantages :
    - code plus court
    - hardware SPI
    - retourne aussi Z (force d'appui sur l'écran)

    Elle s'appelle XPT2046_Touchscreen

    Mais ça déconne toujours...

    Les valeurs que je reçoit sont, quel que soit l'endroit où je touche l'écran :
    - soit X=0 Y=0 Z=4095
    - soit X=26 Y=18 Z=4613
    - soit X=26 Y=18 Z=5669

    Bizarre...

    Le code de la librairie est intéressant, on voit notamment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define SPI_SETTING     SPISettings(2000000, MSBFIRST, SPI_MODE0)
    On retiens une vitesse relativement faible et surtout le mode 0 du SPI

    (quelle saloperie le bus SPI... pourquoi 4 modes différents ?)

    La librairie permet de gérer la broche IRQ avec une vraie interruption mais c'est le foutoir ça se déclenche tout le temps, et je n'ai pas les interruptions et préfère gérer mes événements dans une boucle

    Le code généré est plus court de 416 octets, cela fait 1162 octets de gagnés par rapport au bitbanging de URTouche

    Voici le code de la librairie :

    le fichier .h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    /* Touchscreen library for XPT2046 Touch Controller Chip
     * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice, development funding notice, and this permission
     * notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
     
    #ifndef _XPT2046_Touchscreen_h_
    #define _XPT2046_Touchscreen_h_
     
    #include "Arduino.h"
    #include <SPI.h>
     
    #if ARDUINO < 10600
    #error "Arduino 1.6.0 or later (SPI library) is required"
    #endif
     
    class TS_Point {
    public:
    	TS_Point(void) : x(0), y(0), z(0) {}
    	TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
    	bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
    	bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
    	int16_t x, y, z;
    };
     
    class XPT2046_Touchscreen {
    public:
    	constexpr XPT2046_Touchscreen(uint8_t cspin, uint8_t tirq=255)
    		: csPin(cspin), tirqPin(tirq) { }
    	bool begin();
    	TS_Point getPoint();
    	bool tirqTouched();
    	bool touched();
    	void readData(uint16_t *x, uint16_t *y, uint8_t *z);
    	bool bufferEmpty();
    	uint8_t bufferSize() { return 1; }
    	void setRotation(uint8_t n) { rotation = n % 4; }
    // protected:
    	volatile bool isrWake=true;
     
    private:
    	void update();
    	uint8_t csPin, tirqPin, rotation=1;
    	int16_t xraw=0, yraw=0, zraw=0;
    	uint32_t msraw=0x80000000;
    };
     
    #ifndef ISR_PREFIX
      #if defined(ESP8266)
        #define ISR_PREFIX ICACHE_RAM_ATTR
      #elif defined(ESP32)
        // TODO: should this also be ICACHE_RAM_ATTR ??
        #define ISR_PREFIX IRAM_ATTR
      #else
        #define ISR_PREFIX
      #endif
    #endif
     
    #endif
    Le fichier cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    /* Touchscreen library for XPT2046 Touch Controller Chip
     * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice, development funding notice, and this permission
     * notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
     
    #include "XPT2046_Touchscreen.h"
     
    #define Z_THRESHOLD     400
    #define Z_THRESHOLD_INT	75
    #define MSEC_THRESHOLD  3
    #define SPI_SETTING     SPISettings(2000000, MSBFIRST, SPI_MODE0)
     
    static XPT2046_Touchscreen 	*isrPinptr;
    void isrPin(void);
     
    bool XPT2046_Touchscreen::begin()
    {
    	SPI.begin();
    	pinMode(csPin, OUTPUT);
    	digitalWrite(csPin, HIGH);
    	if (255 != tirqPin) {
    		pinMode( tirqPin, INPUT );
    		attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
    		isrPinptr = this;
    	}
    	return true;
    }
     
    ISR_PREFIX
    void isrPin( void )
    {
    	XPT2046_Touchscreen *o = isrPinptr;
    	o->isrWake = true;
    }
     
    TS_Point XPT2046_Touchscreen::getPoint()
    {
    	update();
    	return TS_Point(xraw, yraw, zraw);
    }
     
    bool XPT2046_Touchscreen::tirqTouched()
    {
    	return (isrWake);
    }
     
    bool XPT2046_Touchscreen::touched()
    {
    	update();
    	return (zraw >= Z_THRESHOLD);
    }
     
    void XPT2046_Touchscreen::readData(uint16_t *x, uint16_t *y, uint8_t *z)
    {
    	update();
    	*x = xraw;
    	*y = yraw;
    	*z = zraw;
    }
     
    bool XPT2046_Touchscreen::bufferEmpty()
    {
    	return ((millis() - msraw) < MSEC_THRESHOLD);
    }
     
    static int16_t besttwoavg( int16_t x , int16_t y , int16_t z ) {
      int16_t da, db, dc;
      int16_t reta = 0;
      if ( x > y ) da = x - y; else da = y - x;
      if ( x > z ) db = x - z; else db = z - x;
      if ( z > y ) dc = z - y; else dc = y - z;
     
      if ( da <= db && da <= dc ) reta = (x + y) >> 1;
      else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
      else reta = (y + z) >> 1;   //    else if ( dc <= da && dc <= db ) reta = (x + y) >> 1;
     
      return (reta);
    }
     
    // TODO: perhaps a future version should offer an option for more oversampling,
    //       with the RANSAC algorithm https://en.wikipedia.org/wiki/RANSAC
     
    void XPT2046_Touchscreen::update()
    {
    	int16_t data[6];
     
    	if (!isrWake) return;
    	uint32_t now = millis();
    	if (now - msraw < MSEC_THRESHOLD) return;
     
    	SPI.beginTransaction(SPI_SETTING);
    	digitalWrite(csPin, LOW);
    	SPI.transfer(0xB1 /* Z1 */);
    	int16_t z1 = SPI.transfer16(0xC1 /* Z2 */) >> 3;
    	int z = z1 + 4095;
    	int16_t z2 = SPI.transfer16(0x91 /* X */) >> 3;
    	z -= z2;
    	if (z >= Z_THRESHOLD) {
    		SPI.transfer16(0x91 /* X */);  // dummy X measure, 1st is always noisy
    		data[0] = SPI.transfer16(0xD1 /* Y */) >> 3;
    		data[1] = SPI.transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
    		data[2] = SPI.transfer16(0xD1 /* Y */) >> 3;
    		data[3] = SPI.transfer16(0x91 /* X */) >> 3;
    	}
    	else data[0] = data[1] = data[2] = data[3] = 0;	// Compiler warns these values may be used unset on early exit.
    	data[4] = SPI.transfer16(0xD0 /* Y */) >> 3;	// Last Y touch power down
    	data[5] = SPI.transfer16(0) >> 3;
    	digitalWrite(csPin, HIGH);
    	SPI.endTransaction();
    	//Serial.printf("z=%d  ::  z1=%d,  z2=%d  ", z, z1, z2);
    	if (z < 0) z = 0;
    	if (z < Z_THRESHOLD) { //	if ( !touched ) {
    		// Serial.println();
    		zraw = 0;
    		if (z < Z_THRESHOLD_INT) { //	if ( !touched ) {
    			if (255 != tirqPin) isrWake = false;
    		}
    		return;
    	}
    	zraw = z;
     
    	// Average pair with least distance between each measured x then y
    	//Serial.printf("    z1=%d,z2=%d  ", z1, z2);
    	//Serial.printf("p=%d,  %d,%d  %d,%d  %d,%d", zraw,
    		//data[0], data[1], data[2], data[3], data[4], data[5]);
    	int16_t x = besttwoavg( data[0], data[2], data[4] );
    	int16_t y = besttwoavg( data[1], data[3], data[5] );
     
    	//Serial.printf("    %d,%d", x, y);
    	//Serial.println();
    	if (z >= Z_THRESHOLD) {
    		msraw = now;	// good read completed, set wait
    		switch (rotation) {
    		  case 0:
    			xraw = 4095 - y;
    			yraw = x;
    			break;
    		  case 1:
    			xraw = x;
    			yraw = y;
    			break;
    		  case 2:
    			xraw = y;
    			yraw = 4095 - x;
    			break;
    		  default: // 3
    			xraw = 4095 - x;
    			yraw = 4095 - y;
    		}
    	}
    }
    et le sketch :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    935
    936
    937
    938
    939
    940
    941
    942
    943
    944
    945
    946
    947
    948
    949
    950
    951
    952
    953
    954
    955
    956
    957
    958
    959
    960
    961
    962
    //Ethernet plus rapide ?
     
    #include <SPI.h>
     
    // DALLE TACTILE ************************************************************************************************************************************************
    /*
    // Calibration à faire avec 003_TFT_Touch_Calibrate_OK
    #include "RLucas_TFT_Touch.h"
    #define t_IRQ 5
    #define t_MISO 7 // ROUGE (TFT OUT) // La broche 4 est utilisée pour le lecteur SD de l'ethernet Shield
    #define t_MOSI 3 // VERT (TFT IN)
    #define t_CS 2  // JAUNE
    #define t_SCK 1 // BLEU
    //URTouch ts(t_SCK, t_CS, t_MOSI, t_MISO, t_IRQ);
    URTouch ts(t_CS, t_IRQ);
    */
    #include <XPT2046_Touchscreen.h>
    #define t_CS 2  // FIL JAUNE
    #define t_IRQ 5 // FIL ORANGE
     
     
    //XPT2046_Touchscreen ts(t_CS, t_IRQ);  // Param 2 - Touch IRQ Pin - interrupt enabled polling
    XPT2046_Touchscreen ts(t_CS);  // No interrupt
     
    // ECRAN TFT ****************************************************************************************************************************************************
    #include "RLucas_TFT_GFX.h"
    #include "RLucas_TFT_ILI9341_config.h" // C'est dans le fichier PDQ_ILI9341_config.h qu'on définit les broches CS, DC et RST :
    //#define ILI9341_CS_PIN    0   // <= /CS pin (chip-select, LOW to get attention of ILI9341, HIGH and it ignores SPI bus)
    //#define ILI9341_DC_PIN    9   // <= DC pin (1=data or 0=command indicator line) also called RS
    //#define ILI9341_RST_PIN   8   // <= RST pin (optional)
    //#define  ILI9341_SAVE_SPCR 0     // <= 0/1 with 1 to save/restore AVR SPI control register (to "play nice" when other SPI use) => prend plus de code et non nécessaire !
    #include "RLucas_TFT_ILI9341.h"      // PDQ: Hardware-specific driver library
    PDQ_ILI9341 tft;      
    #define TFT_PWM_LED 6 // Un transistor PNP permet de piloter le rétroéclairage 
     
    // ETHERNET *****************************************************************************************************************************************************
    #include "RLucas_Ethernet.h"
    // Ethernet Shield 2 : communicates with both the W5500 and SD card using the SPI bus (through the ICSP header).
    // This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega.
    // On both boards, pin 10 is used to select the W5500 and pin 4 for the SD card. These pins cannot be used for general I/O.
    // On the Mega, the hardware SS pin, 53, is not used to select either the W5500 or the SD card, but it must be kept as an output or the SPI interface won't work.
    byte mac[] = {
      0xA8, 0x61, 0x0A, 0xAE, 0x75, 0xCA //Voir étiquette collée sous le Shield
    };
    IPAddress ip(192, 168, 123, 177); //Choisir une IP fixe compatible avec le réseau local ou bien utiliser DHCP
    //IPAddress myDns(212, 27, 40, 240);
    //IPAddress myDns(192, 168, 123, 254); //DNS ou adresse du routeur  - Indispensable si IP Fixe (sans DHCP) et si on souhaite aller sur INTERNET (mais pas en local)
    //IPAddress gateway(192, 168, 123, 254); //Adresse du routeur - Indispensable si IP Fixe (sans DHCP) et si on souhaite aller sur INTERNET (mais pas en local)
    EthernetClient client;
    byte serverIP[] = { 192, 168, 123, 32 }; // Adresse IP du PC Fixe
    #define NetworkTimeout 2000
     
    // To open a port in the Windows 7 Firewall
    // On the Start menu, click Control Panel
    // Click on the System and Security category, then Windows Firewall. If you are not viewing by category, you can simply click on the Window Firewall item.
    // Click on the Advanced Settings link on the left hand side. This will open the Windows Firewall with Advanced Security Management Console application.
    // Click on Inbound Rules on the left hand menu. Under the Actions on the right hand side, click on New Rule. This opens the New Inbound Rule Wizard.
    // Select the Port option and click Next.
    // Select TCP and Specific local ports (80), then enter a comma-separated list of port numbers you want to open and click Next.
    // Select Allow the connection and click Next.
    // Check the boxes next to the desired network types and click Next.
    // Enter a name for your rule - and optionally a description - and click Finish.
    // Your inbound rule should now be displayed on the Inbound Rules list. To remove this rule, simply delete it from the list when you are done.
     
    // VARIABLES GLOBALES *******************************************************************************************************************************************
    // Buffer qui contient les requêtes et les réponses HTTP :
    #define Buffer_HTTP_Len 512
    char Buffer_HTTP[Buffer_HTTP_Len];
    int Buffer_HTTP_Stop; // Les données à traiter sont les octers de Buffer_HTTP de [0] à [Buffer_HTTP_Stop-1]
    int Buffi;
     
    // Variables "RAM" pouvant être écrites par le serveur et conservées :
    #define Buffer_RAM_Len 512
    char Buffer_RAM[Buffer_RAM_Len];
    int R1;
    int R2;
    int W1;
    int H1;
    int W2;
    int H2;
    unsigned int Couleur[14];
    int Palette; // Palette peut valoir 0 ou 7; la couleur à utiliser est définie par Couleur[index+Palette] avec index=0...6
     
    //Variables globales :
    int Status;
    int Touch_X;
    int Touch_Y;
    int Touch_Z;
    unsigned long debut;
    unsigned long duree;
    unsigned long duree2;
    int X1;
    int Y1;
    int X2;
    int Y2;
    int X3;
    int Y3;
    #define LIRE_X1_Y1 1
    #define LIRE_X2_Y2 2
    #define LIRE_X3_Y3 3
    #define LIRE_W1_H1 4
    #define LIRE_W2_H2 5
    uint8_t C1R;
    uint8_t C1G;
    uint8_t C1B;
    uint8_t C2R;
    uint8_t C2G;
    uint8_t C2B;
    int L;
     
    #define LireEntreeAnalogique 1
    #define LireEntreeNumerique 2
    #define LireEntreeLumiere 3
    const int MaxReadedPin = 10;
    byte ReadedPin[MaxReadedPin];
    int ReadedPinValue[MaxReadedPin];
    int ReadedPinIndex;
     
    #define PING_SERVEUR A5
    boolean pinPingServeur;
     
    #define AMBIANT_LIGHT A4
     
    /*
    #define AfficherBmpSansBG 1
    #define AfficherBmpAvecBG 2
    #define AfficherBmpBicolor 3
    */
     
    //char Buffer[20];
     
     
    // SETUP ********************************************************************************************************************************************************
    void setup() {
      Ajuster_Lumiere();
      //duree2=millis();
     
      tft.begin();
      tft.setRotation(0);
     
    /*
      ts.InitTouch(PORTRAIT);
      ts.setPrecision(PREC_EXTREME);
    */
      ts.begin();
      ts.setRotation(1);
     
    /*
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
      tft.setTextSize(1);
    */
      // You can use Ethernet.init(CSpin) to configure the CS pin
      //Ethernet.begin(mac, ip, myDns, gateway); 
      Ethernet.begin(mac, ip);
      pinPingServeur = digitalRead(PING_SERVEUR);
     
      Status=0; // Démarrage
      Network_Contacter_Serveur();
    }
     
    // LOOP *********************************************************************************************************************************************************
    void loop() {
      // Gestion du rétroéclairage :
      Ajuster_Lumiere();
      //duree2=millis();
      // On demande à l'écran tactile s'il y a eu un appui :
      /*
      if (ts.dataAvailable()) {
        ts.read();
        Touch_X = ts.getX();
        Touch_Y = ts.getY();
        if ((Touch_X != -1) && (Touch_Y != -1)) {
          //analogWrite(TFT_PWM_LED,128);// Juste pour indiquer la détection d'une touche
          Network_Contacter_Serveur();
        }
      }
      */
      //if (ts.tirqTouched()) { // La gestion de l'IRQ avec une interruption ne marche pas
      if (!digitalRead(t_IRQ)) { // je gère moi même l'interruption
        //if (ts.touched()) {
          TS_Point p = ts.getPoint();
          Touch_X = p.x;
          Touch_Y = p.y;
          Touch_Z = p.z;
          Network_Contacter_Serveur();
        //}
      }
      //}
     
      // On surveille la broche permettant au serveur de solliciter une requête :
      if (pinPingServeur != digitalRead(PING_SERVEUR)) {
        pinPingServeur = !pinPingServeur;
        Status = 2; //Requête à la demande du serveur
        Network_Contacter_Serveur();
      }
    }
     
    void Ajuster_Lumiere() {
      analogWrite(TFT_PWM_LED, 205 - min(analogRead(AMBIANT_LIGHT) / 3, 205));
    }
     
    // REQUETTE *****************************************************************************************************************************************************
     
    void Network_Contacter_Serveur() {
      do {
        duree2=millis();
        Network_Construire_Requete_Traiter_Reponse();
      } while(Status > 2); // Fonction Force Another Request !
    }
     
    int Network_Envoyer_Requete_Pretraiter_Reponse() {
      int nb;
      char c;
      int i;
      //int j;
      //int nb_deja_lu;
      int RAM_pos;
      byte RAM_len;
      unsigned int longueur;
      byte crc;
      int err_RAM_Ecrite;
     
      duree=millis();
      // Connection au serveur web :
      // client.stop(); // L'arrêt du client prend beaucoup de temps, à faire après
      if (client.connect(serverIP, 80)) {
        client.print(Buffer_HTTP);
     
        //Attente de la réponse du serveur
        debut = millis();
        nb=0;
        while(nb==0){ 
          nb = client.available();
          if (millis()-debut>NetworkTimeout) {break;}
        }
     
        //Lecture de la réponse du serveur :
        if (nb==0) {
          return 1; // ERREUR : Le serveur met trop de temps à répondre
        } else {
          //On élimine l'entête, en cherchant le caractère '<' qui marque le début des données utiles :
          do {
            if (nb==0){
              return 3; // ERREUR : Le début des données n'a pas été trouvé
            }
            c=client.read();
            nb--;
          } while(c!='<');
     
          longueur = nb;
          crc = 0;
     
          if (nb==0){
            // Le serveur ne donne aucune instruction :
            Buffer_HTTP_Stop=0;
        return 9; // ERREUR : Manque Longueur + CRC
          }else{
            // Le serveur donne une ou plusieurs instructions :
            c=client.read();
            crc^=c;
            nb--;
     
            if (c==1) { // Network Resend data again
              // Le serveur demande à renvoyer les données, parce qu'il a mal reçu la requête :
              return 8; // ERREUR : Requête à recommencer
            }
     
            err_RAM_Ecrite = 0; // IMPORTANT : il peut se produire une erreur, alors qu'on a déjà écrit dans Buffer_RAM. Si oui le serveur devra en tenir compte lors du traitement de l'erreur.
     
            while(c==8) {
              // Ecriture dans le RAM buffer - Ces instructions d'écriture dans le RAM buffer ne peuvent être que les premières
              // ce qui permet d'éviter de stocker bêtement ces données en double dans le Buffer HTTP :
              nb-=2;
              if (nb<0){
                return 4 + err_RAM_Ecrite; // ERREUR : Données manquantes 
              }
              c=client.read();
              crc^=c;
              RAM_pos=(byte)c; //client.read();
              if (RAM_pos==255) {
                c=client.read();
                crc^=c;
                RAM_pos+=(byte)c; //client.read();
                nb--;
              }
              c=client.read();
              crc^=c;
              RAM_len=(byte)c; //client.read();
              nb-=RAM_len;
              if (nb<0){
                return 5 + err_RAM_Ecrite; // ERREUR : Données manquantes 
              }
              if (RAM_pos+RAM_len>=Buffer_RAM_Len){
                return 6 + err_RAM_Ecrite; // ERREUR : La position et la longeur d'écriture en RAM dépassent la limite
              }
              err_RAM_Ecrite = 32; // IMPORTANT : il peut se produire une erreur, alors qu'on a déjà écrit dans Buffer_RAM. Si oui le serveur devra en tenir compte lors du traitement de l'erreur.
              for (i=0;i<RAM_len;i++) {
                c=client.read(); // UTILISER PLUTOT : int EthernetClient::read(uint8_t *buf, size_t size) ? puis calculer le CRC ensuite ?
                crc^=c;
                Buffer_RAM[i+RAM_pos]=c; //client.read();
              }
              if (nb==0){
                // Le serveur ne donne aucune autre instruction :
                Buffer_HTTP_Stop=0;
                return 9 + err_RAM_Ecrite; // ERREUR : Manque Longueur + CRC
              }else{
                c=client.read();
                crc^=c;
                nb--;
              }
            }
     
            // Quand on arrive ici, le caractère 'c' qui a été lu auparavent est le premier caractère des instructions :
            Buffer_HTTP[0]=c;
            // Il reste 'nb' caractères à lire :
            if (nb>Buffer_HTTP_Len-2) {
              return 7 + err_RAM_Ecrite; // ERREUR : Trop de données envoyées par le serveur
            } 
            for (i=1;i<nb;i++) { //i<nb au lieu de i<=nb car le CRC ne doit pas être calculé sur lui-même
              c=client.read(); // UTILISER PLUTOT : int EthernetClient::read(uint8_t *buf, size_t size) ? puis calculer le CRC ensuite ?
              crc^=c;
              Buffer_HTTP[i]=c; //client.read();
            }
            c=client.read();
            Buffer_HTTP[i]=c; //=client.read();
            Buffer_HTTP_Stop=i+1;
          }
     
          // Il faut vérifier la longueur et le CRC :
          if (Buffer_HTTP_Stop<3) {
            return 9 + err_RAM_Ecrite; // ERREUR : Manque Longueur + CRC
          }
          Buffi=Buffer_HTTP_Stop-4; // Voir code de LireUInt16()
          if (longueur!=LireUInt16()) {
            return 10 + err_RAM_Ecrite; // ERREUR : Longueur incorrecte
          }
          if (crc!=(byte)Buffer_HTTP[Buffer_HTTP_Stop-1]) {
            return 11 + err_RAM_Ecrite; // ERREUR : CRC incorrect
          }
    /*
          tft.fillScreen(0);
          tft.setCursor(0, 0);
          tft.print("L=");   //263 OK vu avec Wireshark
          tft.print(longueur);
          tft.print(" CRC="); //87 OK !
          tft.print(crc);
          tft.print(" nb=");  //200
          tft.print(nb);
          tft.print(" BHS="); //201
          tft.print(Buffer_HTTP_Stop);
          tft.print(" LD=");  //263 OK !
          Buffi=Buffer_HTTP_Stop-4;
          tft.print(LireUInt16());
          tft.print(" C=");   //87 OK !
          tft.println((byte)Buffer_HTTP[Buffer_HTTP_Stop-1]);
          tft.println();
          j=0;
          for (i=0;i<Buffer_HTTP_Stop;i++) {
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%02x"), (byte)Buffer_HTTP[i]);
            tft.print(Buffer);
            tft.print(F(" "));
            j++;
            if (j>9) {
              j=0;
              tft.println();
            }
          }
          return 11;
    */
          // IMPORTANT : la longueur et le CRC ne doivent pas être exécutés !!!
          Buffer_HTTP_Stop-=3;
     
          return 0; // SUCCES
        }
      } else {
          return 2; // ERREUR : Pas de connection
      }
    }
     
    void Network_Construire_Requete_Traiter_Reponse() {
      int err_code;
      int i;
      int j;
      byte instr;
      int s;
      byte coul_index;
      int pos;
      int pin;
      int value;
      int valueoff;
      int w;
      int crc;
      unsigned int couleur1;
      unsigned int couleur2;
     
      //uint8_t *pointeur;
    /*
      int nb_ai;
      byte ai[50];
      int ai_ind[50];
      nb_ai=0;
    */
      err_code=0;
      do {
        // On construit la requête au serveur ici :
        //snprintf_P(Buffer_HTTP, sizeof(Buffer_HTTP), PSTR("GET /?E=%d&S=%d&X=%d&Y=%d HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"), err_code, Status, Touch_X, Touch_Y);
     
        /*
        strncpy_P(Buffer_HTTP, sizeof(Buffer_HTTP), PSTR("GET /?"));
        i=snprintf_P(Buffer_HTTP+6, sizeof(Buffer_HTTP)-6, PSTR("E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
        strncpy_P(Buffer_HTTP+i+6, sizeof(Buffer_HTTP), PSTR(" HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"));
        */
        /*
        strcpy_P(Buffer_HTTP, PSTR("GET /?"));
        i=6;
        i=sprintf_P(Buffer_HTTP+i, PSTR("E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
        */
        crc = err_code ^ Status ^ Touch_X ^ Touch_Y ^ Touch_Z;
        i=sprintf_P(Buffer_HTTP, PSTR("GET /?E=%d&S=%d&X=%d&Y=%d&Z=%d"), err_code, Status, Touch_X, Touch_Y, Touch_Z);
         if (Status==4) {
          for (j=0;j<ReadedPinIndex;j++) {
            i+=sprintf_P(Buffer_HTTP+i, PSTR("&I%d=%d"), ReadedPin[j], ReadedPinValue[j]);
            crc^=ReadedPinValue[j];
          }
        }
        i+=sprintf_P(Buffer_HTTP+i, PSTR("&C=%d"), crc);
        strcpy_P(Buffer_HTTP+i, PSTR(" HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"));
     
        // Le serveur connait :
        //
        //- Status
        //   0 : Le client démarre les variables et Buffer_RAM sont vides
        //   1 : Fonctionnement normal
        //   2 : Le client fait une requête à la demande du serveur (fil "interruption")
        //   3 : Le client dit au serveur qu'il est prêt a recevoir la suite de la réponse que le serveur avait demandé
        //   4 : Le client envoit la lecture des broches d'entrées que le serveur a demandé
        //
        //- err_code : le client a rencontré une erreur et demande au serveur une nouvelle requête
        //   err_code                  Le serveur a bien eu la requête précédente ?
        //   0 : SUCCES                OUI => traiter la requête normalement
        //   1 : Timeout               NON => traiter la requête normalement
        //   2 : Pas de connection     NON => traiter la requête normalement
        //   3 : Début non trouvé      OUI => juste renvoyer la réponse précédente
        //   4 : Données manquantes    OUI => juste renvoyer la réponse précédente
        //   5 : Données manquantes    OUI => juste renvoyer la réponse précédente
        //   6 : RAM overflow          OUI => juste renvoyer la réponse précédente
        //   7 : Trop de données       OUI => juste renvoyer la réponse précédente
        //   8 : Requête à recommencer OUI mais le serveur a rencontré une erreur et redemande la requete au client => traiter la requête normalement
        //   9 : CRC manquant          OUI => juste renvoyer la réponse précédente
        //   10: Longueur incorrecte   OUI => juste renvoyer la réponse précédente
        //   11: CRC incorrect         OUI => juste renvoyer la réponse précédente
        //
        //   IMPORTANT : err_code est augmenté de 32 si Buffer_RAM a été possiblement corrompu par des données incorrectes.
        //               dans ce cas de figure le serveur devra renvoyer les données pour remplir Buffer_RAM avec des données sûres.
        //
        //   "traiter la requête normalement" :
        //   - Si Status = 0 => le serveur doit envoyer les données d'initialisation
        //   - Si Status = 1 => le serveur doit executer l'action correspondant à la frappe sur le pavé tactile X et Y
        //   - Si Status = 2 => le serveur doit envoyer les données qu'il souhaite (requête client faite à la demande du serveur)
        //   - Si Status = 3 => le serveur doit envoyer la suite des données si il y a une suite disponible 
        //   - Si Status = 4 => le serveur doit lire les données lues, et envoyer la suite des données si il y a une suite disponible 
     
        err_code = Network_Envoyer_Requete_Pretraiter_Reponse();
        duree = millis()-duree;
     
        tft.tftSpiBegin();
        if (err_code==0) {
          // On traite la réponse ici :
          // Les instructions et les données à traiter sont comprises entre Buffer_HTTP[0] et Buffer_HTTP[Buffer_HTTP_Stop-1]
     
          Status=1; // On réinitialise le statut à la valeur "normale"
          ReadedPinIndex = 0;
          Buffi=-1;
     
          while(Buffi<Buffer_HTTP_Stop-1) {
            instr = LireUByte();
            if (instr>31) {
              // Il faut récupérer l'index de la couleur et remettre le numéro de l'instruction de base :
              coul_index = (instr - 32) % 7;
              instr -= coul_index;
              coul_index += Palette;
              if (instr>52 && instr<228) {
                LireXY(LIRE_X1_Y1); // Eviter de copier cette instruction de multiples fois (cases vertes dans le tableau Excel)
              }
            }else{
              if (instr>15 && instr<20) {
                // Dégradés
                LireXY(LIRE_X1_Y1); // Eviter de copier cette instruction de multiples fois (cases vertes dans le tableau Excel)
                LireXY(LIRE_X2_Y2); // Eviter de copier cette instruction de multiples fois (cases bleues dans le tableau Excel)
                if (instr>17) {
                  couleur1 = LireUInt16();                      
                  couleur2 = LireUInt16();
                  instr-=2;
                }else{
                  couleur1 = Couleur[LireUInt8()];                      
                  couleur2 = Couleur[LireUInt8()]; 
                }
                C1R = ((couleur1 >> 11) & 0x1F);
                C1G = ((couleur1 >> 5) & 0x3F);
                C1B = (couleur1 & 0x1F);
                C2R = ((couleur2 >> 11) & 0x1F);
                C2G = ((couleur2 >> 5) & 0x3F);
                C2B = (couleur2 & 0x1F);
              }else{
                if (instr>20 && instr<25) {
                  // Il faut récupérer la taille du texte et remettre le numéro de l'instruction de base :
                  s = instr-20;    
                  instr = 21;
                }
              }
            }
    /*
            ai[nb_ai]=instr;
            ai_ind[nb_ai]=Buffi;
            nb_ai++;
    */
            switch (instr) {
              case 0: // 
                // A FAIRE
                break;
              // case 1: Network Resend data => Traité dans la procédure Network_Faire_Requete();
              case 2: // Network Force other request
                if (Status<3) {Status = 3;} // Force other request (demande la suite) - Il faut laisser le Status à 4 s'il y est déjà
                break;
              case 3: // Write pin
                pin = LireUInt8();
                value = LireUInt8();
                //pinMode(pin, OUTPUT); //déjà dans analogWrite
                analogWrite(pin,value);
                break;
              case 4: // Write pin pulse
                pin = LireUInt8();
                w = LireUInt9();
                value = LireUInt8();
                valueoff = LireUInt8();
                //pinMode(pin, OUTPUT); //déjà dans analogWrite
                analogWrite(pin,value);
                delay(w);
                analogWrite(pin,valueoff);
                break;
              case 5: // Read digital pin
                LireEntree(LireEntreeNumerique);
                break;
              case 6: // Read analog pin
                LireEntree(LireEntreeAnalogique);
                break;
              case 7: // Read Ambiant light
                LireEntree(LireEntreeLumiere);
                break;
              case 9: // Set R1
                R1 = LireUInt9();
                break;
              case 10: // Set R2
                R2 = LireUInt9();
                break;
              case 11: // Set W1 H1
                LireXY(LIRE_W1_H1);
                break;
              case 12: // Set W2 H2
                LireXY(LIRE_W2_H2);
                break;
              case 13: // Set color
                i = LireUInt8();
                Couleur[i] = LireUInt16();
                break;
              case 14: // Set color index 0...6
                Palette=0;
                break;
              case 15: // Set color index 7...13
                Palette=7;
                break;
     
              case 16: // TFT Fill Rect Colormorph H
                L = X2-1;
                for (i=0;i<X2;i++) {
                  tft.drawFastVLine(i+X1, Y1, Y2, CouleurDegrade(i));
                }
                break;
              case 17: // TFT Fill Rect Colormorph V
                L = Y2-1;
                for (i=0;i<Y2;i++) {
                  tft.drawFastHLine(X1, i+Y1, X2, CouleurDegrade(i));
                }
                break;
     
              case 20: // TFT Set text cursor 
                LireXY(LIRE_X1_Y1);
                tft.setCursor(X1, Y1);
                break;
              case 21: // TFT Set text size 
                tft.setTextSize(s);
                break;
              case 25: // TFT Set text wrap off 
                tft.setTextWrap(false);
                break;
              case 26: // TFT Set text wrap on 
                tft.setTextWrap(true);
                break;
              case 27: // TFT Set text color
                  tft.setTextColor(Couleur[LireUInt8()]);
                break;
              case 28: // TFT Set text color & BG color
                  i=LireUInt8();
                  tft.setTextColor(Couleur[i],Couleur[LireUInt8()]);
                break;
              case 29: // TFT Print @RAM
                pos=LireUInt9();
                tft.print((char*)(Buffer_RAM + pos));
                break;
              case 30: // TFT Print
                PrintString();
                break;
              case 31: // TFT Print char
                Buffi++;
                tft.print(Buffer_HTTP[Buffi]);
                break;
     
              case 46: // TFT Fill Screen
                tft.fillScreen(Couleur[coul_index]);
                break;
     
              case 32: // TFT Draw Rect Button
                w = PrintString();
                // A FAIRE
                break;
              case 39: // TFT Draw Circle Button
                w = PrintString();
                // A FAIRE
                break;
     
              case 53: // TFT Draw Line
                LireXY(LIRE_X2_Y2);
                tft.drawLine(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 60: // TFT Draw H Line
                tft.drawFastHLine(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 67: // TFT Draw V Line
                tft.drawFastVLine(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
     
              case 74: // TFT Draw Rect
                LireXY(LIRE_X2_Y2);
                tft.drawRect(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 88: // TFT Draw Rect Size1
                tft.drawRect(X1, Y1, W1, H1, Couleur[coul_index]);
                break;
              case 102: // TFT Draw Rect Size2
                tft.drawRect(X1, Y1, W2, H2, Couleur[coul_index]);
                break;
     
              case 81: // TFT Draw Round Rect
                LireXY(LIRE_X2_Y2);
                tft.drawRoundRect(X1, Y1, X2, Y2, LireUInt9(), Couleur[coul_index]);
                break;
              case 95: // TFT Draw Round Rect Size1 R1
                tft.drawRoundRect(X1, Y1, W1, H1, R1, Couleur[coul_index]);
                break;
              case 109: // TFT Draw Round Rect Size2 R2
                tft.drawRoundRect(X1, Y1, W2, H2, R2, Couleur[coul_index]);
                break;
     
              case 116: // TFT Draw Circle
                tft.drawCircle(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 123: // TFT Draw Circle R1
                tft.drawCircle(X1, Y1, R1, Couleur[coul_index]);
                break;
              case 130: // TFT Draw Circle R2
                tft.drawCircle(X1, Y1, R2, Couleur[coul_index]);
                break;
     
              case 137: // TFT Draw Triangle
                LireXY(LIRE_X2_Y2);
                LireXY(LIRE_X3_Y3);
                tft.drawTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
              case 144: // TFT Draw Triangle
                X2 = X1 + W1;
                Y2 = Y1 + H1;
                X3 = X1 + W2;
                Y3 = Y1 + H2;
                tft.drawTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
     
              case 151: // TFT Fill Rect
                LireXY(LIRE_X2_Y2);
                tft.fillRect(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 165: // TFT Fill Rect Size1
                tft.fillRect(X1, Y1, W1, H1, Couleur[coul_index]);
                break;
              case 179: // TFT Fill Rect Size2
                tft.fillRect(X1, Y1, W2, H2, Couleur[coul_index]);
                break;
     
              case 158: // TFT Fill Round Rect
                LireXY(LIRE_X2_Y2);
                tft.fillRoundRect(X1, Y1, X2, Y2, LireUInt9(), Couleur[coul_index]);
                break;
              case 172: // TFT Fill Round Rect Size1 R1
                tft.fillRoundRect(X1, Y1, W1, H1, R1, Couleur[coul_index]);
                break;
              case 186: // TFT Fill Round Rect Size2 R2
                tft.fillRoundRect(X1, Y1, W2, H2, R2, Couleur[coul_index]);
                break;
     
              case 193: // TFT Fill Circle
                tft.fillCircle(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 200: // TFT Fill Circle R1
                tft.fillCircle(X1, Y1, R1, Couleur[coul_index]);
                break;
              case 207: // TFT Fill Circle R2
                tft.fillCircle(X1, Y1, R2, Couleur[coul_index]);
                break;
     
              case 214: // TFT Fill Triangle
                LireXY(LIRE_X2_Y2);
                LireXY(LIRE_X3_Y3);
                tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
              case 221: // TFT Fill Triangle
                X2 = X1 + W1;
                Y2 = Y1 + H1;
                X3 = X1 + W2;
                Y3 = Y1 + H2;
                tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
     
              case 228: // 
     
                break;
              case 235: // TFT Draw Bitmap RAM
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                //tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], 0, false, LireUInt8());
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], 0, LireUInt8());
                break;
              case 242: // TFT Draw Bitmap RAM + Bicolor
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                j = LireUInt8();
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], Couleur[j], LireUInt8());
                break;
              case 249: // TFT Draw Bitmap RAM + BG
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], Couleur[Palette], LireUInt8());
                break;
     
              default:
                break;
            }
     
          } 
     
     
          // Affichage de debug : -----------------------------------------------------------------------------
          //tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
          tft.setCursor(0, 0);
          tft.print(duree); // Temps pris pour envoyer la requête au serveur et recevoir la réponse
          tft.print(F("ms "));
          tft.print(millis()-duree2-duree);  // Temps pris pour gérer l'appui sur l'écran tactile et l'affichage
          tft.print(F("ms "));
          tft.println(Buffer_HTTP_Stop);
    /*
          tft.println();
          for (i=0;i<8;i++){
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%d %04x"), i, Couleur[i]);
            tft.println(Buffer);
          }
          tft.println();
     
          j=0;
          for (i=0;i<Buffer_HTTP_Stop;i++) {
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%02x"), (byte)Buffer_HTTP[i]);
            tft.print(Buffer);
            tft.print(F(" "));
            j++;
            if (j>9) {
              j=0;
              tft.println();
            }
          }
          tft.println();
          tft.println();
          tft.print(F("Buffer_HTTP_Stop = "));
          tft.println(Buffer_HTTP_Stop);
     
          if (nb_ai>0) {
            tft.print(F("Appels :"));
            tft.println(nb_ai);
          }
          j=0;
          for (i=0;i<nb_ai;i++) {
            tft.print(ai_ind[i]);
            tft.print(F(":"));
            tft.print(ai[i]);
            j++;
            if (j>4) {
              j=0;
              tft.println();
            }else{
                tft.print(F("  "));
            }
          }
    */
          // --------------------------------------------------------------------------------------------------
     
        } else {
          // En cas d'erreur, on affiche et on recommence :
          tft.fillScreen(0);
          tft.setCursor(0, 0);
          tft.print(F("Erreur "));
          tft.print(err_code);
          delay(250);
        }
      tft.tftSpiEnd();
      } while(err_code!=0);
    }
     
    /*
    void AfficherBMP (byte mode) {
      int i;
      unsigned int CoulBG;
      i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
      LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
      if (mode == AfficherBmpBicolor) {
        CoulBG = Couleur[LireUInt8()];
      }else{
        CoulBG = Couleur[Palette];
      }
      tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], CoulBG, mode!=AfficherBmpSansBG, LireUInt8());
    }
    */
     
    void LireEntree(byte mode) {
      int pin;
      Status = 4;
      if (ReadedPinIndex<MaxReadedPin) {
        if (mode==LireEntreeLumiere) {
          pin = AMBIANT_LIGHT;
        }else{
          pin = LireUInt8();
        }
        pinMode(pin, INPUT);
        ReadedPin[ReadedPinIndex] = pin;
        if (mode==LireEntreeNumerique) {
          ReadedPinValue[ReadedPinIndex] = digitalRead(pin);
        }else{
          ReadedPinValue[ReadedPinIndex] = analogRead(pin);
        }
        ReadedPinIndex++;
      }
    }
     
    unsigned int CouleurDegrade(int i) {
      int R;
      int G;
      int B;
      R = int(C2R * i/L + C1R * (L-i)/L);
      G = int(C2G * i/L + C1G * (L-i)/L);
      B = int(C2B * i/L + C1B * (L-i)/L);
      /*
      if (R>31) {R=31;}
      if (G>63) {R=63;}
      if (B>31) {B=31;}
      */
      return (R << 11) | (G << 5) | B;
    }
     
    int PrintString() {
      int i;
      int j;
      Buffi++;
      tft.print(Buffer_HTTP + Buffi);
      for (i=Buffi;i<Buffer_HTTP_Stop;i++) {
        if (Buffer_HTTP[i]==0) {
          j = i - Buffi;
          Buffi = i;
          return j;
        }
      }
      return -1;
    }
     
    byte LireUByte() {
      Buffi++;
      return Buffer_HTTP[Buffi]; 
    }
     
    int LireUInt8() {
      Buffi++;
      return (byte)Buffer_HTTP[Buffi];
    }
     
    int LireUInt9() {
      // Entier compris entre 0 et 510 - Occupe un octet si inférieur à 255
      int tmp;
      Buffi++;
      tmp = (byte)Buffer_HTTP[Buffi];
      if (tmp==255) {
        Buffi++;
        tmp += (byte)Buffer_HTTP[Buffi];
      }
      return tmp;  
    }
     
    /*
    int LireUInt9_RAM() {
      // Entier compris entre 0 et 510 - Occupe un octet si inférieur à 255
      int tmp;
      tmp = (byte)Buffer_RAM[Buffiram];
      Buffiram++;
      if (tmp==255) {
        tmp += (byte)Buffer_RAM[Buffiram];
        Buffiram++;
      }
      return tmp;  
    }
    */
     
    unsigned int LireUInt16() {
      byte MSB;
      byte LSB;
      Buffi+=2;
      MSB = Buffer_HTTP[Buffi-1];
      LSB = Buffer_HTTP[Buffi];
      return (MSB<<8) + LSB;
    }
     
    void LireXY(int num) {
      int tmpX;
      int tmpY;
      tmpX = LireUInt9();
      tmpY = LireUInt9() ;
      switch(num) {
      case LIRE_X1_Y1:
        X1=tmpX;
        Y1=tmpY;
        break;
      case LIRE_X2_Y2:
        X2=tmpX;
        Y2=tmpY;
        break;
      case LIRE_X3_Y3:
        X3=tmpX;
        Y3=tmpY;
        break;
      case LIRE_W1_H1:
        W1=tmpX;
        H1=tmpY;
        break;
      case LIRE_W2_H2:
        W2=tmpX;
        H2=tmpY;
        break;
      }    
    }
    Vu les problèmes que je rencontre il ne faut pas exclure un problème hardware...

    J'ai bien vérifié mon câblage

    Les broches CLK, MOSI et MISO de l'écran TFT et de la dalle tactile sont câblées en parallèle, sur un convertisseur 5V/3.3V
    La broche CS de la dalle tactile est raccordé à la broche 2 de l'Arduino UNI via le convertisseur 5V/3.3V

    La broche IRQ de la dalle tactile est raccordé à la broche 5 de l'Arduino UNI via le convertisseur 5V/3.3V

    La puce de la dalle tactile porte la référence HR2046 1843, c'est bien la bonne puce.

    S'il s'agit d'un problème matériel, bizarre que l'écran TFT et le shield Ethernet fonctionnent parfaitement... le SPI n'est pas "planté".

    Et le programme ne plante pas. J'ai "seulement" des données lues incorrectes

    C'est quand même étrange, sur ces écrans tactiles, que les broches MOSI, MISO et CLK ne soient pas reliées entres elles directement sur le circuit imprimé de l'afficheur...

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  5. #5
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Dernière tentative :

    .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    /* Touchscreen library for XPT2046 Touch Controller Chip
     * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice, development funding notice, and this permission
     * notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
     
    #ifndef _XPT2046_Touchscreen_h_
    #define _XPT2046_Touchscreen_h_
     
    #include "Arduino.h"
    #include <SPI.h>
     
    #if ARDUINO < 10600
    #error "Arduino 1.6.0 or later (SPI library) is required"
    #endif
     
    class TS_Point {
    public:
    	TS_Point(void) : x(0), y(0), z(0) {}
    	TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
    	bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
    	bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
    	int16_t x, y, z;
    };
     
    class XPT2046_Touchscreen {
    public:
    	constexpr XPT2046_Touchscreen(uint8_t cspin, uint8_t tirq)
    		: csPin(cspin), tirqPin(tirq) { }
    	bool begin();
    	TS_Point getPoint();
    	//bool tirqTouched();
    	//bool touched();
    	//void readData(uint16_t *x, uint16_t *y, uint8_t *z);
    	//bool bufferEmpty();
    	uint8_t bufferSize() { return 1; }
    	void setRotation(uint8_t n) { rotation = n % 4; }
    // protected:
    	volatile bool isrWake=true;
     
    private:
    	void update();
    	void update_old();
    	uint8_t csPin, tirqPin, rotation=1;
    	//uint8_t csPin, rotation=1;
    	int16_t xraw=0, yraw=0, zraw=0;
    	//uint32_t msraw=0x80000000;
    };
     
    #ifndef ISR_PREFIX
      #if defined(ESP8266)
        #define ISR_PREFIX ICACHE_RAM_ATTR
      #elif defined(ESP32)
        // TODO: should this also be ICACHE_RAM_ATTR ??
        #define ISR_PREFIX IRAM_ATTR
      #else
        #define ISR_PREFIX
      #endif
    #endif
     
    #endif
    .cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    /* Touchscreen library for XPT2046 Touch Controller Chip
     * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice, development funding notice, and this permission
     * notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
     
    #include "XPT2046_Touchscreen.h"
     
    #define Z_THRESHOLD     400
    #define Z_THRESHOLD_INT	75
    #define MSEC_THRESHOLD  3
    //#define SPI_SETTING     SPISettings(2000000, MSBFIRST, SPI_MODE0)
    #define SPI_SETTING     SPISettings(200000, MSBFIRST, SPI_MODE0)
     
    static XPT2046_Touchscreen 	*isrPinptr;
    //void isrPin(void);
     
    bool XPT2046_Touchscreen::begin()
    {
    	SPI.begin();
    	pinMode(csPin, OUTPUT);
    	digitalWrite(csPin, HIGH);
    /*
    	if (255 != tirqPin) {
    		pinMode( tirqPin, INPUT );
    		attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
    		isrPinptr = this;
    	}
    */
    	return true;
    }
     
    /*
    ISR_PREFIX
    void isrPin( void )
    {
    	XPT2046_Touchscreen *o = isrPinptr;
    	o->isrWake = true;
    }
    */
     
    TS_Point XPT2046_Touchscreen::getPoint()
    {
    	update();
    	return TS_Point(xraw, yraw, zraw);
    }
     
    /*
    bool XPT2046_Touchscreen::tirqTouched()
    {
    	return (isrWake);
    }
    */
    /*
    bool XPT2046_Touchscreen::touched()
    {
    	update();
    	return (zraw >= Z_THRESHOLD);
    }
    */
     
    /*
    void XPT2046_Touchscreen::readData(uint16_t *x, uint16_t *y, uint8_t *z)
    {
    	update();
    	*x = xraw;
    	*y = yraw;
    	*z = zraw;
    }
    */
     
    /*
    bool XPT2046_Touchscreen::bufferEmpty()
    {
    	return ((millis() - msraw) < MSEC_THRESHOLD);
    }
    */
     
    static int16_t besttwoavg( int16_t x , int16_t y , int16_t z ) {
      int16_t da, db, dc;
      int16_t reta = 0;
      if ( x > y ) da = x - y; else da = y - x;
      if ( x > z ) db = x - z; else db = z - x;
      if ( z > y ) dc = z - y; else dc = y - z;
     
      if ( da <= db && da <= dc ) reta = (x + y) >> 1;
      else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
      else reta = (y + z) >> 1;   //    else if ( dc <= da && dc <= db ) reta = (x + y) >> 1;
     
      return (reta);
    }
     
    // TODO: perhaps a future version should offer an option for more oversampling,
    //       with the RANSAC algorithm https://en.wikipedia.org/wiki/RANSAC
     
    void XPT2046_Touchscreen::update()
    {
    	unsigned long tx=0, temp_x=0;
    	unsigned long ty=0, temp_y=0;
    	unsigned long minx=99999, maxx=0;
    	unsigned long miny=99999, maxy=0;
    	int datacount=0;
    	byte	prec=10; // prec doit être supérieur à 5
     
    	SPI.beginTransaction(SPI_SETTING);
    	digitalWrite(csPin, LOW);
     
    	for (int i=0; i<prec; i++) {
    		if (!digitalRead(tirqPin)) {
    			temp_x = SPI.transfer16(0x90);
     
    			if (!digitalRead(tirqPin))	{
    				temp_y = SPI.transfer16(0xD0);
     
    				if ((temp_x>0) and (temp_x<4096) and (temp_y>0) and (temp_y<4096)) {
    					tx+=temp_x;
    					ty+=temp_y;
    					if (temp_x<minx) minx=temp_x;
    					if (temp_x>maxx) maxx=temp_x;
    					if (temp_y<miny) miny=temp_y;
    					if (temp_y>maxy) maxy=temp_y;
    					datacount++;
    				}
    			}
    		}
    	}
     
    	digitalWrite(csPin, HIGH);
    	SPI.endTransaction();
     
    	tx = tx-(minx+maxx);
    	ty = ty-(miny+maxy);
    	datacount -= 2;
     
     
    	//if ((datacount==(prec-2)) or (datacount==1)) {
    	if (datacount>0) {
    		xraw=tx/datacount;
    		yraw=ty/datacount;
    	} else {
    		xraw=tx;
    		yraw=ty;
    	}
    }
     
    void XPT2046_Touchscreen::update_old()
    {
    	int16_t data[6];
     
    	//if (!isrWake) return;
    	//uint32_t now = millis();
    	//if (now - msraw < MSEC_THRESHOLD) return;
     
    	SPI.beginTransaction(SPI_SETTING);
    	digitalWrite(csPin, LOW);
     
    	// SPI.transfer(0xB1 /* Z1 */);
    	// int16_t z1 = SPI.transfer16(0xC1 /* Z2 */) >> 3;
    	// int z = z1 + 4095;
    	// int16_t z2 = SPI.transfer16(0x91 /* X */) >> 3;
    	// z -= z2;
    	//if (z >= Z_THRESHOLD) {
    		SPI.transfer16(0x90 /* X */);  // dummy X measure, 1st is always noisy
    		data[0] = SPI.transfer16(0xD0 /* Y */); //>> 3;
    		data[1] = SPI.transfer16(0x90 /* X */); //>> 3; // make 3 x-y measurements
    		data[2] = SPI.transfer16(0xD0 /* Y */); //>> 3;
    		data[3] = SPI.transfer16(0x90 /* X */); //>> 3;
    	//}	else data[0] = data[1] = data[2] = data[3] = 0;	// Compiler warns these values may be used unset on early exit.
    	data[4] = SPI.transfer16(0xD0 /* Y */); //>> 3;	// Last Y touch power down
    	data[5] = SPI.transfer16(0); //>> 3;
     
    	digitalWrite(csPin, HIGH);
    	SPI.endTransaction();
     
    	//Serial.printf("z=%d  ::  z1=%d,  z2=%d  ", z, z1, z2);
    	/*
    	if (z < 0) z = 0;
    	if (z < Z_THRESHOLD) { //	if ( !touched ) {
    		// Serial.println();
    		zraw = 0;
    		//	if ( !touched ) {
    		//if (z < Z_THRESHOLD_INT) { 			if (255 != tirqPin) isrWake = false;		}
    		//return;
    	}
    	zraw = z;
    	*/
     
    	// Average pair with least distance between each measured x then y
    	//Serial.printf("    z1=%d,z2=%d  ", z1, z2);
    	//Serial.printf("p=%d,  %d,%d  %d,%d  %d,%d", zraw,
    		//data[0], data[1], data[2], data[3], data[4], data[5]);
    	int16_t x = besttwoavg( data[0], data[2], data[4] );
    	int16_t y = besttwoavg( data[1], data[3], data[5] );
     
    	//Serial.printf("    %d,%d", x, y);
    	//Serial.println();
    	//if (z >= Z_THRESHOLD) {
    		//msraw = now;	// good read completed, set wait
    		switch (rotation) {
    		  case 0:
    			xraw = 4095 - y;
    			yraw = x;
    			break;
    		  case 1:
    			xraw = x;
    			yraw = y;
    			break;
    		  case 2:
    			xraw = y;
    			yraw = 4095 - x;
    			break;
    		  default: // 3
    			xraw = 4095 - x;
    			yraw = 4095 - y;
    		}
    	//}
    }
    Le résultat :
    - soit X=144 Y=208
    - soit X=31073 Y=31073

    Je pense que dans la librairie URTouch il y a une façon de traiter les données émises par la dalle tactile qui m'échappe...

    En épluchant les codes on se doute bien que la dalle tactile fait, pour chaque appui, plusieurs mesures et qu'il faut en éliminer certaines et faire avec les autres une moyenne.

    Pour ne rien arranger les différents clones de puces xxx2046 ne doivent pas avoir un comportement identique.

    Il y a peut être également :
    - des problèmes de délais à respecter
    - un buffer de mesure à vider

    Je n'arrives pas à comprendre comment URTouch en bit banging peut fonctionner et aucune des autres tentatives en hardware SPI...

    Il doit y avoir une astuce bien cachée dans URTouch

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  6. #6
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 714
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 714
    Points : 5 393
    Points
    5 393
    Par défaut
    lisez éventuellement ce post - avec sa modification j'avais pu faire fonctionner sans problèmes un écran acheté pour 3 sous
    ça pourrait vous donner des pistes

  7. #7
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Citation Envoyé par Jay M Voir le message
    lisez éventuellement ce post - avec sa modification j'avais pu faire fonctionner sans problèmes un écran acheté pour 3 sous
    ça pourrait vous donner des pistes
    oui je me souviens de ce post, mais c'est une modification à la bibliothèque URTouch en mode bitbanging...

    la nuit porte conseil j'ai d'autres pistes, je vous tiens au courant

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  8. #8
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Alors voici donc le résultat de mes intuitions nocturnes :

    Première tentative de changement au niveau du hardware :

    La broche MISO de l'écran TFT n'est pas utilisée par le logiciel.
    Le fait que la broche MISO de l'écran TFT et la broche MISO de la dalle tactile soit reliées peut poser problème.

    Je débranche donc la broche MISO de l'écran TFT.
    De cette façon, seule la broche MISO de la dalle tactile est reliée au convertisseur 3.3V/5V qui va vers la broche MISO de l'Arduino.

    Le résultat est le même : tout fonctionne (shield Ethernet, écran TFT) sauf les valeurs lues depuis la dalle tactile qui sont incorrectes.

    Deuxième tentative de changement au niveau du hardware :

    Mon convertisseur 3.3V/5V est bi-directionnel. C'est peut être ça qui ne fonctionne pas.
    Je relie donc directement la broche MISO de la dalle tactile à la broche MISO de l'Arduino.

    Ca ne fonctionne encore plus mal : le shield Ethernet n'arrive pas à communiquer au début.
    Je dois débrancher le MISO de la dalle tactile pour avoir des communications
    => peut être un problème lié à la broche CS de la dalle tactile ?
    Chose très intéressante : les valeurs farfelues sur la position de la touche sur l'écran tactile que l'Arduino me renvoie lorsque la dalle tactile a sa broche MISO débranché sont les mêmes.
    Je rebranche, sans éteindre l'Arduino, la broche MISO de la dalle tactile.
    Le shield Ethernet à du mal à fonctionner : erreurs dans les données reçues, détectées par mon code).
    Les valeurs farfelues que l'Arduino me renvoie la position de la touche sur l'écran tactile lorsque sont les mêmes.

    Il semblerait bien qu'on ait un problème avec la broche MISO de la dalle tactile.

    Tout fonctionne normalement lorsque la broche MISO de la dalle tactile est reliée toute seule sur un broche GPI/O, gérée en bitbanging.
    (Cette broche, comme toutes les autres de l'afficheur TFT et de la dalle tactile, est en logique 3.3V.)

    En revanche, quand j'essaye de relier la broche MISO de la dalle tactile sur la broche MISO hardware SPI de l'Arduino
    - soit directement,
    - soit via le convertisseur 3.3V/5V,
    sachant que la broche MISO hardware SPI de l'arduino est aussi utilisée par le Shield Ethernet,
    ça ne fonctionne pas.


    Remarque importante : le convertisseur 3.3V/5V est bidirectionnel, à base de TXS0108E

    L'écran tactile ne respecterait-il pas les spécifications SPI ?
    La broche MISO de la dalle tactile de l'écran TFT est en effet la seule broche qui est une sortie. Toutes les autres sont des entrées (et ne peuvent donc pas perturber les autres périphériques SPI)

    L'absence de perturbation du fonctionnement du Shield Ethernet lorsque la broche MISO de la dalle tactile est reliée à la broche MISO hardware SPI de l'Arduino via le convertisseur bidirectionnel 3.3V/5V me laisse perxplexe...

    Le TXS0108E détecte le sens de la conversion (entrée 3.3V => sortie 5V ou entrée 5V => sortie 3.3V) lorsqu'on "pousse" du courant dedans...

    Lorsque la broche MISO de la dalle tactile est reliée à la broche MISO hardware SPI de l'Arduino via le convertisseur bidirectionnel, peut être que le convertisseur se met en mode entrée 5V => sortie 3.3V ce qui expliquerait que le Shield Ethernet 2 fonctionne correctement...

    Peut être que le Shield Ethernet 2 est fautif lui aussi ? (c'est le shield Ethernet 2 officiel Arduino)

    Voyez vous d'autres tests à faire et/ou une solution ?

    L'interface SPI est la clef de mon projet, elle permet d'avoir à la fois :
    - un système rapide
    - un code source compact
    - une économie de broches I/O

    J'ai juste trois périphériques à faire fonctionner sur ce bus à tour de rôle : Shield Ethernet 2, écran TFT et dalle tactile ; je ne compte pas y renoncer.

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  9. #9
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    La datasheet du XPT2046 est ici : https://ldm-systems.ru/f/doc/catalog...,8/XPT2046.pdf

    On découvre qu'en plus de mesurer les coordonnées X,Y de la touche sur l'écran, et la pression Z, le XPT2046 :
    - possède un capteur de température intégré
    - une broche dédiée à la mesure d'une tension de batterie

    On pourrait lire les données de ces capteurs via le bus SPI...

    La datasheet du TSC2046 est identique.

    On a bien cette phrase sur la broche MISO : "Serial Data Output. Data are shifted on the falling edge of DCLK. This output is high impedance when CS is high."

    Après ma puce n'est pas un XPT2046 mais un clone portant la référence HR2046 suivie de 1843 ; je n'arrive pas à trouver de datasheet.
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  10. #10
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    J'ai repris mon câblage et mon programme précédent, celui qui fonctionne avec le bitbanging, mais en utilisant le câblage suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // LCD PIN       Uno   Connection                  Description
    // -----------   ---   -------------------------   -----------
    // 1  VCC        VCC   5V                          Could be 3.3V or 5V with TFT on-board regulator
    // 2  GND        GND   GND                         GND
    // 3  TFT CS       0   via convertisseur 3.3V/5V   Could be any GPIO pin, but then need to make sure SS isn't a LOW input (or slave SPI mode)
    // 4  TFT RESET    8   via convertisseur 3.3V/5V   Could be any GPIO pin, you can also use Arduino reset pin (if correct voltage).
    // 5  TFT DC/RS    9   via convertisseur 3.3V/5V   Could be any GPIO pin
    // 6  TFT MOSI    11   via convertisseur 3.3V/5V   HW SPI pin (can't change)
    // 7  TFT SCK     13   via convertisseur 3.3V/5V   HW SPI pin (can't change) NOTE: On Uno this causes on-board LED to flicker during SPI use
    // 8  TFT LED      6   commande PWM avec transist  Could be any GPIO pin, LCD screen blanked when LOW, could use GPIO for PWM dimming
    // 9  TFT MISO     -   non connecté                Not used if present, LCD code is currently "write only"
    // 10 Touch SCK    1   via convertisseur 3.3V/5V   Could be any GPIO pin - SPI Bitbanging
    // 11 Touch CS     2   via résistance 10K          Could be any GPIO pin
    // 12 Touch MOSI   3   via convertisseur 3.3V/5V   Could be any GPIO pin - SPI Bitbanging
    // 13 Touch MISO   7   via convertisseur 3.3V/5V   Could be any GPIO pin - SPI Bitbanging
    // 14 Touch IRQ    5   via résistance 10K          Could be any GPIO pin
     
    // Ethernet Sh   Uno   Connection                  Description
    // -----------   ---   -------------------------   -----------
    // 4  CS SD        4   directe via shield          Could be any GPIO pin
    // 10 CS Eth.     10   directe via shield          Could be any GPIO pin)
    // 11 MOSI        11   directe via shield          HW SPI pin (can't change)
    // 12 MISO        12   directe via shield          HW SPI pin (can't change)
    // 13 SCK         13   directe via shield          HW SPI pin (can't change) NOTE: On Uno this causes on-board LED to flicker during SPI use
    Et ça ne fonctionne pas (touches très mal détectées et mauvaises valeurs lues)

    Donc je modifie mon câblage pour que la broche MISO de la dalle tactile soit câblée directement vers la broche GPIO 7 de l'Arduino et tout refonctionne normalement !

    Le problème vient donc (aussi) du convertisseur 3.3V<=>5V

    J'ai fait un autre test : relier la broche CS de la dalle tactile à la broche 2 de l'Arduino via le convertisseur 5V/3.3V... et ça ne fonctionne plus aussi !

    Il faut relier la broche CS de la dalle tactile à la broche 2 de l'Arduino via une résistance de 10K et ça fonctionne

    Je me dit qu'il est possible que l'entrée/sortie en question sur le convertisseur 5V/3.3V soit grillée...

    Je permute avec une autre broche, et ça ne fonctionne plus

    => je viens de trouver une panne : sur mon convertisseur 3.3V/5V, j'ai une entrée/sortie qui ne fonctionne plus, et c'est celle-là que j'utilisais pour le MISO de la dalle tactile...

    En voilà du temps perdu... Il n'y a plus qu'à tout recâbler et à retester.
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  11. #11
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    J'ai donc refait le câblage et les tests

    J'ai pris la précaution d'intercaler entre la sortie 5V du convertisseur 3.3V/5V et la broche 12 MISO SPI de l'Arduino une résistance de 1K

    Le convertisseur n'a pas grillé sans raison...

    J'ai aussi laissé les broches CS et IRQ câblées sur de la même façon que précédemment (en direct via une résistance de 10K)

    Le résultat est exactement le même, impossible de lire correctement les touches sur la dalle tactile
    X=-4096 Y=8191 Z=4095 en permanence

    Si je débranche le fil de la broche 12 MISO SPI de l'Arduino
    E=0 S=1 X=4095 Y=0 Z=4095 en permanence

    Si je branche le fil MISO de la dalle tactile directement sur la broche 12 MISO SPI de l'Arduino plantage du shield Ethernet

    Code de la lib avec le .h et le .cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    /* Touchscreen library for XPT2046 Touch Controller Chip
     * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice, development funding notice, and this permission
     * notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
     
    #ifndef _XPT2046_Touchscreen_h_
    #define _XPT2046_Touchscreen_h_
     
    #include "Arduino.h"
    #include <SPI.h>
     
    #if ARDUINO < 10600
    #error "Arduino 1.6.0 or later (SPI library) is required"
    #endif
     
    class TS_Point {
    public:
    	TS_Point(void) : x(0), y(0), z(0) {}
    	TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
    	bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
    	bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
    	int16_t x, y, z;
    };
     
    class XPT2046_Touchscreen {
    public:
    	constexpr XPT2046_Touchscreen(uint8_t cspin, uint8_t tirq=255)
    		: csPin(cspin), tirqPin(tirq) { }
    	bool begin();
    	TS_Point getPoint();
    	bool tirqTouched();
    	bool touched();
    	void readData(uint16_t *x, uint16_t *y, uint8_t *z);
    	bool bufferEmpty();
    	uint8_t bufferSize() { return 1; }
    	void setRotation(uint8_t n) { rotation = n % 4; }
    // protected:
    	volatile bool isrWake=true;
     
    private:
    	void update();
    	uint8_t csPin, tirqPin, rotation=1;
    	int16_t xraw=0, yraw=0, zraw=0;
    	uint32_t msraw=0x80000000;
    };
     
    #ifndef ISR_PREFIX
      #if defined(ESP8266)
        #define ISR_PREFIX ICACHE_RAM_ATTR
      #elif defined(ESP32)
        // TODO: should this also be ICACHE_RAM_ATTR ??
        #define ISR_PREFIX IRAM_ATTR
      #else
        #define ISR_PREFIX
      #endif
    #endif
     
    #endif
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    /* Touchscreen library for XPT2046 Touch Controller Chip
     * Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice, development funding notice, and this permission
     * notice shall be included in all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
     
    #include "XPT2046_Touchscreen.h"
     
    #define Z_THRESHOLD     400
    #define Z_THRESHOLD_INT	75
    #define MSEC_THRESHOLD  3
    //#define SPI_SETTING     SPISettings(2000000, MSBFIRST, SPI_MODE0)
    #define SPI_SETTING     SPISettings(1000000, MSBFIRST, SPI_MODE0) 
     
    static XPT2046_Touchscreen 	*isrPinptr;
    void isrPin(void);
     
    bool XPT2046_Touchscreen::begin()
    {
    	SPI.begin();
    	pinMode(csPin, OUTPUT);
    	digitalWrite(csPin, HIGH);
    	if (255 != tirqPin) {
    		pinMode( tirqPin, INPUT );
    		attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
    		isrPinptr = this;
    	}
    	return true;
    }
     
    ISR_PREFIX
    void isrPin( void )
    {
    	XPT2046_Touchscreen *o = isrPinptr;
    	o->isrWake = true;
    }
     
    TS_Point XPT2046_Touchscreen::getPoint()
    {
    	update();
    	return TS_Point(xraw, yraw, zraw);
    }
     
    bool XPT2046_Touchscreen::tirqTouched()
    {
    	return (isrWake);
    }
     
    bool XPT2046_Touchscreen::touched()
    {
    	update();
    	return (zraw >= Z_THRESHOLD);
    }
     
    void XPT2046_Touchscreen::readData(uint16_t *x, uint16_t *y, uint8_t *z)
    {
    	update();
    	*x = xraw;
    	*y = yraw;
    	*z = zraw;
    }
     
    bool XPT2046_Touchscreen::bufferEmpty()
    {
    	return ((millis() - msraw) < MSEC_THRESHOLD);
    }
     
    static int16_t besttwoavg( int16_t x , int16_t y , int16_t z ) {
      int16_t da, db, dc;
      int16_t reta = 0;
      if ( x > y ) da = x - y; else da = y - x;
      if ( x > z ) db = x - z; else db = z - x;
      if ( z > y ) dc = z - y; else dc = y - z;
     
      if ( da <= db && da <= dc ) reta = (x + y) >> 1;
      else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
      else reta = (y + z) >> 1;   //    else if ( dc <= da && dc <= db ) reta = (x + y) >> 1;
     
      return (reta);
    }
     
    // TODO: perhaps a future version should offer an option for more oversampling,
    //       with the RANSAC algorithm https://en.wikipedia.org/wiki/RANSAC
     
    void XPT2046_Touchscreen::update()
    {
    	int16_t data[6];
     
    	if (!isrWake) return;
    	uint32_t now = millis();
    	if (now - msraw < MSEC_THRESHOLD) return;
     
    	SPI.beginTransaction(SPI_SETTING);
    	digitalWrite(csPin, LOW);
    	SPI.transfer(0xB1 /* Z1 */);
    	int16_t z1 = SPI.transfer16(0xC1 /* Z2 */) >> 3;
    	int z = z1 + 4095;
    	int16_t z2 = SPI.transfer16(0x91 /* X */) >> 3;
    	z -= z2;
    	if (z >= Z_THRESHOLD) {
    		SPI.transfer16(0x91 /* X */);  // dummy X measure, 1st is always noisy
    		data[0] = SPI.transfer16(0xD1 /* Y */) >> 3;
    		data[1] = SPI.transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
    		data[2] = SPI.transfer16(0xD1 /* Y */) >> 3;
    		data[3] = SPI.transfer16(0x91 /* X */) >> 3;
    	}
    	else data[0] = data[1] = data[2] = data[3] = 0;	// Compiler warns these values may be used unset on early exit.
    	data[4] = SPI.transfer16(0xD0 /* Y */) >> 3;	// Last Y touch power down
    	data[5] = SPI.transfer16(0) >> 3;
    	digitalWrite(csPin, HIGH);
    	SPI.endTransaction();
    	//Serial.printf("z=%d  ::  z1=%d,  z2=%d  ", z, z1, z2);
    	if (z < 0) z = 0;
    	if (z < Z_THRESHOLD) { //	if ( !touched ) {
    		// Serial.println();
    		zraw = 0;
    		if (z < Z_THRESHOLD_INT) { //	if ( !touched ) {
    			if (255 != tirqPin) isrWake = false;
    		}
    		return;
    	}
    	zraw = z;
     
    	// Average pair with least distance between each measured x then y
    	//Serial.printf("    z1=%d,z2=%d  ", z1, z2);
    	//Serial.printf("p=%d,  %d,%d  %d,%d  %d,%d", zraw,
    		//data[0], data[1], data[2], data[3], data[4], data[5]);
    	int16_t x = besttwoavg( data[0], data[2], data[4] );
    	int16_t y = besttwoavg( data[1], data[3], data[5] );
     
    	//Serial.printf("    %d,%d", x, y);
    	//Serial.println();
    	if (z >= Z_THRESHOLD) {
    		msraw = now;	// good read completed, set wait
    		switch (rotation) {
    		  case 0:
    			xraw = 4095 - y;
    			yraw = x;
    			break;
    		  case 1:
    			xraw = x;
    			yraw = y;
    			break;
    		  case 2:
    			xraw = y;
    			yraw = 4095 - x;
    			break;
    		  default: // 3
    			xraw = 4095 - x;
    			yraw = 4095 - y;
    		}
    	}
    }
    Le sketch :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    935
    936
    937
    938
    939
    940
    941
    942
    943
    944
    945
    946
    947
    948
    949
    950
    951
    952
    953
    954
    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    //Ethernet plus rapide ?
     
    #include <SPI.h>
     
    // LCD PIN       Uno   Connection                  Description
    // -----------   ---   -------------------------   -----------
    // 1  VCC        VCC   5V                          Could be 3.3V or 5V with TFT on-board regulator
    // 2  GND        GND   GND                         GND
    // 3  TFT CS       0   via convertisseur 3.3V/5V   Could be any GPIO pin, but then need to make sure SS isn't a LOW input (or slave SPI mode)
    // 4  TFT RESET    8   via convertisseur 3.3V/5V   Could be any GPIO pin, you can also use Arduino reset pin (if correct voltage).
    // 5  TFT DC/RS    9   via convertisseur 3.3V/5V   Could be any GPIO pin
    // 6  TFT MOSI    11   via convertisseur 3.3V/5V   HW SPI pin (can't change)
    // 7  TFT SCK     13   via convertisseur 3.3V/5V   HW SPI pin (can't change) NOTE: On Uno this causes on-board LED to flicker during SPI use
    // 8  TFT LED      6   commande PWM avec transist  Could be any GPIO pin, LCD screen blanked when LOW, could use GPIO for PWM dimming
    // 9  TFT MISO     -   non connecté                Not used if present, LCD code is currently "write only"
    // 10 Touch SCK   13   via convertisseur 3.3V/5V   HW SPI pin (can't change) NOTE: On Uno this causes on-board LED to flicker during SPI use
    // 11 Touch CS     2   via résistance 10K          Could be any GPIO pin
    // 12 Touch MOSI  11   via convertisseur 3.3V/5V   HW SPI pin (can't change)
    // 13 Touch MISO  12   via convertisseur 3.3V/5V   HW SPI pin (can't change)
    // 14 Touch IRQ    5   via résistance 10K          Could be any GPIO pin
     
    // Ethernet Sh   Uno   Connection                  Description
    // -----------   ---   -------------------------   -----------
    // 4  CS SD        4   directe via shield          Could be any GPIO pin
    // 10 CS Eth.     10   directe via shield          Could be any GPIO pin)
    // 11 MOSI        11   directe via shield          HW SPI pin (can't change)
    // 12 MISO        12   directe via shield          HW SPI pin (can't change)
    // 13 SCK         13   directe via shield          HW SPI pin (can't change) NOTE: On Uno this causes on-board LED to flicker during SPI use
     
    // DALLE TACTILE ************************************************************************************************************************************************
    #include <XPT2046_Touchscreen.h>
    #define t_CS 2  // FIL VERT
    #define t_IRQ 5 // FIL BLEU
     
    //XPT2046_Touchscreen ts(t_CS, t_IRQ);  // Param 2 - Touch IRQ Pin - interrupt enabled polling
    XPT2046_Touchscreen ts(t_CS);  // No interrupt
     
    // ECRAN TFT ****************************************************************************************************************************************************
    #include "RLucas_TFT_GFX.h"
    #include "RLucas_TFT_ILI9341_config.h" // C'est dans le fichier PDQ_ILI9341_config.h qu'on définit les broches CS, DC et RST :
    //#define ILI9341_CS_PIN    0   // <= /CS pin (chip-select, LOW to get attention of ILI9341, HIGH and it ignores SPI bus)
    //#define ILI9341_DC_PIN    9   // <= DC pin (1=data or 0=command indicator line) also called RS
    //#define ILI9341_RST_PIN   8   // <= RST pin (optional)
    //#define  ILI9341_SAVE_SPCR 0     // <= 0/1 with 1 to save/restore AVR SPI control register (to "play nice" when other SPI use) => prend plus de code et non nécessaire !
    #include "RLucas_TFT_ILI9341.h"      // PDQ: Hardware-specific driver library
    PDQ_ILI9341 tft;      
    #define TFT_PWM_LED 6 // Un transistor PNP permet de piloter le rétroéclairage 
     
    // ETHERNET *****************************************************************************************************************************************************
    #include "RLucas_Ethernet.h"
    // Ethernet Shield 2 : communicates with both the W5500 and SD card using the SPI bus (through the ICSP header).
    // This is on digital pins 10, 11, 12, and 13 on the Uno and pins 50, 51, and 52 on the Mega.
    // On both boards, pin 10 is used to select the W5500 and pin 4 for the SD card. These pins cannot be used for general I/O.
    // On the Mega, the hardware SS pin, 53, is not used to select either the W5500 or the SD card, but it must be kept as an output or the SPI interface won't work.
    byte mac[] = {
      0xA8, 0x61, 0x0A, 0xAE, 0x75, 0xCA //Voir étiquette collée sous le Shield
    };
    IPAddress ip(192, 168, 123, 177); //Choisir une IP fixe compatible avec le réseau local ou bien utiliser DHCP
    //IPAddress myDns(212, 27, 40, 240);
    //IPAddress myDns(192, 168, 123, 254); //DNS ou adresse du routeur  - Indispensable si IP Fixe (sans DHCP) et si on souhaite aller sur INTERNET (mais pas en local)
    //IPAddress gateway(192, 168, 123, 254); //Adresse du routeur - Indispensable si IP Fixe (sans DHCP) et si on souhaite aller sur INTERNET (mais pas en local)
    EthernetClient client;
    byte serverIP[] = { 192, 168, 123, 32 }; // Adresse IP du PC Fixe
    #define NetworkTimeout 2000
     
    // To open a port in the Windows 7 Firewall
    // On the Start menu, click Control Panel
    // Click on the System and Security category, then Windows Firewall. If you are not viewing by category, you can simply click on the Window Firewall item.
    // Click on the Advanced Settings link on the left hand side. This will open the Windows Firewall with Advanced Security Management Console application.
    // Click on Inbound Rules on the left hand menu. Under the Actions on the right hand side, click on New Rule. This opens the New Inbound Rule Wizard.
    // Select the Port option and click Next.
    // Select TCP and Specific local ports (80), then enter a comma-separated list of port numbers you want to open and click Next.
    // Select Allow the connection and click Next.
    // Check the boxes next to the desired network types and click Next.
    // Enter a name for your rule - and optionally a description - and click Finish.
    // Your inbound rule should now be displayed on the Inbound Rules list. To remove this rule, simply delete it from the list when you are done.
     
    // VARIABLES GLOBALES *******************************************************************************************************************************************
    // Buffer qui contient les requêtes et les réponses HTTP :
    #define Buffer_HTTP_Len 512
    char Buffer_HTTP[Buffer_HTTP_Len];
    int Buffer_HTTP_Stop; // Les données à traiter sont les octers de Buffer_HTTP de [0] à [Buffer_HTTP_Stop-1]
    int Buffi;
     
    // Variables "RAM" pouvant être écrites par le serveur et conservées :
    #define Buffer_RAM_Len 512
    char Buffer_RAM[Buffer_RAM_Len];
    int R1;
    int R2;
    int W1;
    int H1;
    int W2;
    int H2;
    unsigned int Couleur[14];
    int Palette; // Palette peut valoir 0 ou 7; la couleur à utiliser est définie par Couleur[index+Palette] avec index=0...6
     
    //Variables globales :
    int Status;
    int Touch_X;
    int Touch_Y;
    int Touch_Z;
    unsigned long debut;
    unsigned long duree;
    unsigned long duree2;
    int X1;
    int Y1;
    int X2;
    int Y2;
    int X3;
    int Y3;
    #define LIRE_X1_Y1 1
    #define LIRE_X2_Y2 2
    #define LIRE_X3_Y3 3
    #define LIRE_W1_H1 4
    #define LIRE_W2_H2 5
    uint8_t C1R;
    uint8_t C1G;
    uint8_t C1B;
    uint8_t C2R;
    uint8_t C2G;
    uint8_t C2B;
    int L;
     
    #define LireEntreeAnalogique 1
    #define LireEntreeNumerique 2
    #define LireEntreeLumiere 3
    const int MaxReadedPin = 10;
    byte ReadedPin[MaxReadedPin];
    int ReadedPinValue[MaxReadedPin];
    int ReadedPinIndex;
     
    #define PING_SERVEUR A5
    boolean pinPingServeur;
     
    #define AMBIANT_LIGHT A4
     
    /*
    #define AfficherBmpSansBG 1
    #define AfficherBmpAvecBG 2
    #define AfficherBmpBicolor 3
    */
     
    //char Buffer[20];
     
     
    // SETUP ********************************************************************************************************************************************************
    void setup() {
      // Toutes les broches CS à 1 :
      digitalWrite(t_CS, HIGH);
      digitalWrite(ILI9341_CS_PIN, HIGH);
      digitalWrite(10, HIGH);  // Shield Ethernet - W5500
      digitalWrite(4, HIGH); // Shield Ethernet - Carte SD
     
      Ajuster_Lumiere();
      //duree2=millis();
     
      tft.begin();
      tft.setRotation(0);
     
    /*
      ts.InitTouch(PORTRAIT);
      ts.setPrecision(PREC_EXTREME);
    */
      //ts.begin();
      ts.setRotation(0);
     
    /*
      tft.fillScreen(ILI9341_BLACK);
      tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
      tft.setTextSize(1);
    */
      // You can use Ethernet.init(CSpin) to configure the CS pin
      //Ethernet.begin(mac, ip, myDns, gateway); 
      Ethernet.begin(mac, ip);
      pinPingServeur = digitalRead(PING_SERVEUR);
     
      Status=0; // Démarrage
      Network_Contacter_Serveur();
    }
     
    // LOOP *********************************************************************************************************************************************************
    void loop() {
      // Gestion du rétroéclairage :
      Ajuster_Lumiere();
      //duree2=millis();
      // On demande à l'écran tactile s'il y a eu un appui :
      /*
      if (ts.dataAvailable()) {
        ts.read();
        Touch_X = ts.getX();
        Touch_Y = ts.getY();
        if ((Touch_X != -1) && (Touch_Y != -1)) {
          //analogWrite(TFT_PWM_LED,128);// Juste pour indiquer la détection d'une touche
          Network_Contacter_Serveur();
        }
      }
      */
      //if (ts.tirqTouched()) { // La gestion de l'IRQ avec une interruption ne marche pas
      if (!digitalRead(t_IRQ)) { // je gère moi même l'interruption
        if (ts.touched()) {
          TS_Point p = ts.getPoint();
          Touch_X = p.x;
          Touch_Y = p.y;
          Touch_Z = p.z;
          Network_Contacter_Serveur();
        }
      }
      //}
     
      // On surveille la broche permettant au serveur de solliciter une requête :
      if (pinPingServeur != digitalRead(PING_SERVEUR)) {
        pinPingServeur = !pinPingServeur;
        Status = 2; //Requête à la demande du serveur
        Network_Contacter_Serveur();
      }
    }
     
    void Ajuster_Lumiere() {
      analogWrite(TFT_PWM_LED, 205 - min(analogRead(AMBIANT_LIGHT) / 3, 205));
    }
     
    // REQUETTE *****************************************************************************************************************************************************
     
    void Network_Contacter_Serveur() {
      do {
        duree2=millis();
        Network_Construire_Requete_Traiter_Reponse();
      } while(Status > 2); // Fonction Force Another Request !
    }
     
    int Network_Envoyer_Requete_Pretraiter_Reponse() {
      int nb;
      char c;
      int i;
      //int j;
      //int nb_deja_lu;
      int RAM_pos;
      byte RAM_len;
      unsigned int longueur;
      byte crc;
      int err_RAM_Ecrite;
     
      duree=millis();
      // Connection au serveur web :
      // client.stop(); // L'arrêt du client prend beaucoup de temps, à faire après
      if (client.connect(serverIP, 80)) {
        client.print(Buffer_HTTP);
     
        //Attente de la réponse du serveur
        debut = millis();
        nb=0;
        while(nb==0){ 
          nb = client.available();
          if (millis()-debut>NetworkTimeout) {break;}
        }
     
        //Lecture de la réponse du serveur :
        if (nb==0) {
          return 1; // ERREUR : Le serveur met trop de temps à répondre
        } else {
          //On élimine l'entête, en cherchant le caractère '<' qui marque le début des données utiles :
          do {
            if (nb==0){
              return 3; // ERREUR : Le début des données n'a pas été trouvé
            }
            c=client.read();
            nb--;
          } while(c!='<');
     
          longueur = nb;
          crc = 0;
     
          if (nb==0){
            // Le serveur ne donne aucune instruction :
            Buffer_HTTP_Stop=0;
        return 9; // ERREUR : Manque Longueur + CRC
          }else{
            // Le serveur donne une ou plusieurs instructions :
            c=client.read();
            crc^=c;
            nb--;
     
            if (c==1) { // Network Resend data again
              // Le serveur demande à renvoyer les données, parce qu'il a mal reçu la requête :
              return 8; // ERREUR : Requête à recommencer
            }
     
            err_RAM_Ecrite = 0; // IMPORTANT : il peut se produire une erreur, alors qu'on a déjà écrit dans Buffer_RAM. Si oui le serveur devra en tenir compte lors du traitement de l'erreur.
     
            while(c==8) {
              // Ecriture dans le RAM buffer - Ces instructions d'écriture dans le RAM buffer ne peuvent être que les premières
              // ce qui permet d'éviter de stocker bêtement ces données en double dans le Buffer HTTP :
              nb-=2;
              if (nb<0){
                return 4 + err_RAM_Ecrite; // ERREUR : Données manquantes 
              }
              c=client.read();
              crc^=c;
              RAM_pos=(byte)c; //client.read();
              if (RAM_pos==255) {
                c=client.read();
                crc^=c;
                RAM_pos+=(byte)c; //client.read();
                nb--;
              }
              c=client.read();
              crc^=c;
              RAM_len=(byte)c; //client.read();
              nb-=RAM_len;
              if (nb<0){
                return 5 + err_RAM_Ecrite; // ERREUR : Données manquantes 
              }
              if (RAM_pos+RAM_len>=Buffer_RAM_Len){
                return 6 + err_RAM_Ecrite; // ERREUR : La position et la longeur d'écriture en RAM dépassent la limite
              }
              err_RAM_Ecrite = 32; // IMPORTANT : il peut se produire une erreur, alors qu'on a déjà écrit dans Buffer_RAM. Si oui le serveur devra en tenir compte lors du traitement de l'erreur.
              for (i=0;i<RAM_len;i++) {
                c=client.read(); // UTILISER PLUTOT : int EthernetClient::read(uint8_t *buf, size_t size) ? puis calculer le CRC ensuite ?
                crc^=c;
                Buffer_RAM[i+RAM_pos]=c; //client.read();
              }
              if (nb==0){
                // Le serveur ne donne aucune autre instruction :
                Buffer_HTTP_Stop=0;
                return 9 + err_RAM_Ecrite; // ERREUR : Manque Longueur + CRC
              }else{
                c=client.read();
                crc^=c;
                nb--;
              }
            }
     
            // Quand on arrive ici, le caractère 'c' qui a été lu auparavent est le premier caractère des instructions :
            Buffer_HTTP[0]=c;
            // Il reste 'nb' caractères à lire :
            if (nb>Buffer_HTTP_Len-2) {
              return 7 + err_RAM_Ecrite; // ERREUR : Trop de données envoyées par le serveur
            } 
            for (i=1;i<nb;i++) { //i<nb au lieu de i<=nb car le CRC ne doit pas être calculé sur lui-même
              c=client.read(); // UTILISER PLUTOT : int EthernetClient::read(uint8_t *buf, size_t size) ? puis calculer le CRC ensuite ?
              crc^=c;
              Buffer_HTTP[i]=c; //client.read();
            }
            c=client.read();
            Buffer_HTTP[i]=c; //=client.read();
            Buffer_HTTP_Stop=i+1;
          }
     
          // Il faut vérifier la longueur et le CRC :
          if (Buffer_HTTP_Stop<3) {
            return 9 + err_RAM_Ecrite; // ERREUR : Manque Longueur + CRC
          }
          Buffi=Buffer_HTTP_Stop-4; // Voir code de LireUInt16()
          if (longueur!=LireUInt16()) {
            return 10 + err_RAM_Ecrite; // ERREUR : Longueur incorrecte
          }
          if (crc!=(byte)Buffer_HTTP[Buffer_HTTP_Stop-1]) {
            return 11 + err_RAM_Ecrite; // ERREUR : CRC incorrect
          }
    /*
          tft.fillScreen(0);
          tft.setCursor(0, 0);
          tft.print("L=");   //263 OK vu avec Wireshark
          tft.print(longueur);
          tft.print(" CRC="); //87 OK !
          tft.print(crc);
          tft.print(" nb=");  //200
          tft.print(nb);
          tft.print(" BHS="); //201
          tft.print(Buffer_HTTP_Stop);
          tft.print(" LD=");  //263 OK !
          Buffi=Buffer_HTTP_Stop-4;
          tft.print(LireUInt16());
          tft.print(" C=");   //87 OK !
          tft.println((byte)Buffer_HTTP[Buffer_HTTP_Stop-1]);
          tft.println();
          j=0;
          for (i=0;i<Buffer_HTTP_Stop;i++) {
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%02x"), (byte)Buffer_HTTP[i]);
            tft.print(Buffer);
            tft.print(F(" "));
            j++;
            if (j>9) {
              j=0;
              tft.println();
            }
          }
          return 11;
    */
          // IMPORTANT : la longueur et le CRC ne doivent pas être exécutés !!!
          Buffer_HTTP_Stop-=3;
     
          return 0; // SUCCES
        }
      } else {
          return 2; // ERREUR : Pas de connection
      }
    }
     
    void Network_Construire_Requete_Traiter_Reponse() {
      int err_code;
      int i;
      int j;
      byte instr;
      int s;
      byte coul_index;
      int pos;
      int pin;
      int value;
      int valueoff;
      int w;
      int crc;
      unsigned int couleur1;
      unsigned int couleur2;
     
      //uint8_t *pointeur;
    /*
      int nb_ai;
      byte ai[50];
      int ai_ind[50];
      nb_ai=0;
    */
      err_code=0;
      do {
        // On construit la requête au serveur ici :
        //snprintf_P(Buffer_HTTP, sizeof(Buffer_HTTP), PSTR("GET /?E=%d&S=%d&X=%d&Y=%d HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"), err_code, Status, Touch_X, Touch_Y);
     
        /*
        strncpy_P(Buffer_HTTP, sizeof(Buffer_HTTP), PSTR("GET /?"));
        i=snprintf_P(Buffer_HTTP+6, sizeof(Buffer_HTTP)-6, PSTR("E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
        strncpy_P(Buffer_HTTP+i+6, sizeof(Buffer_HTTP), PSTR(" HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"));
        */
        /*
        strcpy_P(Buffer_HTTP, PSTR("GET /?"));
        i=6;
        i=sprintf_P(Buffer_HTTP+i, PSTR("E=%d&S=%d&X=%d&Y=%d"), err_code, Status, Touch_X, Touch_Y);
        */
        crc = err_code ^ Status ^ Touch_X ^ Touch_Y ^ Touch_Z;
        i=sprintf_P(Buffer_HTTP, PSTR("GET /?E=%d&S=%d&X=%d&Y=%d&Z=%d"), err_code, Status, Touch_X, Touch_Y, Touch_Z);
         if (Status==4) {
          for (j=0;j<ReadedPinIndex;j++) {
            i+=sprintf_P(Buffer_HTTP+i, PSTR("&I%d=%d"), ReadedPin[j], ReadedPinValue[j]);
            crc^=ReadedPinValue[j];
          }
        }
        i+=sprintf_P(Buffer_HTTP+i, PSTR("&C=%d"), crc);
        strcpy_P(Buffer_HTTP+i, PSTR(" HTTP/1.1\r\nHost:\r\nConnection: close\r\n\r\n"));
     
        // Le serveur connait :
        //
        //- Status
        //   0 : Le client démarre les variables et Buffer_RAM sont vides
        //   1 : Fonctionnement normal
        //   2 : Le client fait une requête à la demande du serveur (fil "interruption")
        //   3 : Le client dit au serveur qu'il est prêt a recevoir la suite de la réponse que le serveur avait demandé
        //   4 : Le client envoit la lecture des broches d'entrées que le serveur a demandé
        //
        //- err_code : le client a rencontré une erreur et demande au serveur une nouvelle requête
        //   err_code                  Le serveur a bien eu la requête précédente ?
        //   0 : SUCCES                OUI => traiter la requête normalement
        //   1 : Timeout               NON => traiter la requête normalement
        //   2 : Pas de connection     NON => traiter la requête normalement
        //   3 : Début non trouvé      OUI => juste renvoyer la réponse précédente
        //   4 : Données manquantes    OUI => juste renvoyer la réponse précédente
        //   5 : Données manquantes    OUI => juste renvoyer la réponse précédente
        //   6 : RAM overflow          OUI => juste renvoyer la réponse précédente
        //   7 : Trop de données       OUI => juste renvoyer la réponse précédente
        //   8 : Requête à recommencer OUI mais le serveur a rencontré une erreur et redemande la requete au client => traiter la requête normalement
        //   9 : CRC manquant          OUI => juste renvoyer la réponse précédente
        //   10: Longueur incorrecte   OUI => juste renvoyer la réponse précédente
        //   11: CRC incorrect         OUI => juste renvoyer la réponse précédente
        //
        //   IMPORTANT : err_code est augmenté de 32 si Buffer_RAM a été possiblement corrompu par des données incorrectes.
        //               dans ce cas de figure le serveur devra renvoyer les données pour remplir Buffer_RAM avec des données sûres.
        //
        //   "traiter la requête normalement" :
        //   - Si Status = 0 => le serveur doit envoyer les données d'initialisation
        //   - Si Status = 1 => le serveur doit executer l'action correspondant à la frappe sur le pavé tactile X et Y
        //   - Si Status = 2 => le serveur doit envoyer les données qu'il souhaite (requête client faite à la demande du serveur)
        //   - Si Status = 3 => le serveur doit envoyer la suite des données si il y a une suite disponible 
        //   - Si Status = 4 => le serveur doit lire les données lues, et envoyer la suite des données si il y a une suite disponible 
     
        err_code = Network_Envoyer_Requete_Pretraiter_Reponse();
        duree = millis()-duree;
     
        tft.tftSpiBegin();
        if (err_code==0) {
          // On traite la réponse ici :
          // Les instructions et les données à traiter sont comprises entre Buffer_HTTP[0] et Buffer_HTTP[Buffer_HTTP_Stop-1]
     
          Status=1; // On réinitialise le statut à la valeur "normale"
          ReadedPinIndex = 0;
          Buffi=-1;
     
          while(Buffi<Buffer_HTTP_Stop-1) {
            instr = LireUByte();
            if (instr>31) {
              // Il faut récupérer l'index de la couleur et remettre le numéro de l'instruction de base :
              coul_index = (instr - 32) % 7;
              instr -= coul_index;
              coul_index += Palette;
              if (instr>52 && instr<228) {
                LireXY(LIRE_X1_Y1); // Eviter de copier cette instruction de multiples fois (cases vertes dans le tableau Excel)
              }
            }else{
              if (instr>15 && instr<20) {
                // Dégradés
                LireXY(LIRE_X1_Y1); // Eviter de copier cette instruction de multiples fois (cases vertes dans le tableau Excel)
                LireXY(LIRE_X2_Y2); // Eviter de copier cette instruction de multiples fois (cases bleues dans le tableau Excel)
                if (instr>17) {
                  couleur1 = LireUInt16();                      
                  couleur2 = LireUInt16();
                  instr-=2;
                }else{
                  couleur1 = Couleur[LireUInt8()];                      
                  couleur2 = Couleur[LireUInt8()]; 
                }
                C1R = ((couleur1 >> 11) & 0x1F);
                C1G = ((couleur1 >> 5) & 0x3F);
                C1B = (couleur1 & 0x1F);
                C2R = ((couleur2 >> 11) & 0x1F);
                C2G = ((couleur2 >> 5) & 0x3F);
                C2B = (couleur2 & 0x1F);
              }else{
                if (instr>20 && instr<25) {
                  // Il faut récupérer la taille du texte et remettre le numéro de l'instruction de base :
                  s = instr-20;    
                  instr = 21;
                }
              }
            }
    /*
            ai[nb_ai]=instr;
            ai_ind[nb_ai]=Buffi;
            nb_ai++;
    */
            switch (instr) {
              case 0: // 
                // A FAIRE
                break;
              // case 1: Network Resend data => Traité dans la procédure Network_Faire_Requete();
              case 2: // Network Force other request
                if (Status<3) {Status = 3;} // Force other request (demande la suite) - Il faut laisser le Status à 4 s'il y est déjà
                break;
              case 3: // Write pin
                pin = LireUInt8();
                value = LireUInt8();
                //pinMode(pin, OUTPUT); //déjà dans analogWrite
                analogWrite(pin,value);
                break;
              case 4: // Write pin pulse
                pin = LireUInt8();
                w = LireUInt9();
                value = LireUInt8();
                valueoff = LireUInt8();
                //pinMode(pin, OUTPUT); //déjà dans analogWrite
                analogWrite(pin,value);
                delay(w);
                analogWrite(pin,valueoff);
                break;
              case 5: // Read digital pin
                LireEntree(LireEntreeNumerique);
                break;
              case 6: // Read analog pin
                LireEntree(LireEntreeAnalogique);
                break;
              case 7: // Read Ambiant light
                LireEntree(LireEntreeLumiere);
                break;
              case 9: // Set R1
                R1 = LireUInt9();
                break;
              case 10: // Set R2
                R2 = LireUInt9();
                break;
              case 11: // Set W1 H1
                LireXY(LIRE_W1_H1);
                break;
              case 12: // Set W2 H2
                LireXY(LIRE_W2_H2);
                break;
              case 13: // Set color
                i = LireUInt8();
                Couleur[i] = LireUInt16();
                break;
              case 14: // Set color index 0...6
                Palette=0;
                break;
              case 15: // Set color index 7...13
                Palette=7;
                break;
     
              case 16: // TFT Fill Rect Colormorph H
                L = X2-1;
                for (i=0;i<X2;i++) {
                  tft.drawFastVLine(i+X1, Y1, Y2, CouleurDegrade(i));
                }
                break;
              case 17: // TFT Fill Rect Colormorph V
                L = Y2-1;
                for (i=0;i<Y2;i++) {
                  tft.drawFastHLine(X1, i+Y1, X2, CouleurDegrade(i));
                }
                break;
     
              case 20: // TFT Set text cursor 
                LireXY(LIRE_X1_Y1);
                tft.setCursor(X1, Y1);
                break;
              case 21: // TFT Set text size 
                tft.setTextSize(s);
                break;
              case 25: // TFT Set text wrap off 
                tft.setTextWrap(false);
                break;
              case 26: // TFT Set text wrap on 
                tft.setTextWrap(true);
                break;
              case 27: // TFT Set text color
                  tft.setTextColor(Couleur[LireUInt8()]);
                break;
              case 28: // TFT Set text color & BG color
                  i=LireUInt8();
                  tft.setTextColor(Couleur[i],Couleur[LireUInt8()]);
                break;
              case 29: // TFT Print @RAM
                pos=LireUInt9();
                tft.print((char*)(Buffer_RAM + pos));
                break;
              case 30: // TFT Print
                PrintString();
                break;
              case 31: // TFT Print char
                Buffi++;
                tft.print(Buffer_HTTP[Buffi]);
                break;
     
              case 46: // TFT Fill Screen
                tft.fillScreen(Couleur[coul_index]);
                break;
     
              case 32: // TFT Draw Rect Button
                w = PrintString();
                // A FAIRE
                break;
              case 39: // TFT Draw Circle Button
                w = PrintString();
                // A FAIRE
                break;
     
              case 53: // TFT Draw Line
                LireXY(LIRE_X2_Y2);
                tft.drawLine(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 60: // TFT Draw H Line
                tft.drawFastHLine(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 67: // TFT Draw V Line
                tft.drawFastVLine(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
     
              case 74: // TFT Draw Rect
                LireXY(LIRE_X2_Y2);
                tft.drawRect(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 88: // TFT Draw Rect Size1
                tft.drawRect(X1, Y1, W1, H1, Couleur[coul_index]);
                break;
              case 102: // TFT Draw Rect Size2
                tft.drawRect(X1, Y1, W2, H2, Couleur[coul_index]);
                break;
     
              case 81: // TFT Draw Round Rect
                LireXY(LIRE_X2_Y2);
                tft.drawRoundRect(X1, Y1, X2, Y2, LireUInt9(), Couleur[coul_index]);
                break;
              case 95: // TFT Draw Round Rect Size1 R1
                tft.drawRoundRect(X1, Y1, W1, H1, R1, Couleur[coul_index]);
                break;
              case 109: // TFT Draw Round Rect Size2 R2
                tft.drawRoundRect(X1, Y1, W2, H2, R2, Couleur[coul_index]);
                break;
     
              case 116: // TFT Draw Circle
                tft.drawCircle(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 123: // TFT Draw Circle R1
                tft.drawCircle(X1, Y1, R1, Couleur[coul_index]);
                break;
              case 130: // TFT Draw Circle R2
                tft.drawCircle(X1, Y1, R2, Couleur[coul_index]);
                break;
     
              case 137: // TFT Draw Triangle
                LireXY(LIRE_X2_Y2);
                LireXY(LIRE_X3_Y3);
                tft.drawTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
              case 144: // TFT Draw Triangle
                X2 = X1 + W1;
                Y2 = Y1 + H1;
                X3 = X1 + W2;
                Y3 = Y1 + H2;
                tft.drawTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
     
              case 151: // TFT Fill Rect
                LireXY(LIRE_X2_Y2);
                tft.fillRect(X1, Y1, X2, Y2, Couleur[coul_index]);
                break;
              case 165: // TFT Fill Rect Size1
                tft.fillRect(X1, Y1, W1, H1, Couleur[coul_index]);
                break;
              case 179: // TFT Fill Rect Size2
                tft.fillRect(X1, Y1, W2, H2, Couleur[coul_index]);
                break;
     
              case 158: // TFT Fill Round Rect
                LireXY(LIRE_X2_Y2);
                tft.fillRoundRect(X1, Y1, X2, Y2, LireUInt9(), Couleur[coul_index]);
                break;
              case 172: // TFT Fill Round Rect Size1 R1
                tft.fillRoundRect(X1, Y1, W1, H1, R1, Couleur[coul_index]);
                break;
              case 186: // TFT Fill Round Rect Size2 R2
                tft.fillRoundRect(X1, Y1, W2, H2, R2, Couleur[coul_index]);
                break;
     
              case 193: // TFT Fill Circle
                tft.fillCircle(X1, Y1, LireUInt9(), Couleur[coul_index]);
                break;
              case 200: // TFT Fill Circle R1
                tft.fillCircle(X1, Y1, R1, Couleur[coul_index]);
                break;
              case 207: // TFT Fill Circle R2
                tft.fillCircle(X1, Y1, R2, Couleur[coul_index]);
                break;
     
              case 214: // TFT Fill Triangle
                LireXY(LIRE_X2_Y2);
                LireXY(LIRE_X3_Y3);
                tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
              case 221: // TFT Fill Triangle
                X2 = X1 + W1;
                Y2 = Y1 + H1;
                X3 = X1 + W2;
                Y3 = Y1 + H2;
                tft.fillTriangle(X1, Y1, X2, Y2, X3, Y3, Couleur[coul_index]);
                break;
     
              case 228: // 
     
                break;
              case 235: // TFT Draw Bitmap RAM
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                //tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], 0, false, LireUInt8());
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], 0, LireUInt8());
                break;
              case 242: // TFT Draw Bitmap RAM + Bicolor
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                j = LireUInt8();
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], Couleur[j], LireUInt8());
                break;
              case 249: // TFT Draw Bitmap RAM + BG
                i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
                LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
                tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], Couleur[Palette], LireUInt8());
                break;
     
              default:
                break;
            }
     
          } 
     
     
          // Affichage de debug : -----------------------------------------------------------------------------
          //tft.setTextColor(ILI9341_RED, ILI9341_BLACK);
          tft.setCursor(0, 0);
          tft.print(duree); // Temps pris pour envoyer la requête au serveur et recevoir la réponse
          tft.print(F("ms "));
          tft.print(millis()-duree2-duree);  // Temps pris pour gérer l'appui sur l'écran tactile et l'affichage
          tft.print(F("ms "));
          tft.println(Buffer_HTTP_Stop);
    /*
          tft.println();
          for (i=0;i<8;i++){
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%d %04x"), i, Couleur[i]);
            tft.println(Buffer);
          }
          tft.println();
     
          j=0;
          for (i=0;i<Buffer_HTTP_Stop;i++) {
            snprintf_P(Buffer, sizeof(Buffer), PSTR("%02x"), (byte)Buffer_HTTP[i]);
            tft.print(Buffer);
            tft.print(F(" "));
            j++;
            if (j>9) {
              j=0;
              tft.println();
            }
          }
          tft.println();
          tft.println();
          tft.print(F("Buffer_HTTP_Stop = "));
          tft.println(Buffer_HTTP_Stop);
     
          if (nb_ai>0) {
            tft.print(F("Appels :"));
            tft.println(nb_ai);
          }
          j=0;
          for (i=0;i<nb_ai;i++) {
            tft.print(ai_ind[i]);
            tft.print(F(":"));
            tft.print(ai[i]);
            j++;
            if (j>4) {
              j=0;
              tft.println();
            }else{
                tft.print(F("  "));
            }
          }
    */
          // --------------------------------------------------------------------------------------------------
     
        } else {
          // En cas d'erreur, on affiche et on recommence :
          tft.fillScreen(0);
          tft.setCursor(0, 0);
          tft.print(F("Erreur "));
          tft.print(err_code);
          delay(250);
        }
      tft.tftSpiEnd();
      } while(err_code!=0);
    }
     
    /*
    void AfficherBMP (byte mode) {
      int i;
      unsigned int CoulBG;
      i = LireUInt9(); // La position du bitmap dans Buffer_RAM est dans Buffer_HTTP
      LireXY(LIRE_X1_Y1); // X1 et Y1 sont dans Buffer_HTTP
      if (mode == AfficherBmpBicolor) {
        CoulBG = Couleur[LireUInt8()];
      }else{
        CoulBG = Couleur[Palette];
      }
      tft.drawBitmap(X1, Y1, (byte*)(Buffer_RAM + i + 2), Buffer_RAM[i], Buffer_RAM[i+1], Couleur[coul_index], CoulBG, mode!=AfficherBmpSansBG, LireUInt8());
    }
    */
     
    void LireEntree(byte mode) {
      int pin;
      Status = 4;
      if (ReadedPinIndex<MaxReadedPin) {
        if (mode==LireEntreeLumiere) {
          pin = AMBIANT_LIGHT;
        }else{
          pin = LireUInt8();
        }
        pinMode(pin, INPUT);
        ReadedPin[ReadedPinIndex] = pin;
        if (mode==LireEntreeNumerique) {
          ReadedPinValue[ReadedPinIndex] = digitalRead(pin);
        }else{
          ReadedPinValue[ReadedPinIndex] = analogRead(pin);
        }
        ReadedPinIndex++;
      }
    }
     
    unsigned int CouleurDegrade(int i) {
      int R;
      int G;
      int B;
      R = int(C2R * i/L + C1R * (L-i)/L);
      G = int(C2G * i/L + C1G * (L-i)/L);
      B = int(C2B * i/L + C1B * (L-i)/L);
      /*
      if (R>31) {R=31;}
      if (G>63) {R=63;}
      if (B>31) {B=31;}
      */
      return (R << 11) | (G << 5) | B;
    }
     
    int PrintString() {
      int i;
      int j;
      Buffi++;
      tft.print(Buffer_HTTP + Buffi);
      for (i=Buffi;i<Buffer_HTTP_Stop;i++) {
        if (Buffer_HTTP[i]==0) {
          j = i - Buffi;
          Buffi = i;
          return j;
        }
      }
      return -1;
    }
     
    byte LireUByte() {
      Buffi++;
      return Buffer_HTTP[Buffi]; 
    }
     
    int LireUInt8() {
      Buffi++;
      return (byte)Buffer_HTTP[Buffi];
    }
     
    int LireUInt9() {
      // Entier compris entre 0 et 510 - Occupe un octet si inférieur à 255
      int tmp;
      Buffi++;
      tmp = (byte)Buffer_HTTP[Buffi];
      if (tmp==255) {
        Buffi++;
        tmp += (byte)Buffer_HTTP[Buffi];
      }
      return tmp;  
    }
     
    /*
    int LireUInt9_RAM() {
      // Entier compris entre 0 et 510 - Occupe un octet si inférieur à 255
      int tmp;
      tmp = (byte)Buffer_RAM[Buffiram];
      Buffiram++;
      if (tmp==255) {
        tmp += (byte)Buffer_RAM[Buffiram];
        Buffiram++;
      }
      return tmp;  
    }
    */
     
    unsigned int LireUInt16() {
      byte MSB;
      byte LSB;
      Buffi+=2;
      MSB = Buffer_HTTP[Buffi-1];
      LSB = Buffer_HTTP[Buffi];
      return (MSB<<8) + LSB;
    }
     
    void LireXY(int num) {
      int tmpX;
      int tmpY;
      tmpX = LireUInt9();
      tmpY = LireUInt9() ;
      switch(num) {
      case LIRE_X1_Y1:
        X1=tmpX;
        Y1=tmpY;
        break;
      case LIRE_X2_Y2:
        X2=tmpX;
        Y2=tmpY;
        break;
      case LIRE_X3_Y3:
        X3=tmpX;
        Y3=tmpY;
        break;
      case LIRE_W1_H1:
        W1=tmpX;
        H1=tmpY;
        break;
      case LIRE_W2_H2:
        W2=tmpX;
        H2=tmpY;
        break;
      }    
    }
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  12. #12
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Je refais le test en supprimant la résistance de 1K intercalée entre la sortie 5V du convertisseur 3.3V/5V et la broche 12 MISO SPI de l'Arduino

    Toujours pareil, X=-4096 Y=8191 Z=4095 en permanence

    Je refais mon câblage précédent (bitbanging), ça fonctionne - ma manipulation n'a pas grillé une autre E/S du convertisseur 3.3V/5V

    Cependant il aurai fallu que je fasse un test complet sans la résistance de 1K, c'est à dire en éteignant et en allument la carte Arduino.
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  13. #13
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    J'ai écrit à l'auteur de URTouch.h et lui ai exposé le problème.

    Il m'a répondu de façon détaillée :

    Hi,

    The XPT2046 is not a true SPI device. According to the datasheet it should be compatible with SPI but there is no mention of sharing the bus with other devices. I have no idea if it would work or not.

    My original touch library was written for the ADS7843 touch controller (now discontinued I believe) and the datasheet for that device did not even mention SPI so bit-banging was the best option.

    The ADS7843 and the XPT2046 share the same communication protocol so the XPT2046 just worked with the library without modifications.

    Also; none of the display shields at the time connected the touch controller pins to the hardware SPI pins on the Arduino, so again it would not make any sense to add support for hardware SPI.

    As none of the serial/SPI displays supported by UTFT have touch screens there has not been any reason to actually implement hardware SPI for pin sharing.

    As for using bit-banging over hardware SPI in UTFT; most of the serial displays originally supported used a 4-pin interface which required 9-bit SPI transfers which the Arduinos did not support.

    Bit-banging was therefore the better option as it would work with both 4-pin and 5-pin interfaces, even if it is slower than true hardware SPI.
    Pourtant la datasheet du XPT2046 laisse planer le doute.
    Et la librairie XPT2046_Touchscreen.h utilise le hardware SPI... Mais ont-ils fait des tests avec d'autres périphériques SPI ?

    Tout en sachant que mes afficheurs ne sont pas munis de XPT2046 mais d'un "clone" dont la datasheet est introuvable...

    C'est un peu ça le piège du SPI... beaucoup de périphériques et de bibliothèques sont "vendues" comme étant "SPI" mais j'ai un peu comme l'impression que leurs fabricants ne les ont pas testés avec d'autres périphériques SPI.

    Personne n'imaginerais une telle situation avec des périphériques USB

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  14. #14
    Modérateur

    Homme Profil pro
    Ingénieur électricien
    Inscrit en
    Septembre 2008
    Messages
    1 267
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur électricien

    Informations forums :
    Inscription : Septembre 2008
    Messages : 1 267
    Points : 4 829
    Points
    4 829
    Par défaut
    Bonsoir à tous

    Un point que j'avais oublié et que je viens de revoir en cherchant la doc pour un projet perso.
    Le SPI a quatre modes.
    Si entre deux périphériques SPI le mode n'est pas le même et si la configuration ne se fait qu'à l'initialisation (ce qui est l’approche normale quant un périph SPI est seul), et bien il en découle que le premier initialisé ne marchera plus après que le second soit initialisé. Puisque le second va modifier le mode SPI et que cela va aussi s'appliquer aux communication du premier. Dans un tel cas, il faut modifier la configuration du SPI de l'AVR avant chaque usage.
    Le deuxième point qui pourrait poser problème, c'est le mauvais usage du Chip Select (un CS qui est laissé actif hors transmission), c'est possible quand le périph est seul, pas quand ils sont plusieurs. (et vu que sur AVR cela n'est géré que par le code). Ce deuxième point est quand-même moins probable car le CS est souvent utilisé pour indiqué le début d'un nouveau message multi-octet.

    Le premier point illustre parfaitement la différence entre concevoir un système, puisque toutes ces informations seront prises en compte dès le départ, et assembler des shields sans comprendre ce qu'il y a derrière.

    Bonne suite

    Delias

  15. #15
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Citation Envoyé par Delias Voir le message
    Le SPI a quatre modes.
    Si entre deux périphériques SPI le mode n'est pas le même et si la configuration ne se fait qu'à l'initialisation (ce qui est l’approche normale quant un périph SPI est seul), et bien il en découle que le premier initialisé ne marchera plus après que le second soit initialisé.
    Très juste ; d'ailleurs il n'y a pas que le mode, mais aussi la vitesse !
    D'où la présence de la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SPI.beginTransaction(SPI_SETTING);
    dans le code

    Citation Envoyé par Delias Voir le message
    Le deuxième point qui pourrait poser problème, c'est le mauvais usage du Chip Select (un CS qui est laissé actif hors transmission), c'est possible quand le périph est seul, pas quand ils sont plusieurs. (et vu que sur AVR cela n'est géré que par le code).
    La aussi, la broche CS bien est gérée dans le code.

    La réponse de l'auteur de URTouch semble convaincante... Comme il l'a remarqué, les shield TFT tactiles ne relient que l'écran TFT au broches SPI, et pas la dalle tactile.

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

Discussions similaires

  1. [Hardware portable] Comment entrer un code Ascii?
    Par l.sage dans le forum Ordinateurs
    Réponses: 13
    Dernier message: 11/08/2005, 13h04
  2. [Hardware] Peut on desactiver le clavier?
    Par ZoumZoumMan dans le forum C++Builder
    Réponses: 12
    Dernier message: 30/11/2003, 22h10
  3. Hardware et Software VertexProcessing
    Par CladStrife dans le forum DirectX
    Réponses: 18
    Dernier message: 14/10/2003, 15h16
  4. Port Parallèle EPP ou ECP, hardware vs software ?
    Par TONIAPEL dans le forum Assembleur
    Réponses: 3
    Dernier message: 21/08/2003, 01h39
  5. [TOMCAT] affichage arborescence au lieu d'éxécuter la servle
    Par lombra dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 13/08/2003, 13h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo