Dernière mise à jour le 12/01/2021

Présentation


Dans cette rubrique nous allons voir comment programmer la cam OpenMV en maitre afin que celle-ci communique avec le PIC18F4550 (esclave) sur le bus I2C. J’ai été surpris!! En effet il y a un décalage de bits à réaliser vers la droite  au niveau de l’adressage (1er octet), soit pour la cam OpenMV soit pour le PIC18F4550 mais pas les 2 à la fois!!. D’ailleurs j’en profite pour vous dire que ce décalage est aussi présent niveau du 1er octet entre le PIC et un Arduino UNO, il doit aussi être réaliser et pour démonstration vous pouvez vous rendre sur ce lien Communication I2C – Mode Ecriture – Arduino(Maitre) -> PIC 18F4550 (Esclave)
Nous verrons comment voir un tel décalage, et pour cela, nous allons nous servir de la cam OpenMV M7 qui utilise un processeur STM32F765VI ARM Cortex a 216 MHz, mais la version plus récente qui est la cam OpenMV H7 quant à elle utilise un processeur ARM Cortex M7 fonctionnant a 400 MHz. La différence vous l’aurez compris plus rapide pour le traitement d’image par exemple. Mais en ce qui concerne la liaison I2C le principe reste le même il ne faut pas oublier de décaler ce fameux bit vers la droite pour communiquer entre  microcontrôleur camOpenMV (ou Arduino UNO).

Compatibilité python OpenMV vers PIC18F4550 – tests EasyPicV7 – recherche adresse


Décalage d’adresse pour compatibilité ?
oui! effectivement, il faut réaliser un décalage car sinon rien ne fonctionne pas!.

Un jour je me suis posé la question si il était possible de brancher directement mon PIC18F4550 via les broches RB0(SDA) et RB1(SCL) sur les broches de la cam OpenMV qui sont P4(SCL) et P5(SDA) – ou P7(SCL) et P8(SDA) avec des résitances de tirages à 1K ohm. Pour la cam OpenMV, j’ai choisi P4 et P5 pour la création du BUS 2, et apres quelque ligne de code j’ai exécuté le script Python et là c’est le drame !! rien ne fonctionnais et aucune réception niveau PIC. Hum ?! Pourquoi ?


Pour en avoir le cœur net, j’ai donc envoyé directement l’adresse cAdrr = 0x02 sur afin que le PORTD éclaire la led RD1, et à ce moment je me suis rendu compte que c’était RD2 d’allumé et non RD1 – 1bit de plus sur la droite donc décalage à gauche !.


En réfléchissant je me suis rendu compte qu’il y a décalage vers la gauche à cause de ce bit suplémentaire (bit de poids faible)!! bizarre ?!
J’ai donc décalé l’adresse cAdrr = 0x02 >> 1 (côté cam OpenMV) vers la droite pour retirer ce bit supplémentaire afin que ce ne ça soit pas la led RD2 mais bien RD1. Après plusieurs test que nous allons voir un peu plus bas tout fonctionne à merveille et la cam OpenMV est désormais compatible avec le PIC18F4550!!


D’une manière général, si par exemple:

– cAdrr = 0x02 >> 1 (côté cam OpenMV) alors cAdrr = 0x02 (côté PIC) pour compatibilité !

– cAdrr = 0x02 (côté cam OpenMV) alors cAdrr = 0x04 (côté PIC) pour compatibilité !

Toujours réaliser le décalage de 1 (>> 1 ) côté cam OpenMV ou Arduino UNO !

Cam OpenMV (Maître) – PIC18F4550 (Esclave)


MAÎTRE – Programmation Python – Cam OpenMV STM32F765VI ARM

# Maître – OpenMV I2C – Python – Electronique71.com

from pyb import I2C
import utime

i2c = I2C(2) # creation du bus I2C
i2c.init(I2C.MASTER, baudrate=100000) # initialisation du maître sur 100Khz

# 0x02 >> 1 : +1 bit à droite (décalage vers la gauche de l'adresse donne 0x04 pour PIC)
cAdrr = 0x02 >> 1
# si cAdrr = 0x02 côté cam OpenMV alors mettre cAdrr = 0x04 côté PIC18F4550 pour compatibilité !

while(True):

    # Vérifie si l'esclave répond à cette adresse:
    # -> renvoi True si l'esclave répond
    # -> renvoi False si l'escalve ne répond pas
    validation = i2c.is_ready(cAdrr)

    if (validation == True):
        i2c.send('A', addr = cAdrr) # Ecriture caractère 'A' led RD0 et RD6 allumées
        utime.sleep_ms(500)

        i2c.send('B', addr = cAdrr) # Ecriture caractère 'B' led RD1 et RD6 allumées
        utime.sleep_ms(500)

        i2c.send(0x01, addr = cAdrr) # Ecriture hexa '0x01' led RD0 allumé
        utime.sleep_ms(500)

        i2c.send(0xF0, addr = cAdrr) # Ecriture hexa '0xF0' led RD4 à RD7 allumées
        utime.sleep_ms(500)


Fonctionnement programmation Python

Dans le programme python ci-dessus, j’ai fixé une adresse nommée “cAdrr” de valeur 0x02 en hex (soit 2 en decimal ou bien 00000010b en binaire) mais comme vous pouvez le constater j’ai réalisé via l’opérateur ‘>>’ un décalage de 1 bit vers la gauche je rajoute en définitive 1 bit vers la droite pour que l’adresse se décale entièrement vers la gauche et je me retrouve non plus à 0x02 comme adresse mais à 0x04!! (soit 4 en décimal ou bien 00000100b en binaire), c’est la ou réside la subtilité afin de pouvoir communiquer avec le PIC18F4550 qui lui pour le coup est configuré en esclave avec pour adresse cAdrr = 0x02 qu’il ne faudra pas changer!.
Pour la suite, une fois que l’adresse a été vérifiée et validé, la cam ne fais que d’envoyer des données au PIC18F4550 qui lui les affichera sur son PORTD.


Lettre A donne un code binaire 01000001b soit 41h (h = hexa) soit led RD0 et RD6 allumées sur platine
Lettre B donne un code binaire 01000010b soit 42h (h = hexa) soit led RD1 et RD6 allumées sur platine
0x01 donne un code binaire 00000001b soit led RD0 allumé sur platine
0xF0 donne un code binaire 11110000b soit led RD4 à RD7 allumées sur platine

Bien sûr rien ne vous empêche de faire l’inverse c’est à dire de mettre pour le PIC cAdrr = 0x04 et garder pour la cam OpenMV cAdrr = 0x02 car le décalage a été réalisé cette fois-ci côté PIC !!.

ESCLAVE – Programmation MikroC – PIC18F4550

// Esclave – PIC18F455 I2C – MikroC – Electronique71.com

const cAdrr = 0x02; // cAdrr = 0x02 correspond à l'adresse de l'esclave
// Si cAdrr = 0x04 côté PIC alors mettre cAddr = 0x02 côté cam OpemMV pour compatibilité !

void interrupt() // On contrôle chaque interruptions
{
  if (PIR1.SSPIF == 1)
  {
    // SSPSTAT.R_W  -> bit0 = 1: Lecture  ou  bit0 = 0: Ecriture
    if (SSPSTAT.R_W == 1)
    {
      // Lecture -> Esclave vers Maître
      SSPBUF = 0xF0;   // Données sont ajoutée dans le buffer pour la lecture
    }
    else if (SSPSTAT.R_W == 0)
    {
      // Ecriture -> Maître vers Esclave
      LATD = SSPBUF;   // Affichage des données envoyée par le maitre pour ecriture
    }

  }

    SSPCON1.CKP = 1; // On relache l'horloge pour lancer la suite
    PIR1.SSPIF = 0;  // On remet à zéro le drapeau d'interruption et on attent la prochaine !
}

void init()
{

  ADCON1 = 0xFF;      //  On configure toutes les broches en numérique (0 ou 1)

  ADCON0.ADON = 0;   // On désactive le module de convertisseur analogique numérique

  CMCON = 0x07;      // On désactive le mode comparateur

  TRISB = 0x03;      // config les broches du PORTB - RB0 et RB1 comme entrée (SDA/SCL)
  PORTB = 0x00;
  LATB = 0x00;

  TRISD = 0x00;      // Configuration PORTD en sortie pour la lecture
  PORTD = 0x00;
  LATD = 0x00;

  INTCON.GIE = 1;    // On active les interruptions globales 
  INTCON.PEIE = 1;   // On active les interruptions périphériques 
 
  PIE1.SSPIE = 1;    // On active le MSSP ( Module port série synch principal I2C ou SPI) 
  PIR1.SSPIF = 0;    // On met le drapeau d'interrutpion à zéro pour commencer 
 
  SSPCON1.SSPEN = 1; // On active les broches RB0 et RB1 en mode SDA et SCL
 
  // On active le mode 7 bits (0 à 7 = 8 bits) avec interruptions sur bit Start et Bit Stop 
  SSPCON1.SSPM0 = 0;
  SSPCON1.SSPM1 = 1;
  SSPCON1.SSPM2 = 1;
  SSPCON1.SSPM3 = 1;

  SSPADD = cAdrr;    // Configuration de l'adresse de l'esclave du PIC 18F4550

  SSPSTAT.SMP = 1;   //  vitesse de communication 100 Khz (standard)

  SSPCON2.SEN = 1;   // On active l'étirement de l'horloge

  Delay_ms(100);     // On attend un peu la fin de l'initialisation
}

void main()
{
  init(); // Initialisation du PIC18F4550

  while (1)
  {
    // On ne fait rien ...
  }
}


Fonctionnement programmation MikroC

Rien de particulier à dire, le PIC18F4550 est configuré en mode esclave pour plus de détails vous rendre sur ce lien PIC18F4550 – mode esclave (slave)


Conclusion

Ces deux programmation (Python et MikroC) permet uniquement via la cam OpenMV programmer en tant que maître d’envoyer des données sur l’esclave qui est le PIC18F4550 à l’adresse correspondante. Une fois les données reçues, le PIC18F4550 va gérer ces données par l’intermédiaire des interruptions afin de renvoyer les valeurs lues qui émane du maître et de les afficher sur son PORTD (allumées les différentes led du PORTD). Le but recherché dans ce chapitre était uniquement d’arriver à faire dialoguer la cam et le PIC18F4550 ensemble.

Test sur platine EasyPIC V7


L’envoi des données via la cam OpenMV sont récupéré par les interruptions du PIC18F4550 afin qu’il affiches sur le PORTD ces données. On remarque bien toutes les 500ms un changement d’état ce qui permet d’afficher les leds de la platine EasyPIC V7.

Le cablâge est réalisés sur le PORTC broche RC3(SCL) vers RB1(SCL du PIC18F4550) et RC4(SDA) vers RB0(SDA du PIC18F4550). En effet ce pont entre le PORTC permet de ramener les résistances de 4k7 sur le PORTB où sont reliés les broches SDA et SCL du PIC18F4550 situé sur la platine EasyPicV7. Ne pas oublier de placer les switchs (SW4) RC3 et RC4 en postion “ON” afin de mettre en circulation les résistances PULL-UP de 1K ohm de la platine EasyPicV7.

    
  (‘A’ donne 01000001b)          (‘B’ donne 01000010b)

      
 (0x01 donne 00000001b)        (0xF0 donne 11110000b)

Historiques


12/01/2021
– Ajout commentaire sur cAdrr = 0x02 (cam OpenMV) et cAdrr = 0x04 (PIC18F4550)

10/01/2021
-1er mise à disposition