Cours:ErB32019
Sommaire
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 :
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.
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.