======== Programmes Arduino Minitel ========
==== Librairies ====
[[https://github.com/eserandour/Minitel1B_Soft|Libraries Minitel1B_Soft]]
{{ :start:arduino:minitel:socket.jpg?direct&600 |}}
*prise Arduino D2(RX) sur 3 minitel (TX)
*prise Arduino D3(TX) sur 1 minitel (RX)
*prise Arduino GND sur 2 minitel (Masse)
==== Minitel Demo====
== Minitel-Esp32 Test Laison serie entre minitel et terminal arduino ou esp32===
// OK apres test
void setup() {
Serial.begin(115200); // port debug
Serial2.begin(1200, SERIAL_7E1); // port minitel
}
void loop() {
// redirection debug -> minitel
while (Serial.available() > 0) {
Serial2.write(Serial.read());
}
// redirection minitel -> debug
while (Serial2.available() > 0) {
Serial.write(Serial2.read());
}
}
== Minitel-ESP32 Test differant affichage==
// Code OK apres test
////////////////////////////////////////////////////////////////////////
/*
Minitel1B_Hard - Démo - Version du 11 juin 2017 à 16h00
Copyright 2016, 2017 - Eric Sérandour
>> Légèrement adapté pour l'ESP32 par iodeo
Documentation utilisée :
Spécifications Techniques d'Utilisation du Minitel 1B
http://543210.free.fr/TV/stum1b.pdf
////////////////////////////////////////////////////////////////////////
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// DEBUT DU PROGRAMME
////////////////////////////////////////////////////////////////////////
#include
Minitel minitel(Serial2); // Le port utilisé sur ESP32
int wait = 10000;
////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200); // Le port de débug
minitel.changeSpeed(minitel.searchSpeed());
}
////////////////////////////////////////////////////////////////////////
void loop() {
demoCaracteres();
demoGraphic();
demoTailles();
demoCouleurs();
demoCurseur();
}
////////////////////////////////////////////////////////////////////////
void newPage(String titre) {
minitel.newScreen();
minitel.println(titre);
for (int i=1; i<=40; i++) {
minitel.writeByte(0x7E);
}
minitel.moveCursorReturn(1);
}
////////////////////////////////////////////////////////////////////////
void demoCaracteres() {
newPage("LES CARACTERES");
// Mode texte
minitel.println("MODE TEXTE SANS LIGNAGE :");
for (int i=0x20; i<=0x7F; i++) {
minitel.writeByte(i);
}
minitel.moveCursorReturn(2);
minitel.println("MODE TEXTE AVEC LIGNAGE :");
minitel.attributs(DEBUT_LIGNAGE); // En mode texte, le lignage est déclenché par le premier espace rencontré (0x20).
for (int i=0x20; i<=0x7F; i++) {
minitel.writeByte(i);
}
minitel.attributs(FIN_LIGNAGE);
minitel.moveCursorReturn(2);
// Mode semi-graphique
minitel.textMode();
minitel.println("MODE SEMI-GRAPHIQUE SANS LIGNAGE :");
minitel.graphicMode();
for (int i=0x20; i<=0x7F; i++) {
minitel.writeByte(i);
}
minitel.moveCursorReturn(2);
minitel.textMode();
minitel.println("MODE SEMI-GRAPHIQUE AVEC LIGNAGE :");
minitel.graphicMode();
minitel.attributs(DEBUT_LIGNAGE);
for (int i=0x20; i<=0x7F; i++) {
minitel.writeByte(i);
}
minitel.attributs(FIN_LIGNAGE);
minitel.moveCursorReturn(2);
delay(wait);
}
////////////////////////////////////////////////////////////////////////
void demoGraphic() {
newPage("LA FONCTION GRAPHIC");
minitel.textMode();
minitel.println("Un caractère semi-graphique est composé de 6 pseudo-pixels :");
minitel.println();
minitel.graphicMode();
minitel.attributs(DEBUT_LIGNAGE);
minitel.writeByte(0x7F);
minitel.attributs(FIN_LIGNAGE);
minitel.textMode();
minitel.print(" avec lignage ou ");
minitel.graphicMode();
minitel.writeByte(0x7F);
minitel.textMode();
minitel.println(" sans lignage.");
minitel.println();
String chaine = "";
chaine += "minitel.graphic(0b101011) donne ";
minitel.textMode();
minitel.print(chaine);
minitel.graphicMode();
minitel.graphic(0b101011);
minitel.textMode();
minitel.println();
minitel.println();
chaine = "";
chaine += "minitel.graphic(0b110110,30,15) donne ";
minitel.print(chaine);
minitel.graphicMode();
minitel.graphic(0b110110,30,15);
minitel.noCursor();
delay(2*wait);
}
////////////////////////////////////////////////////////////////////////
void demoTailles() {
newPage("LES TAILLES");
minitel.println("GRANDEUR_NORMALE");
minitel.attributs(DOUBLE_HAUTEUR);
minitel.print("DOUBLE_HAUTEUR");
minitel.attributs(DOUBLE_LARGEUR);
minitel.println();
minitel.println("DOUBLE_LARGEUR");
minitel.attributs(DOUBLE_GRANDEUR);
minitel.println("DOUBLE_GRANDEUR");
minitel.println();
minitel.attributs(GRANDEUR_NORMALE);
minitel.attributs(DEBUT_LIGNAGE); // En mode texte, le lignage est déclenché par le premier espace rencontré (0x20).
minitel.println("SEULEMENT EN MODE TEXTE");
minitel.attributs(FIN_LIGNAGE);
minitel.println();
delay(wait);
}
////////////////////////////////////////////////////////////////////////
void demoCouleurs() {
newPage("LES COULEURS");
for (int i=0; i<=1; i++) {
if (i==0) { minitel.textMode(); }
if (i==1) { minitel.graphicMode(); }
minitel.attributs(INVERSION_FOND);
minitel.print("CARACTERE_NOIR, FOND_BLANC");
minitel.attributs(FOND_NORMAL);
minitel.println(" (INVERSION)");
minitel.attributs(CARACTERE_ROUGE);
minitel.println("CARACTERE_ROUGE");
minitel.attributs(CARACTERE_VERT);
minitel.println("CARACTERE_VERT");
minitel.attributs(CARACTERE_JAUNE);
minitel.println("CARACTERE_JAUNE");
minitel.attributs(CARACTERE_BLEU);
minitel.println("CARACTERE_BLEU");
minitel.attributs(CARACTERE_MAGENTA);
minitel.println("CARACTERE_MAGENTA");
minitel.attributs(CARACTERE_CYAN);
minitel.println("CARACTERE_CYAN");
minitel.attributs(CARACTERE_BLANC);
minitel.println("CARACTERE_BLANC");
minitel.println();
}
delay(wait);
}
////////////////////////////////////////////////////////////////////////
void demoCurseur() {
minitel.cursor();
newPage("DEPLACER LE CURSEUR");
minitel.moveCursorXY(20,12);
for (int i=1; i<=100; i++) {
delay(100);
switch (random(4)) {
case 0: minitel.moveCursorRight(1+random(3)); break;
case 1: minitel.moveCursorLeft(1+random(3)); break;
case 2: minitel.moveCursorDown(1+random(3)); break;
case 3: minitel.moveCursorUp(1+random(3)); break;
}
}
newPage("POSITIONNER LE CURSEUR");
minitel.textMode();
for (int i=1; i<1000; i++) {
minitel.moveCursorXY(1+random(40),3+random(22));
minitel.writeByte(0x20 + random(0x60));
}
minitel.newScreen();
minitel.textMode();
minitel.noCursor();
for (int i=1; i<1000; i++) {
if (random(4)<3) { minitel.textMode(); }
else {
minitel.graphicMode();
minitel.attributs(DEBUT_LIGNAGE);
}
minitel.attributs(0x4C+random(5));
minitel.writeByte(0x20 + random(0x60));
minitel.attributs(FIN_LIGNAGE);
}
}
////////////////////////////////////////////////////////////////////////
==== ESP32-Minitel Pong ====
//Programme OK
#include
#define MINITEL_PORT Serial2 //for ESP32
//#define MINITEL_PORT Serial1 //for Leonardo
#define DEBUG true
#define DEBUG_PORT Serial
#if DEBUG // Debug enabled
#define debugBegin(x) DEBUG_PORT.begin(x)
#define debugPrint(x) DEBUG_PORT.println(x)
#define debugPrintHEX(x) DEBUG_PORT.println(x,HEX)
#define debugPrintBIN(x) DEBUG_PORT.println(x,BIN)
#else // Debug disabled : Empty macro functions
#define debugBegin(x)
#define debugPrint(x)
#define debugPrintHEX(x)
#define debugPrintBIN(x)
#endif
// SOUND FX
#define SOUND 1 // score using bip
//#define SOUND2 1 // hit using modem connection
// SCREEN SIZE
#define WIDTH 40
#define HEIGHT 24
// GAME FIELD
#define X1 2 //player1 column
#define X2 40 //player2 column
#define XNET 21 //net column
#define SPACE 2 //score digit space
#define YSCORE 2 //score top row
#define WSCORE 2 //score width
#define HSCORE 4 //score height
#define XSCORE1 14 //player 1 score column - align right
#define XSCORE1_U XSCORE1-WSCORE+1 //unit digit
#define XSCORE1_T XSCORE1_U-WSCORE-SPACE //tenth digit
#define XSCORE2 26 //player 2 score column - align left
#define XSCORE2_T XSCORE2 // unit digit
#define XSCORE2_U XSCORE2+WSCORE+SPACE // tenth digit
// GAME PARAMETER
#define NBALL 15 //NB OF BALLS IN THE MATCH
// BALL DIRECTION
#define HAUT_DROITE 1
#define BAS_DROITE 2
#define BAS_GAUCHE 3
#define HAUT_GAUCHE 4
Minitel minitel(MINITEL_PORT);
int yP1 = 13; //player1 position
int yP2 = 13; //player2 position
int xBall = 0;
int yBall = 0;
int xBallOld = 0;
int yBallOld = 0;
int d = HAUT_DROITE; //ball direction
int p1 = 0; //player1 score
int p2 = 0; //player2 score
int startingCounter = 0;
int level = 2; //the smaller the quicker
int bypassCounter = 0;
int hitCounter = 0; //nb hit
bool ping = true;
const byte digit[10][WSCORE*HSCORE] = { // digit de 0 à 9 sur 2 cellules par 4
// les cellules sont décrites horizontalement de gauche a droite et de haut en bas
{0b111110,0b111101,0b101010,0b010101,0b101010,0b010101,0b101111,0b011111}, //0
{0b000000,0b010101,0b000000,0b010101,0b000000,0b010101,0b000000,0b010101}, //1
{0b111100,0b111101,0b001111,0b011111,0b101010,0b000000,0b101111,0b001111}, //2
{0b111100,0b111101,0b001111,0b011111,0b000000,0b010101,0b001111,0b011111}, //3
{0b101010,0b010101,0b101111,0b011111,0b000000,0b010101,0b000000,0b010101}, //4
{0b111110,0b111100,0b101111,0b001111,0b000000,0b010101,0b001111,0b011111}, //5
{0b101010,0b000000,0b101111,0b001111,0b101010,0b010101,0b101111,0b011111}, //6
{0b111100,0b111101,0b000000,0b010101,0b000000,0b010101,0b000000,0b010101}, //7
{0b111110,0b111101,0b101111,0b011111,0b101010,0b010101,0b101111,0b011111}, //8
{0b111110,0b111101,0b101111,0b011111,0b000000,0b010101,0b000000,0b010101} //9
};
// image of welcome page
// made from jpg using processing IDE
// +jpgtovdt2.pde (PAMAL) to get vdt from jpg
// +conversion_videotex_hex (Eserandour) to get hex from vdt
typedef unsigned char PROGMEM prog_uchar;
const int LONGUEUR_TRAME_IMAGE = 1650;
const prog_uchar IMAGE[] PROGMEM = {0x0C,0x0E,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x37,0x37,0x23,0x27,0x2D,0x6F,0x3B,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x27,0x2F,0x6F,0x2F,0x7F,0x2F,0x1B,0x51,0x3F,0x1B,0x55,0x2F,0x2F,0x2F,0x2F,0x1B,0x51,0x6F,0x1B,0x50,0x2B,0x6F,0x77,0x3F,0x2F,0x1B,0x51,0x3F,0x1B,0x53,0x2F,0x1B,0x57,0x2F,0x2F,0x2F,0x1B,0x52,0x2F,0x1B,0x50,0x2F,0x6F,0x2B,0x7F,0x3F,0x2B,0x1B,0x55,0x3F,0x1B,0x56,0x2F,0x2F,0x1B,0x55,0x2F,0x1B,0x50,0x2F,0x6F,0x7B,0x37,0x27,0x3F,0x1B,0x55,0x2F,0x1B,0x57,0x2F,0x2F,0x2F,0x1B,0x52,0x6F,0x1B,0x50,0x6F,0x70,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x2B,0x63,0x62,0x22,0x1B,0x45,0x22,0x1B,0x40,0x6B,0x1B,0x50,0x6F,0x2F,0x2F,0x1B,0x57,0x37,0x1B,0x45,0x21,0x1B,0x47,0x71,0x71,0x69,0x31,0x1B,0x43,0x22,0x1B,0x40,0x2B,0x1B,0x55,0x6F,0x1B,0x50,0x6F,0x3F,0x1B,0x54,0x3F,0x1B,0x57,0x27,0x1B,0x46,0x21,0x1B,0x47,0x7B,0x72,0x1B,0x43,0x22,0x1B,0x40,0x2B,0x1B,0x54,0x6F,0x1B,0x50,0x2B,0x35,0x1B,0x51,0x3F,0x1B,0x57,0x27,0x1B,0x46,0x21,0x1B,0x47,0x61,0x34,0x7A,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x6A,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7A,0x1B,0x43,0x68,0x1B,0x40,0x7C,0x74,0x1B,0x46,0x30,0x1B,0x43,0x22,0x1B,0x40,0x1B,0x52,0x6B,0x1B,0x50,0x37,0x1B,0x57,0x37,0x1B,0x43,0x21,0x1B,0x47,0x68,0x1B,0x40,0x78,0x7C,0x1B,0x56,0x7C,0x1B,0x57,0x7C,0x1B,0x41,0x30,0x1B,0x47,0x21,0x1B,0x41,0x22,0x1B,0x40,0x1B,0x55,0x6F,0x1B,0x50,0x3F,0x1B,0x53,0x37,0x1B,0x47,0x1B,0x57,0x21,0x1B,0x42,0x60,0x1B,0x40,0x78,0x7C,0x1B,0x45,0x30,0x1B,0x47,0x7B,0x1B,0x40,0x6A,0x1B,0x50,0x77,0x1B,0x54,0x3F,0x1B,0x44,0x1B,0x57,0x25,0x1B,0x47,0x21,0x1B,0x42,0x60,0x1B,0x40,0x78,0x1B,0x56,0x7C,0x1B,0x57,0x7C,0x1B,0x56,0x7E,0x1B,0x50,0x7A,0x75,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7E,0x1B,0x43,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x3D,0x1B,0x45,0x1B,0x57,0x35,0x1B,0x47,0x3A,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x51,0x37,0x1B,0x42,0x1B,0x57,0x25,0x1B,0x47,0x77,0x1B,0x40,0x7A,0x1B,0x50,0x7C,0x78,0x24,0x61,0x1B,0x55,0x7D,0x1B,0x41,0x1B,0x57,0x30,0x1B,0x47,0x38,0x1B,0x40,0x6A,0x1B,0x50,0x2B,0x1B,0x41,0x1B,0x57,0x35,0x1B,0x47,0x6F,0x1B,0x44,0x6A,0x1B,0x40,0x1B,0x50,0x7E,0x37,0x1B,0x53,0x35,0x1B,0x47,0x1B,0x57,0x62,0x1B,0x42,0x6A,0x1B,0x40,0x1B,0x50,0x6B,0x1B,0x53,0x35,0x1B,0x47,0x1B,0x57,0x21,0x1B,0x42,0x60,0x1B,0x40,0x1B,0x52,0x7E,0x1B,0x50,0x74,0x7D,0x67,0x78,0x7E,0x75,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x3F,0x1B,0x43,0x2A,0x1B,0x40,0x2F,0x23,0x1B,0x43,0x21,0x1B,0x46,0x60,0x1B,0x40,0x1B,0x52,0x7A,0x1B,0x55,0x35,0x1B,0x47,0x1B,0x57,0x21,0x1B,0x43,0x68,0x1B,0x40,0x1B,0x54,0x6A,0x1B,0x50,0x6A,0x2F,0x7D,0x23,0x22,0x1B,0x57,0x35,0x1B,0x47,0x23,0x1B,0x45,0x6A,0x1B,0x40,0x1B,0x50,0x6B,0x1B,0x41,0x1B,0x57,0x35,0x1B,0x47,0x2E,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x35,0x1B,0x56,0x35,0x1B,0x47,0x1B,0x57,0x3F,0x1B,0x46,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x1B,0x44,0x1B,0x57,0x35,0x1B,0x47,0x72,0x1B,0x44,0x6A,0x1B,0x40,0x1B,0x50,0x3F,0x1B,0x53,0x2F,0x2F,0x2F,0x1B,0x52,0x6F,0x1B,0x50,0x6B,0x3F,0x1B,0x55,0x35,0x1B,0x47,0x1B,0x57,0x7D,0x6A,0x70,0x1B,0x43,0x60,0x1B,0x41,0x70,0x1B,0x40,0x7A,0x1B,0x50,0x7E,0x1B,0x55,0x35,0x1B,0x47,0x1B,0x57,0x30,0x1B,0x43,0x2A,0x1B,0x40,0x1B,0x55,0x6B,0x1B,0x50,0x73,0x6B,0x6B,0x2C,0x78,0x1B,0x57,0x35,0x1B,0x47,0x74,0x1B,0x45,0x6A,0x1B,0x40,0x1B,0x50,0x7E,0x1B,0x41,0x1B,0x57,0x35,0x1B,0x47,0x6F,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7C,0x35,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x37,0x1B,0x46,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x1B,0x44,0x1B,0x57,0x35,0x1B,0x47,0x76,0x1B,0x41,0x6A,0x1B,0x40,0x1B,0x50,0x25,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x60,0x3A,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7E,0x7F,0x1B,0x55,0x35,0x1B,0x47,0x1B,0x57,0x7D,0x1B,0x43,0x6A,0x1B,0x40,0x1B,0x55,0x7C,0x7C,0x1B,0x50,0x7E,0x7E,0x78,0x1B,0x54,0x7D,0x1B,0x41,0x1B,0x57,0x34,0x1B,0x47,0x79,0x1B,0x40,0x2A,0x1B,0x51,0x6F,0x1B,0x50,0x6A,0x6A,0x3F,0x1B,0x53,0x3F,0x1B,0x46,0x1B,0x57,0x21,0x1B,0x47,0x7A,0x1B,0x40,0x7A,0x1B,0x50,0x61,0x1B,0x41,0x1B,0x57,0x35,0x1B,0x47,0x25,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x35,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7C,0x1B,0x46,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x1B,0x56,0x75,0x1B,0x43,0x1B,0x57,0x30,0x22,0x1B,0x40,0x2B,0x1B,0x55,0x7C,0x1B,0x46,0x1B,0x57,0x35,0x1B,0x47,0x37,0x1B,0x40,0x1B,0x53,0x6A,0x1B,0x50,0x2A,0x7F,0x1B,0x55,0x35,0x1B,0x47,0x1B,0x57,0x6E,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x75,0x7F,0x7F,0x35,0x1B,0x56,0x7D,0x1B,0x45,0x1B,0x57,0x30,0x1B,0x47,0x3D,0x1B,0x42,0x22,0x1B,0x40,0x23,0x23,0x23,0x1B,0x43,0x21,0x1B,0x47,0x6B,0x1B,0x40,0x68,0x1B,0x50,0x7E,0x34,0x1B,0x41,0x1B,0x57,0x35,0x1B,0x47,0x68,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x35,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x70,0x1B,0x46,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7D,0x1B,0x57,0x74,0x1B,0x47,0x30,0x22,0x1B,0x44,0x22,0x1B,0x46,0x21,0x1B,0x47,0x77,0x1B,0x40,0x1B,0x53,0x6A,0x1B,0x50,0x27,0x7F,0x1B,0x51,0x35,0x1B,0x47,0x1B,0x57,0x68,0x1B,0x43,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x6B,0x7F,0x7F,0x7F,0x75,0x35,0x1B,0x52,0x7D,0x1B,0x57,0x70,0x1B,0x46,0x30,0x1B,0x47,0x70,0x7E,0x70,0x1B,0x41,0x60,0x1B,0x40,0x78,0x1B,0x50,0x7E,0x6B,0x75,0x1B,0x41,0x1B,0x57,0x35,0x1B,0x47,0x70,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x35,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x70,0x1B,0x46,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7D,0x76,0x1B,0x57,0x7D,0x30,0x1B,0x43,0x30,0x1B,0x47,0x70,0x60,0x1B,0x40,0x1B,0x53,0x6A,0x1B,0x50,0x6F,0x37,0x1B,0x51,0x7D,0x1B,0x53,0x7C,0x7C,0x1B,0x50,0x7E,0x6A,0x7F,0x7F,0x7F,0x7F,0x7D,0x7D,0x7E,0x1B,0x54,0x7D,0x1B,0x56,0x7C,0x7C,0x1B,0x52,0x7E,0x1B,0x50,0x7E,0x7E,0x7C,0x7E,0x7F,0x1B,0x55,0x7D,0x7C,0x7E,0x1B,0x50,0x7E,0x75,0x1B,0x54,0x7D,0x1B,0x55,0x7C,0x7C,0x1B,0x50,0x7E,0x6C,0x7D,0x7C,0x7E,0x1B,0x51,0x7D,0x1B,0x52,0x7C,0x7C,0x1B,0x50,0x7E,0x7A,0x7D,0x7D,0x7E,0x7D,0x7C,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7D,0x7E,0x7E,0x7D,0x7C,0x71,0x7E,0x7F,0x7F,0x7F,0x7F,0x7D,0x7D,0x7E,0x7F,0x7F,0x7C,0x7D,0x7F,0x7D,0x7E,0x7F,0x7F,0x7F,0x7F,0x70,0x70,0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
//const int LONGUEUR_TRAME_IMAGE = 1666;
//const prog_uchar IMAGE[] PROGMEM = {0x0C,0x0E,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x3F,0x1B,0x51,0x2F,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x37,0x1B,0x57,0x23,0x23,0x23,0x2F,0x1B,0x50,0x6F,0x7F,0x7F,0x7F,0x7F,0x1B,0x56,0x3F,0x1B,0x57,0x23,0x1B,0x41,0x21,0x1B,0x45,0x23,0x1B,0x40,0x23,0x1B,0x52,0x6F,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x1B,0x57,0x3F,0x1B,0x41,0x21,0x1B,0x47,0x7F,0x1B,0x45,0x22,0x1B,0x40,0x6B,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x1B,0x54,0x3F,0x1B,0x57,0x2F,0x23,0x1B,0x44,0x23,0x1B,0x40,0x1B,0x53,0x6B,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x7F,0x7F,0x7F,0x1B,0x40,0x2A,0x1B,0x54,0x6F,0x1B,0x50,0x7F,0x7F,0x1B,0x57,0x27,0x1B,0x47,0x21,0x7F,0x1B,0x42,0x60,0x1B,0x46,0x30,0x1B,0x47,0x7F,0x1B,0x45,0x22,0x1B,0x40,0x1B,0x52,0x6B,0x1B,0x50,0x7F,0x7F,0x1B,0x57,0x3F,0x1B,0x43,0x21,0x1B,0x46,0x60,0x1B,0x40,0x70,0x1B,0x45,0x30,0x1B,0x43,0x22,0x1B,0x40,0x6F,0x1B,0x50,0x7F,0x7F,0x1B,0x52,0x3F,0x1B,0x41,0x1B,0x57,0x21,0x1B,0x47,0x7F,0x1B,0x46,0x60,0x1B,0x42,0x70,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x51,0x7C,0x1B,0x57,0x34,0x1B,0x47,0x22,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7F,0x1B,0x53,0x3F,0x1B,0x43,0x1B,0x57,0x21,0x1B,0x44,0x60,0x1B,0x40,0x1B,0x53,0x7E,0x1B,0x50,0x7E,0x7D,0x1B,0x57,0x74,0x1B,0x43,0x30,0x1B,0x44,0x2A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x1B,0x57,0x21,0x1B,0x47,0x60,0x1B,0x40,0x7E,0x1B,0x50,0x7F,0x1B,0x53,0x75,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x54,0x3F,0x1B,0x57,0x21,0x1B,0x47,0x60,0x1B,0x40,0x78,0x1B,0x54,0x7E,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x55,0x35,0x1B,0x47,0x1B,0x57,0x35,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7F,0x1B,0x44,0x1B,0x57,0x25,0x1B,0x47,0x7F,0x1B,0x40,0x1B,0x56,0x7E,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x1B,0x57,0x75,0x1B,0x47,0x7F,0x1B,0x40,0x1B,0x53,0x6A,0x1B,0x50,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x56,0x37,0x1B,0x47,0x1B,0x57,0x21,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x2A,0x1B,0x56,0x2F,0x1B,0x57,0x25,0x1B,0x47,0x60,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7F,0x1B,0x43,0x1B,0x57,0x35,0x1B,0x44,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x34,0x1B,0x44,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x57,0x35,0x1B,0x47,0x68,0x1B,0x40,0x1B,0x55,0x6A,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x7F,0x7F,0x7F,0x1B,0x40,0x60,0x1B,0x54,0x7E,0x1B,0x50,0x7F,0x1B,0x43,0x1B,0x57,0x35,0x1B,0x44,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x35,0x1B,0x45,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x51,0x6A,0x1B,0x50,0x37,0x1B,0x44,0x1B,0x57,0x23,0x23,0x1B,0x40,0x1B,0x53,0x6B,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x60,0x70,0x7C,0x1B,0x54,0x7E,0x1B,0x50,0x7F,0x7F,0x1B,0x46,0x1B,0x57,0x35,0x1B,0x42,0x22,0x1B,0x40,0x1B,0x54,0x6F,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x1B,0x55,0x3F,0x1B,0x47,0x1B,0x57,0x25,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x56,0x35,0x1B,0x47,0x1B,0x57,0x22,0x1B,0x40,0x1B,0x53,0x6B,0x1B,0x50,0x75,0x1B,0x44,0x1B,0x57,0x70,0x1B,0x47,0x7F,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x57,0x35,0x1B,0x47,0x7F,0x1B,0x40,0x2A,0x1B,0x50,0x6F,0x7F,0x7F,0x1B,0x54,0x3F,0x1B,0x57,0x25,0x1B,0x47,0x7F,0x1B,0x40,0x1B,0x53,0x7A,0x1B,0x50,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x1B,0x55,0x7D,0x1B,0x43,0x1B,0x57,0x34,0x1B,0x41,0x22,0x1B,0x40,0x1B,0x56,0x6F,0x1B,0x51,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x51,0x7D,0x1B,0x41,0x1B,0x57,0x30,0x1B,0x47,0x7F,0x1B,0x40,0x22,0x2B,0x27,0x1B,0x41,0x21,0x1B,0x47,0x7F,0x1B,0x40,0x68,0x1B,0x50,0x7F,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x7F,0x1B,0x57,0x75,0x1B,0x47,0x30,0x1B,0x46,0x22,0x1B,0x40,0x23,0x1B,0x47,0x7F,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x1B,0x56,0x6A,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x56,0x7D,0x1B,0x57,0x30,0x1B,0x47,0x30,0x7F,0x7F,0x60,0x1B,0x40,0x78,0x1B,0x50,0x7E,0x7F,0x7F,0x1B,0x42,0x1B,0x57,0x35,0x1B,0x47,0x6A,0x1B,0x40,0x1B,0x50,0x6A,0x7F,0x35,0x1B,0x47,0x1B,0x57,0x7F,0x1B,0x40,0x6A,0x1B,0x50,0x7F,0x7F,0x7D,0x1B,0x57,0x74,0x1B,0x42,0x30,0x1B,0x47,0x7F,0x7F,0x1B,0x44,0x1B,0x53,0x6A,0x1B,0x40,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x52,0x7D,0x1B,0x57,0x7C,0x1B,0x56,0x7E,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x1B,0x57,0x7D,0x7C,0x7C,0x7E,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x1B,0x57,0x7C,0x7C,0x1B,0x50,0x7E,0x7F,0x7D,0x1B,0x57,0x7C,0x7E,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x1B,0x51,0x7D,0x1B,0x57,0x7C,0x7C,0x1B,0x53,0x7E,0x1B,0x50,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
void setup() {
debugBegin(115200);
debugPrint("debug port ready");
delay(500); // wait minitel to init
//init minitel at 4800 bauds
if (minitel.searchSpeed() != 4800) { // search speed
if (minitel.changeSpeed(4800) < 0) { // set to 4800 if different
minitel.searchSpeed(); // search speed again if change has failed
}
}
minitel.modeVideotex();
minitel.echo(false);
}
void loop() {
welcome();
startGame();
}
void welcome() {
//draw welcome screen
minitel.newScreen();
minitel.attributs(CARACTERE_BLANC);
minitel.attributs(FOND_NOIR);
for (int i=0; ip2) drawScore1(p1);
else drawScore2(p2);
#ifdef SOUND
minitel.bip();
delay(1000);
minitel.bip();
delay(1000);
minitel.bip();
delay(1000);
#else delay(5000);
#endif
#ifdef SOUND2
if (!ping) ping = pingpong(ping);
#endif
p1 = 0;
p2 = 0;
yP1 = 13;
yP2 = 13;
xBall = 0;
yBall = 0;
ping = true;
}
void handlePlayer() {
int dy1 = 0;
int dy2 = 0;
byte key = getKeyCodeOverride();
if (key == 215 && yP1<22) dy1++;
if (key == 209 && yP1>3) dy1--;
if (key == 78 && yP2<22) dy2++;
if (key == 202 && yP2>3) dy2--;
minitel.graphic(0b111111, X1, yP1+3*dy1);
minitel.moveCursorXY(X1, yP1-2*dy1);
if (dy1!=0) minitel.graphic(0b000000);
else minitel.graphic(0b111111); //preserve frame rate
yP1+=dy1;
minitel.graphic(0b111111, X2, yP2+3*dy2);
minitel.moveCursorXY(40, yP2-2*dy2);
if (dy2!=0) minitel.graphic(0b000000);
else minitel.graphic(0b111111); //preserve frame rate
yP2+=dy2;
}
void playGame() {
handlePlayer();
if (startingCounter > 0) {
countdown();
}
else {
//updateLevel
if (hitCounter == 3) level=1;
if (hitCounter == 6) level=0;
if (bypassCounter < level) {
//bypass frame to slow down
bypassCounter++;
}
else {
bypassCounter=0;
xBallOld = xBall;
yBallOld = yBall;
// move ball
if(d == HAUT_DROITE){
xBall+=2;
yBall--;
}
if(d == BAS_DROITE){
xBall+=2;
yBall++;
}
if(d == BAS_GAUCHE){
xBall-=2;
yBall++;
}
if(d == HAUT_GAUCHE){
xBall-=2;
yBall--;
}
//erase old ball
eraseBall(xBallOld, yBallOld);
//draw new ball
minitel.graphic(0b111111, xBall, yBall);
// top limit
if(yBall == 1) {
if(d == HAUT_DROITE) d = BAS_DROITE;
if(d == HAUT_GAUCHE) d = BAS_GAUCHE;
}
// bottom limit
if(yBall == HEIGHT) {
if (d == BAS_GAUCHE) d = HAUT_GAUCHE;
if (d == BAS_DROITE) d = HAUT_DROITE;
}
// player1 side
if (xBall <= X1 + 2) {
// player1 send back
if(abs(yBall-yP1) < 3) {
if(d == BAS_GAUCHE) d = BAS_DROITE;
if(d == HAUT_GAUCHE) d = HAUT_DROITE;
hitCounter++;
#ifdef SOUND2
ping = pingpong(ping);
#endif
}
else{ // player2 win
#ifdef SOUND
minitel.bip();
#endif
p2++;
drawScore2(p2);
initGame();
}
}
// player2 side
if (xBall >= X2 - 2) {
// player2 send back
if(abs(yBall-yP2) < 3) {
if(d == BAS_DROITE) d = BAS_GAUCHE;
if(d == HAUT_DROITE) d = HAUT_GAUCHE;
hitCounter++;
#ifdef SOUND2
ping = pingpong(ping);
#endif
}
else{ // player1 win
#ifdef SOUND
minitel.bip();
#endif
p1++;
drawScore1(p1);
initGame();
}
}
}
}
}
bool pingpong(bool ping) {
if (ping) {
minitel.connexion(true);
return false;
}
else {
minitel.connexion(false);
return true;
}
}
void eraseBall(int x, int y) {
// erase ball preserving game field and score
minitel.moveCursorXY(x,y);
bool erase = true;
if (x == XNET) { // Ball in net
if (y%2 == 1) erase = false;
}
if (y >= YSCORE && y < YSCORE + HSCORE) { // Ball in score
if (x >= XSCORE1_T && x < XSCORE1_T + WSCORE) { //ball in score1 tenth
if (p1 >= 10) {
drawDigit(p1/10, XSCORE1_T, YSCORE);
erase = false;
}
}
if (x >= XSCORE1_U && x < XSCORE1_U + WSCORE) { //ball in score1 unit
drawDigit(p1%10, XSCORE1_U, YSCORE);
erase = false;
}
if (x >= XSCORE2_T && x < XSCORE2_T + WSCORE) { //ball in score2 tenth
if (p2 >= 10) {
drawDigit(p2/10, XSCORE2_T, YSCORE);
erase = false;
}
}
if (x >= XSCORE2_U && x < XSCORE2_U + WSCORE) { //ball in score2 unit
drawDigit(p2%10, XSCORE2_U, YSCORE);
erase = false;
}
}
if (erase) minitel.graphic(0b000000);
}
/*void drawDigit(int num, int x, int y) {
for (int i = 0; i < WSCORE; i++) {
for (int j = 0; j < HSCORE; j++) {
minitel.graphic(digit[num][i+WSCORE*j],x+i,y+j);
}
}
}*/
void initGame() {
// init level
hitCounter = 0;
level = 2;
bypassCounter = 2;
// get random starting point
xBallOld = xBall;
yBallOld = yBall;
d = random(1,4);
xBall = random(1,5)*2+1;
if (d>2) xBall = 40-xBall;
yBall = random(3,22);
// draw new ball
minitel.graphic(0b111111, xBall, yBall);
// starting countdown
startingCounter = 10;
}
void countdown() {
if (xBallOld != 0) {
if (startingCounter == 8) {
minitel.attributs(CARACTERE_BLEU);
minitel.graphic(0b111111, xBallOld, yBallOld);
minitel.attributs(CARACTERE_BLANC);
}
if (startingCounter == 6) {
minitel.attributs(CARACTERE_VERT);
minitel.graphic(0b111111, xBallOld, yBallOld);
minitel.attributs(CARACTERE_BLANC);
}
if (startingCounter == 4) {
minitel.attributs(CARACTERE_BLEU);
minitel.graphic(0b111111, xBallOld, yBallOld);
minitel.attributs(CARACTERE_BLANC);
}
if (startingCounter == 2) {
minitel.attributs(CARACTERE_VERT);
minitel.graphic(0b111111, xBallOld, yBallOld);
minitel.attributs(CARACTERE_BLANC);
}
if (startingCounter == 1) {
minitel.graphic(0b000000, xBallOld, yBallOld); //erase ball
#ifdef SOUND2
ping = pingpong(ping);
#endif
}
}
startingCounter--;
}
byte getKeyCodeOverride() {
byte b = 255;
if (MINITEL_PORT.available()) {
b = MINITEL_PORT.read();
MINITEL_PORT.flush();
debugPrint(b);
}
return b;
}
void drawGameField() {
//draw net
for (int i = 1; i < HEIGHT; i+=2) {
minitel.graphic(0b111111, 21, i);
}
//draw players
for (int i = -2; i < 3; i++) {
minitel.graphic(0b111111,X1,yP1+i);
minitel.graphic(0b111111,X2,yP2+i);
}
// draw score
drawScore1(p1);
drawScore2(p2);
}
void drawScore1(int score) {
drawDigit(score%10, XSCORE1_U, YSCORE);
if (score>=10) drawDigit(score/10, XSCORE1_T, YSCORE);
}
void drawScore2(int score) {
drawDigit(score%10, XSCORE2_U, YSCORE);
if (score>=10) drawDigit(score/10, XSCORE2_T, YSCORE);
}
void drawDigit(int num, int x, int y) {
for (int i = 0; i < WSCORE; i++) {
for (int j = 0; j < HSCORE; j++) {
minitel.graphic(digit[num][i+WSCORE*j],x+i,y+j);
}
}
}
#include
SoftwareSerial mySerial(2, 3);
byte gauche = 8;
byte droite = 9;
byte bas = 10;
byte haut = 11;
byte debutDeLigne = 13;
byte hautGauche = 30;
byte hautGaucheEfface = 12;
byte separateurDeSousArticle = 31;
byte remplissageEspace = 24; //Remplit le reste da la rangée avec des espaces
byte CBleu = 68; // caractère niveau gris bleu
byte CBlanc = 71; // caractère couleur blanche
byte Clignote = 72 ; // caractère clignote
byte Fixe = 73 ; // caractère fixe
byte NormalH = 76 ; // taille caractère normal
byte DoubleH = 77 ; // double hauteur
byte Ligne = 90 ; // caractère souligné
byte SLigne = 89; // annule soulingé
short incomming;
char inascii = » »;
short outcomming;
int TS = 0; // touche spéciale
String TSS = « »; // touche spéciale texte
void setup() {
Serial.begin(1200); // port serie vers le PC
mySerial.begin(1200); // port serie vers le minitel
mySerial.write(hautGaucheEfface); //efface l’écran
// serialprint7(0x0E); // passe en mode graphique
delay(500);
sendMessage(« BONJOUR »);
CR();
sendMessage(« BONSOIR »);
Gauche(3);
sendMessage(« REBONSOIR »);
Droite(3);
delay(1000);
sendMessage(« JOUR »);
CR();
ESC(Clignote);
sendMessage(« BONJOUR »);
ESC(Fixe);
CR();
CR();
ESC(DoubleH);
sendMessage(« BONJOUR »);
CR();
ESC(NormalH);
ESC(CBleu);
sendMessage(« BONJOUR »);
CR();
ESC(CBlanc);
sendMessage(« BONJOUR »);
CR();
ESC(Ligne);
sendMessage( » BONJOUR »);
CR();
ESC(SLigne);
sendMessage(« BONJOUR »);
CR();
Serial.println( » « );
}
char modifyParity(char c) {
char i = 1 << 6;
boolean p = false;
c &= B01111111;
while (i) {
if (c & i) {
p = !p;
}
i >>= 1;
}
c |= p << 7;
return c;
}
void sendMessage(char *msg) {
int i = 0;
while (msg[i]) {
serialprint7(msg[i]);
i++;
}
Serial.write(msg);
Serial.flush();
}
void serialprint7(byte b) // permet d’ecrire en 7 bits + parité sur le software serial
{
boolean i = false;
for (int j = 0; j < 8; j++)
{
if (bitRead(b, j) == 1) i = !i; //calcul de la parité
}
if (i) bitWrite(b, 7, 1); //ecriture de la partié
else bitWrite(b, 7, 0); //ecriture de la partié
mySerial.write(b);//ecriture du byte sur le software serial
}
void Gauche(int g) {
for (int i = 0; i <= g; i++) {
serialprint7(9);
}
}
void Droite(int g) {
for (int i = 0; i <= g; i++) {
serialprint7(8);
}
}
void Haut(int g) {
for (int i = 0; i <= g; i++) {
serialprint7(11);
}
}
void ESC(int c){
serialprint7(27);
serialprint7(c);
}
void CR() {
serialprint7(13);
serialprint7(10);
}
void loop() //tout ce que je recois sur le port serie, je le renvoi sur le software serial
{
// Serial.println(« loop »);
if (Serial.available()) {
outcomming = Serial.read();
Serial.print(« saisie ardiuno: »);
Serial.println (outcomming);
// serialprint7(incomming);
serialprint7(outcomming);
}
if (mySerial.available()) {
incomming = mySerial.read() & B01111111; // ignore parity check // ignore parity check
Serial.print(« saisie minitel : »);
inascii = char(incomming);
Serial.println (inascii);
if (TS == 1) {
touchespeciales();
TS = 0;
}
if (incomming == 19) {
TS = 1;
}
}
}
void touchespeciales() {
switch (incomming) {
case 70:
Serial.println (« Sommaire »);
TSS = « Sommaire »;
break;
case 69:
Serial.println (« Annulation »);
TSS = « Annulation »;
break;
case 66:
Serial.println (« Retour »);
TSS = « Retour »;
break;
case 67:
Serial.println (« Repetition »);
TSS = « Repetition »;
break;
case 68:
Serial.println (« Guide »);
TSS = « Guide »;
break;
case 71:
Serial.println (« Correction »);
TSS = « Correction » ;
break;
case 72:
Serial.println (« Suite »);
TSS = « Suite »;
break;
case 65:
Serial.println (« Envoi »);
TSS = « Envoi »;
break;
case 89:
Serial.println (« Connexion »);
TSS = « Connexion »;
break;
}
}
==== Programme 2 Minitel1B_ChessUI.ino====
// programme tester = OK
#include
#define MINITEL_PORT Serial2 //for ESP32
//#define MINITEL_PORT Serial1 //for Leonardo
#define DEBUG true
#define DEBUG_PORT Serial
#if DEBUG // Debug enabled
#define debugBegin(x) DEBUG_PORT.begin(x)
#define debugPrint(x) DEBUG_PORT.println(x)
#define debugPrintHEX(x) DEBUG_PORT.println(x,HEX)
#define debugPrintBIN(x) DEBUG_PORT.println(x,BIN)
#else // Debug disabled : Empty macro functions
#define debugBegin(x)
#define debugPrint(x)
#define debugPrintHEX(x)
#define debugPrintBIN(x)
#endif
#define CASE_WIDTH 4
#define CASE_HEIGHT 3
#define BOARD_TOP 1
#define BOARD_LEFT 1
#define PIECE_WIDTH 3
#define PIECE_HEIGHT 3
#define SCORE_TOP 1
#define SCORE_LEFT 33
#define SCORE_WIDTH 8
#define SCORE_HEIGHT 24
#define SCORE_BLACK_TOP 1
#define SCORE_WHITE_TOP 16
#define SCORE_HEIGHT_2 9 // indiv. score frame
#define SCORE_MOVE_TOP 10
#define SCORE_HEIGHT_3 6 // move frame
Minitel minitel(MINITEL_PORT);
enum { VOID, PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING};
enum {_BLACK = 0,_WHITE = 128};
byte piece[7][PIECE_WIDTH*PIECE_HEIGHT] = {
// pieces en caractères semi-graphiques 3 par 3 décrites par lignes de haut-gauche à bas-droite
{0b000000, 0b000000, 0b000000, 0b000000, 0b000000, 0b000000, 0b000000, 0b000000, 0b000000}, // VOID
{0b000000, 0b000000, 0b000000, 0b000101, 0b101111, 0b000000, 0b000100, 0b101100, 0b000000}, // PAWN
{0b000010, 0b000010, 0b000010, 0b110101, 0b111101, 0b100000, 0b011100, 0b011100, 0b001000}, // ROOK
{0b000000, 0b000111, 0b000010, 0b011110, 0b011101, 0b101010, 0b001100, 0b111100, 0b001000}, // KNIGHT
{0b000001, 0b001011, 0b000000, 0b111111, 0b101111, 0b101010, 0b011100, 0b111100, 0b001000}, // BISHOP
{0b001001, 0b000011, 0b001000, 0b000111, 0b101111, 0b000010, 0b111100, 0b011100, 0b101000}, // QUEEN
{0b000001, 0b001011, 0b000000, 0b000111, 0b101111, 0b000010, 0b111100, 0b011100, 0b101000} // KING
};
byte board[8][8] { //top-left to bottom-right - _BLACK or _WHITE added later
/*{ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK },
{PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN },
{VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },
{VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },
{VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },
{VOID, VOID, VOID, VOID, VOID, VOID, VOID, VOID },
{PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN, PAWN },
{ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK }*/
};
int cx = 0; // 0-7 > A-H
int cy = 7; // 0-7 > 8-1
int scx = -1; // first case selected
int scy = -1; //
String moveStr = " - ";
String lastStr = " - ";
byte player = _WHITE;
void setup() {
debugBegin(115200);
debugPrint("> Debug start");
delay(500);
// Minitel setup
int baud = minitel.searchSpeed();
debugPrint("> Minitel is at " + String(baud) + "bds");
if (baud != 4800) {
debugPrint("> Set to 4800 bauds");
if (minitel.changeSpeed(4800) < 0) { // try set speed to 4800 if needed
debugPrint(" *** Failed to change speed ***");
minitel.searchSpeed(); // search back if failed
}
}
//minitel.modeVideotex();
minitel.echo(false);
minitel.extendedKeyboard(); //need arrows
minitel.clearScreen();
minitel.moveCursorXY(1,1);
minitel.noCursor();
minitel.attributs(FIXE);
debugPrint("> Minitel setup done");
// Intialize game board
initBoard();
drawBoard();
drawAllPieces();
drawScoreBoard();
//hoverCase(cx,cy, true);
}
String keyboardInput = "";
void loop() {
char c = 0;
c = getKeyboardInput();
switch (c) {
// nothing
case 0: break;
// move on board
case UP: moveUp(); break;
case DOWN: moveDown(); break;
case LEFT: moveLeft(); break;
case RIGHT: moveRight(); break;
// cancel selection
case DEL:
case CAN:
if (scx != -1) { // cancel selection
selectCase(scx, scy, false);
scx = -1; scy = -1;
moveStr = " - ";
writeMove();
}
break;
// move selection
case CR:
if (scx == -1 || scy == -1) {
// first case selection
scx = cx;
scy = cy;
selectCase(cx, cy, true);
moveStr.setCharAt(1,cx+65); // A(65)-H
moveStr.setCharAt(2,56-cy); // 8(56)-1
writeMove();
}
else {
if (cx == scx && cy == scy) {
// cancel first case selection
selectCase(cx, cy, false);
moveStr = " - ";
writeMove();
scx = -1; scy = -1;
}
else {
// second case selection
//TODO: verifiy legal move
moveStr.setCharAt(4,cx+65); // A(65)-H
moveStr.setCharAt(5,56-cy); // 8(56)-1
writeMove();
board[cx][cy] = board[scx][scy];
board[scx][scy] = VOID;
erasePiece(scx, scy);
selectCase(scx, scy, false);
drawPiece(cx, cy, board[cx][cy]);
scx = -1; scy = -1;
if (player == _WHITE) player = _BLACK;
else player = _WHITE;
lastStr = moveStr;
moveStr = " - ";
redrawMove();
}
}
break;
}
}
void initBoard() {
for (int i = 0; i < 5; i++) board[i][0] = (i+2) + _BLACK;
for (int i = 5; i < 8; i++) board[i][0] = (5-i+4) + _BLACK;
for (int i = 0; i < 8; i++) board[i][1] = PAWN + _BLACK;
for (int j = 2; j < 6; j++) {
for (int i = 0; i < 8; i++) board[i][j] = VOID;
}
for (int i = 0; i < 5; i++) board[i][7] = (i+2) + _WHITE;
for (int i = 5; i < 8; i++) board[i][7] = (5-i+4) + _WHITE;
for (int i = 0; i < 8; i++) board[i][6] = PAWN + _WHITE;
}
void drawBoard() {
minitel.textMode();
minitel.attributs(GRANDEUR_NORMALE);
minitel.graphicMode();
minitel.moveCursorXY(BOARD_LEFT, BOARD_TOP);
bool dark = false;
int cy = 8;
while (cy > 0) {
int row = 1;
while (row <= CASE_HEIGHT) {
int cx = 1;
while (cx < 9) {
if (dark) minitel.attributs(FOND_BLEU);
else minitel.attributs(FOND_VERT);
minitel.graphic(0b000000);
minitel.repeat(CASE_WIDTH - 1);
if (row < 3) {
minitel.moveCursorLeft(CASE_WIDTH);
minitel.textMode();
if (dark) minitel.attributs(CARACTERE_BLEU);
else minitel.attributs(CARACTERE_VERT);
minitel.attributs(INVERSION_FOND);
if (row == 1) minitel.printChar(cx+64); // A-H
else minitel.printChar(cy+48); // 1-8
minitel.moveCursorRight(CASE_WIDTH - 1);
minitel.graphicMode();
}
dark = !dark;
cx++;
}
minitel.moveCursorLeft(CASE_WIDTH*8);
minitel.moveCursorDown(1);
row++;
}
dark = !dark;
cy--;
}
}
void drawScoreBoard() {
drawBackground();
drawFrame(SCORE_LEFT, SCORE_BLACK_TOP, SCORE_WIDTH, SCORE_HEIGHT_2, _BLACK);
//drawFrame(SCORE_LEFT, SCORE_MOVE_TOP, SCORE_WIDTH, SCORE_HEIGHT_3, _WHITE);
drawFrame(SCORE_LEFT, SCORE_WHITE_TOP, SCORE_WIDTH, SCORE_HEIGHT_2, _WHITE);
minitel.textMode();
minitel.attributs(GRANDEUR_NORMALE);
int sx = SCORE_BLACK_TOP;
minitel.attributs(CARACTERE_NOIR);
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("BLACK ");
minitel.attributs(FOND_NORMAL);
sx+=2;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("time:");
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(" --:--");
minitel.attributs(FOND_NORMAL);
sx+=2;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("str:");
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(" --");
sx = SCORE_MOVE_TOP;
minitel.attributs(CARACTERE_BLANC);
minitel.attributs(FOND_NORMAL);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("move:");
minitel.attributs(CARACTERE_BLANC);
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(moveStr);
minitel.attributs(CARACTERE_NOIR);
minitel.attributs(FOND_NORMAL);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("last:");
minitel.attributs(CARACTERE_NOIR);
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(lastStr);
sx = SCORE_WHITE_TOP;
minitel.attributs(CARACTERE_BLANC);
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("WHITE ");
minitel.attributs(FOND_NORMAL);
sx+=2;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("time:");
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(" --:--");
minitel.attributs(FOND_NORMAL);
sx+=2;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("str:");
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(" --");
}
void drawBackground() {
int sy = SCORE_TOP;
minitel.graphicMode();
minitel.attributs(FOND_MAGENTA);
while (sy < SCORE_TOP + SCORE_HEIGHT) {
minitel.moveCursorXY(SCORE_LEFT,sy);
minitel.graphic(0b000000);
minitel.repeat(SCORE_WIDTH-1);
sy++;
}
}
void writeMove() {
minitel.textMode();
if (player == _WHITE) {
minitel.attributs(CARACTERE_BLANC);
minitel.attributs(INVERSION_FOND);
}
minitel.moveCursorXY(SCORE_LEFT+1,SCORE_MOVE_TOP+2);
minitel.print(moveStr);
}
void redrawMove() {
int sx = SCORE_MOVE_TOP;
minitel.textMode();
if (player == _WHITE) minitel.attributs(CARACTERE_BLANC);
else minitel.attributs(CARACTERE_NOIR);
minitel.attributs(FOND_NORMAL);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("move:");
if (player == _WHITE) minitel.attributs(CARACTERE_BLANC);
else minitel.attributs(CARACTERE_NOIR);
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(moveStr);
if (player == _WHITE) minitel.attributs(CARACTERE_NOIR);
else minitel.attributs(CARACTERE_BLANC);
minitel.attributs(FOND_NORMAL);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print("last:");
if (player == _WHITE) minitel.attributs(CARACTERE_NOIR);
else minitel.attributs(CARACTERE_BLANC);
minitel.attributs(INVERSION_FOND);
sx++;
minitel.moveCursorXY(SCORE_LEFT+1,sx);
minitel.print(lastStr);
}
void drawFrame(int x, int y, int w, int h, int c) {
int sy = y;
minitel.graphicMode();
minitel.attributs(FOND_MAGENTA);
if (c == _BLACK) minitel.attributs(CARACTERE_NOIR);
else minitel.attributs(CARACTERE_BLANC);
minitel.moveCursorXY(x,sy);
minitel.graphic(0b000001);
minitel.graphic(0b000011);
minitel.repeat(w-3);
minitel.graphic(0b000010);
sy++;
while (sy < y + h - 1) {
minitel.moveCursorXY(x,sy);
minitel.graphic(0b010101);
minitel.graphic(0b000000);
minitel.repeat(w-3);
minitel.graphic(0b101010);
sy++;
}
minitel.moveCursorXY(x,sy);
minitel.graphic(0b010000);
minitel.graphic(0b110000);
minitel.repeat(w-3);
minitel.graphic(0b100000);
}
void drawPiece(int cx, int cy, byte pc) {
// x : from 0 to 7 - left to right
// y : from 0 to 7 - top to bottom
int x = cx * CASE_WIDTH + 1;
int y = cy * CASE_HEIGHT + 1;
byte color = _BLACK;
if (pc > _WHITE) color = _WHITE;
byte p = pc - color;
minitel.graphicMode();
if (color == _WHITE) {
minitel.attributs(DEBUT_LIGNAGE);
minitel.attributs(CARACTERE_BLANC);
}
else { // _BLACK
minitel.attributs(CARACTERE_NOIR);
}
if ((cx+cy)%2 == 1) minitel.attributs(FOND_BLEU);
else minitel.attributs(FOND_VERT);
for (int j = 0; j < PIECE_HEIGHT; j++) {
minitel.moveCursorXY(x+1,y+j);
for (int i = 0; i < PIECE_WIDTH; i++) {
minitel.graphic(piece[p][i+j*PIECE_WIDTH]);
}
}
if (color == _WHITE) {
minitel.attributs(FIN_LIGNAGE);
}
}
void erasePiece(int cx, int cy) {
// x : from 0 to 7 - left to right
// y : from 0 to 7 - top to bottom
drawPiece(cx, cy, VOID);
}
void drawAllPieces() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (j<2 || j>5) drawPiece(i, j, board[i][j]);
}
}
}
void hoverCase(int cx, int cy, bool hover) {
if (cx == scx && cy == scy) selectCase(cx, cy, true);
else {
int x = cx*CASE_WIDTH + 1;
int y = cy*CASE_HEIGHT + 3;
bool dark = false;
if ((cx+cy)%2 == 1) dark = true;
minitel.moveCursorXY(x,y);
minitel.graphicMode();
if (dark) minitel.attributs(FOND_BLEU);
else minitel.attributs(FOND_VERT);
if (hover) {
minitel.attributs(CARACTERE_BLANC);
minitel.graphic(0b111111);
}
else minitel.graphic(0b000000);
}
}
void selectCase(int cx, int cy, bool sel) {
int x = cx*CASE_WIDTH + 1;
int y = cy*CASE_HEIGHT + 3;
bool dark = false;
if ((cx+cy)%2 == 1) dark = true;
minitel.moveCursorXY(x,y);
minitel.graphicMode();
if (dark) minitel.attributs(FOND_BLEU);
else minitel.attributs(FOND_VERT);
if (sel) {
minitel.attributs(CARACTERE_NOIR);
minitel.graphic(0b111111);
}
else {
minitel.graphic(0b000000);
}
}
void moveUp() {
if (cy > 0) {
hoverCase(cx,cy, false);
cy--;
hoverCase(cx,cy, true);
}
}
void moveDown() {
if (cy < 7) {
hoverCase(cx,cy, false);
cy++;
hoverCase(cx,cy, true);
}
}
void moveLeft() {
if (cx > 0) {
hoverCase(cx,cy, false);
cx--;
hoverCase(cx,cy, true);
}
}
void moveRight() {
if (cx < 7) {
hoverCase(cx,cy, false);
cx++;
hoverCase(cx,cy, true);
}
}
char getKeyboardInput() {
unsigned long key = minitel.getKeyCode();
if (key != 0) {
debugPrintHEX(key);
// key redirection/inhibition
switch (key) {
// cancel selection
case CORRECTION:
case ANNULATION:
case RETOUR:
case ESC:
return CAN; break;
// validate selection
case ENVOI:
case SP:
return CR; break;
// navigate
case TOUCHE_FLECHE_HAUT: return UP; break;
case TOUCHE_FLECHE_BAS: return DOWN; break;
case TOUCHE_FLECHE_DROITE: return RIGHT; break;
case TOUCHE_FLECHE_GAUCHE: return LEFT; break;
// inhibited
case CONNEXION_FIN:
case SOMMAIRE:
case REPETITION:
case GUIDE:
case SUITE:
return 0; break;
default: return key;
}
}
else return 0;
}
=== Minitel-ESP32 Demo Teaser ===
//Faire Reset de l'ESP32 à chaque démmarrage du minitel
/*
* Sample code for connexion to minitel videotex server via websocket
* Requirements: ESP32 connected to minitel DIN port and a WiFi connexion
*
* created by iodeo - dec 2021
*/
#include
#include // src: https://github.com/Links2004/arduinoWebSockets.git
#include // src: https://github.com/eserandour/Minitel1B_Hard.git
// ---------------------------------------
// ------ Minitel port configuration
#define MINITEL_PORT Serial2 // for Minitel-ESP32 devboard
#define MINITEL_BAUD 4800 // 1200 / 4800 / 9600 depending on minitel type
#define MINITEL_DISABLE_ECHO true // true if characters are repeated when typing
// ---------------------------------------
// ------ Debug port configuration
#define DEBUG true
#if DEBUG
#define DEBUG_PORT Serial // for Minitel-ESP32 devboard
#define DEBUG_BAUD 115200 // set serial monitor accordingly
#define debugBegin(x) DEBUG_PORT.begin(x)
#define debugPrintf(...) DEBUG_PORT.printf(__VA_ARGS__)
#else // Empty macro functions
#define debugBegin(x)
#define debugPrintf(...)
#endif
// ---------------------------------------
// ------ WiFi credentials
const char* ssid = "xxxxxxxxxxxxx"; // your wifi network
const char* password = "xxxxxxxxxxxxxxxxxxx"; // your wifi password
// ---------------------------------------
// ------ Websocket server
/****** TELETEL.ORG --------- connecté le 2 mar 2022
*//*
// ws://home.teletel.org:9001/
char* host = "home.teletel.org";
int port = 9001;
char* path = "/";
bool ssl = false;
int ping_ms = 0;
char* protocol = "";
/**/
/****** 3615 ----------------- connecté le 2 mar 2022
// wss://3615co.de/ws
char* host = "3615co.de";
int port = 80;
char* path = "/ws";
bool ssl = false;
int ping_ms = 0;
char* protocol = "";
/**/
/****** AE ------------------- connecté le 2 mar 2022
// ws://3611.re/ws
// websocket payload length of 0
char* host = "3611.re";
int port = 80;
char* path = "/ws";
bool ssl = false;
int ping_ms = 0;
char* protocol = "";
/**/
/****** HACKER -------------- connecté le 2 mar 2022
// ws://mntl.joher.com:2018/?echo
// websocket payload length up to 873
char* host = "mntl.joher.com";
int port = 2018;
char* path = "/?echo";
bool ssl = false;
int ping_ms = 0;
char* protocol = "";
/**/
/****** TEASER --------------- connecté le 2 mar 2022
// ws://minitel.3614teaser.fr:8080/ws
char* host = "minitel.3614teaser.fr";
int port = 8080;
char* path = "/ws";
bool ssl = false;
int ping_ms = 10000;
char* protocol = "tty";
/**/
/****** SM ------------------- connecté le 2 mar 2022*/
// wss://wss.3615.live:9991/?echo
// websocket payload length up to 128
char* host = "wss.3615.live";
int port = 9991;
char* path = "/?echo";
bool ssl = true;
int ping_ms = 0;
char* protocol = "";
/**/
WiFiClient client;
WebSocketsClient webSocket;
Minitel minitel(MINITEL_PORT);
void setup() {
debugBegin(DEBUG_BAUD);
debugPrintf("\n-----------------------\n");
debugPrintf("\n> Debug port ready\n");
// We initiate minitel communication
debugPrintf("\n> Minitel setup\n");
int baud = minitel.searchSpeed();
if (baud != MINITEL_BAUD) baud = minitel.changeSpeed(MINITEL_BAUD);
debugPrintf(" - Baud detected: %u\n", baud);
if (MINITEL_DISABLE_ECHO) {
minitel.echo(false);
debugPrintf(" - Echo disabled\n");
}
// We connect to WiFi network
debugPrintf("\n> Wifi setup\n");
debugPrintf(" Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
debugPrintf(".");
}
debugPrintf("\n WiFi connected with IP %s\n", WiFi.localIP().toString().c_str());
// We connect to Websocket server
debugPrintf("\n> Websocket connection\n");
if (protocol[0] == '\0') {
if (ssl) webSocket.beginSSL(host, port, path);
else webSocket.begin(host, port, path);
}
else {
debugPrintf(" - subprotocol added\n");
if (ssl) webSocket.beginSSL(host, port, path, protocol);
else webSocket.begin(host, port, path, protocol);
}
webSocket.onEvent(webSocketEvent);
if (ping_ms != 0) {
debugPrintf(" - heartbeat ping added\n");
// start heartbeat (optional)
// ping server every ping_ms
// expect pong from server within 3000 ms
// consider connection disconnected if pong is not received 2 times
webSocket.enableHeartbeat(ping_ms, 3000, 2);
}
debugPrintf("\n> End of setup\n\n");
}
void loop() {
// Websocket -> Minitel
webSocket.loop();
// Minitel -> Websocket
uint32_t key = minitel.getKeyCode(false);
if (key != 0) {
debugPrintf("[KB] got code: %X\n", key);
// prepare data to send over websocket
uint8_t payload[4];
size_t len = 0;
for (len = 0; key != 0 && len < 4; len++) {
payload[3-len] = uint8_t(key);
key = key >> 8;
}
webSocket.sendTXT(payload+4-len, len);
}
}
void webSocketEvent(WStype_t type, uint8_t * payload, size_t len) {
switch(type) {
case WStype_DISCONNECTED:
debugPrintf("[WS] Disconnected!\n");
break;
case WStype_CONNECTED:
debugPrintf("[WS] Connected to url: %s\n", payload);
break;
case WStype_TEXT:
debugPrintf("[WS] got %u chars\n", len);
if (len > 0) {
debugPrintf(" > %s\n", payload);
for (size_t i = 0; i < len; i++) {
minitel.writeByte(payload[i]);
}
}
break;
case WStype_BIN:
debugPrintf("[WS] got %u binaries - ignored\n", len);
break;
case WStype_ERROR:
debugPrintf("[WS] WStype_ERROR\n");
break;
case WStype_FRAGMENT_TEXT_START:
debugPrintf("[WS] WStype_FRAGMENT_TEXT_START\n");
break;
case WStype_FRAGMENT_BIN_START:
debugPrintf("[WS] WStype_FRAGMENT_BIN_START\n");
break;
case WStype_FRAGMENT:
debugPrintf("[WS] WStype_FRAGMENT\n");
break;
case WStype_FRAGMENT_FIN:
debugPrintf("[WS] WStype_FRAGMENT_FIN\n");
break;
}
}