DIY : Fabriquer Un Ohmmètre Numérique À Base D’Arduino !

Introduction: DIY : Fabriquer Un Ohmmètre Numérique À Base D’Arduino !

About: Passionné d'électronique numérique et de nouvelle technologie ! https://www.youtube.com/channel/UCl9vi6y04pBl-RajOrFJI8g?view_as=subscriber

Salut à tous dans cet instructables je vais vous partager comment réaliser un Ohmmètre très simplement qui peut effectuer des mesures précises !

Step 1: Intro

Salut à tous dans cet instructables je vais vous partager un petit projet que j'ai réalisé, c'est un Ohmmètre numérique basé sur Arduino, il peut mesurer différente valeur de résistance dans une plage de 100Ω à1MΩ avec une précision qui dépend principalement du pourcentage de tolérance de vos résistances qui varie de 1% à 10%, j'ai ajouté un écran Oled de 0.96'pouce pour afficher la valeur de la résistance mesuré directement ainsi que quelque fonction graphique qui donne un coté finis à cet ohmmètre.

Step 2: Le Principe De Fonctionnement

Sans plus tarder rentrons dans le vive du sujet, alors comment faire pour mesurer la valeur d’une résistance ? c’est extrêmement simple, tout repose sur un montage basique en électronique qu’est le pont diviseur de tension non chargé, son nom est particulièrement explicite, à l’aide de deux résistance vous pouvez abaisser la tension en sortie du pont diviseur avec un calcul très simple. Par exemple nous avons 5V en entré et nous souhaitons une tension de 3.3v pour adapter la tension pour ensuite utiliser un capteur, de ce fait il faut dimensionner les résistance R1 et R2 de sorte à obtenir 3.3v, premièrement on fixe la valeur de la résistance de référence la résistance R2 à 1000 Ω et en retournant l’expression ont déduit que R1 vaut 500 Ω environ et nous obtenons bien nos 3.3v en sortie du montage. Nous allons justement utiliser le même principe de fonctionnement, R2 sera la résistance de référence connu dans le code et R1 sera la résistance mesurée, en connaissant tous les paramètre, tension d’entrée et de sortie, Ve et Vs, R2=1000 Ω nous pouvons déduire la résistance mesurée.

Step 3: Et Au Niveau De L'Arduino ?

Alors comment tout cela s’articule au niveau de l’Arduino,
alors en sortie du pont diviseur nous aurons une entré analogique qui va lire la valeur en sortie du pont diviseur, les valeurs récupérer sur l’Arduino sont codé sur 10bit soit 1023 valeur, la valeur 1023 signifie 5v, la valeur 512 2.5v et ainsi de suite, du coup avec une petite règle de trois vous déduisez la tension de sortie et vous l’injecter dans le calcul et enfin vous déduisez la résistance mesurée. Voilà en gros le principe.

Néanmoins il y à une petite subtilité qu’il faut que je vous explique, dès que vous souhaitez mesurer une résistance supérieure à celle de référence, admettons 10kΩ la tension sera très faible et un phénomène de chute de tension rendra la mesure totalement imprécise avec des % d’erreur énorme, de ce fait il faut augmenter la valeur de la résistance de référence, on retrouve le même principe avec un voltmètre ou un ampèremètre ou l’on doit changer de calibre manuellement ou automatiquement pour avoir une mesure précise, de ce fait j’ai fait en sorte que l’ajustement du bon calibre ce fasse automatiquement pour une mesure optimale et surtout qu’on ait pas à le faire, pour ma part j’ai ajouté 4 calibre ou quatre résistance si vous voulez, qui vont de 0 à 1kΩ, de 1kΩ à 10kΩ, de 10kΩ à 100kΩ et enfin de 100kΩ à un 1MΩ, plus vous ajouter de calibre plus ce sera précis logiquement même si on obtient des valeurs assez précise et stable avec ces quatre valeur différente de résistance de référence.

Step 4: Changement De Calibre/résistance

Mais concrètement comment est-ce que nous allons nous y prendre pour changer de résistance sans agir manuellement ? pour ce faire nous allons commander les entrées digitales de sorte qu’elle soit en haute impédance ce qui veut dire ni à l’état bas ni à l’état haut mais équivalent à un circuit ouvert en déclarant la broche en input avec la fonction pinmode, donc quand les broches sont en haute impédance c’est que nous les utilisons pas, à contrario pour choisir la résistance de référence que l’on souhaite ont met la broche voulu en output et on met à l’état bas la broche pour générer une masse sur cette broche et de ce fait rendre la résistance comme celle étant de référence, et de l’autre côté nous avons la broche 13 qui sera continuellement à l’état haut soit 5V .

Step 5: Le Code

El famoso le code,

Au niveau du code, il y à 4 grande étape à chaque passage dans la boucle, la première est de lire la valeur de la broche analogique en sortie du pont diviseur de tension, seconde étape convertir la valeur en tension, ensuite injecter la valeur de la tension dans le calcul et obtenir la valeur de la résistance et enfin dans un if, si la valeur de la résistance mesuré est inférieure à la résistance de référence on reste dans le if et on affiche la valeur à l’écran oled, sinon on change de calibre donc on augmente la valeur de la résistance de référence jusqu’à que la résistance mesuré soit dans le bon calibre. J’ai rajouté une petite fonction qui est plutôt gadget mais intéressant c’est la prise en compte du pourcentage de tolérance d’une résistance, par défaut dans le code j’ai mis 10%, donc par exemple quand ont à une résistance de 1000Ω avec un pourcentage de 10% ce serait inutile d’augmenter de calibre si la résistance mesure 1025Ω admettons car c’est compris dans les 10%, cette fonction je l’ai implémenté dans les différents if.

/* Ohmmeter by DRS_Electronic               */
/* YT Channel :  https://youtu.be/qL6H22AmzxQ*/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

int Ve=13,calibre=1,intervlow=0,intervhigh=0; /* Applique le 5V*/ /*la var calibre permet de changer de calibre de mesure*/
const int ref1=1000,ref2=10000,ref3=100000,ref4=1000000; /*Résistance de référence de différent calibre*/
const int etat_bas1= 5;
const int etat_bas2= 6;
const int etat_bas3= 7;
const int etat_bas4= 8; /* D5 pour ref1 | D6 pour ref2 | D7 pour ref3 | D8 pour ref4 */
int Rm=0; /* Résistance à mesurer */
float buffer=0,input=A0,Vs=0; /* la variable buffer récupère la tension mesuré | input est la sonde de tension | Vs la tension de sortie*/
int x=1,y=1,i=0; /* variable qui commande la position de la fonction ohmlogo | i est utilisé dans le setup*/

void setup()
{
Serial.begin(9600);
pinMode(Ve, OUTPUT);
pinMode(etat_bas1, OUTPUT);
pinMode(etat_bas2, OUTPUT);
pinMode(etat_bas3, OUTPUT);
pinMode(etat_bas4, OUTPUT);
pinMode(input, INPUT);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.setTextSize( 2 );
display.setTextColor( WHITE );
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20,6);
display.println("Ohmmetre");
display.setTextSize(1);
display.setCursor(20,25);
display.println("By DRS");
ohmlogo();
res();
for(i=0;i<=100;i++)
{
display.setTextSize( 2 );
display.setTextColor( WHITE );
display.clearDisplay();
display.setTextSize(2);
display.setCursor(20,6);
display.println("Ohmmetre");
display.setTextSize(1);
display.setCursor(20,25);
display.println("By DRS");
ohmlogo();
res();
display.setTextSize(2);
display.setCursor(65,35);
display.print(i);
display.println(" %");
delay(15);
display.display();
}
delay(500);
}

void loop()
{
switch(calibre){
case 1: /* calibre 0-1k*/
Serial.println("Cas n°1");
delay(500);
digitalWrite(Ve, HIGH); /* Applique le 5v */
pinMode(etat_bas1,OUTPUT); /* GND */
pinMode(etat_bas2, INPUT); /* HZ */
pinMode(etat_bas3, INPUT); /* HZ */
pinMode(etat_bas4, INPUT); /* HZ */
digitalWrite(etat_bas1, LOW);
Vs = analogRead(input);
buffer = ((Vs/1024.0)*5);
Rm = (((5/buffer)-1)*ref1);
intervlow = ref1-(ref1*0.1);
intervhigh = ref1+(ref1*0.1);
if(Rm==0){ rmnull(); }
else{
if(((Rm>=intervlow)&&(Rm<=intervhigh)) || (Rm<=ref1)){
display.clearDisplay();
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(5,20);
display.println("La resistance vaut: ");
display.setTextSize(2);
display.setCursor(15,35);
display.print(Rm);
display.println(" Ohm");
display.display();
calibre=1;
delay(2500);
}
else{
calibre = 2; /* permet de changer le calibre */
}
}
break;
case 2: /* calibre 1k-10k*/
Serial.println("Cas n°2");
delay(500);
digitalWrite(Ve, HIGH); /* Applique le 5v */
pinMode(etat_bas2, OUTPUT); /* GND */
pinMode(etat_bas1, INPUT); /* HZ */
pinMode(etat_bas3, INPUT); /* HZ */
pinMode(etat_bas4, INPUT); /* HZ */
digitalWrite(etat_bas2, LOW);
Vs = analogRead(input);
buffer = ((Vs/1024.0)*5);
Rm = (((5/buffer)-1)*ref2);
intervlow = ref2-(ref2*0.1);
intervhigh = ref2+(ref2*0.1);
if(Rm==0){ rmnull(); }
else{
if((Rm>=intervlow)&&(Rm<=intervhigh) || (Rm<=ref2)){
display.clearDisplay();
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(5,20);
display.println("La resistance vaut: ");
display.setTextSize(2);
display.setCursor(15,35);
display.print(Rm);
display.println(" Ohm");
display.display();
calibre=1;
delay(2500);
}
else{
calibre = 3; /* permet de changer le calibre */
}
}
break;
case 3:
Serial.println("Cas n°3");
delay(500); /* calibre 10k-100k*/
digitalWrite(Ve, HIGH); /* Applique le 5v */
pinMode(etat_bas3, OUTPUT); /* GND */
pinMode(etat_bas1, INPUT); /* HZ */
pinMode(etat_bas2, INPUT); /* HZ */
pinMode(etat_bas4, INPUT); /* HZ */
digitalWrite(etat_bas3, LOW);
Vs = analogRead(input);
buffer = ((Vs/1024.0)*5);
Rm = (((5/buffer)-1)*ref3);
intervlow = ref3-(ref3*0.1);
intervhigh = ref3+(ref3*0.1);
if(Rm==0){ rmnull(); }
else{
if((Rm>=intervlow)&&(Rm<=intervhigh) || (Rm<=ref3)){
display.clearDisplay();
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(5,20);
display.println("La resistance vaut: ");
display.setTextSize(1);
display.setCursor(15,35);
display.print(Rm);
display.println(" Ohm");
display.display();
calibre=1;
delay(2500);
}
else{
calibre = 4; /* permet de changer le calibre */
}
}
break;
case 4:
Serial.println("Cas n°4");
delay(500); /* calibre 100k-1M*/
digitalWrite(Ve, HIGH); /* Applique le 5v */
pinMode(etat_bas3, OUTPUT); /* GND */
pinMode(etat_bas1, INPUT); /* HZ */
pinMode(etat_bas2, INPUT); /* HZ */
pinMode(etat_bas4, INPUT); /* HZ */
digitalWrite(etat_bas3, LOW);
Vs = analogRead(input);
buffer = ((Vs/1024.0)*5);
Rm = (((5/buffer)-1)*ref4);
intervlow = ref4-(ref4*0.1);
intervhigh = ref4+(ref4*0.1);
if(Rm==0){ rmnull(); }
else{
if((Rm>=intervlow)&&(Rm<=intervhigh) || (Rm<=ref4)){
display.clearDisplay();
display.setTextColor(WHITE);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(5,20);
display.println("La resistance vaut: ");
display.setTextSize(1);
display.setCursor(15,35);
display.print(Rm);
display.println(" Ohm");
display.display();
calibre=1;
delay(2500);
}
else{
/* calibre = 4; permet de changer le calibre si vous souhaitez un ajouter un */
}
}
break;
default:
break;
}
}

void ohmlogo(){
display.drawPixel(x+2,y+18,WHITE); display.drawPixel(x+2,y+19,WHITE); display.drawPixel(x+3,y+19,WHITE); display.drawPixel(x+4,y+19,WHITE); display.drawPixel(x+5,y+19,WHITE);
display.drawPixel(x+5,y+18,WHITE); display.drawPixel(x+4,y+17,WHITE); display.drawPixel(x+3,y+16,WHITE); display.drawPixel(x+3,y+15,WHITE); display.drawPixel(x+3,y+14,WHITE); display.drawPixel(x+4,y+13,WHITE); display.drawPixel(x+5,y+12,WHITE);
display.drawPixel(x+6,y+11,WHITE); display.drawPixel(x+7,y+11,WHITE); display.drawPixel(x+8,y+11,WHITE); display.drawPixel(x+9,y+11,WHITE);
display.drawPixel(x+10,y+12,WHITE); display.drawPixel(x+11,y+13,WHITE); display.drawPixel(x+12,y+14,WHITE); display.drawPixel(x+12,y+15,WHITE); display.drawPixel(x+12,y+16,WHITE); display.drawPixel(x+11,y+17,WHITE); display.drawPixel(x+10,y+18,WHITE); display.drawPixel(x+10,y+19,WHITE); display.drawPixel(x+11,y+19,WHITE); display.drawPixel(x+12,y+19,WHITE); display.drawPixel(x+13,y+19,WHITE); display.drawPixel(x+13,y+18,WHITE);
}

void res(){
int x=20; /* variable locale pour controler la postion de la fonction */
display.drawRect(15,x+25,5,1,WHITE); display.drawPixel(20,x+25,WHITE); display.drawPixel(20,x+24,WHITE); display.drawPixel(20,x+26,WHITE); display.drawPixel(21,x+23,WHITE); display.drawPixel(21,x+27,WHITE); display.drawRect(22,x+22,3,1,WHITE); display.drawRect(22,x+28,3,1,WHITE); display.drawRect(25,x+27,16,1,WHITE); display.drawRect(25,x+23,16,1,WHITE); display.drawRect(41,x+22,3,1,WHITE); display.drawRect(41,x+28,3,1,WHITE); display.drawPixel(44,x+23,WHITE); display.drawPixel(44,x+27,WHITE); display.drawPixel(45,x+24,WHITE); display.drawPixel(45,x+25,WHITE); display.drawPixel(45,x+26,WHITE); display.drawRect(46,x+25,5,1,WHITE); display.drawRect(28,x+24,2,3,WHITE); display.drawRect(34,x+24,2,3,WHITE);
}

void rmnull() /*fonction qui gère l'affichage quand la valeur de rm est nulle */
{
display.setTextColor( WHITE );
display.clearDisplay();
display.setTextSize(1);
display.setCursor(10,20);
display.println("Veuillez inserer une resistance");
res();
display.display();
delay(1000);
}

Step 6: Commentaire Sur Le Code

Je vous l'accorde le code est lourd dans sa structure mais si je l'ai articulé ainsi c'est pour pouvoir rajouter autant de résistance/calibre que vous le souhaitez pour accroitre la précision de votre ohmmètre quand bien même celui-là l'est déjà relativement, j'ai opté pour un switch case, un case par calibre, à l'intérieur de ce case deux test type if, le premier vérifie si une résistance est inseré, si aucune résistance est inserée la fonction rmnull(), second if nous testons si la valeur calculée de la résistance contenue dans la variable Rm, si cette dernière est comprise dans la plage de valeur donnée dans ce cas là on affiche la valeur à l'écran oled avec une petite tempo de 2.5s.Dans le cas contraire la valeur du calibre est augmenté et effectue le même test mais avec une autre résistance de référence.


Be the First to Share

    Recommendations

    • Space Contest

      Space Contest
    • Tinkercad Student Design Contest

      Tinkercad Student Design Contest
    • Plastic Challenge

      Plastic Challenge

    4 Comments

    0
    Billy60
    Billy60

    7 months ago on Step 1

    Bonjour, je viens de terminer ce montage et il ne fonctionne que sous le 1e calibre Ref = 1000. Sur les calibres plus forts à partir de Ref = 10 000:
    - l'affichage devient fou. le moniteur série indique des valeurs de Vs erratiques, de 1 à 280.
    - Toutes les R testées affichent: pour une 18K: elle est comptée de 12 à 38 ohms, pour plus fortes, elles sont mesurées à -25576.
    Bref, c'est théorique et ne fonctionne pas si 'correctement'. Y aurait il un correctif ?
    Merci

    0
    DRS_electronic
    DRS_electronic

    Reply 7 months ago

    Bonjour,
    J'ai re-tester le montage cela fonctionne correctement pour ma part...
    En revanche il m'est arrivé quelque embuche lors de la conception de ce dernier que vous pourriez tester :
    ->Sur certain clone notamment les arduino nano la tension en sortie des broches digitale (D13 qui nous intéresse) ne délivre pas 5V ce qui fausse tout le calcul de la valeur -> donc utiliser une alim 5v stabilisé.
    ->Le montage réalisé fonctionne avec des résistance 1/4W
    ->Tolérance des résistances qui induise forcément des écart par rapport à la valeur théorique annoncé par le constructeur
    ->La breadboard est un cauchemars pour les montage dit de précision
    Si vous avez un correctif à me proposer je suis preneur, le principe utilisé est celui présent dans les appareil de mesure numérique à quelque détail prêt. ;)

    0
    Billy60
    Billy60

    Reply 6 months ago

    Je reprends la plume pour vous montrer ce que j'ai trouvé dans les datasheets:


    4.6.1 Analog Input Circuitry
    The analog input circuitry for single ended channels is illustrated in Figure 24-8. An analog
    source applied to ADCn is subjected to the pin capacitance and input leakage of that pin, regardless
    of whether that channel is selected as input for the ADC. When the channel is selected, the
    source must drive the S/H capacitor through the series resistance (combined resistance in the
    input path).
    The ADC is optimized for analog signals with an output impedance of approximately 10 k? or
    less. If such a source is used, the sampling time will be negligible. If a source with higher impedance
    is used, the sampling time will depend on how long time the source needs to charge the
    S/H capacitor, with can vary widely. The user is recommended to only use low impedance
    sources with slowly varying signals, since this minimizes the required charge transfer to the S/H
    capacitor.
    Signal components higher than the Nyquist frequency (fADC/2) should not be present for either
    kind of channels, to avoid distortion from unpredictable signal convolution. The user is advised
    to remove high frequency components with a low-pass filter before applying the signals as
    inputs to the ADC.

    Voilà
    CQFD !
    la Zin effectivement utilisable est bien de 10k , c'est une limite dans l'analogique de l'arduino.
    Donc il faut faire précéder l'entrée A0 du signal venant du pont diviseur par un ampliop suiveur de courant, à gain 1.
    ça devrait aller ainsi.

    0
    Billy60
    Billy60

    Reply 6 months ago

    Bonjour DRS
    Je viens de refaire ce montage sur une Nano en soudant dessus les R et les fils, pour éliminer les faux contacts.
    Le montage fonctionne mieux si je branche le +5V au lieu de D13 HIGH. Je suppose qu'il y a des problèmes dans les impédances d'entrées et de sorties...
    Pour le reste c'est toujours pareil.
    La tolérance des R diviseurs ne fait rien, il suffit de rentrer leur valeur mesurée. Leur Wattage non plus, c'est leur valeur qui compte.
    J'obtiens un bon fonctionnement jusqu'à des res mesurées de 10k.
    Au delà je retrouve l'affichage erroné (valeurs négatives de -25655 etc, variable ...)

    Je l'ai ensuite refait sur une carte Uno. Là toutes les valeurs sont fausses et négatives-23870, puis -27152 etc, avec une R mesurée de 56K.

    je pense donc que les impédances hautes (non connectées selon le switch), faussent tout.
    Peut être faudrait il prévoir que les valeurs non connectées aient des R Pull up vers le 5V, du genre 5 MOhms ?

    C'est sûr que le sketch fonctionne, puisqu'il va bien jusqu'à 10k. c'est ensuite que ça va pas: c'est donc dans les parties hardware, je suppose.
    Qu'en pensez vous ? Avec vous une video de votre montage mesurant bien des R de fortes valeurs (220k par exemple) ?
    Merci !