Cours:ErB32019 : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
m (Utilisation du shield CNC)
m (Caractéristiques)
 
(33 révisions intermédiaires par le même utilisateur non affichées)
Ligne 1 : Ligne 1 :
 +
=Projet GPS tracker=
 +
Ce que l'on cherche à réaliser est décrit dans cette vidéo : [https://www.youtube.com/watch?v=D20uSl_JHrk Arduino GPS tracker and Google Maps Tutorial] ou ce cours de 49mn : [https://www.youtube.com/watch?v=OsMoowoB2Rg LESSON 22: Build an Arduino GPS Tracker]
 +
 +
=Propeller clock=
 +
Ce projet est donné depuis un certain nombre d'années et va continuer encore cette année. Il se fera avec des Leds et non plus a bandeau de leds numérique (WS2812 rgb leds). Voir la vidéo : [https://www.youtube.com/watch?v=HYtftl7_pO0 Arduino NANO Propeller LED Analog Clock]
 +
 +
Vous pouvez trouver aussi [https://www.electronicshub.org/pov-display-using-arduino/ un document explicatif] avec un peu de code. Une autre technique utilisant un registre à décalage 74HC595 [https://ijireeice.com/wp-content/uploads/2014/12/IJIREEICE-15.pdf est présentée ICI].
 +
 +
Il vous est possible de choisir une autre technologie que le microcontrôleur, à savoir le FPGA.
 +
 +
=Optical Flow=
 +
Ce projet peut concerner un ou deux binômes mais alors en concurrence. Autrement dit, s'il y a deux binômes il y a deux projets différents.
 +
 +
Ce que l'on cherche à faire est présenté dans cette vidéo : [https://www.youtube.com/watch?v=8P_5KFCGcTg Arduino based pan-tilt optical flow tracking] Vous disposerez de
 +
* tourelle pan/tilt et ses servomoteurs
 +
* Optical Flow Sensor APM2.5 improve position hold accuracy Multicopter ADNS 3080
 +
* Ecran 2,8'
 +
* microcontrôleur ou FPGA au choix
 +
 +
Du code pour lire le composant ADNS 3080 peut être trouvé sur gitHub :
 +
* [https://github.com/Lauszus/ADNS3080 ADNS3080]
 +
* [https://github.com/Neumi/OpticalFlowA3080ArduinoProcessing Optical Flow A3080 Arduino and Processing]
 +
==Caractéristiques du capteur==
 +
*<b>Caractéristiques</b> : ce capteur est basé sur le capteur de souris ADNS3080 qui est un bon choix pour le flux optique.
 +
*<b>Haute résolution :</b> images 30x30 pixels, ce qui signifie qu'il peut avoir des fonctionnalités que les petites souris ne peuvent pas avoir.
 +
*<b>Haute vitesse :</b> taux de mise à jour de 2000 à 6400 images par seconde, ce qui contribue à de meilleures performances de faible luminosité que les autres capteurs de souris.
 +
* Interface SPI, ce qui signifie qu'elle peut être interfacée à de nombreux micro-contrôleurs et coexistent avec d'autres capteurs.
 +
* Destiné à s'interfacer avec un microcontrôleur 5V.
 +
* Objectif de 8mm avec FOV de 11 degrés.
 +
* Monture d'objectif Standard M12x0.5, ce qui signifie que vous pouvez remplacer l'objectif facilement.
 +
 +
Instruction d'utilisation:
 +
* Il fonctionne bien dans les environnements extérieurs éclairés.
 +
* Il ne fonctionne pas bien avec les lumières fluorescentes (le clignotement perturbe le capteur).
 +
* Il faut une surface non uniforme pour voir le mouvement (les tapis unis ne sont pas son ami).
 +
 +
==Solution intermédiaire : optical flow et écran avec MSP432==
 +
<source lang=arduino>
 +
#include <SPI.h>
 +
 +
/*************************
 +
* Carte SD ----- Launchpad
 +
* TM4C123G (ARM)
 +
* GND ----------- GND
 +
* +3.3 ---------- Vcc
 +
* CS ------------ PB5 (PB_5)
 +
* MOSI ---------- PB7 (PB_7)
 +
* SCK ----------- PB4 (PB_4)
 +
* MISO ---------- PB6 (PB_6)
 +
*
 +
**************************/
 +
 +
//#define PIN_SS        PB_5
 +
#define PIN_MISO      14
 +
#define PIN_MOSI      15
 +
#define PIN_SCK      7
 +
 +
#define PIN_MOUSECAM_RESET    17
 +
#define PIN_MOUSECAM_CS        18
 +
 +
#define ADNS3080_PIXELS_X                30
 +
#define ADNS3080_PIXELS_Y                30
 +
 +
#define ADNS3080_PRODUCT_ID            0x00
 +
#define ADNS3080_REVISION_ID          0x01
 +
#define ADNS3080_MOTION                0x02
 +
#define ADNS3080_DELTA_X              0x03
 +
#define ADNS3080_DELTA_Y              0x04
 +
#define ADNS3080_SQUAL                0x05
 +
#define ADNS3080_PIXEL_SUM            0x06
 +
#define ADNS3080_MAXIMUM_PIXEL        0x07
 +
#define ADNS3080_CONFIGURATION_BITS    0x0a
 +
#define ADNS3080_EXTENDED_CONFIG      0x0b
 +
#define ADNS3080_DATA_OUT_LOWER        0x0c
 +
#define ADNS3080_DATA_OUT_UPPER        0x0d
 +
#define ADNS3080_SHUTTER_LOWER        0x0e
 +
#define ADNS3080_SHUTTER_UPPER        0x0f
 +
#define ADNS3080_FRAME_PERIOD_LOWER    0x10
 +
#define ADNS3080_FRAME_PERIOD_UPPER    0x11
 +
#define ADNS3080_MOTION_CLEAR          0x12
 +
#define ADNS3080_FRAME_CAPTURE        0x13
 +
#define ADNS3080_SROM_ENABLE          0x14
 +
#define ADNS3080_FRAME_PERIOD_MAX_BOUND_LOWER      0x19
 +
#define ADNS3080_FRAME_PERIOD_MAX_BOUND_UPPER      0x1a
 +
#define ADNS3080_FRAME_PERIOD_MIN_BOUND_LOWER      0x1b
 +
#define ADNS3080_FRAME_PERIOD_MIN_BOUND_UPPER      0x1c
 +
#define ADNS3080_SHUTTER_MAX_BOUND_LOWER          0x1e
 +
#define ADNS3080_SHUTTER_MAX_BOUND_UPPER          0x1e
 +
#define ADNS3080_SROM_ID              0x1f
 +
#define ADNS3080_OBSERVATION          0x3d
 +
#define ADNS3080_INVERSE_PRODUCT_ID    0x3f
 +
#define ADNS3080_PIXEL_BURST          0x40
 +
#define ADNS3080_MOTION_BURST          0x50
 +
#define ADNS3080_SROM_LOAD            0x60
 +
 +
#define ADNS3080_PRODUCT_ID_VAL        0x17
 +
 +
 +
 +
//Basic Colors
 +
#define RED  0xf800
 +
#define GREEN  0x07e0
 +
#define BLUE  0x001f
 +
#define BLACK  0x0000
 +
#define YELLOW  0xffe0
 +
#define WHITE  0xffff
 +
 +
//Other Colors
 +
#define CYAN  0x07ff 
 +
#define BRIGHT_RED  0xf810 
 +
#define GRAY1  0x8410 
 +
#define GRAY2  0x4208 
 +
 +
//TFT resolution 240*320
 +
#define MIN_X  0
 +
#define MIN_Y  0
 +
#define MAX_X  239
 +
#define MAX_Y  319
 +
 +
#define FONT_SPACE 6
 +
#define FONT_X 8
 +
#define FONT_Y 8
 +
 +
 +
const uint8_t simpleFont[][8] =
 +
{
 +
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 +
  {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
 +
  {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
 +
  {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
 +
  {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
 +
  {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
 +
  {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
 +
  {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
 +
  {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
 +
  {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
 +
  {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
 +
  {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
 +
  {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
 +
  {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
 +
  {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
 +
  {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
 +
  {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
 +
  {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
 +
  {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
 +
  {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
 +
  {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
 +
  {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
 +
  {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
 +
  {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
 +
  {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
 +
  {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
 +
  {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
 +
  {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
 +
  {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
 +
  {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
 +
  {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
 +
  {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
 +
  {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
 +
  {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
 +
  {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
 +
  {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
 +
  {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
 +
  {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
 +
  {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
 +
  {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
 +
  {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
 +
  {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
 +
  {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
 +
  {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
 +
  {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
 +
  {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
 +
  {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
 +
  {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
 +
  {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
 +
  {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
 +
  {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
 +
  {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
 +
  {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
 +
  {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
 +
  {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
 +
  {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
 +
  {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
 +
  {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
 +
  {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
 +
  {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
 +
  {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
 +
  {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
 +
  {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
 +
  {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
 +
  {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
 +
  {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
 +
  {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
 +
  {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
 +
  {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
 +
  {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
 +
  {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
 +
  {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
 +
  {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
 +
  {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
 +
  {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
 +
  {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
 +
  {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
 +
  {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
 +
  {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
 +
  {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
 +
  {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
 +
  {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
 +
  {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
 +
  {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
 +
  {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
 +
  {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
 +
  {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
 +
  {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
 +
  {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
 +
  {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
 +
  {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
 +
  {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
 +
  {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
 +
  {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
 +
  {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
 +
  {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
 +
};
 +
 +
void TFT_sendCMD(uint8_t index);
 +
void TFT_WRITE_DATA(uint8_t data);
 +
void TFT_sendData(uint16_t data);
 +
void TFT_WRITE_Package(uint16_t *data, uint8_t howmany);
 +
void TFT_backlight_on(void);
 +
void TFT_backlight_off(void);
 +
uint8_t TFT_Read_Register(uint8_t Addr, uint8_t xParameter);
 +
void TFT_TFTinit (void);
 +
uint8_t TFT_readID(void);
 +
void TFT_setCol(uint16_t StartCol,uint16_t EndCol);
 +
void TFT_setPage(uint16_t StartPage,uint16_t EndPage);
 +
void TFT_fillScreen(uint16_t XL, uint16_t XR, uint16_t YU, uint16_t YD, uint16_t color);
 +
void TFT_fillScreen2(void);
 +
void TFT_setXY(uint16_t poX, uint16_t poY);
 +
void TFT_setPixel(uint16_t poX, uint16_t poY,uint16_t color);
 +
void TFT_drawChar( uint8_t ascii, uint16_t poX, uint16_t poY,uint16_t size, uint16_t fgcolor, uint16_t bgcolor);
 +
void TFT_drawString(char *string,uint16_t poX, uint16_t poY, uint16_t size,uint16_t fgcolor, uint16_t bgcolor);
 +
void TFT_fillRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width, uint16_t color);
 +
void  TFT_drawHorizontalLine( uint16_t poX, uint16_t poY,uint16_t length,uint16_t color);
 +
void TFT_drawLine( uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1,uint16_t color);
 +
void TFT_drawVerticalLine( uint16_t poX, uint16_t poY, uint16_t length,uint16_t color);
 +
void TFT_drawRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width,uint16_t color);
 +
void TFT_drawCircle(int poX, int poY, int r,uint16_t color);
 +
void TFT_fillCircle(int poX, int poY, int r,uint16_t color);
 +
void TFT_drawTraingle( int poX1, int poY1, int poX2, int poY2, int poX3, int poY3, uint16_t color);
 +
uint8_t TFT_drawNumber(long long_num,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor);
 +
uint8_t TFT_drawFloat(float floatNumber,uint8_t decimal,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor);
 +
 +
uint8_t SPI_transfer(uint8_t data);
 +
void SPI_init();
 +
 +
// CAMERA
 +
void mousecam_reset();
 +
int mousecam_init();
 +
void mousecam_write_reg(int reg, int val);
 +
int mousecam_read_reg(int reg);
 +
 +
struct MD
 +
{
 +
byte motion;
 +
char dx, dy;
 +
byte squal;
 +
word shutter;
 +
byte max_pix;
 +
};
 +
 +
void mousecam_read_motion(struct MD *p);
 +
 +
// pdata must point to an array of size ADNS3080_PIXELS_X x ADNS3080_PIXELS_Y
 +
// you must call mousecam_reset() after this if you want to go back to normal operation
 +
int mousecam_frame_capture(byte *pdata);
 +
 +
 +
 +
 +
 +
/*
 +
int main() {
 +
  uint8_t i, t[4];
 +
  uint16_t cmpt=0;
 +
// init
 +
//  SPI_init();
 +
 
 +
  TFT_TFTinit (); //init TFT library
 +
  TFT_backlight_on();                          // turn on the background light
 +
   
 +
  TFT_drawChar('S',0,0,1,RED,BLACK);              // draw char: 'S', (0, 0), size: 1, color: RED
 +
   
 +
  TFT_drawChar('E',10,10,2,BLUE,BLACK);          // draw char: 'E', (10, 10), size: 2, color: BLUE
 +
   
 +
  TFT_drawChar('E',20,40,3,GREEN,BLACK);          // draw char: 'E', (20, 40), size: 3, color: GREEN
 +
   
 +
  TFT_drawChar('E',30,80,4,YELLOW,BLACK);        // draw char: 'E', (30, 80), size: 4, color: YELLOW
 +
   
 +
  TFT_drawChar('D',40,120,4,YELLOW,BLACK);        // draw char: 'D', (40, 120), size: 4, color: YELLOW
 +
   
 +
  TFT_drawString("Hello",0,180,3,CYAN,BLACK);    // draw string: "hello", (0, 180), size: 3, color: CYAN
 +
   
 +
  TFT_drawString("World!!",60,220,4,WHITE,BLACK); // draw string: "world!!", (80, 230), size: 4, color: WHITE
 +
// loop
 +
  while(1) {
 +
                             
 +
//  TFT_backlight_on(); 
 +
//  _delay_ms(1000);                       
 +
//  TFT_backlight_off(); 
 +
//  _delay_ms(1000);
 +
//  TFT_fillScreen(0, 239, 0, 319, GREEN);
 +
  TFT_drawLine(0,0,239,319,RED);            //start: (0, 0) end: (239, 319), color : RED
 +
 
 +
  TFT_drawVerticalLine(60,100,100,GREEN);  // Draw a vertical line
 +
                                              // start: (60, 100) length: 100 color: green
 +
                                       
 +
  TFT_drawHorizontalLine(30,60,150,BLUE);  //Draw a horizontal line
 +
                                              //start: (30, 60), high: 150, color: blue
 +
  }
 +
  return 0;
 +
}
 +
*/
 +
 +
void setup() {
 +
  // put your setup code here, to run once:
 +
  pinMode(31,OUTPUT); // P3.1 = 31 = DC
 +
  pinMode(13,OUTPUT); //SSEL = CS = P3.6 = 18
 +
  pinMode(2,OUTPUT); //led = = P6.0 = 2
 +
  pinMode(17,OUTPUT);  // RST = P5.7 = 17
 +
  pinMode(RED_LED,OUTPUT);
 +
  pinMode(PIN_MISO,INPUT);
 +
  pinMode(PIN_MOSI,OUTPUT);
 +
  pinMode(PIN_SCK,OUTPUT);
 +
  SPI.begin();
 +
 
 +
}
 +
 +
void loop() {
 +
  byte frame[ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y];
 +
  uint8_t cmpt=0;
 +
  uint16_t gris;
 +
//*********************** gestion camera **********************
 +
 
 +
  SPI.setClockDivider(SPI_CLOCK_DIV32);
 +
  SPI.setDataMode(SPI_MODE3);
 +
  SPI.setBitOrder(MSBFIRST);
 +
  if(mousecam_init()==-1)
 +
  {
 +
    //Serial.println("Mouse cam failed to init");
 +
    while(1);
 +
  }
 +
 
 +
  // put your main code here, to run repeatedly:
 +
  //  TFT_backlight_on(); 
 +
//  _delay_ms(1000);                       
 +
//  TFT_backlight_off(); 
 +
//  _delay_ms(1000);
 +
//  TFT_fillScreen(0, 239, 0, 319, GREEN);
 +
/*
 +
  TFT_drawLine(0,0,239,319,RED);            //start: (0, 0) end: (239, 319), color : RED
 +
 
 +
  TFT_drawVerticalLine(60,100,100,GREEN);  // Draw a vertical line
 +
                                              // start: (60, 100) length: 100 color: green
 +
                                       
 +
  TFT_drawHorizontalLine(30,60,150,BLUE);  //Draw a horizontal line
 +
                                              //start: (30, 60), high: 150, color: blue
 +
 +
  delay(500);
 +
  cmpt++;
 +
 
 +
 
 +
  if (cmpt & 0x01)  digitalWrite(RED_LED,HIGH); else  digitalWrite(RED_LED,LOW);
 +
  //Serial.println("Bonjour");
 +
  */
 +
 
 +
  if(mousecam_frame_capture(frame)==0) {
 +
//*********** Gestion écran *************
 +
    //SPI.begin();
 +
  SPI.setClockDivider(SPI_CLOCK_DIV8);
 +
  SPI.setDataMode(SPI_MODE0);
 +
  SPI.setBitOrder(MSBFIRST);
 +
  //Serial.begin(9600);
 +
    TFT_TFTinit();
 +
    TFT_backlight_on();    // turn on the background light
 +
  //TFT_fillScreen(0, 240, 0,320, GREEN);
 +
    for (int j=0; j<=32; j++){
 +
      for (int i=0;i<32;i++) {
 +
        gris =frame[j+32*i]+ (frame[j+32*i] << 6) + (frame[j+32*i]<<11) ;
 +
        TFT_fillRectangle(7*i,9*j, 5, 7, gris);
 +
        //TFT_fillCircle(7.5*i,9*j, 4,  gris);
 +
     
 +
      } // for 
 +
    } // for
 +
  } //  if(mousecam_frame_capture(frame)==0)
 +
  delay(10000);
 +
}
 +
 +
 +
void TFT_sendCMD(uint8_t index)
 +
{
 +
  /*
 +
  PORTC &= 0xF7; // CD low
 +
  PORTC &= 0xFB; // SSEL=CS = Low
 +
  SPI_transfer(index);
 +
  PORTC |= 0x04; // SSEL=CS = high
 +
  */
 +
  // CD = P3.7 = 31
 +
  digitalWrite(31,LOW);
 +
  //SSEL = CS = P3.6 = 13
 +
  digitalWrite(13,LOW);
 +
  SPI.transfer(index);
 +
  digitalWrite(13,HIGH); 
 +
}
 +
 +
void TFT_WRITE_DATA(uint8_t data)
 +
{
 +
  /*
 +
  PORTC |= 0x08; // CD High
 +
  PORTC &= 0xFB; // SSEL=CS = Low
 +
  SPI_transfer(data);
 +
  PORTC |= 0x04; // SSEL=CS = High
 +
*/ 
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
  SPI.transfer(data);
 +
  digitalWrite(13,HIGH);
 +
}
 +
 +
void TFT_sendData(uint16_t data)
 +
{
 +
  uint8_t data1 = data>>8;
 +
  uint8_t data2 = data&0xff;
 +
/*  PORTC |= 0x08; // CD High
 +
  PORTC &= 0xFB; // SSEL=CS =Low
 +
  SPI_transfer(data1);
 +
  SPI_transfer(data2);
 +
  PORTC |= 0x04; // SSEL=CS high
 +
*/
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
  SPI.transfer(data1);
 +
  SPI.transfer(data2);
 +
  digitalWrite(13,HIGH);
 +
}
 +
 +
void TFT_WRITE_Package(uint16_t *data, uint8_t howmany)
 +
{
 +
  uint8_t  data1 = 0;
 +
  uint8_t  data2 = 0;
 +
/*
 +
  PORTC |= 0x08; // CD High
 +
  PORTC &= 0xFB; // SSEL=CS low
 +
  uint8_t count=0;
 +
  for(count=0;count<howmany;count++)
 +
  {
 +
      data1 = data[count]>>8;
 +
      data2 = data[count]&0xff;
 +
      SPI_transfer(data1);
 +
      SPI_transfer(data2);
 +
  }
 +
  PORTC |= 0x04; // SSEL=CS
 +
  */
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
  uint8_t count=0;
 +
  for(count=0;count<howmany;count++)
 +
  {
 +
      data1 = data[count]>>8;
 +
      data2 = data[count]&0xff;
 +
      SPI.transfer(data1);
 +
      SPI.transfer(data2);
 +
  }
 +
  digitalWrite(13,HIGH);
 +
}
 +
 +
void TFT_backlight_on(void)
 +
{
 +
  //PORTC |= 0x20; 
 +
  digitalWrite(2,HIGH); //led = = P6.0 = 2
 +
}
 +
 +
 +
void TFT_backlight_off(void)
 +
{
 +
  //PORTC &= 0xDF;//LED off
 +
  digitalWrite(2,LOW); //led = = P6.0 = 2
 +
}
 +
 +
uint8_t TFT_Read_Register(uint8_t Addr, uint8_t xParameter)
 +
{
 +
  uint8_t data=0;
 +
 +
  /*
 +
  TFT_sendCMD(0xd9);                                                 
 +
  TFT_WRITE_DATA(0x10+xParameter);
 +
  PORTC &= 0xF7; // CD low                                 
 +
  PORTC &= 0xFB; // SSEL=CS low
 +
  SPI_transfer(Addr);
 +
  PORTC |= 0x08; // CD high
 +
  data = SPI_transfer(0);
 +
  PORTC |= 0x04; // SSEL=CS high
 +
  */
 +
  TFT_sendCMD(0xd9);                                                    /* ext command                */
 +
  TFT_WRITE_DATA(0x10+xParameter);
 +
  digitalWrite(31,LOW); // CD = P3.7 = 31
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
  SPI.transfer(Addr);
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  data = SPI.transfer(0);
 +
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
 +
  return data;
 +
}
 +
 +
void TFT_TFTinit(void)
 +
{
 +
 +
  //PORTC |= 0x04; // SSEL=CS high
 +
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
 +
  //PORTC &= 0xFB; // SSEL=CS low
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
    // PORTC &= 0xF7; // CD low
 +
  digitalWrite(31,LOW); // CD = P3.7 = 31
 +
  //PORTC &= 0xDF;//LED off
 +
  digitalWrite(2,LOW); //led = = P6.0 = 2
 +
  //PORTC &= 0xEF; // RST low
 +
  digitalWrite(17,LOW); // RST = P5.7 = 17
 +
      // b3=CPOL, b2=CPHA, b1=SPR1 b0=SPR0
 +
      //SPCR &= ~((1<<CPOL) | (1<<CPHA)); // mode 0
 +
      //SPCR |= (1<<SPR1); // poids faible division = 2
 +
      //SPSR |= (1 << 1); // poids fort division = 8
 +
  SPI.begin();
 +
  SPI.setDataMode(SPI_MODE0);
 +
  SPI.setBitOrder(MSBFIRST);
 +
  SPI.setClockDivider(SPI_CLOCK_DIV16);
 +
  //SPI_transfer(0);  // Strawman transfer, fixes USCI issue on G2553
 +
  SPI.transfer(0);
 +
  //    PORTC |= 0x04; // SSEL=CS high ????
 +
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
 +
  //    PORTC |= 0x08; // CD high
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  //    PORTC |= 3;  // DEBUG ou cela bloque-t-il ?
 +
  uint8_t i=0, TFTDriver=0;
 +
 +
  //PORTC &= 0xEF; // RST low
 +
  digitalWrite(17,LOW); // RST = P5.7 = 17
 +
  delay(10);
 +
  //PORTC |= 0x10; // RST high
 +
  digitalWrite(17,HIGH); // RST = P5.7 = 17
 +
 +
  for(i=0;i<3;i++)
 +
  {
 +
      TFTDriver = TFT_readID();
 +
  }
 +
 +
  TFT_sendCMD(0xCB); 
 +
  TFT_WRITE_DATA(0x39);
 +
  TFT_WRITE_DATA(0x2C);
 +
  TFT_WRITE_DATA(0x00);
 +
  TFT_WRITE_DATA(0x34);
 +
  TFT_WRITE_DATA(0x02);
 +
 +
  TFT_sendCMD(0xCF); 
 +
  TFT_WRITE_DATA(0x00);
 +
  TFT_WRITE_DATA(0XC1);
 +
  TFT_WRITE_DATA(0X30);
 +
 +
  TFT_sendCMD(0xE8); 
 +
  TFT_WRITE_DATA(0x85);
 +
  TFT_WRITE_DATA(0x00);
 +
  TFT_WRITE_DATA(0x78);
 +
 +
  TFT_sendCMD(0xEA); 
 +
  TFT_WRITE_DATA(0x00);
 +
  TFT_WRITE_DATA(0x00);
 +
 +
  TFT_sendCMD(0xED); 
 +
  TFT_WRITE_DATA(0x64);
 +
  TFT_WRITE_DATA(0x03);
 +
  TFT_WRITE_DATA(0X12);
 +
  TFT_WRITE_DATA(0X81);
 +
 +
  TFT_sendCMD(0xF7); 
 +
  TFT_WRITE_DATA(0x20);
 +
 +
  TFT_sendCMD(0xC0);    //Power control
 +
  TFT_WRITE_DATA(0x23);  //VRH[5:0]
 +
 +
  TFT_sendCMD(0xC1);    //Power control
 +
  TFT_WRITE_DATA(0x10);  //SAP[2:0];BT[3:0]
 +
 +
  TFT_sendCMD(0xC5);    //VCM control
 +
  TFT_WRITE_DATA(0x3e);  //Contrast
 +
  TFT_WRITE_DATA(0x28);
 +
 +
  TFT_sendCMD(0xC7);    //VCM control2
 +
  TFT_WRITE_DATA(0x86); //--
 +
 +
  TFT_sendCMD(0x36);    // Memory Access Control
 +
  TFT_WRITE_DATA(0x48);  //C8  //48 68绔栧睆//28 E8 妯睆
 +
 +
  TFT_sendCMD(0x3A);   
 +
  TFT_WRITE_DATA(0x55);
 +
 +
  TFT_sendCMD(0xB1);   
 +
  TFT_WRITE_DATA(0x00); 
 +
  TFT_WRITE_DATA(0x13);
 +
 +
  TFT_sendCMD(0xB6);    // Display Function Control
 +
  TFT_WRITE_DATA(0x08);
 +
  TFT_WRITE_DATA(0x82);
 +
  TFT_WRITE_DATA(0x27); 
 +
 +
  TFT_sendCMD(0xF2);    // 3Gamma Function Disable
 +
  TFT_WRITE_DATA(0x00);
 +
 +
  TFT_sendCMD(0x26);    //Gamma curve selected
 +
  TFT_WRITE_DATA(0x01);
 +
 +
  TFT_sendCMD(0xE0);    //Set Gamma
 +
  TFT_WRITE_DATA(0x0F);
 +
  TFT_WRITE_DATA(0x31);
 +
  TFT_WRITE_DATA(0x2B);
 +
  TFT_WRITE_DATA(0x0C);
 +
  TFT_WRITE_DATA(0x0E);
 +
  TFT_WRITE_DATA(0x08);
 +
  TFT_WRITE_DATA(0x4E);
 +
  TFT_WRITE_DATA(0xF1);
 +
  TFT_WRITE_DATA(0x37);
 +
  TFT_WRITE_DATA(0x07);
 +
  TFT_WRITE_DATA(0x10);
 +
  TFT_WRITE_DATA(0x03);
 +
  TFT_WRITE_DATA(0x0E);
 +
  TFT_WRITE_DATA(0x09);
 +
  TFT_WRITE_DATA(0x00);
 +
 +
  TFT_sendCMD(0XE1);    //Set Gamma
 +
  TFT_WRITE_DATA(0x00);
 +
  TFT_WRITE_DATA(0x0E);
 +
  TFT_WRITE_DATA(0x14);
 +
  TFT_WRITE_DATA(0x03);
 +
  TFT_WRITE_DATA(0x11);
 +
  TFT_WRITE_DATA(0x07);
 +
  TFT_WRITE_DATA(0x31);
 +
  TFT_WRITE_DATA(0xC1);
 +
  TFT_WRITE_DATA(0x48);
 +
  TFT_WRITE_DATA(0x08);
 +
  TFT_WRITE_DATA(0x0F);
 +
  TFT_WRITE_DATA(0x0C);
 +
  TFT_WRITE_DATA(0x31);
 +
  TFT_WRITE_DATA(0x36);
 +
  TFT_WRITE_DATA(0x0F);
 +
 +
  TFT_sendCMD(0x11);    //Exit Sleep
 +
  delay(120);
 +
 +
  TFT_sendCMD(0x29);  //Display on
 +
  TFT_sendCMD(0x2c); 
 +
  TFT_fillScreen2();
 +
}
 +
 +
uint8_t TFT_readID(void)
 +
{
 +
  uint8_t i=0;
 +
  uint8_t data[3] ;
 +
  uint8_t ID[3] = {0x00, 0x93, 0x41};
 +
  uint8_t ToF=1;
 +
  for(i=0;i<3;i++)
 +
  {
 +
      data[i]=TFT_Read_Register(0xd3,i+1);
 +
      if(data[i] != ID[i])
 +
      {
 +
          ToF=0;
 +
      }
 +
  }
 +
   
 +
  return ToF;
 +
}
 +
 +
void TFT_setCol(uint16_t StartCol,uint16_t EndCol)
 +
{
 +
  TFT_sendCMD(0x2A);                                                    /* Column Command address    */
 +
  TFT_sendData(StartCol);
 +
  TFT_sendData(EndCol);
 +
}
 +
 +
void TFT_setPage(uint16_t StartPage,uint16_t EndPage)
 +
{
 +
  TFT_sendCMD(0x2B);                                                    /* Column Command address    */
 +
  TFT_sendData(StartPage);
 +
  TFT_sendData(EndPage);
 +
}
 +
 +
void TFT_fillScreen(uint16_t XL, uint16_t XR, uint16_t YU, uint16_t YD, uint16_t color)
 +
{
 +
  unsigned long  XY=0;
 +
  unsigned long i=0;
 +
 +
  if(XL > XR)
 +
  {
 +
      XL = XL^XR;
 +
      XR = XL^XR;
 +
      XL = XL^XR;
 +
  }
 +
  if(YU > YD)
 +
  {
 +
      YU = YU^YD;
 +
      YD = YU^YD;
 +
      YU = YU^YD;
 +
  }
 +
//*********** a redefinir la fonction constrain !!!!!!!!!!!!!!!!!!
 +
  //XL = constrain(XL, MIN_X,MAX_X);
 +
  //XR = constrain(XR, MIN_X,MAX_X);
 +
  //YU = constrain(YU, MIN_Y,MAX_Y);
 +
  //YD = constrain(YD, MIN_Y,MAX_Y);
 +
 +
  XY = (XR-XL+1);
 +
  XY = XY*(YD-YU+1);
 +
 +
  TFT_setCol(XL,XR);
 +
  TFT_setPage(YU, YD);
 +
  TFT_sendCMD(0x2c);                                                /* start to write to display ra */
 +
                                                                      /* m                          */
 +
  //PORTC |= 0x08; // CD high
 +
  //PORTC &= 0xFB; // SSEL=CS low
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
 +
  uint8_t Hcolor = color>>8;
 +
  uint8_t Lcolor = color&0xff;
 +
  for(i=0; i < XY; i++)
 +
  {
 +
      SPI.transfer(Hcolor);
 +
      SPI.transfer(Lcolor);
 +
  }
 +
 +
  //PORTC |= 0x04; // SSEL=CS high
 +
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
 +
}
 +
 +
void TFT_fillScreen2(void)
 +
{
 +
  uint16_t i;
 +
  TFT_setCol(0, 239);
 +
  TFT_setPage(0, 319);
 +
  TFT_sendCMD(0x2c);                                                /* start to write to display ra */
 +
                                                                      /* m                          */
 +
  //PORTC |= 0x08; // CD high
 +
  //PORTC &= 0xFB; // SSEL=CS low
 +
  digitalWrite(31,HIGH); // CD = P3.7 = 31
 +
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
 +
  for(i=0; i<38400; i++)
 +
  {
 +
    /* SPI_transfer(0);
 +
      SPI_transfer(0);
 +
      SPI_transfer(0);
 +
      SPI_transfer(0);*/
 +
      SPI.transfer(0);
 +
      SPI.transfer(0);
 +
      SPI.transfer(0);
 +
      SPI.transfer(0);
 +
  }
 +
  //PORTC |= 0x04; // SSEL=CS high
 +
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
 +
}
 +
 +
 +
void TFT_setXY(uint16_t poX, uint16_t poY)
 +
{
 +
  TFT_setCol(poX, poX);
 +
  TFT_setPage(poY, poY);
 +
  TFT_sendCMD(0x2c);
 +
}
 +
 +
void TFT_setPixel(uint16_t poX, uint16_t poY,uint16_t color)
 +
{
 +
  TFT_setXY(poX, poY);
 +
  TFT_sendData(color);
 +
}
 +
 +
void TFT_drawChar( uint8_t ascii, uint16_t poX, uint16_t poY,uint16_t size, uint16_t fgcolor, uint16_t bgcolor)
 +
{
 +
 +
  //fillRectangle(poX, poY, poX+FONT_X*size, poY+FONT_Y*size, BLACK);
 +
  int i;
 +
  uint8_t f;
 +
 +
  if((ascii>=32)&&(ascii<=127))
 +
  {
 +
      ;
 +
  }
 +
  else
 +
  {
 +
      ascii = '?'-32;
 +
  }
 +
  for (i =0; i<FONT_X; i++ ) {
 +
      uint8_t temp = simpleFont[ascii-0x20][i];
 +
      for(f=0;f<8;f++)
 +
      {
 +
          if((temp>>f)&0x01)
 +
          {
 +
              TFT_fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor);
 +
          }
 +
    else
 +
  TFT_fillRectangle(poX+i*size, poY+f*size, size, size, bgcolor);
 +
 +
      }
 +
 +
  }
 +
}
 +
 +
void TFT_drawString(char *string,uint16_t poX, uint16_t poY, uint16_t size,uint16_t fgcolor, uint16_t bgcolor)
 +
{
 +
  while(*string)
 +
  {
 +
      TFT_drawChar(*string, poX, poY, size, fgcolor, bgcolor);
 +
      *string++;
 +
 +
      if(poX < MAX_X)
 +
      {
 +
          poX += FONT_SPACE*size;                                  /* Move cursor right          */
 +
      }
 +
  }
 +
}
 +
 +
//fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor);
 +
void TFT_fillRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width, uint16_t color)
 +
{
 +
  TFT_fillScreen(poX, poX+length, poY, poY+width, color);
 +
}
 +
 +
void  TFT_drawHorizontalLine( uint16_t poX, uint16_t poY,
 +
uint16_t length,uint16_t color)
 +
{
 +
  int i;
 +
  TFT_setCol(poX,poX + length);
 +
  TFT_setPage(poY,poY);
 +
  TFT_sendCMD(0x2c);
 +
  for(i=0; i<length; i++)
 +
  TFT_sendData(color);
 +
}
 +
 +
 +
int abs(int data) {
 +
  if (data > 0) return data; else return -data;
 +
}
 +
 +
void TFT_drawLine( uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1,uint16_t color)
 +
{
 +
 +
  int x = x1-x0;
 +
  int y = y1-y0;
 +
  int dx = abs(x), sx = x0<x1 ? 1 : -1;
 +
  int dy = -abs(y), sy = y0<y1 ? 1 : -1;
 +
  int err = dx+dy, e2;                                              /* error value e_xy          */
 +
  for (;;){                                                        /* loop                      */
 +
      TFT_setPixel(x0,y0,color);
 +
      e2 = 2*err;
 +
      if (e2 >= dy) {                                              /* e_xy+e_x > 0              */
 +
          if (x0 == x1) break;
 +
          err += dy; x0 += sx;
 +
      }
 +
      if (e2 <= dx) {                                              /* e_xy+e_y < 0              */
 +
          if (y0 == y1) break;
 +
          err += dx; y0 += sy;
 +
      }
 +
  }
 +
 +
}
 +
 +
void TFT_drawVerticalLine( uint16_t poX, uint16_t poY, uint16_t length,uint16_t color)
 +
{
 +
  int i;
 +
  TFT_setCol(poX,poX);
 +
  TFT_setPage(poY,poY+length);
 +
  TFT_sendCMD(0x2c);
 +
  for(i=0; i<length; i++)
 +
  TFT_sendData(color);
 +
}
 +
 +
void TFT_drawRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width,uint16_t color)
 +
{
 +
  TFT_drawHorizontalLine(poX, poY, length, color);
 +
  TFT_drawHorizontalLine(poX, poY+width, length, color);
 +
  TFT_drawVerticalLine(poX, poY, width,color);
 +
  TFT_drawVerticalLine(poX + length, poY, width,color);
 +
 +
}
 +
 +
void TFT_drawCircle(int poX, int poY, int r,uint16_t color)
 +
{
 +
  int x = -r, y = 0, err = 2-2*r, e2;
 +
  do {
 +
      TFT_setPixel(poX-x, poY+y,color);
 +
      TFT_setPixel(poX+x, poY+y,color);
 +
      TFT_setPixel(poX+x, poY-y,color);
 +
      TFT_setPixel(poX-x, poY-y,color);
 +
      e2 = err;
 +
      if (e2 <= y) {
 +
          err += ++y*2+1;
 +
          if (-x == y && e2 <= x) e2 = 0;
 +
      }
 +
      if (e2 > x) err += ++x*2+1;
 +
  } while (x <= 0);
 +
}
 +
 +
void TFT_fillCircle(int poX, int poY, int r,uint16_t color)
 +
{
 +
  int x = -r, y = 0, err = 2-2*r, e2;
 +
  do {
 +
 +
      TFT_drawVerticalLine(poX-x, poY-y, 2*y, color);
 +
      TFT_drawVerticalLine(poX+x, poY-y, 2*y, color);
 +
 +
      e2 = err;
 +
      if (e2 <= y) {
 +
          err += ++y*2+1;
 +
          if (-x == y && e2 <= x) e2 = 0;
 +
      }
 +
      if (e2 > x) err += ++x*2+1;
 +
  } while (x <= 0);
 +
 +
}
 +
 +
void TFT_drawTraingle( int poX1, int poY1, int poX2, int poY2, int poX3, int poY3, uint16_t color)
 +
{
 +
  TFT_drawLine(poX1, poY1, poX2, poY2,color);
 +
  TFT_drawLine(poX1, poY1, poX3, poY3,color);
 +
  TFT_drawLine(poX2, poY2, poX3, poY3,color);
 +
}
 +
 +
uint8_t TFT_drawNumber(long long_num,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor)
 +
{
 +
  uint8_t char_buffer[10] = "";
 +
  uint8_t i = 0;
 +
  uint8_t f = 0;
 +
 +
 +
  if (long_num < 0)
 +
  {
 +
      f=1;
 +
      TFT_drawChar('-',poX, poY, size, fgcolor, bgcolor);
 +
      long_num = -long_num;
 +
      if(poX < MAX_X)
 +
      {
 +
          poX += FONT_SPACE*size;                                  /* Move cursor right          */
 +
      }
 +
  }
 +
  else if (long_num == 0)
 +
  {
 +
      f=1;
 +
      TFT_drawChar('0',poX, poY, size, fgcolor, bgcolor);
 +
      return f;
 +
      if(poX < MAX_X)
 +
      {
 +
          poX += FONT_SPACE*size;                                  /* Move cursor right          */
 +
      }
 +
  }
 +
 +
 +
  while (long_num > 0)
 +
  {
 +
      char_buffer[i++] = long_num % 10;
 +
      long_num /= 10;
 +
  }
 +
 +
  f = f+i;
 +
  for(; i > 0; i--)
 +
  {
 +
      TFT_drawChar('0'+ char_buffer[i - 1],poX, poY, size, fgcolor, bgcolor);
 +
      if(poX < MAX_X)
 +
      {
 +
          poX+=FONT_SPACE*size;                                    /* Move cursor right          */
 +
      }
 +
  }
 +
  return f;
 +
}
 +
 +
uint8_t TFT_drawFloat(float floatNumber,uint8_t decimal,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor)
 +
{
 +
  uint16_t temp=0;
 +
  float decy=0.0;
 +
  float rounding = 0.5;
 +
  uint8_t f=0;
 +
  uint8_t i;
 +
  if(floatNumber<0.0)
 +
  {
 +
      TFT_drawChar('-',poX, poY, size, fgcolor, bgcolor);
 +
      floatNumber = -floatNumber;
 +
      if(poX < MAX_X)
 +
      {
 +
          poX+=FONT_SPACE*size;                                    /* Move cursor right          */
 +
      }
 +
      f =1;
 +
  }
 +
  for (i=0; i<decimal; ++i)
 +
  {
 +
      rounding /= 10.0;
 +
  }
 +
  floatNumber += rounding;
 +
 +
  temp = (uint16_t)floatNumber;
 +
  uint8_t howlong=TFT_drawNumber(temp,poX, poY, size, fgcolor, bgcolor);
 +
  f += howlong;
 +
  if((poX+8*size*howlong) < MAX_X)
 +
  {
 +
      poX+=FONT_SPACE*size*howlong;                                /* Move cursor right          */
 +
  }
 +
 +
  if(decimal>0)
 +
  {
 +
      TFT_drawChar('.',poX, poY, size, fgcolor, bgcolor);
 +
      if(poX < MAX_X)
 +
      {
 +
          poX+=FONT_SPACE*size;                                    /* Move cursor right          */
 +
      }
 +
      f +=1;
 +
  }
 +
  decy = floatNumber-temp;                                          /* decimal part,  4          */
 +
  for(i=0;i<decimal;i++)                                 
 +
  {
 +
      decy *=10;                                                    /* for the next decimal      */
 +
      temp = decy;                                                  /* get the decimal            */
 +
      TFT_drawNumber(temp,poX, poY, size, fgcolor, bgcolor);
 +
      floatNumber = -floatNumber;
 +
      if(poX < MAX_X)
 +
      {
 +
          poX+=FONT_SPACE*size;                                    /* Move cursor right          */
 +
      }
 +
      decy -= temp;
 +
  }
 +
  f +=decimal;
 +
  return f;
 +
}
 +
 +
 +
void mousecam_reset()
 +
{
 +
  digitalWrite(PIN_MOUSECAM_RESET,HIGH);
 +
  delay(1); // reset pulse >10us
 +
  digitalWrite(PIN_MOUSECAM_RESET,LOW);
 +
  delay(35); // 35ms from reset to functional
 +
}
 +
 +
int mousecam_init()
 +
{
 +
  pinMode(PIN_MOUSECAM_RESET,OUTPUT);
 +
  pinMode(PIN_MOUSECAM_CS,OUTPUT);
 +
 
 +
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
 +
 
 +
  mousecam_reset();
 +
 
 +
  int pid = mousecam_read_reg(ADNS3080_PRODUCT_ID);
 +
  if(pid != ADNS3080_PRODUCT_ID_VAL)
 +
    return -1;
 +
 +
  // turn on sensitive mode
 +
  mousecam_write_reg(ADNS3080_CONFIGURATION_BITS, 0x19);
 +
 +
  return 0;
 +
}
 +
 +
void mousecam_write_reg(int reg, int val)
 +
{
 +
  digitalWrite(PIN_MOUSECAM_CS, LOW);
 +
  SPI.transfer(reg | 0x80);
 +
  SPI.transfer(val);
 +
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
 +
  delayMicroseconds(50);
 +
}
 +
 +
int mousecam_read_reg(int reg)
 +
{
 +
  digitalWrite(PIN_MOUSECAM_CS, LOW);
 +
  SPI.transfer(reg);
 +
  delayMicroseconds(75);
 +
  int ret = SPI.transfer(0xff);
 +
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
 +
  delayMicroseconds(1);
 +
  return ret;
 +
}
 +
 +
void mousecam_read_motion(struct MD *p)
 +
{
 +
  digitalWrite(PIN_MOUSECAM_CS, LOW);
 +
  SPI.transfer(ADNS3080_MOTION_BURST);
 +
  delayMicroseconds(75);
 +
  p->motion =  SPI.transfer(0xff);
 +
  p->dx =  SPI.transfer(0xff);
 +
  p->dy =  SPI.transfer(0xff);
 +
  p->squal =  SPI.transfer(0xff);
 +
  p->shutter =  SPI.transfer(0xff)<<8;
 +
  p->shutter |=  SPI.transfer(0xff);
 +
  p->max_pix =  SPI.transfer(0xff);
 +
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
 +
  delayMicroseconds(5);
 +
}
 +
 +
// pdata must point to an array of size ADNS3080_PIXELS_X x ADNS3080_PIXELS_Y
 +
// you must call mousecam_reset() after this if you want to go back to normal operation
 +
int mousecam_frame_capture(byte *pdata)
 +
{
 +
  mousecam_write_reg(ADNS3080_FRAME_CAPTURE,0x83);
 +
 
 +
  digitalWrite(PIN_MOUSECAM_CS, LOW);
 +
 
 +
  SPI.transfer(ADNS3080_PIXEL_BURST);
 +
  delayMicroseconds(50);
 +
 
 +
  int pix;
 +
  byte started = 0;
 +
  int count;
 +
  int timeout = 0;
 +
  int ret = 0;
 +
  for(count = 0; count < ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y; )
 +
  {
 +
    pix = SPI.transfer(0xff);
 +
    delayMicroseconds(10);
 +
    if(started==0)
 +
    {
 +
      if(pix&0x40)
 +
        started = 1;
 +
      else
 +
      {
 +
        timeout++;
 +
        if(timeout==100)
 +
        {
 +
          ret = -1;
 +
          break;
 +
        }
 +
      }
 +
    }
 +
    if(started==1)
 +
    {
 +
      pdata[count++] = (pix & 0x3f)<<2; // scale to normal grayscale byte range
 +
    }
 +
  }
 +
 +
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
 +
  delayMicroseconds(14);
 +
 
 +
  return ret;
 +
}
 +
</source>
 +
 +
=Robotique mobile : Coupe de France des IUT GEII 2020 =
 +
Il s'agit donc de préparer un robot pour la Coupe de France des IUT GEII 2020. Pour voir de quoi il s'agit, vous pouvez regarder [http://www.festivalrobotiquecachan.fr/edition-2019/coupe-de-france-des-iut-geii-2019/ la version 2019 ICI].
 +
 +
Le règlement 2020 est disponible. Il a été validé lors de la réunion du 17 octobre 2019 à Cachan par l'ensemble des participant :
 +
 +
[https://drive.google.com/file/d/1JnPi6Ug5wbRR7LcKigHnS9gUkkDZYa6v/view?usp=sharing Reglement 2020]
 +
 +
Les principales nouveautés pour 2020 sont :
 +
 +
*Les étudiants de Licence Pro ont le droit de participer.
 +
 +
*Plus besoin d'être au filet pour marquer des points. Les robots doivent toujours crever un ballon pour valider leur score, mais il n'est plus nécessaire d'être dans la bande du filet pour marquer, il suffit juste que le robot soit arrêté, où que se soit, et qu'il ne bouge plus pour avoir le droit de crever le ballon. En revanche, le faire au filet rapporte 3 points supplémentaires.
 +
 +
*La base mobile du robot (châssis, moteurs, transmissions, roues et batterie) n'est plus obligatoire, elle est juste recommandée, mais on peut utiliser tout type de moteur, châssis, roue, transmission ou batterie à condition qu'ils respectent les contraintes du règlement :
 +
*Pas plus de 24V de tension dans le robot.
 +
*Pas plus de 2 roues motrices.
 +
*Le seul contact entre les roues motrices et le sol doit obligatoirement être un joint torique de référence Oring 133610.
 +
*Pas de batteries Lithium Polymère, ou Lithium Cobalt (voir tous les détails concernant les batteries en technologie Lithium dans le règlement).
 +
==Voir aussi==
 +
*[https://www.youtube.com/watch?v=JPPTRj0KWbg TB6612FNG H-Bridge Motor Controller - Better than L298N?]
 +
*[https://fr.wikiversity.org/wiki/Micro_contr%C3%B4leurs_AVR/Travail_pratique/Utilisation_du_MPU9250 Utilisation du MPU9250 (9DOF)]
 +
 
=Projet robotique mobile : challenge GEII/GMP=
 
=Projet robotique mobile : challenge GEII/GMP=
==Utilisation d'un moteur pas à pas==
+
La réalisation de ce projet nécessitera deux binômes.
 +
* un binôme s'occupera du déplacement et de ramener les cylindres dans notre camp
 +
* l'autre binôme sera responsable de l'empilement des cylindres
 +
Ce projet devra être complètement fonctionnel en fin de S3 à l'aide de deux télécommandes.
 +
 
 +
Il sera poursuivi sur S4 avec comme objectif de le rendre autonome.
 +
 
 +
{{Aide|Comment commencer ?}}
 +
 
 +
 
 +
 
 +
 
 +
 
 +
Vous devez essayer de rédiger avec le plus de détail (pas forcément technique) un scénario décrivant l'exécution du challenge. Pour vous aider dans vos démarches, [[Media:Réglement_RM_V20.pdf|Le règlement 2020]] est consultable maintenant.
 +
 
 +
{{finAide}}
 +
 
 +
 
 +
==Indications : Utilisation d'un moteur pas à pas==
 
===Utilisation du shield CNC===
 
===Utilisation du shield CNC===
 
Ce [http://osoyoo.com/2017/04/07/arduino-uno-cnc-shield-v3-0-a4988/ shield CNC] est en principe dédié aux imprimantes 3D et notre version utilise la commande de puissance A4988. Nous utilisons la partie réservée à l'axe Y. Trois broches sont nécessaires :
 
Ce [http://osoyoo.com/2017/04/07/arduino-uno-cnc-shield-v3-0-a4988/ shield CNC] est en principe dédié aux imprimantes 3D et notre version utilise la commande de puissance A4988. Nous utilisons la partie réservée à l'axe Y. Trois broches sont nécessaires :
Ligne 42 : Ligne 1 227 :
  
 
Nous étudierons une autre possibilité avec un [https://www.instructables.com/id/Control-DC-and-stepper-motors-with-L298N-Dual-Moto/ L298N].
 
Nous étudierons une autre possibilité avec un [https://www.instructables.com/id/Control-DC-and-stepper-motors-with-L298N-Dual-Moto/ L298N].
 +
 +
===Étude du L298N===
 +
 +
La carte [https://www.instructables.com/id/Control-DC-and-stepper-motors-with-L298N-Dual-Moto/ L298N et son utilisation est présentée ICI]. Il est donc facile de l'utiliser surtout associé à la [https://github.com/arduino-libraries/Stepper librairie Stepper (github)]. Le seul problème rencontré était dû au fait que la masse de l'Arduino et la masse du L298N n'étaient pas reliées.
 +
 +
==Voir aussi==
 +
*[https://fr.wikiversity.org/wiki/Micro_contr%C3%B4leurs_AVR/Travail_pratique/Utilisation_du_MPU9250 Utilisation du MPU9250 (9DOF)]

Version actuelle datée du 4 avril 2021 à 14:29

Projet GPS tracker

Ce que l'on cherche à réaliser est décrit dans cette vidéo : Arduino GPS tracker and Google Maps Tutorial ou ce cours de 49mn : LESSON 22: Build an Arduino GPS Tracker

Propeller clock

Ce projet est donné depuis un certain nombre d'années et va continuer encore cette année. Il se fera avec des Leds et non plus a bandeau de leds numérique (WS2812 rgb leds). Voir la vidéo : Arduino NANO Propeller LED Analog Clock

Vous pouvez trouver aussi un document explicatif avec un peu de code. Une autre technique utilisant un registre à décalage 74HC595 est présentée ICI.

Il vous est possible de choisir une autre technologie que le microcontrôleur, à savoir le FPGA.

Optical Flow

Ce projet peut concerner un ou deux binômes mais alors en concurrence. Autrement dit, s'il y a deux binômes il y a deux projets différents.

Ce que l'on cherche à faire est présenté dans cette vidéo : Arduino based pan-tilt optical flow tracking Vous disposerez de

  • tourelle pan/tilt et ses servomoteurs
  • Optical Flow Sensor APM2.5 improve position hold accuracy Multicopter ADNS 3080
  • Ecran 2,8'
  • microcontrôleur ou FPGA au choix

Du code pour lire le composant ADNS 3080 peut être trouvé sur gitHub :

Caractéristiques du capteur

  • Caractéristiques : ce capteur est basé sur le capteur de souris ADNS3080 qui est un bon choix pour le flux optique.
  • Haute résolution : images 30x30 pixels, ce qui signifie qu'il peut avoir des fonctionnalités que les petites souris ne peuvent pas avoir.
  • Haute vitesse : taux de mise à jour de 2000 à 6400 images par seconde, ce qui contribue à de meilleures performances de faible luminosité que les autres capteurs de souris.
  • Interface SPI, ce qui signifie qu'elle peut être interfacée à de nombreux micro-contrôleurs et coexistent avec d'autres capteurs.
  • Destiné à s'interfacer avec un microcontrôleur 5V.
  • Objectif de 8mm avec FOV de 11 degrés.
  • Monture d'objectif Standard M12x0.5, ce qui signifie que vous pouvez remplacer l'objectif facilement.

Instruction d'utilisation:

  • Il fonctionne bien dans les environnements extérieurs éclairés.
  • Il ne fonctionne pas bien avec les lumières fluorescentes (le clignotement perturbe le capteur).
  • Il faut une surface non uniforme pour voir le mouvement (les tapis unis ne sont pas son ami).

Solution intermédiaire : optical flow et écran avec MSP432

#include <SPI.h>

/*************************
* Carte SD ----- Launchpad
* TM4C123G (ARM)
* GND ----------- GND
* +3.3 ---------- Vcc
* CS ------------ PB5 (PB_5)
* MOSI ---------- PB7 (PB_7)
* SCK ----------- PB4 (PB_4)
* MISO ---------- PB6 (PB_6)
*
**************************/ 

//#define PIN_SS        PB_5
#define PIN_MISO      14
#define PIN_MOSI      15
#define PIN_SCK       7

#define PIN_MOUSECAM_RESET     17
#define PIN_MOUSECAM_CS        18

#define ADNS3080_PIXELS_X                 30
#define ADNS3080_PIXELS_Y                 30

#define ADNS3080_PRODUCT_ID            0x00
#define ADNS3080_REVISION_ID           0x01
#define ADNS3080_MOTION                0x02
#define ADNS3080_DELTA_X               0x03
#define ADNS3080_DELTA_Y               0x04
#define ADNS3080_SQUAL                 0x05
#define ADNS3080_PIXEL_SUM             0x06
#define ADNS3080_MAXIMUM_PIXEL         0x07
#define ADNS3080_CONFIGURATION_BITS    0x0a
#define ADNS3080_EXTENDED_CONFIG       0x0b
#define ADNS3080_DATA_OUT_LOWER        0x0c
#define ADNS3080_DATA_OUT_UPPER        0x0d
#define ADNS3080_SHUTTER_LOWER         0x0e
#define ADNS3080_SHUTTER_UPPER         0x0f
#define ADNS3080_FRAME_PERIOD_LOWER    0x10
#define ADNS3080_FRAME_PERIOD_UPPER    0x11
#define ADNS3080_MOTION_CLEAR          0x12
#define ADNS3080_FRAME_CAPTURE         0x13
#define ADNS3080_SROM_ENABLE           0x14
#define ADNS3080_FRAME_PERIOD_MAX_BOUND_LOWER      0x19
#define ADNS3080_FRAME_PERIOD_MAX_BOUND_UPPER      0x1a
#define ADNS3080_FRAME_PERIOD_MIN_BOUND_LOWER      0x1b
#define ADNS3080_FRAME_PERIOD_MIN_BOUND_UPPER      0x1c
#define ADNS3080_SHUTTER_MAX_BOUND_LOWER           0x1e
#define ADNS3080_SHUTTER_MAX_BOUND_UPPER           0x1e
#define ADNS3080_SROM_ID               0x1f
#define ADNS3080_OBSERVATION           0x3d
#define ADNS3080_INVERSE_PRODUCT_ID    0x3f
#define ADNS3080_PIXEL_BURST           0x40
#define ADNS3080_MOTION_BURST          0x50
#define ADNS3080_SROM_LOAD             0x60

#define ADNS3080_PRODUCT_ID_VAL        0x17



//Basic Colors
#define RED  0xf800
#define GREEN   0x07e0
#define BLUE  0x001f
#define BLACK   0x0000
#define YELLOW  0xffe0
#define WHITE   0xffff

//Other Colors
#define CYAN  0x07ff  
#define BRIGHT_RED  0xf810  
#define GRAY1   0x8410  
#define GRAY2   0x4208  

//TFT resolution 240*320
#define MIN_X   0
#define MIN_Y   0
#define MAX_X   239
#define MAX_Y   319

#define FONT_SPACE 6
#define FONT_X 8
#define FONT_Y 8


const uint8_t simpleFont[][8] =
{
  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
  {0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
  {0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
  {0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
  {0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
  {0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
  {0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
  {0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
  {0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
  {0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
  {0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
  {0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
  {0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
  {0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
  {0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
  {0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
  {0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
  {0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
  {0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
  {0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
  {0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
  {0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
  {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
  {0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
  {0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
  {0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
  {0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
  {0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
  {0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
  {0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
  {0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
  {0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
  {0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
  {0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
  {0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
  {0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
  {0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
  {0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
  {0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
  {0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
  {0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
  {0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
  {0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
  {0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
  {0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
  {0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
  {0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
  {0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
  {0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
  {0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
  {0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
  {0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
  {0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
  {0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
  {0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
  {0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
  {0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
  {0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
  {0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
  {0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
  {0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
  {0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
  {0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
  {0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
  {0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
  {0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
  {0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
  {0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
  {0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
  {0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
  {0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
  {0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
  {0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
  {0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
  {0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
  {0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
  {0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
  {0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
  {0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
  {0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
  {0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
  {0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
  {0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
  {0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
  {0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
  {0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
  {0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
  {0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
  {0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
  {0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
  {0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
};

void TFT_sendCMD(uint8_t index);
void TFT_WRITE_DATA(uint8_t data);
void TFT_sendData(uint16_t data);
void TFT_WRITE_Package(uint16_t *data, uint8_t howmany);
void TFT_backlight_on(void);
void TFT_backlight_off(void);
uint8_t TFT_Read_Register(uint8_t Addr, uint8_t xParameter);
void TFT_TFTinit (void);
uint8_t TFT_readID(void);
void TFT_setCol(uint16_t StartCol,uint16_t EndCol);
void TFT_setPage(uint16_t StartPage,uint16_t EndPage);
void TFT_fillScreen(uint16_t XL, uint16_t XR, uint16_t YU, uint16_t YD, uint16_t color);
void TFT_fillScreen2(void);
void TFT_setXY(uint16_t poX, uint16_t poY);
void TFT_setPixel(uint16_t poX, uint16_t poY,uint16_t color);
void TFT_drawChar( uint8_t ascii, uint16_t poX, uint16_t poY,uint16_t size, uint16_t fgcolor, uint16_t bgcolor);
void TFT_drawString(char *string,uint16_t poX, uint16_t poY, uint16_t size,uint16_t fgcolor, uint16_t bgcolor);
void TFT_fillRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width, uint16_t color);
void  TFT_drawHorizontalLine( uint16_t poX, uint16_t poY,uint16_t length,uint16_t color);
void TFT_drawLine( uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1,uint16_t color);
void TFT_drawVerticalLine( uint16_t poX, uint16_t poY, uint16_t length,uint16_t color);
void TFT_drawRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width,uint16_t color);
void TFT_drawCircle(int poX, int poY, int r,uint16_t color);
void TFT_fillCircle(int poX, int poY, int r,uint16_t color);
void TFT_drawTraingle( int poX1, int poY1, int poX2, int poY2, int poX3, int poY3, uint16_t color);
uint8_t TFT_drawNumber(long long_num,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor);
uint8_t TFT_drawFloat(float floatNumber,uint8_t decimal,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor);

uint8_t SPI_transfer(uint8_t data);
void SPI_init();

// CAMERA 
void mousecam_reset();
int mousecam_init();
void mousecam_write_reg(int reg, int val);
int mousecam_read_reg(int reg);

struct MD
{
 byte motion;
 char dx, dy;
 byte squal;
 word shutter;
 byte max_pix;
};

void mousecam_read_motion(struct MD *p);

// pdata must point to an array of size ADNS3080_PIXELS_X x ADNS3080_PIXELS_Y
// you must call mousecam_reset() after this if you want to go back to normal operation
int mousecam_frame_capture(byte *pdata);





/*
int main() {
  uint8_t i, t[4];
  uint16_t cmpt=0;
// init
//   SPI_init();
   
   TFT_TFTinit (); //init TFT library
   TFT_backlight_on();                          // turn on the background light
    
  TFT_drawChar('S',0,0,1,RED,BLACK);              // draw char: 'S', (0, 0), size: 1, color: RED
    
  TFT_drawChar('E',10,10,2,BLUE,BLACK);           // draw char: 'E', (10, 10), size: 2, color: BLUE
    
  TFT_drawChar('E',20,40,3,GREEN,BLACK);          // draw char: 'E', (20, 40), size: 3, color: GREEN
    
  TFT_drawChar('E',30,80,4,YELLOW,BLACK);         // draw char: 'E', (30, 80), size: 4, color: YELLOW
    
  TFT_drawChar('D',40,120,4,YELLOW,BLACK);        // draw char: 'D', (40, 120), size: 4, color: YELLOW
    
  TFT_drawString("Hello",0,180,3,CYAN,BLACK);     // draw string: "hello", (0, 180), size: 3, color: CYAN
    
  TFT_drawString("World!!",60,220,4,WHITE,BLACK); // draw string: "world!!", (80, 230), size: 4, color: WHITE
// loop
  while(1) {
                               
//  TFT_backlight_on();  
//  _delay_ms(1000);                         
//  TFT_backlight_off();  
//  _delay_ms(1000);
//  TFT_fillScreen(0, 239, 0, 319, GREEN);
  TFT_drawLine(0,0,239,319,RED);            //start: (0, 0) end: (239, 319), color : RED
   
  TFT_drawVerticalLine(60,100,100,GREEN);   // Draw a vertical line
                                              // start: (60, 100) length: 100 color: green
                                         
  TFT_drawHorizontalLine(30,60,150,BLUE);   //Draw a horizontal line
                                              //start: (30, 60), high: 150, color: blue
  }
  return 0;
}
*/

void setup() {
  // put your setup code here, to run once:
  pinMode(31,OUTPUT); // P3.1 = 31 = DC
  pinMode(13,OUTPUT); //SSEL = CS = P3.6 = 18
  pinMode(2,OUTPUT); //led = = P6.0 = 2
  pinMode(17,OUTPUT);  // RST = P5.7 = 17
  pinMode(RED_LED,OUTPUT);
  pinMode(PIN_MISO,INPUT);
  pinMode(PIN_MOSI,OUTPUT);
  pinMode(PIN_SCK,OUTPUT);
  SPI.begin();
  
}

void loop() {
  byte frame[ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y];
  uint8_t cmpt=0;
  uint16_t gris;
//*********************** gestion camera **********************
  
  SPI.setClockDivider(SPI_CLOCK_DIV32);
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  if(mousecam_init()==-1)
  {
    //Serial.println("Mouse cam failed to init");
    while(1);
  }
  
  // put your main code here, to run repeatedly:
  //  TFT_backlight_on();  
//  _delay_ms(1000);                         
//  TFT_backlight_off();  
//  _delay_ms(1000);
//  TFT_fillScreen(0, 239, 0, 319, GREEN);
/*
  TFT_drawLine(0,0,239,319,RED);            //start: (0, 0) end: (239, 319), color : RED
   
  TFT_drawVerticalLine(60,100,100,GREEN);   // Draw a vertical line
                                              // start: (60, 100) length: 100 color: green
                                         
  TFT_drawHorizontalLine(30,60,150,BLUE);   //Draw a horizontal line
                                              //start: (30, 60), high: 150, color: blue

  delay(500);
  cmpt++;
  
   
  if (cmpt & 0x01)  digitalWrite(RED_LED,HIGH); else  digitalWrite(RED_LED,LOW);
  //Serial.println("Bonjour");
  */
  
  if(mousecam_frame_capture(frame)==0) {
//*********** Gestion écran *************
    //SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV8);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  //Serial.begin(9600);
    TFT_TFTinit();
    TFT_backlight_on();     // turn on the background light 
  //TFT_fillScreen(0, 240, 0,320, GREEN);
    for (int j=0; j<=32; j++){
      for (int i=0;i<32;i++) {
        gris =frame[j+32*i]+ (frame[j+32*i] << 6) + (frame[j+32*i]<<11) ;
        TFT_fillRectangle(7*i,9*j, 5, 7, gris); 
        //TFT_fillCircle(7.5*i,9*j, 4,  gris);
       
      } // for  
    } // for
  } //  if(mousecam_frame_capture(frame)==0)
  delay(10000); 
}


void TFT_sendCMD(uint8_t index)
{
  /*
  PORTC &= 0xF7; // CD low
  PORTC &= 0xFB; // SSEL=CS = Low
  SPI_transfer(index);
  PORTC |= 0x04; // SSEL=CS = high
  */
   // CD = P3.7 = 31
   digitalWrite(31,LOW);
   //SSEL = CS = P3.6 = 13
   digitalWrite(13,LOW);
   SPI.transfer(index);
   digitalWrite(13,HIGH);  
}

void TFT_WRITE_DATA(uint8_t data)
{
  /*
  PORTC |= 0x08; // CD High
  PORTC &= 0xFB; // SSEL=CS = Low
  SPI_transfer(data);
  PORTC |= 0x04; // SSEL=CS = High
*/  
   digitalWrite(31,HIGH); // CD = P3.7 = 31
   digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
   SPI.transfer(data);
   digitalWrite(13,HIGH);
}

void TFT_sendData(uint16_t data)
{
  uint8_t data1 = data>>8;
  uint8_t data2 = data&0xff;
/*  PORTC |= 0x08; // CD High
  PORTC &= 0xFB; // SSEL=CS =Low
  SPI_transfer(data1);
  SPI_transfer(data2);
  PORTC |= 0x04; // SSEL=CS high
*/
   digitalWrite(31,HIGH); // CD = P3.7 = 31
   digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
   SPI.transfer(data1);
   SPI.transfer(data2);
   digitalWrite(13,HIGH);
}

void TFT_WRITE_Package(uint16_t *data, uint8_t howmany)
{
  uint8_t  data1 = 0;
  uint8_t   data2 = 0;
/*
  PORTC |= 0x08; // CD High
  PORTC &= 0xFB; // SSEL=CS low
  uint8_t count=0;
  for(count=0;count<howmany;count++)
  {
      data1 = data[count]>>8;
      data2 = data[count]&0xff;
      SPI_transfer(data1);
      SPI_transfer(data2);
  }
  PORTC |= 0x04; // SSEL=CS
  */
  digitalWrite(31,HIGH); // CD = P3.7 = 31
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
  uint8_t count=0;
  for(count=0;count<howmany;count++)
  {
      data1 = data[count]>>8;
      data2 = data[count]&0xff;
      SPI.transfer(data1);
      SPI.transfer(data2);
  }
  digitalWrite(13,HIGH);
}

void TFT_backlight_on(void)
{
  //PORTC |= 0x20;  
  digitalWrite(2,HIGH); //led = = P6.0 = 2
}


void TFT_backlight_off(void)
{
  //PORTC &= 0xDF;//LED off
  digitalWrite(2,LOW); //led = = P6.0 = 2
}

uint8_t TFT_Read_Register(uint8_t Addr, uint8_t xParameter)
{
  uint8_t data=0;

  /*
  TFT_sendCMD(0xd9);                                                   
  TFT_WRITE_DATA(0x10+xParameter);
  PORTC &= 0xF7; // CD low                                   
  PORTC &= 0xFB; // SSEL=CS low
  SPI_transfer(Addr);
  PORTC |= 0x08; // CD high
  data = SPI_transfer(0);
  PORTC |= 0x04; // SSEL=CS high
  */
  TFT_sendCMD(0xd9);                                                    /* ext command                */
  TFT_WRITE_DATA(0x10+xParameter);
  digitalWrite(31,LOW); // CD = P3.7 = 31
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
  SPI.transfer(Addr);
  digitalWrite(31,HIGH); // CD = P3.7 = 31
  data = SPI.transfer(0);
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
  return data;
}

void TFT_TFTinit(void)
{

  //PORTC |= 0x04; // SSEL=CS high
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
  //PORTC &= 0xFB; // SSEL=CS low
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
    // PORTC &= 0xF7; // CD low
  digitalWrite(31,LOW); // CD = P3.7 = 31
  //PORTC &= 0xDF;//LED off
  digitalWrite(2,LOW); //led = = P6.0 = 2
  //PORTC &= 0xEF; // RST low
  digitalWrite(17,LOW); // RST = P5.7 = 17
      // b3=CPOL, b2=CPHA, b1=SPR1 b0=SPR0
      //SPCR &= ~((1<<CPOL) | (1<<CPHA)); // mode 0
      //SPCR |= (1<<SPR1); // poids faible division = 2
      //SPSR |= (1 << 1); // poids fort division = 8
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  //SPI_transfer(0);  // Strawman transfer, fixes USCI issue on G2553
  SPI.transfer(0);
  //    PORTC |= 0x04; // SSEL=CS high ????
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
  //    PORTC |= 0x08; // CD high
  digitalWrite(31,HIGH); // CD = P3.7 = 31
  //    PORTC |= 3;  // DEBUG ou cela bloque-t-il ?
  uint8_t i=0, TFTDriver=0;

  //PORTC &= 0xEF; // RST low
  digitalWrite(17,LOW); // RST = P5.7 = 17
  delay(10);
  //PORTC |= 0x10; // RST high
  digitalWrite(17,HIGH); // RST = P5.7 = 17

  for(i=0;i<3;i++)
  {
      TFTDriver = TFT_readID();
  }

  TFT_sendCMD(0xCB);  
  TFT_WRITE_DATA(0x39);
  TFT_WRITE_DATA(0x2C);
  TFT_WRITE_DATA(0x00);
  TFT_WRITE_DATA(0x34);
  TFT_WRITE_DATA(0x02);

  TFT_sendCMD(0xCF);  
  TFT_WRITE_DATA(0x00);
  TFT_WRITE_DATA(0XC1);
  TFT_WRITE_DATA(0X30);

  TFT_sendCMD(0xE8);  
  TFT_WRITE_DATA(0x85);
  TFT_WRITE_DATA(0x00);
  TFT_WRITE_DATA(0x78);

  TFT_sendCMD(0xEA);  
  TFT_WRITE_DATA(0x00);
  TFT_WRITE_DATA(0x00);

  TFT_sendCMD(0xED);  
  TFT_WRITE_DATA(0x64);
  TFT_WRITE_DATA(0x03);
  TFT_WRITE_DATA(0X12);
  TFT_WRITE_DATA(0X81);

  TFT_sendCMD(0xF7);  
  TFT_WRITE_DATA(0x20);

  TFT_sendCMD(0xC0);    //Power control
  TFT_WRITE_DATA(0x23);   //VRH[5:0]

  TFT_sendCMD(0xC1);    //Power control
  TFT_WRITE_DATA(0x10);   //SAP[2:0];BT[3:0]

  TFT_sendCMD(0xC5);    //VCM control
  TFT_WRITE_DATA(0x3e);   //Contrast
  TFT_WRITE_DATA(0x28);

  TFT_sendCMD(0xC7);    //VCM control2
  TFT_WRITE_DATA(0x86); //--

  TFT_sendCMD(0x36);    // Memory Access Control
  TFT_WRITE_DATA(0x48);   //C8  //48 68绔栧睆//28 E8 妯睆

  TFT_sendCMD(0x3A);    
  TFT_WRITE_DATA(0x55);

  TFT_sendCMD(0xB1);    
  TFT_WRITE_DATA(0x00);  
  TFT_WRITE_DATA(0x13);

  TFT_sendCMD(0xB6);    // Display Function Control
  TFT_WRITE_DATA(0x08);
  TFT_WRITE_DATA(0x82);
  TFT_WRITE_DATA(0x27);  
 
  TFT_sendCMD(0xF2);    // 3Gamma Function Disable
  TFT_WRITE_DATA(0x00);

  TFT_sendCMD(0x26);    //Gamma curve selected
  TFT_WRITE_DATA(0x01);

  TFT_sendCMD(0xE0);    //Set Gamma
  TFT_WRITE_DATA(0x0F);
  TFT_WRITE_DATA(0x31);
  TFT_WRITE_DATA(0x2B);
  TFT_WRITE_DATA(0x0C);
  TFT_WRITE_DATA(0x0E);
  TFT_WRITE_DATA(0x08);
  TFT_WRITE_DATA(0x4E);
  TFT_WRITE_DATA(0xF1);
  TFT_WRITE_DATA(0x37);
  TFT_WRITE_DATA(0x07);
  TFT_WRITE_DATA(0x10);
  TFT_WRITE_DATA(0x03);
  TFT_WRITE_DATA(0x0E);
  TFT_WRITE_DATA(0x09);
  TFT_WRITE_DATA(0x00);

  TFT_sendCMD(0XE1);    //Set Gamma
  TFT_WRITE_DATA(0x00);
  TFT_WRITE_DATA(0x0E);
  TFT_WRITE_DATA(0x14);
  TFT_WRITE_DATA(0x03);
  TFT_WRITE_DATA(0x11);
  TFT_WRITE_DATA(0x07);
  TFT_WRITE_DATA(0x31);
  TFT_WRITE_DATA(0xC1);
  TFT_WRITE_DATA(0x48);
  TFT_WRITE_DATA(0x08);
  TFT_WRITE_DATA(0x0F);
  TFT_WRITE_DATA(0x0C);
  TFT_WRITE_DATA(0x31);
  TFT_WRITE_DATA(0x36);
  TFT_WRITE_DATA(0x0F);

  TFT_sendCMD(0x11);    //Exit Sleep
  delay(120);

  TFT_sendCMD(0x29);  //Display on
  TFT_sendCMD(0x2c);   
  TFT_fillScreen2();
}

uint8_t TFT_readID(void)
{
  uint8_t i=0;
  uint8_t data[3] ;
  uint8_t ID[3] = {0x00, 0x93, 0x41};
  uint8_t ToF=1;
  for(i=0;i<3;i++)
  {
      data[i]=TFT_Read_Register(0xd3,i+1);
      if(data[i] != ID[i])
      {
          ToF=0;
      }
  }
    
  return ToF;
}

void TFT_setCol(uint16_t StartCol,uint16_t EndCol)
{
  TFT_sendCMD(0x2A);                                                    /* Column Command address     */
  TFT_sendData(StartCol);
  TFT_sendData(EndCol);
}

void TFT_setPage(uint16_t StartPage,uint16_t EndPage)
{
  TFT_sendCMD(0x2B);                                                    /* Column Command address     */
  TFT_sendData(StartPage);
  TFT_sendData(EndPage);
}

void TFT_fillScreen(uint16_t XL, uint16_t XR, uint16_t YU, uint16_t YD, uint16_t color)
{
  unsigned long  XY=0;
  unsigned long i=0;

  if(XL > XR)
  {
      XL = XL^XR;
      XR = XL^XR;
      XL = XL^XR;
  }
  if(YU > YD)
  {
      YU = YU^YD;
      YD = YU^YD;
      YU = YU^YD;
  }
//*********** a redefinir la fonction constrain !!!!!!!!!!!!!!!!!!
  //XL = constrain(XL, MIN_X,MAX_X);
  //XR = constrain(XR, MIN_X,MAX_X);
  //YU = constrain(YU, MIN_Y,MAX_Y);
  //YD = constrain(YD, MIN_Y,MAX_Y);

  XY = (XR-XL+1);
  XY = XY*(YD-YU+1);

  TFT_setCol(XL,XR);
  TFT_setPage(YU, YD);
  TFT_sendCMD(0x2c);                                                /* start to write to display ra */
                                                                      /* m                          */
  //PORTC |= 0x08; // CD high
  //PORTC &= 0xFB; // SSEL=CS low
  digitalWrite(31,HIGH); // CD = P3.7 = 31
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13

  uint8_t Hcolor = color>>8;
  uint8_t Lcolor = color&0xff;
  for(i=0; i < XY; i++)
  {
      SPI.transfer(Hcolor);
      SPI.transfer(Lcolor);
  }

  //PORTC |= 0x04; // SSEL=CS high
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
}

void TFT_fillScreen2(void)
{
  uint16_t i;
  TFT_setCol(0, 239);
  TFT_setPage(0, 319);
  TFT_sendCMD(0x2c);                                                /* start to write to display ra */
                                                                      /* m                          */
  //PORTC |= 0x08; // CD high
  //PORTC &= 0xFB; // SSEL=CS low
  digitalWrite(31,HIGH); // CD = P3.7 = 31
  digitalWrite(13,LOW); //SSEL = CS = P3.6 = 13
  for(i=0; i<38400; i++)
  {
    /* SPI_transfer(0);
      SPI_transfer(0);
      SPI_transfer(0);
      SPI_transfer(0);*/
      SPI.transfer(0);
      SPI.transfer(0);
      SPI.transfer(0);
      SPI.transfer(0);
  }
  //PORTC |= 0x04; // SSEL=CS high
  digitalWrite(13,HIGH); //SSEL = CS = P3.6 = 13
}


void TFT_setXY(uint16_t poX, uint16_t poY)
{
  TFT_setCol(poX, poX);
  TFT_setPage(poY, poY);
  TFT_sendCMD(0x2c);
}

void TFT_setPixel(uint16_t poX, uint16_t poY,uint16_t color)
{
  TFT_setXY(poX, poY);
  TFT_sendData(color);
}

void TFT_drawChar( uint8_t ascii, uint16_t poX, uint16_t poY,uint16_t size, uint16_t fgcolor, uint16_t bgcolor)
{

  //fillRectangle(poX, poY, poX+FONT_X*size, poY+FONT_Y*size, BLACK);
  int i;
  uint8_t f;

  if((ascii>=32)&&(ascii<=127))
  {
      ;
  }
  else
  {
      ascii = '?'-32;
  }
  for (i =0; i<FONT_X; i++ ) {
      uint8_t temp = simpleFont[ascii-0x20][i];
      for(f=0;f<8;f++)
      {
          if((temp>>f)&0x01)
          {
              TFT_fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor);
          }
    else
  TFT_fillRectangle(poX+i*size, poY+f*size, size, size, bgcolor);

      }

  }
}

void TFT_drawString(char *string,uint16_t poX, uint16_t poY, uint16_t size,uint16_t fgcolor, uint16_t bgcolor)
{
  while(*string)
  {
      TFT_drawChar(*string, poX, poY, size, fgcolor, bgcolor);
      *string++;

      if(poX < MAX_X)
      {
          poX += FONT_SPACE*size;                                   /* Move cursor right          */
      }
  }
}

//fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor);
void TFT_fillRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width, uint16_t color)
{
  TFT_fillScreen(poX, poX+length, poY, poY+width, color);
}

void  TFT_drawHorizontalLine( uint16_t poX, uint16_t poY,
uint16_t length,uint16_t color)
{
  int i;
  TFT_setCol(poX,poX + length);
  TFT_setPage(poY,poY);
  TFT_sendCMD(0x2c);
  for(i=0; i<length; i++)
  TFT_sendData(color);
}


int abs(int data) {
  if (data > 0) return data; else return -data;
}

void TFT_drawLine( uint16_t x0,uint16_t y0,uint16_t x1, uint16_t y1,uint16_t color)
{

  int x = x1-x0;
  int y = y1-y0;
  int dx = abs(x), sx = x0<x1 ? 1 : -1;
  int dy = -abs(y), sy = y0<y1 ? 1 : -1;
  int err = dx+dy, e2;                                              /* error value e_xy           */
  for (;;){                                                         /* loop                       */
      TFT_setPixel(x0,y0,color);
      e2 = 2*err;
      if (e2 >= dy) {                                               /* e_xy+e_x > 0               */
          if (x0 == x1) break;
          err += dy; x0 += sx;
      }
      if (e2 <= dx) {                                               /* e_xy+e_y < 0               */
          if (y0 == y1) break;
          err += dx; y0 += sy;
      }
  }

}

void TFT_drawVerticalLine( uint16_t poX, uint16_t poY, uint16_t length,uint16_t color)
{
  int i;
  TFT_setCol(poX,poX);
  TFT_setPage(poY,poY+length);
  TFT_sendCMD(0x2c);
  for(i=0; i<length; i++)
  TFT_sendData(color);
}

void TFT_drawRectangle(uint16_t poX, uint16_t poY, uint16_t length, uint16_t width,uint16_t color)
{
  TFT_drawHorizontalLine(poX, poY, length, color);
  TFT_drawHorizontalLine(poX, poY+width, length, color);
  TFT_drawVerticalLine(poX, poY, width,color);
  TFT_drawVerticalLine(poX + length, poY, width,color);

}

void TFT_drawCircle(int poX, int poY, int r,uint16_t color)
{
  int x = -r, y = 0, err = 2-2*r, e2;
  do {
      TFT_setPixel(poX-x, poY+y,color);
      TFT_setPixel(poX+x, poY+y,color);
      TFT_setPixel(poX+x, poY-y,color);
      TFT_setPixel(poX-x, poY-y,color);
      e2 = err;
      if (e2 <= y) {
          err += ++y*2+1;
          if (-x == y && e2 <= x) e2 = 0;
      }
      if (e2 > x) err += ++x*2+1;
  } while (x <= 0);
}

void TFT_fillCircle(int poX, int poY, int r,uint16_t color)
{
  int x = -r, y = 0, err = 2-2*r, e2;
  do {

      TFT_drawVerticalLine(poX-x, poY-y, 2*y, color);
      TFT_drawVerticalLine(poX+x, poY-y, 2*y, color);

      e2 = err;
      if (e2 <= y) {
          err += ++y*2+1;
          if (-x == y && e2 <= x) e2 = 0;
      }
      if (e2 > x) err += ++x*2+1;
  } while (x <= 0);

}

void TFT_drawTraingle( int poX1, int poY1, int poX2, int poY2, int poX3, int poY3, uint16_t color)
{
  TFT_drawLine(poX1, poY1, poX2, poY2,color);
  TFT_drawLine(poX1, poY1, poX3, poY3,color);
  TFT_drawLine(poX2, poY2, poX3, poY3,color);
}

uint8_t TFT_drawNumber(long long_num,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor)
{
  uint8_t char_buffer[10] = "";
  uint8_t i = 0;
  uint8_t f = 0;


  if (long_num < 0)
  {
      f=1;
      TFT_drawChar('-',poX, poY, size, fgcolor, bgcolor);
      long_num = -long_num;
      if(poX < MAX_X)
      {
          poX += FONT_SPACE*size;                                   /* Move cursor right          */
      }
  }
  else if (long_num == 0)
  {
      f=1;
      TFT_drawChar('0',poX, poY, size, fgcolor, bgcolor);
      return f;
      if(poX < MAX_X)
      {
          poX += FONT_SPACE*size;                                   /* Move cursor right          */
      }
  }


  while (long_num > 0)
  {
      char_buffer[i++] = long_num % 10;
      long_num /= 10;
  }

  f = f+i;
  for(; i > 0; i--)
  {
      TFT_drawChar('0'+ char_buffer[i - 1],poX, poY, size, fgcolor, bgcolor);
      if(poX < MAX_X)
      {
          poX+=FONT_SPACE*size;                                     /* Move cursor right          */
      }
  }
  return f;
}

uint8_t TFT_drawFloat(float floatNumber,uint8_t decimal,uint16_t poX, uint16_t poY,uint16_t size,uint16_t fgcolor, uint16_t bgcolor)
{
  uint16_t temp=0;
  float decy=0.0;
  float rounding = 0.5;
  uint8_t f=0;
  uint8_t i;
  if(floatNumber<0.0)
  {
      TFT_drawChar('-',poX, poY, size, fgcolor, bgcolor);
      floatNumber = -floatNumber;
      if(poX < MAX_X)
      {
          poX+=FONT_SPACE*size;                                     /* Move cursor right          */
      }
      f =1;
  }
  for (i=0; i<decimal; ++i)
  {
      rounding /= 10.0;
  }
  floatNumber += rounding;

  temp = (uint16_t)floatNumber;
  uint8_t howlong=TFT_drawNumber(temp,poX, poY, size, fgcolor, bgcolor);
  f += howlong;
  if((poX+8*size*howlong) < MAX_X)
  {
      poX+=FONT_SPACE*size*howlong;                                 /* Move cursor right          */
  }

  if(decimal>0)
  {
      TFT_drawChar('.',poX, poY, size, fgcolor, bgcolor);
      if(poX < MAX_X)
      {
          poX+=FONT_SPACE*size;                                     /* Move cursor right          */
      }
      f +=1;
  }
  decy = floatNumber-temp;                                          /* decimal part,  4           */
  for(i=0;i<decimal;i++)                                   
  {
      decy *=10;                                                    /* for the next decimal       */
      temp = decy;                                                  /* get the decimal            */
      TFT_drawNumber(temp,poX, poY, size, fgcolor, bgcolor);
      floatNumber = -floatNumber;
      if(poX < MAX_X)
      {
          poX+=FONT_SPACE*size;                                     /* Move cursor right          */
      }
      decy -= temp;
  }
  f +=decimal;
  return f;
}


void mousecam_reset()
{
  digitalWrite(PIN_MOUSECAM_RESET,HIGH);
  delay(1); // reset pulse >10us
  digitalWrite(PIN_MOUSECAM_RESET,LOW);
  delay(35); // 35ms from reset to functional
}

int mousecam_init()
{
  pinMode(PIN_MOUSECAM_RESET,OUTPUT);
  pinMode(PIN_MOUSECAM_CS,OUTPUT);
  
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
  
  mousecam_reset();
  
  int pid = mousecam_read_reg(ADNS3080_PRODUCT_ID);
  if(pid != ADNS3080_PRODUCT_ID_VAL)
    return -1;

  // turn on sensitive mode
  mousecam_write_reg(ADNS3080_CONFIGURATION_BITS, 0x19);

  return 0;
}

void mousecam_write_reg(int reg, int val)
{
  digitalWrite(PIN_MOUSECAM_CS, LOW);
  SPI.transfer(reg | 0x80);
  SPI.transfer(val);
  digitalWrite(PIN_MOUSECAM_CS,HIGH);
  delayMicroseconds(50);
}

int mousecam_read_reg(int reg)
{
  digitalWrite(PIN_MOUSECAM_CS, LOW);
  SPI.transfer(reg);
  delayMicroseconds(75);
  int ret = SPI.transfer(0xff);
  digitalWrite(PIN_MOUSECAM_CS,HIGH); 
  delayMicroseconds(1);
  return ret;
}

void mousecam_read_motion(struct MD *p)
{
  digitalWrite(PIN_MOUSECAM_CS, LOW);
  SPI.transfer(ADNS3080_MOTION_BURST);
  delayMicroseconds(75);
  p->motion =  SPI.transfer(0xff);
  p->dx =  SPI.transfer(0xff);
  p->dy =  SPI.transfer(0xff);
  p->squal =  SPI.transfer(0xff);
  p->shutter =  SPI.transfer(0xff)<<8;
  p->shutter |=  SPI.transfer(0xff);
  p->max_pix =  SPI.transfer(0xff);
  digitalWrite(PIN_MOUSECAM_CS,HIGH); 
  delayMicroseconds(5);
}

// pdata must point to an array of size ADNS3080_PIXELS_X x ADNS3080_PIXELS_Y
// you must call mousecam_reset() after this if you want to go back to normal operation
int mousecam_frame_capture(byte *pdata)
{
  mousecam_write_reg(ADNS3080_FRAME_CAPTURE,0x83);
  
  digitalWrite(PIN_MOUSECAM_CS, LOW);
  
  SPI.transfer(ADNS3080_PIXEL_BURST);
  delayMicroseconds(50);
  
  int pix;
  byte started = 0;
  int count;
  int timeout = 0;
  int ret = 0;
  for(count = 0; count < ADNS3080_PIXELS_X * ADNS3080_PIXELS_Y; )
  {
    pix = SPI.transfer(0xff);
    delayMicroseconds(10);
    if(started==0)
    {
      if(pix&0x40)
        started = 1;
      else
      {
        timeout++;
        if(timeout==100)
        {
          ret = -1;
          break;
        }
      }
    }
    if(started==1)
    {
      pdata[count++] = (pix & 0x3f)<<2; // scale to normal grayscale byte range
    }
  }

  digitalWrite(PIN_MOUSECAM_CS,HIGH); 
  delayMicroseconds(14);
  
  return ret;
}

Robotique mobile : Coupe de France des IUT GEII 2020

Il s'agit donc de préparer un robot pour la Coupe de France des IUT GEII 2020. Pour voir de quoi il s'agit, vous pouvez regarder la version 2019 ICI.

Le règlement 2020 est disponible. Il a été validé lors de la réunion du 17 octobre 2019 à Cachan par l'ensemble des participant :

Reglement 2020

Les principales nouveautés pour 2020 sont :

  • Les étudiants de Licence Pro ont le droit de participer.
  • Plus besoin d'être au filet pour marquer des points. Les robots doivent toujours crever un ballon pour valider leur score, mais il n'est plus nécessaire d'être dans la bande du filet pour marquer, il suffit juste que le robot soit arrêté, où que se soit, et qu'il ne bouge plus pour avoir le droit de crever le ballon. En revanche, le faire au filet rapporte 3 points supplémentaires.
  • La base mobile du robot (châssis, moteurs, transmissions, roues et batterie) n'est plus obligatoire, elle est juste recommandée, mais on peut utiliser tout type de moteur, châssis, roue, transmission ou batterie à condition qu'ils respectent les contraintes du règlement :
  • Pas plus de 24V de tension dans le robot.
  • Pas plus de 2 roues motrices.
  • Le seul contact entre les roues motrices et le sol doit obligatoirement être un joint torique de référence Oring 133610.
  • Pas de batteries Lithium Polymère, ou Lithium Cobalt (voir tous les détails concernant les batteries en technologie Lithium dans le règlement).

Voir aussi

Projet robotique mobile : challenge GEII/GMP

La réalisation de ce projet nécessitera deux binômes.

  • un binôme s'occupera du déplacement et de ramener les cylindres dans notre camp
  • l'autre binôme sera responsable de l'empilement des cylindres

Ce projet devra être complètement fonctionnel en fin de S3 à l'aide de deux télécommandes.

Il sera poursuivi sur S4 avec comme objectif de le rendre autonome.

Bluebg.png
Aidesmall.png
À propos de cette image

Comment commencer ?



Vous devez essayer de rédiger avec le plus de détail (pas forcément technique) un scénario décrivant l'exécution du challenge. Pour vous aider dans vos démarches, Le règlement 2020 est consultable maintenant.


Indications : Utilisation d'un moteur pas à pas

Utilisation du shield CNC

Ce shield CNC est en principe dédié aux imprimantes 3D et notre version utilise la commande de puissance A4988. Nous utilisons la partie réservée à l'axe Y. Trois broches sont nécessaires :

  • une broche pour choisir la direction de rotation (dirY dans notre code)
  • une broche pour envoyer les impultions (pulseY dans notre code)
  • unz broche pour valider le fonctionnement (stepperEN dans notre code)

Les positions de ces trois broches sont déterminées par le shield. Voici le code Arduino correspondant :

const uint8_t dirY = 6;
const uint8_t pulseY=3;
const uint8_t stepperEN=8;

uint8_t dir = 0;
void setup() {
  // put your setup code here, to run once:
 pinMode(dirY,OUTPUT);
 pinMode(pulseY,OUTPUT);
 pinMode(stepperEN,OUTPUT);
 digitalWrite(stepperEN,LOW);
 digitalWrite(dirY,dir);
 
}

void loop() {
  // put your main code here, to run repeatedly:
  static uint16_t step=0;
  digitalWrite(pulseY,HIGH);
  digitalWrite(pulseY,LOW);
  delay(5);
  step++;
  if (step>200) {
    step=0;
    dir ^= 1;
    digitalWrite(dirY,dir);
  }

}

Il est possible de n'utiliser que la partie électronique de puissance A4988 seule et de faire un circuit pour le relier à un Arduino nano.

Nous étudierons une autre possibilité avec un L298N.

Étude du L298N

La carte L298N et son utilisation est présentée ICI. Il est donc facile de l'utiliser surtout associé à la librairie Stepper (github). Le seul problème rencontré était dû au fait que la masse de l'Arduino et la masse du L298N n'étaient pas reliées.

Voir aussi