Dernière révision : septembre 2023










Projet Arduino n° 6

Philippe Notez (philippe.notez@musee-info.fr)





Sommaire

Introduction

L’électronique et l’informatique ont profondément modifié notre société. C’est certainement la révolution industrielle la plus rapide de l’histoire de l’humanité. En effet, l’ordinateur que nous connaissons aujourd’hui était tout simplement inimaginable il y a seulement une cinquantaine d’années. Et avec les Arduino, les ESP8266 ou les Raspberry Pi Pico, l'aventure est loin d'être terminée.

L’auteur ne pourra en aucun cas être tenu responsable des dommages qui résulteraient de l’utilisation des informations publiées sur ce site, sous licence Creative Commons BY-NC-SA. Toute reproduction ou modification d'un document, même partielle, est autorisée à condition que son origine et le nom de l'auteur soient clairement indiqués (BY), qu'il soit utilisé à des fins non commerciales (NC), que son mode de diffusion soit identique au document initial (SA), et que cela ne porte pas atteinte à l’auteur.

Ce document présente un projet utilisant une carte Arduino, en espérant toujours être le plus clair et précis possible. Malgré tout le soin apporté à la rédaction, l'auteur vous remercie de bien vouloir le contacter si vous relevez la moindre erreur ou omission, et vous souhaite une agréable lecture.

Si vous avez apprécié ce document, vous pouvez faire un don ici. Merci pour votre soutien.


Objectif

Générer une courbe à l'aide d'un module MCP4725 (DAC 12 bits I2C).


Niveau




Matériel utilisé
  • une carte Arduino (j'utilise une carte Arduino Due, mais vous pouvez utiliser une autre carte)
  • un module MCP4725
  • des câbles Dupont
  • un câble USB pour la liaison avec l'ordinateur

Programme (sketch)

La compilation pour un Arduino Due génère une erreur. Pour la corriger, il faut modifier le fichier ~/.arduino.../packages/arduino/hardware/sam/.../platform.txt en ajoutant -fpermissive à la fin de la ligne compiler.cpp.flags.

mcp4725_2.ino
// générer une courbe à l'aide d'un module MCP4725 (DAC 12 bits I2C)

#include <Wire.h>
#include <Adafruit_MCP4725.h>

#define texte_erreur "Erreur sur la saisie !"

Adafruit_MCP4725 dac;
unsigned char type_courbe=0;
int val_fixe,nbr_pas,nbr_cycles;
long periode,duree_pas;

void setup(void)
  {
  Wire.begin();
  dac.begin(0x60);          // adresse I2C (0x60 ou 0x62)
  dac.setVoltage(0,false);  // false : ne pas enregistrer la valeur dans l'EEPROM
  Serial.begin(9600);
  Serial.write(13);
  Serial.write(10);
  modif_par();
  }

void loop(void)
  {
  int compteur,num_pas,valeur;
  float val_angle,pas;
  unsigned long debut;

  if (type_courbe==48) dac.setVoltage(val_fixe,false);
  else
    {
    if (nbr_cycles==-1) compteur=1;
    else compteur=nbr_cycles;
    while (compteur>0)
      {
      num_pas=0;
      switch (type_courbe)
        {
        // sinus
        case 49 :
          val_angle=-PI/2;
          pas=(2*PI)/nbr_pas;
          while (num_pas<nbr_pas)
            {
            valeur=2048+(sin(val_angle)*2047);  // 1 à 4095
            dac.setVoltage(valeur,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            val_angle+=pas;
            num_pas++;
            }
          break;
        // demi-sinus
        case 50 :
          val_angle=0;
          pas=PI/nbr_pas;
          while (num_pas<nbr_pas)
            {
            valeur=sin(val_angle)*4095; // 0 à 4095
            dac.setVoltage(valeur,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            val_angle+=pas;
            num_pas++;
            }
          break;
        // demi-sinus (demi-période)
        case 51 :
          val_angle=0;
          pas=PI/(nbr_pas/2);
          while (num_pas<(nbr_pas/2))
            {
            valeur=sin(val_angle)*4095; // 0 à 4095
            dac.setVoltage(valeur,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            val_angle+=pas;
            num_pas++;
            }
          while (num_pas<nbr_pas)
            {
            dac.setVoltage(0,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            num_pas++;
            }
          break;
        // triangle
        case 52 :
          pas=8192/nbr_pas;
          valeur=0;
          while (num_pas<nbr_pas)
            {
            dac.setVoltage(valeur,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            if (num_pas<(nbr_pas/2)) valeur+=pas;
            else valeur-=pas;
            num_pas++;
            }
          break;
        // triangle (demi-période)
        case 53 :
          pas=16384/nbr_pas;
          valeur=0;
          while (num_pas<(nbr_pas/2))
            {
            dac.setVoltage(valeur,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            if (num_pas<(nbr_pas/4)) valeur+=pas;
            else valeur-=pas;
            num_pas++;
            }
          while (num_pas<nbr_pas)
            {
            dac.setVoltage(0,false);
            debut=millis();
            while (millis()-debut<duree_pas) ;
            num_pas++;
            }
        }
      if (nbr_cycles!=-1) compteur--;
      }
    }
  }

void modif_par()
  {
  unsigned char car=0,i=0,tab_val_fixe[5],tab_nbr_pas[5],tab_periode[7],tab_nbr_cycles[5],saisie=0;

  // type de courbe
  Serial.write("Entrez le type de courbe (0 = valeur fixe, 1 = sinus, 2 = demi-sinus, 3 = demi-sinus (demi-période), 4 = triangle, 5 = triangle (demi-période) : ");
  while (car!=13) if (Serial.available()>0)
    {
    car=Serial.read();
    if (car!=13) type_courbe=car;
    }
  if ((type_courbe<48) || (type_courbe>53))
    {
    Serial.write(13);
    Serial.write(10);
    Serial.write(13);
    Serial.write(10);
    Serial.write(texte_erreur);
    delay(1000);
    exit(0);
    }
  Serial.write(type_courbe);
  Serial.write(13);
  Serial.write(10);
  Serial.write(13);
  Serial.write(10);
  // valeur fixe
  if (type_courbe==48)
    {
    Serial.write("Entrez la valeur (1 à 4095 = 1,22 mV à 5 V) : ");
    car=0;
    while ((car!=13) && (i<4)) if (Serial.available()>0)
      {
      car=Serial.read();
      if (car!=13) tab_val_fixe[i++]=car;
      }
    while (car!=13) car=Serial.read();
    tab_val_fixe[i]=0;
    val_fixe=atoi(tab_val_fixe);
    if ((val_fixe<1) || (val_fixe>4095))
      {
      Serial.write(13);
      Serial.write(10);
      Serial.write(13);
      Serial.write(10);
      Serial.write(texte_erreur);
      delay(1000);
      exit(0);
      }
    Serial.write(tab_val_fixe,strlen(tab_val_fixe));
    Serial.write(13);
    Serial.write(10);
    Serial.write(13);
    Serial.write(10);
    }
  else
    {
    // nombre de pas pour une période
    // 10 pas --> 1000 mV / pas
    // 20 pas ---> 500 mV / pas
    // 50 pas ---> 200 mV / pas
    // 100 pas --> 100 mV / pas
    // 200 pas ---> 50 mV / pas
    // 500 pas ---> 20 mV / pas
    // 1000 pas --> 10 mV / pas
    // 2000 pas ---> 5 mV / pas
    Serial.write("Entrez le nombre de pas pour une période (10, 20, 50, 100, 200, 500 ou 1000) : ");
    car=0;
    i=0;
    while ((car!=13) && (i<4)) if (Serial.available()>0)
      {
      car=Serial.read();
      if (car!=13) tab_nbr_pas[i++]=car;
      }
    while (car!=13) car=Serial.read();
    tab_nbr_pas[i]=0;
    nbr_pas=atoi(tab_nbr_pas);
    if ((nbr_pas!=10) && (nbr_pas!=20) && (nbr_pas!=50) && (nbr_pas!=100) && (nbr_pas!=200) && (nbr_pas!=500) && (nbr_pas!=1000))
      {
      Serial.write(13);
      Serial.write(10);
      Serial.write(13);
      Serial.write(10);
      Serial.write(texte_erreur);
      delay(1000);
      exit(0);
      }
    Serial.write(tab_nbr_pas,strlen(tab_nbr_pas));
    Serial.write(13);
    Serial.write(10);
    Serial.write(13);
    Serial.write(10);
    // période (604800 s = 7 jours)
    Serial.write("Entrez la période (1 à 604800 s) : ");
    car=0;
    i=0;
    while ((car!=13) && (i<6)) if (Serial.available()>0)
      {
      car=Serial.read();
      if (car!=13) tab_periode[i++]=car;
      }
    while (car!=13) car=Serial.read();
    tab_periode[i]=0;
    periode=atol(tab_periode);
    if ((periode<1) || (periode>604800))
      {
      Serial.write(13);
      Serial.write(10);
      Serial.write(13);
      Serial.write(10);
      Serial.write(texte_erreur);
      delay(1000);
      exit(0);
      }
    duree_pas=(periode*1000)/nbr_pas;
    Serial.write(tab_periode,strlen(tab_periode));
    Serial.write(13);
    Serial.write(10);
    Serial.write(13);
    Serial.write(10);
    // nombre de cycles
    Serial.write("Entrez le nombre de cycles (1 à 9999, -1 = infini) : ");
    car=0;
    i=0;
    while ((car!=13) && (i<4)) if (Serial.available()>0)
      {
      car=Serial.read();
      if (car!=13) tab_nbr_cycles[i++]=car;
      }
    while (car!=13) car=Serial.read();
    tab_nbr_cycles[i]=0;
    nbr_cycles=atoi(tab_nbr_cycles);
    if ((nbr_cycles<-1) || (nbr_cycles==0) || (nbr_cycles>9999))
      {
      Serial.write(13);
      Serial.write(10);
      Serial.write(13);
      Serial.write(10);
      Serial.write(texte_erreur);
      delay(1000);
      exit(0);
      }
    Serial.write(tab_nbr_cycles,strlen(tab_nbr_cycles));
    }
  }







Documentation complémentaire

Haut de page