Go Down

Topic: SPI avec TFT et MIRF (Read 2610 times) previous topic - next topic

BossOfScandalz

Quote
Es-tu sûr d'avoir indiqué une même clé unique pour la communication entre les 2 nrf?
oui, je suis toujours sur le programme de test

coté RC:
Code: [Select]
 Mirf.setTADDR((byte *) "nrf02"); // Adresse de transmission
  Mirf.setRADDR((byte *) "nrf01"); // Adresse de réception


coté bateau:
Code: [Select]
 Mirf.setTADDR((byte *) "nrf01"); // Adresse de transmission
  Mirf.setRADDR((byte *) "nrf02"); // Adresse de réception


Cela fonctionne lorsque j'enlève la fonction TFT.


Quote
Merci pour ton commentaire, mais mon but ici est un peu brisé du coup car mon projet est un sujet polémique dont je ne peux faire usage pour aider les gens. Par contre je peux aider les gens avec l'expérience que j'ai eu grâce à ce projet effectivement, c'est ce que j'essaye de faire mais c'est pas évident car les bibliothèques concurrentes sont très bordéliques !
En tous cas, je serais ou aller voir, quand je souhaiterais créer des programmes "propre" et surtout pour apprendre à programmer autrement qu'avec arduino.
J'ai des ATMEGA328 version CMS avec un programmer ISP, j'avais pour objectif de charger le bootloader mais finalement je vais y réfléchir sérieusement, lorsque je voudrais faire des projet encore plus DIY.

Quote
Tu sais que j'aimerais bien (rien que pour combler les demandes que j'ai eu en ce sens), personnellement j'ai pas encore eu l'application de ce genre d'écran parce que j'utilise mes afficheurs à led qui dans mon esprit ont un coté plus vintage que j'aime bien, et sont dédiés à l'affichage de caractères à la fois numérique mais aussi alpha (numérique).

Par contre cela ne m'a pas empêché d'en acheté un une fois mais la conception même de l'écran m'a déplu donc je l'ai donné à quelqu'un. J'étais parti pourtant pour en faire une classe, j'avais commencé à réfléchir à des fonctions de tracé de polygones et d'anticrénelage.
Si vraiment j'ai des gros problème a finaliser ce projet, je serais partant pour tester avec ton module_sm et eventuelement reflechir sur une classe (bien sur, il va de soit que je vais devoir passer du temps a comprendre avant de me lancer)

Quote
J'ai moi aussi en projet (futur) une radiocommande avec mes afficheurs à led, mais je réfléchi encore si je dois fabriquer les joystick en alu avec le système 2 axes ou si j'en achète des tous faits... La c'est plus la contrainte de passer des journées devant ma fraiseuse avec le coût en électricité que ça implique (triphasé).
Super intéressante cette machine, moi j'ai construit juste la coque de la RC en contre plaqué et balsa et les joystick commandés sur un site chinoi a 7€/pièce, la qualité est satisfaisante, surtout le point milieu (avec des joystick de manette PS2, la catastrophe, enfin il faut adapter le programme). Sinon j'ai plusieurs afficheur, un de nokia (du basique), un oled (je ne pensais pas qu'il était si petit), j'ai donc opté pour le tft 1.8pouce du point de vue du nombre d'élément a afficher (batterie rc et bateau, position des joystick avec leur trim, vitesse, vitesse max, distance entre moi et bateau, heure + temps depuis le depart, ...)

Quote
Ok, et si tu place Mirf.init(); après ça donne quoi?
si je fais ça:
Code: [Select]

void setup(){
LCD.begin();  
Mirf.init();
LCD.background(WHITE);
Mirf.init();
}

void loop(){
envoie + reception
}


cela fonctionne

mais ceci
Code: [Select]

void setup(){
LCD.begin();  
Mirf.init();

}

void loop(){

Mirf.init();
envoie + reception
LCD.drawRect(127, 104, 32, 100, BLACK);
.... et l'affichage de toute les données énoncé juste avant
 
}



Cela ne fonctionne plus. D'un côté je me vois pas laisser un programme comme ça...


BossOfScandalz

#16
Jan 22, 2017, 01:51 am Last Edit: Jan 22, 2017, 02:13 am by BossOfScandalz
Après mesure de la fréquence de la clock, j'obtiens:

La clock du TFT, si mes calculs sont bon:
freq = 1 / DELTA T = 1 / 0.25µs = 4MHz


La clock du NRF
freq = 25MHz ?? >8MHz impossible, je pense qu'il y a un conflit ?

Faut-il impérativement la même Horloge, étant donné qu'elle est active seulement lorsque SS est a low?

Sinon je testerais de verifier les 2 slaveSelect en meme temps pour voir si il n'y en a pas un qui déborde sur l'autre.






sylvainmahe

Quote
D'un côté je me vois pas laisser un programme comme ça...
C'est clair, être obligé de remettre Mirf.init après chaque appel à lcd...

Quote
freq = 25MHz ?? >8MHz impossible, je pense qu'il y a un conflit ?
Ici ça veut peut être dire que l'une des 2 classes change la fréquence mais ça me parait bizarre ce 25Mhz sorti de nul part (je parle du prescaler SPI dans le 328p).


En fait après tes tests, je pense que l'une des 2 classes (sans doute TFT) ne remet peut être pas une pin dans le bon état !

C'est tout à fait possible que l'une des 2 classes (et les choses inclues dans ces classes éventuellement) permutent une pin (SPI software) en utilisant un registre PIN au lieu d'un registre PORT.

Autrement dit, quand on utilise un registre PIN pour changer d'état une ou plusieurs pins du 328p, ce registre permute l'état d'un (ou plusieurs) bit en tenant compte de l'état initial du bit, par exemple un état 0 devient forcément 1 et un état 1 devient forcément 0 si on demande le changement, il ne peut en être autrement.

En revanche, avec un registre PORT du 328p, on choisi (fixe) l'état du bit qu'on veut, quel que soit l'état initial du bit. Par exemple un bit à l'état 0 peut rester à 0 si on décide de le mettre à 0 (c'est à dire même si on pensait qu'il était en fait à 1 au départ), et inversement.

Donc l'utilité de ces 2 registres est vraiment différente pour changer l'état d'une pin du 328p. A noter que l'utilisation des registres PIN est plus rapide que les registres PORT.



Ça signifie que je pense que l'une des 2 classes que tu utilises (à une certaine étape de son code) prend pour acquis l'état d'une pin du 328p, et utilise donc un registre PIN pour changer l'état. Du coup la fameuse pin à la fin de la procédure se retrouve dans un état non souhaité.

Je vais re-regarder ça si je trouve l'endroit ou i y a ce soucis.
Après, peut être que je me trompe et que ce n'est pas ça, mais honnêtement s'en est bien le symptôme.


Quote
j'avais pour objectif de charger le bootloader mais finalement je vais y réfléchir sérieusement, lorsque je voudrais faire des projet encore plus DIY.
Oui franchement le bootloader ne sert à rien mise à part te permettre de connecter ta carte en usb via le ftdi embarqué, ce qui est une utilité bien relative à mon sens (faut en avoir l'utilité, personnellement je ne l'ai jamais eu...).
En plus ça prend un peu de mémoire et ça ralenti le démarrage du 328p.


Quote
Si vraiment j'ai des gros problème a finaliser ce projet, je serais partant pour tester avec ton module_sm et eventuelement reflechir sur une classe (bien sur, il va de soit que je vais devoir passer du temps a comprendre avant de me lancer)
Pas de soucis je serais la pour t'aider si besoin ;)


Quote
j'ai construit juste la coque de la RC en contre plaqué et balsa et les joystick commandés sur un site chinoi a 7€/pièce, la qualité est satisfaisante
Vraiment cool ;) J'aimerais bien voir des photos.
Pour ma part c'est un peu ce que je projette de faire, une radiocommande en bois, ça fait un coté amateur que j'aime bien.

sylvainmahe

Donc j'ai pas mal reparcouru les différents fichiers dépendants, dans Adafruit_ST7735.cpp il y a ce genre de chose plusieurs fois:
Code: [Select]
SPCRbackup = SPCR;
      SPCR = mySPCR;
      SPI.transfer(c);
SPCR = SPCRbackup;


Ce qui signifie une sauvegarde de la config SPI précédente du 328p (du registre SPCR), la communication avec l'écran avec les paramètres SPI de la clase Adafruit_ST7735, et la restitution des paramètres SPI précédemment sauvegardés (pour qu'ils soient bon pour Mirf).


La question c'est: est ce que Mirf change un paramètre SPI qui ne serait pas sauvegardé ici dans ce bout de code mais qui serait vital au bon fonctionnement, je pense au registre SPSR ou SPDR, franchement je ne pense pas.

Par contre, si a un moment donné la pin CS du SPI passe à l'état bas (en étant en input à un moment donné), il me semble que le SPI du 328p passe du mode master au mode slave, je ne me rappel plus mais je crois que pour repasser au mode master il faut clairement l'indiquer au registre SPCR.

Par contre j'ai trouvé ça dans Adafruit_ST7735.cpp:
Code: [Select]
*csport &= ~cspinmask;
CS à l'état bas, et:
Code: [Select]
*csport |= cspinmask;
CS à l'état haut, donc ils utilisent bien le registre PORT. De toute façon les CS des 2 classes sont indépendant donc...

BossOfScandalz

Merci pour tes recherches.

Je fais des recherches aussi de mon côté, je trouve que la lib TFT est compliqué, elle appel pleins de lib, difficile de si retrouver.
Je commence a comprendre mieux le problème que j'ai et je t'en remercie.

J'ai plusieurs piste:
-Soit je continu a persister pour trouver le problème dans cette librairie qui me fait pas vraiment rigoler.
-Soit j'utilise un écran dont-il n'utilise pas le SPI
-Soit j'utilise un 2nd arduino, comme ça chacun gère le module (et je gagne en rapidité)
-Soit j'abandonne arduino, pour partir sur ton projet ou j'ai survoler quelque classe, certe je vais passer plus de temps a comprendre mais comme tu l'as dit, c'est bien plus intéressant de comprendre le fonctionnement pur de l'atmega 328. Cela me fera surement gagné du temps par la suite.

Bref je suis en pleine réflexion...



sylvainmahe

#20
Jan 23, 2017, 07:00 pm Last Edit: Jan 24, 2017, 09:58 am by sylvainmahe
Je te comprends c'est un peu énervant.

Bon de mon coté j'ai avancé un peu en lisant le datasheet du ST7735 le composant qui gère ton écran et pour aller plus vite en regardant quelques exemples sur le net.

De ce que je comprends par rapport à mon expérience sur d'autres composants, je pense qu'il n'y a pas besoin de pin reset, on doit pouvoir la laisser tout le temps à l'état haut dans la majorité des cas.

A priori pour démarrer/initialiser le composant ça doit donner ceci:

Procédure de démarrage:
Code: [Select]
//SS état bas
0b00010001//sortir du mode veille
//SS état haut
//attendre 120ms
//SS état bas
0b00101001//écran on
//SS état haut


Avec ca normalement l'écran est démarré, c'est pas plus compliqué.
(Les 0bxxxxxxxx sont des commandes à envoyer au composant en SPI)


Ensuite: Procédure pour écrire un (ou des) pixel à l'écran:
Code: [Select]
//SS état bas
0b00101010//selection de la zone x à rafraichir
//SS état haut
0bxxxxxxxxxxxxxxxx//x min
0bxxxxxxxxxxxxxxxx//x max
//SS état bas
0b00101011//selection de la zone y à rafraichir
//SS état haut
0bxxxxxxxxxxxxxxxx//y min
0bxxxxxxxxxxxxxxxx//y max
//SS état bas
0b00101100//demande d'écriture dans la RAM
//SS état haut
0b00000000000000rrrrrrggggggbbbbbb//écriture de la couleur du pixel en rgb 6 bits par couleur (r6b6g6, mais possible à mettre en r5g6b5 16 bits au total pour éviter d'écrire des 0 pour rien)


Curieusement, j'ai vu un exemple avec ceci: les "valeurs" qu'on envoi en SPI, contrairement aux "commandes", ne doivent pas être faites pin SS (cs) à l'état bas. Sans avoir l'écran je ne peux rien tester mais de ce que j'ai vu c'est bien comme ça que le composant comprend que c'est une "commande" et que éventuellement les "valeurs" qui arrivent après cette "commande" sont bien des données (de pixel par exemple). Franchement ce truc la est à vérifier car c'est la première fois que je vois ça en SPI, donc pour moi c'est super chelou...


Pour les pixels, même si ce n'est pas le cas de l'exemple ci-dessus, en r5g6b5 (16 bits) au lieu de r6g6b6 (18 bits), je pense que c'est pas un problème en 16 bits car notre œil est plus sensible à la couleur verte que le bleu ou encore le rouge, donc le fait que le bleu ou le rouge n'ont que 5 bits soit une résolution plus faible serait on va dire à peu prêt cohérent avec la réalité physique.


Si j'avais un écran je testerais ça sous la forme d'une petite classe St7735.h et .cpp en quelques minutes (y a rien de compliqué), mais n'ayant pas d'écran, je peux difficilement valider ce que j'ai écris et t'en proposer une version compatible pour ton Arduino !

sylvainmahe

Ah oui chose importante que j'ai oublié également:
Quote
Soit j'abandonne arduino, pour partir sur ton projet
C'est que j'utilise mes propres cartes électroniques, carte qui ont une distribution des pins d'entrées/sorties différentes d'Arduino (plus cohérentes en fait).

Donc changer de système soit tu t'y fait en comprenant la distribution des pins sur mes cartes versus les cartes Arduino uno (c'est pas bien compliqué), soit tu reprogrammes juste cette partie dans Module relative à l'ordre des pins (la non plus c'est pas bien long à faire), soit tu fabriques (ou fait fabriquer) l'une de mes cartes (plan dispo etc...).


Dans tous les cas, faut bien réfléchir à ce que tout cela implique, mais honnêtement je pense que quelqu'un va débarquer sur le forum et va te trouver une solution pour ce conflit Mirf.h vs TFT.h ;)

BossOfScandalz

Super pour tes recherches,
J'ai donc passé ma soirée a essayer de comprendre la doc de l'écran, en comparant la lib adafruit. Je comprend mieux comment cela fonctionne.

Je vais donc tester de ne pas utiliser la lib TFT, juste appeler la lib SPI et communiquer avec l'écran en appliquant ta solution.

Sinon je t'ai envoyé des photos en MP sur ton mail du blog.

Je te tiens au courant.
Un grand merci

BossOfScandalz

Je viens de tester ce code:
Code: [Select]
#include <SPI.h>      // Pour la communication via le port SPI

const int CS = 7;
const int DC = 6;

void setup() {

  Serial.begin(9600);
  SPI.begin();
  pinMode(CS, OUTPUT);
  pinMode(DC, OUTPUT);
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));

  digitalWrite(DC, LOW); //Commande
  digitalWrite(CS, LOW); //SS état bas
  SPI.transfer(0x11);//sortir du mode veille
  digitalWrite(CS, HIGH); //SS état haut
  delay (120);
  digitalWrite(CS, LOW); //SS état bas
  SPI.transfer(0x29);//on
  digitalWrite(CS, HIGH); //SS état haut

  digitalWrite(CS, LOW); //SS état bas
  SPI.transfer(0x2A); //x
  digitalWrite(CS, HIGH); //SS état haut
  digitalWrite(DC, HIGH); //valeur
  SPI.transfer(0x0000);
  SPI.transfer(0x007f);

  digitalWrite(DC, LOW); //Commande
  digitalWrite(CS, LOW); //SS état bas
  SPI.transfer(0x2B); //y
  digitalWrite(CS, HIGH); //SS état haut
  digitalWrite(DC, HIGH); //valeur
  SPI.transfer(0x0000);
  SPI.transfer(0x009f);

  digitalWrite(DC, LOW); //Commande
  digitalWrite(CS, LOW); //SS état bas
  SPI.transfer(0x2C); // write to ram
  digitalWrite(CS, HIGH); //SS état haut
  digitalWrite(DC, HIGH); //valeur
  SPI.transfer(0x0003);
  SPI.transfer(0xf03f); // color

}

void loop() {
  // put your main code here, to run repeatedly:

}


Ecran blanc, J'ai essayé plusieurs chose mais aucune amélioration.

Du coup, j'ai rajouter la pin DC
Quote
Display data/command selection pin in MCU interface.
-D/CX='1': display data or parameter.
-D/CX='0': command data.
J'utilise bien le SPI avec ce code ?

BossOfScandalz

Sinon dans la lib adafruit, il y a ceci qui doit permettre de regler l'écran:
Code: [Select]
Gcmd[] = {                  // Initialization commands for 7735B screens
    19,                       // 18 commands in list:
    ST7735_SWRESET,   DELAY,  //  1: Software reset, no args, w/delay
      50,                     //     50 ms delay
    ST7735_SLPOUT ,   DELAY,  //  2: Out of sleep mode, no args, w/delay
      100,                    //     255 = 500 ms delay
    0x26 , 1,  // 3: Set default gamma
      0x04,                     //     16-bit color
    0xb1, 2,              // 4: Frame Rate
      0x0b,
      0x14,
    0xc0, 2,                    // 5: VRH1[4:0] & VC[2:0]
      0x08,
      0x00,
    0xc1, 1,                    // 6: BT[2:0]
      0x05,
    0xc5, 2,                    // 7: VMH[6:0] & VML[6:0]
      0x41,
      0x30,
    0xc7, 1,                    // 8: LCD Driving control
      0xc1,
    0xEC, 1,                    // 9: Set pumping color freq
      0x1b,
    0x3a , 1 + DELAY,          // 10: Set color format
      0x55,                     //     16-bit color
      100,
    0x2a, 4,                    // 11: Set Column Address
      0x00,
      0x00,
      0x00,
      0x7f,
    0x2b, 4,                    // 12: Set Page Address
      0x00,
      0x00,
      0x00,
      0x9f,
    0x36, 1,                    // 12+1: Set Scanning Direction
      0xc8,
    0xb7, 1, // 14: Set Source Output Direciton
      0x00,
    0xf2, 1, // 15: Enable Gamma bit
      0x00,
    0xe0, 15 + DELAY, // 16: magic
      0x28, 0x24, 0x22, 0x31,
      0x2b, 0x0e, 0x53, 0xa5,
      0x42, 0x16, 0x18, 0x12,
      0x1a, 0x14, 0x03,
      50,
    0xe1, 15 + DELAY, // 17: more magic
      0x17, 0x1b, 0x1d, 0x0e,
      0x14, 0x11, 0x2c, 0xa5,
      0x3d, 0x09, 0x27, 0x2d,
      0x25, 0x2b, 0x3c,
      50,
    ST7735_NORON  ,   DELAY,  // 17: Normal display on, no args, w/delay
      10,                     //     10 ms delay
    ST7735_DISPON ,   DELAY,  // 18: Main screen turn on, no args, w/delay
      255 };                  //     255 = 500 ms delay


Il faut voir si elles sont toutes nécessaire.

sylvainmahe

#25
Jan 25, 2017, 04:40 pm Last Edit: Jan 25, 2017, 04:41 pm by sylvainmahe
Quote
Ecran blanc, J'ai essayé plusieurs chose mais aucune amélioration.
Attention il faut bien vérifier que la pin reset du composant est à l'état haut, et que si ça ne fonctionne toujours pas lui faire faire un petit reset (haut bas haut) au tout début (une seule fois) et attendre également à la fin de ce reset 120ms.

Pour ici la coloration des pixels:
Quote
SPI.transfer(0xf03f);
Ceci modifie uniquement le 1er pixel de la zone sélectionnée.

Pour tout changer il faut appeler autant de fois à suivre la commande spi qu'il n'y a de pixels à l'écran !


Pour la pin DC j'en sais rien du tout.


Quote
Sinon dans la lib adafruit, il y a ceci qui doit permettre de regler l'écran:
Oui c'est un tableau de commandes, on doit les retrouver dans le datasheet.

BossOfScandalz

Effectivement la pin reset sur LOW affiche un ecran blanc, maintenant a HIGH j'ai un écran bizarre (la même chose que j'avais avant (1/4 de seconde) au demarrage.
Il y a donc du mieux :)

Je vais regarder ceci tranquillement. Merci pour la piste


BossOfScandalz

Je viens de réussir a afficher le background avec une couleur voulu, seulement, je suis obligé de passer par la fonction Gcmd pour que l'écran fonctionne, seulement l'affichage est très lent (environ 2-3 secondes pour afficher tous les pixel sur l'écran)

J'ai repris la librairie existante pour garder (en suivant l'appel a la fonction background (color))
le code:
Code: [Select]
#include <SPI.h>      // Pour la communication via le port SPI
#define DELAY 0x80

PROGMEM const static unsigned char
Gcmd[] = {                  // Initialization commands for 7735B screens
  19,                       // 18 commands in list:
  0x01,   DELAY,  //  1: Software reset, no args, w/delay
  50,                     //     50 ms delay
  0x11 ,   DELAY,  //  2: Out of sleep mode, no args, w/delay
  100,                    //     255 = 500 ms delay
  0x26 , 1,        // 3: Set default gamma
  0x04,                     //     16-bit color
  0xb1, 2,                // 4: Frame Rate
  0x0b,
  0x14,
  0xc0, 2,                    // 5: VRH1[4:0] & VC[2:0]
  0x08,
  0x00,
  0xc1, 1,                    // 6: BT[2:0]
  0x05,
  0xc5, 2,                    // 7: VMH[6:0] & VML[6:0]
  0x41,
  0x30,
  0xc7, 1,                    // 8: LCD Driving control
  0xc1,
  0xEC, 1,                    // 9: Set pumping color freq
  0x1b,
  0x3a , 1 + DELAY,           // 10: Set color format
  0x55,                     //     16-bit color
  100,
  0x2a, 4,                    // 11: Set Column Address
  0x00,
  0x00,
  0x00,
  0x7f,
  0x2b, 4,                    // 12: Set Page Address
  0x00,
  0x00,
  0x00,
  0x9f,
  0x36, 1,                    // 12+1: Set Scanning Direction
  0xc8,
  0xb7, 1,      // 14: Set Source Output Direciton
  0x00,
  0xf2, 1,      // 15: Enable Gamma bit
  0x00,
  0xe0, 15 + DELAY,   // 16: magic
  0x28, 0x24, 0x22, 0x31,
  0x2b, 0x0e, 0x53, 0xa5,
  0x42, 0x16, 0x18, 0x12,
  0x1a, 0x14, 0x03,
  50,
  0xe1, 15 + DELAY,   // 17: more magic
  0x17, 0x1b, 0x1d, 0x0e,
  0x14, 0x11, 0x2c, 0xa5,
  0x3d, 0x09, 0x27, 0x2d,
  0x25, 0x2b, 0x3c,
  50,
  0x13  ,   DELAY,  // 17: Normal display on, no args, w/delay
  10,                     //     10 ms delay
  0x29 ,   DELAY,  // 18: Main screen turn on, no args, w/delay
  255
};                  //     255 = 500 ms delay


const int CS = 7;
const int DC = 6;
const int RST = 5;


void setAddrTFT (uint8_t x0 , uint8_t y0, uint8_t x1, uint8_t y1) {
  // Localiser le pixel:
  writecmd (0x2A);
  writedata (0x00);
  writedata (x0);
  writedata (0x00);
  writedata (x1);

  writecmd (0x2B);
  writedata (0x00);
  writedata (y0);
  writedata (0x00);
  writedata (y1);

  writecmd (0x2C);
}

void writecmd (uint8_t c) {
  SPI.beginTransaction(SPISettings(4000000L, MSBFIRST, SPI_MODE0));
  digitalWrite(DC, LOW);
  digitalWrite(CS, LOW);
  SPI.transfer(c);
  digitalWrite(CS, LOW);
  SPI.endTransaction();
}

void writedata (uint8_t c) {
  SPI.beginTransaction(SPISettings(4000000L, MSBFIRST, SPI_MODE0));
  digitalWrite(DC, HIGH);
  digitalWrite(CS, LOW);
  SPI.transfer(c);
  digitalWrite(CS, LOW);
  SPI.endTransaction();
}

void drawPixel (uint16_t x , uint16_t y , uint16_t color) {
  //Serial.print("..drawpixel..");
  if ((x < 0) || (x >= 128) || (y < 0) || (y >= 160));

  setAddrTFT (x, y, x + 10 , y + 10);
  SPI.beginTransaction(SPISettings(4000000L, MSBFIRST, SPI_MODE0));
  digitalWrite(DC, HIGH);
  digitalWrite(CS, LOW);
  SPI.transfer(color >> 8);
  SPI.transfer(color);
  digitalWrite(CS, LOW);
  SPI.endTransaction();

}

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


  for (; y0 <= y1 ; y0++) {

    drawPixel (x0, y0, color);

  }


}

void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
{

  drawLine(x, y, x, y + h - 1, color);
}

void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
{
  for (int16_t i = x; i < x + w; i++) {
    drawFastVLine(i, y, h, color);
  }
}
void background (uint16_t color) {
  fillRect(0, 0, 120, 150, color);

}

uint16_t newColor(uint8_t r, uint8_t g, uint8_t b)
{
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}

void background(uint8_t red, uint8_t green, uint8_t blue)
{
  background(newColor(red, green, blue));
}

void commandList(const uint8_t *addr) {

  uint8_t  numCommands, numArgs;
  uint16_t ms;

  numCommands = pgm_read_byte(addr++);   // Number of commands to follow
  while (numCommands--) {                // For each command...
    writecmd(pgm_read_byte(addr++)); //   Read, issue command
    numArgs  = pgm_read_byte(addr++);    //   Number of args to follow
    ms       = numArgs & DELAY;          //   If hibit set, delay follows args
    numArgs &= ~DELAY;                   //   Mask out delay bit
    while (numArgs--) {                  //   For each argument...
      writedata(pgm_read_byte(addr++));  //     Read, issue argument
    }

    if (ms) {
      ms = pgm_read_byte(addr++); // Read post-command delay time (ms)
      if (ms == 255) ms = 500;    // If 255, delay for 500 ms
      delay(ms);
    }
  }
}

void setup() {
  Serial.begin(9600);
  pinMode(CS, OUTPUT);
  pinMode(DC, OUTPUT);
  pinMode(RST, OUTPUT);

  SPI.begin();

  SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz (half speed)

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);

  digitalWrite(CS, LOW);
  digitalWrite(RST, HIGH); //Reset
  delay(500);
  digitalWrite(RST, LOW);
  delay(500);
  digitalWrite(RST, HIGH);
  delay(500);
  commandList(Gcmd);

  /* writecmd(0x01);      // COMMANDE POUR ACTIVER L ECRAN MAIS NE FONCTIONNE PAS
     delay(50);
     writecmd(0x11);
     delay(500);
       writecmd(0x13);
     delay(10);
     writecmd(0x29);
     delay(500);*/
 // SPI.beginTransaction(SPISettings(4000000L, MSBFIRST, SPI_MODE0));
  //background (0, 25, 0); //bleu
  fillRect(0, 0, 128, 160, 0xf0f0);
  fillRect(0, 0, 128, 160, 0xFFFF);
  // SPI.endTransaction();
  Serial.println("..FINISH");
}

void loop() {
  // put your main code here, to run repeatedly:

}


J'aimerai initialiser le strick minimum pour que l'écran m'affiche mes pixels, a une vitesse raisonnable, Je vais essayer d'enlever le maximum dans Gcmd


BossOfScandalz

#28
Jan 29, 2017, 10:52 am Last Edit: Jan 29, 2017, 11:01 am by BossOfScandalz
Du coup j'ai trouvé une config minimum pour faire fonctionner le tft:
Code: [Select]
writecmd(0x36);  //Memory data access control
  writedata(0x40);
  writedata(0x80);
  writedata(0x08);


  writecmd(0x11);
  delay(100);


  writecmd(0x3A); // pixel format (nécessaire au fonctionnement)
  writedata(0x05);
  delay(100);

  writecmd(0x29);
  delay(500);


Par contre affichage de tous les pixels, temps=3secondes (voir plus)

J'ai également testé d'intégrer la lib mirf avec toujours le même programme de test:
Code: [Select]
void nrf24() {
  unsigned long time_message = millis(); // On garde le temps actuel retourné par millis()

  Serial.print("Ping ... ");
  Mirf.send((byte *) &time_message); // On envoie le temps actuel en utilisant une astuce pour transformer le long en octets
  while (Mirf.isSending()); // On attend la fin de l'envoi

  // Attente de la réponse
  while (!Mirf.dataReady()) { // On attend de recevoir quelque chose
    if (millis() - time_message > 1000 ) { // Si on attend depuis plus d'une seconde
      Serial.println("Pas de pong"); // C'est le drame ...
      return;
    }
  }

  // La réponse est disponible
  Mirf.getData((byte *) &time_message); // On récupère la réponse

  // On affiche le temps de latence (sans division par deux)
  Serial.print("Pong: ");
  Serial.print(millis() - time_message);
  Serial.println("ms");

}

Le programme affiche ping ... pong 57846256ms (le chiffre varie)
Donc pour moi la ligne MOSI de l'arduino pollue le nrf. Sur la partie récepteur, aucune donné est reçu et envoyée.

J'ai également testé de rajouter avec le nrf
Code: [Select]

 SPI.beginTransaction(SPISettings(10000000L, MSBFIRST, SPI_MODE0));
  nrf24 ();
  SPI.endTransaction();
SPI.beginTransaction(SPISettings(4000000L, MSBFIRST, SPI_MODE0));
  fillRect(0, 0, 128, 160, 0xFFFF);
  SPI.endTransaction();

La fréquence est bonne pour le spi du nrf ?

Affaire a suivre

sylvainmahe

#29
Jan 29, 2017, 02:19 pm Last Edit: Jan 29, 2017, 02:21 pm by sylvainmahe
Le datasheet de l'ATmega328P ne certifie pas une vitesse SPI au delà de la fréquence d'horloge divisée par 4, soit 16Mhz / 4 = 4Mhz dans ton cas.

C'est ce que je programme dans un soucis de rester dans les données constructeur, après, tout est possible j'ai envie de dire...

Sans connaître ce qu'il y a dans la fonction SPISettings que tu utilises, je dirais que:
Code: [Select]
SPI.beginTransaction(SPISettings(10000000L, MSBFIRST, SPI_MODE0));
Fait tourner le SPI à 10Mhz (le max il me semble), et:
Code: [Select]
SPI.beginTransaction(SPISettings(4000000L, MSBFIRST, SPI_MODE0));
à 4Mhz.

Le nRF24L01P qu'en à lui est donné pour 10Mbps max (soit 10Mhz dans ce cas)(voir ici ou page 8 du datasheet).


Bravo pour tes tests sinon, je vois que tu ne lâches pas. Espérons que tu y arrives mais c'est clair que c'est chiant de bosser avec du code pourri.

Go Up