Réalisation d'un potentiostat pour mon TIPE

LOL :winking_face_with_tongue:

j'ai modifié le programme pour mettre une table mais j'ai encore un problème . Lorsque je mets une fréquence élevée, la sinusoïde se déforme malgré mon filtre RC .
pouvez vous m'aider ?

Si c'est la partie électronique, je ne pourrais probablement pas t'aider, mais mets ton code, ainsi ce que tu constate comme déformation.

#define N     256         // N=2^8, 8 bits

#define Phi   N/2         // 90*356/360          

#define pi    3.1415926535897932384626433832795

#define f0    1.00

#include <LiquidCrystal.h>
#include <math.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int a = 10;
float ct = A0;
float c = 0;


float amplitude = 5;


unsigned int i_sin=0,i; 

double sin_x, SinCos[N];



void setup()

{

  // Génération du signal sinusoïdal en format 8 bits

  for(i=0;i<N;i++)

  {

    sin_x=amplitude*sin(2.00*pi*f0*(float)i/((float)N-1.00));

    SinCos[i]=0.5*(sin_x+1.00)*(N-1.00); //[-1,1]=> [0,2^8-1]

  }




  // Initialisation du port série - Affichage des signaux

  Serial.begin(9600);




  // Init indices des tableaux

  i_sin=0;

  

}




void loop()

{

  // Affichage du signal sinus

  Serial.println( SinCos[i_sin]);

  
  c = analogRead(ct);

    
  Serial.print("  ");
  Serial.println(c);
  

  // Mise à jour des indices

  i_sin++; i_sin=i_sin%(N-1);

  

}

Je suis désolé, mais je ne comprends pas.
tu parles de filtre RC, mais ton programme semble uniquement utiliser le moniteur série.
Tu parles aussi de fréquence élevé, c'est à dire

Donc peut tu détailler ce que tu essaye de faire, ce que tu t'attends et ce qui ne va pas?

Je souhaite appliquer une tension sinusoïdale a une cellule électrochimique pour ensuite mesurer l'amplitude et le déphasage de sa réponse en courant pour avoir accès a son inpédance.

Dès que je met une fréquence de plus de 20 Hz, le signal se déforme.

Et tu veux combien de hertz, avec quelle précision?

Je ne pense pas que la fréquence doive être précise, par contre la valeur de la fréquence doit être connue avec précision pour le calcul de l’impédance.
Ce n’est la même chose.

Je t’ai donné un lien où tu aurais pu trouver comment obtenir, simplement, un signal carré avec un timer en mode CTC.

Note : avec un micro avr, le timer 0 est utilisé par les fonction de temps : delay, delayMicrosecond, milli et micro .
Il est préférable de ne pas y toucher et d’utiliser le timer 1 qui est 16 bits ou le timer 2 qui est 8 bits.

Pour obtenir une sinusoïde tu peux ajouter un filtre passe bas, ou mieux passe bande, construit avec un ampli op.

Pour le déphasage, le micro atmega 328p a un mode comparateur.
Je sais qu’il existe, je ne m’en suis jamais servi, tu peux lire le chapitre concerné dans la datasheet pour voir s’il convient.

Attention :
En analogique les composants déphasent.
En numérique les composants ont un temps de traversée, qui est une autre forme du déphasage.
En premier lieu il faut que tu connaisse la valeur théorique attendue du déphasage que tu dois mesurer.
Ensuite il faut que tu évalues si le déphasage parasite apporté par l’appareil de mesure peut etre négligé, à 40 Hz je suppose que oui, mais on ne suppose pas on vérifie, ou s’il faut faire un étalonnage et une calibration (manuelle ou automatique).

Les sorties sur l’interface série sont utiles pour la mise au point.
Sauf que tu fais un appareil de mesure et elles ne doivent pas intervenir pendant la phase de mesure, surtout avec les 9600 bauds préhistoriques que tu conserves malgré les mises en garde.

NOTE IMPORTANTE :
Pour ton sujet, il ne faut pas te limiter aux fonction arduino, elles sont lentes parce que bourrées de dispositifs anticonnerie. Toutes les possibilités des microcontroleurs avr comme l’atmega328p ne sont exploitées par les fonctions arduino.
Passage obligé pour ton sujet : lire la datasheet du micro.x

Je connais la fréquence puisque c'est celle de la tension d'entrée et j'aimerait faire un mesure sur une plage de 10 Hz à kHz . j'ai déjà un filtre RC passe bas construit avec un ampli op mais le signale se déforme quand même.

Je n'arrive plus à suivre.
Je découvre que tu ne veux pas simplement mesurer une impédance à 40 Hz mais que tu veux faire un balayage en fréquence.

Dis clairement en une seule fois ce que tu dois faire au lieu de distiller les informations au compte gouttes.

Tu veux générer la fréquence avec le micro où tu peux utiliser un générateur de fréquence variable piloté par le micro ?
Ce générateur peut être un DDS piloté par le micro.

Tu veux mesurer des amplitudes de signal sinusoïdal avec quoi ?
Avec analogRead ?
Il te faut trouver l'amplitude maximale et minimale du signal , pour cela il faut plusieurs dizaines de points de mesure. Le convertisseur analogique/digital du micro travaille t-il assez vite pour une fréquence fondamentale de 1 kHz ?
Réponse : datasheet du micro !
Faudre t-il un ADC externe plus performant ?

As tu a ta disposition, c'est dire un usage autorisé dans ton projet, des vrais appareils de mesure programmables ?

C'est bien flou tout çà.

Désoler pour avoir donner des information au compte gouttes. Je pensait que si je réglais le problème pour une fréquence, ça fonctionnera pour toute .Je souhaite générer le signale par le carte arduino. Pour les mesures, j'ai un programme python qui me permet de filtrer la sortie puis avec le module scipy de touver les paramètre de mon signal de sortie.
J'ai aussi du matériels comme des oscilloscope à ma disposition.

mon programme python:

import numpy as np
import csv
import os
import serial 
import matplotlib.pyplot as plt
import time
from scipy.optimize import curve_fit
from scipy import signal

os.chdir(os.path.dirname(__file__))


def read_serial_data(port, baudrate):
    ser = serial.Serial(port, baudrate)
    data = []
    try:
        T_debut = time.time()
        
        while time.time() - T_debut <= 10:
            line = ser.readline().decode('utf-8').strip()

            if line:
                values = line.split()  # sépare les nombres par espace
                for v in values:
                    data.append(float(v))
    except KeyboardInterrupt:
        pass
    finally:
        ser.close()
    return np.array(data)


    
# Change ton port avec celui sur lequel ton Arduino est connecté
raw_data = read_serial_data('COM3', 9600)

data_entrees = raw_data[::2]
data_sorties = raw_data[1::2]

min_len = min(len(data_entrees), len(data_sorties))
data_entrees = data_entrees[:min_len]
data_sorties = data_sorties[:min_len]

temps = np.arange(min_len)


with open('data.csv', mode='w', newline='') as file:
    writer = csv.writer(file)
    writer.writerow(['Entrees', 'Sorties'])
    for entree, sortie in zip(data_entrees, data_sorties):
        writer.writerow([entree, sortie])



sos = signal.butter(1, [10,30], 'bp', fs=1000, output='sos')
filtered = signal.sosfilt(sos, data_sorties)


def sinus(x, A, w, phi, C):
    return A * np.sin(w * x + phi) + C

# Ajustement
params, _ = curve_fit(sinus,temps, filtered)

A, w, phi, C = params

print("Paramètres :", params)
temps_fit= np.linspace(min(temps), max(temps), 1000)
y_fit = sinus(temps_fit, A, w, phi, C)


plt.figure()
plt.plot(data_entrees, label='Entrees(mV)',color='blue')
plt.plot(data_sorties, label='Sorties(uA)',color='orange')
plt.plot(filtered, label='Sorties filtré  (uA)',color='green')

# plt.scatter(temps,filtered)
plt.plot(temps_fit, y_fit,label='sinusoïde (uA)', color='red')

plt.xlabel('temps (s)')
plt.ylabel('Amplitude')
plt.legend()
plt.grid()
plt.savefig('data_plot.png')
plt.show()

Il n'est pas forcément facile de deviner à quoi ca correspond exactement.

Si on prends rien que ton graphe, tu parles du signal d'entrée en bleu ?
Déjà d'après ton échelle la fréquence est de 0.2Hz.
D'ailleurs ton graph à 3 courbe, mais ton programme en produit que 2!!

Donc si je comprends bien, dans un premier temps tu cherches a "grapher" via le port série ce que ton programme produit ?

Ton programme ne gère aucune fréquence, donc j'ai du mal a comprendre comment tu peux avoir des problèmes de signal en fonction de ta fréquence?
en l'état chaque println doit prendre quelque milliseconde, d'après l'IA entre 8 à 15ms(si quelqu'un peut confirmer), donc au maximum tu pourrait produire un signal 1/0.015 /2 = environs 3 Hz, si tu envoyais deux points opposés(ce qui correspond à ton graphe bleu).
la tu envois à 33Hz une sinusoïde de 256 points.

C'est une erreur classique :slight_smile:, moins tu donnes d'information plus tu obliges les personnes a supposer des choses, donc de risquer de s'éloigner de ton cas.

Après tu as deux choix,

  • soit tu veux comprendre exactement ce que tu fais, dans ce cas, fait une chose après l'autre.
  • soit tu veux atteindre ton résultat le plus vite possible, alors suit à la lettre ce que te préconise un expert comme @68tjs par exemple.

Mais dans tout les cas, si tu ne donne pas toutes les informations, plus du risque de partir sur un mauvais chemin et galérer à faire ton projet :slight_smile:

Je ne suis pas un expert !

J’ai simplement roulé ma bosse donc j’ai de certaines expériences en développement et la plus importante est qu’on ne fait pas plusieurs choses nouvelle en même temps.
On prepare aussi son travail, même si, en fonction de l’avancement du développement, on est amené a modifier régulièrement.
On le prepare PAR ECRIT, tant que cela reste dans la tete on ne voit pas les erreurs. Le fait de rediger apporte une aide impressionnante d’efficacité.

Et dans ce domaine Arduino, la seule référence fiable est celle des fabricants des composants, micro compris,, ce n’est ni celle de la société Arduino et encore moins celle de Youtube.

Quant à ce projet, honnêtement je dois dire que je ne comprends rien. Ce doit etre l’age.

Question déjà évoquée au #8


Oui, et très curieusement le signal en sortie est environ 4.5 plus lent. Par quel mystère???


Et comme évoqué au #9 il y a d'autres solutions et étant donné que maintenant on sait que la fréquence doit varier je pense que la proposition d'utiliser un module DDS parait pertinente.

Exact, j'avais oublié :frowning:

Oui personnellement je suis du même avis que vous deux, après il y a l'aspect didactique de tout faire avec les capacités "limité" d'une Uno.
Pour un étudiant, je préconiserais de d'abords ou en parallèle évaluer la faisabilité avec une Uno, puis/et la réalisation d'un instrument répondant parfaitement au cahier des charges.