Générateur de rampes programmables

Bonjour,
Avec ma Arduino Uno je voudrai développer un programme afin de générer des rampes répétitives d'une durée t1.
Cette durée t1 doit être paramétrable entre 50ms et 500ms.
L'amplitude A des rampes doit aussi être paramétrable entre 0 et +5V.
La sortie analogique de l'Arduino générant ces rampes va attaquer l'entrée d'un amplificateur de tension ayant une résistance d'entrée Rin de 5kOhms. A la sortie de cet ampli, on a des rampes amplifiées d'amplitude allant de 0 à 50V.
Ces rampes amplifiées vont ensuite servir à polariser une sonde de tension.
L'Arduino aura une autre tâche à réaliser pendant qu'il génèrera la rampe ;
En effet, lorsqu'il commencera à générer la rampe il doit en même temps commencer à faire des acquisitions du signal de sortie de la sonde et lorsque la rampe aura atteint sa tension max +A (donc au bout du temps t1), l'Arduino devra stopper l'acquisition des données de la sonde.
A ce moment là, la sortie analogique de l'Arduino est à 0 pendant un temps t2 paramétrable entre 10ms et 5 secondes. Puis on recommence de façon répétitive ce cycle générant la rampe avec acquisition des données de la sonde.
Par exemple, on peut réitérer ce cycle de rampes-acquisition pour un nombre de 100 fois.

Quelqu’un peut-il m’aider svp pour écrire ce programme ?

Pour éclaircir les idées, j'ai fait sous PDF, un schéma synoptique de fonctionnement.
Mais hélas je ne peux pas vous le communiquer en pièce-jointe car le Forum Arduino me dit que je ne peux pas car je suis un nouvel utilisateur. Dommage !

Merci pour votre aide,
Cordialement,
Guy_7

Peux tu donner le niveau d'aide que tu souhaite et l'investissement personnel que tu veux y apporter.
Je dis ça car tu aura un nombre de réponse proportionnel à ton investissement.

As tu déjà développé sur Arduino?
As tu choisi un Arduino en particulier ?
Comment compte tu rendre ton projet paramétrable?

Ce message est la suite de celui de septembre 2022.

Il va falloir être un peu plus volontaire si tu veux de l'aide.

Si le forum francophone avait une devise elle pourrait être "Aides toi et le forum t'aidera"
Nous ne faisons pas à la place, nous guidons, nous expliquons ce qui n'est pas compris, nous signalons les erreurs.
Notre but n'est pas de rouler les mécaniques en présentant du tout cuit, mais en transmettant notre savoir, de permettre aux débutants de pouvoir se passer de nous en devenant autonomes.
En échange, du coté demandeur, il faut être actif.

Note : Tu peux déjà faire des recherches sur les mots en caractères gras qui suivent.

Retour au sujet :

Dans un UNO il n'y a pas de DAC (digital analog converter).
Ce qu'Arduino appelle avec beaucoup d'erreurs analogWrite devrait s'appeler pwmWrite.
→ Il serait bon de connaitre les possibilités de la carte que tu as choisi depuis septembre 2022.

Le micro de la carte UNO l'atmega328p ne sait générer que des signaux numériques.
La PWM est un signal numérique répétitif, d'amplitude 5V, de rapport cyclique modifiable par programation.

Ce signal numérique, si on le fait passer dans un filtre passe bas (souvent un simple filtre Résistance Condensateur), peut donner un signal continu d'amplitude variable en fonction du rapport cyclique.
Associé à une gestion du temps (voir la différence entre delay() et millis() ) ce pourrait être ton générateur de rampe.

Tu peux aussi utiliser un vrai DAC en module externe, commandable de préférence en I2C.

Pour faire varier l'amplitude de la rampe il est envisageable d'utiliser un potentiomètre numérique commandable en I2C.

Il est possible et souhaitable que tu reçoives d'autres propositions de solutions.
Ce sera à toi d'en choisir une dans le tas.

PS :
N'hésite pas a décrire ce que tu veux faire en faisant plusieurs petits messages : cela débloquera le compteur pour que tu puisses envoyer des pièces jointes.
Le seuil doit être 10 ou 50 messages.

Important :
Un multimètre est indispensable, je conseille fortement un analyseur logique clone de Saleae. Chacun des deux appareils est simple d'emploi et coûte moins de 10 €.
Un oscilloscope est bien plus cher et, si on n'a pas appris a s'en servir, pourra donner des mesures fausses, je ne conseille pas, mais ce n'est que mon avis.

Salut ,
Voici le programme de générateur de rampes que j'ai développé :

#define PWM_out 9 // Sortie PWM
#define N 300 // A faire varier en fonction du choix de la pente de la rampe
#define Pas_us 10 // Définit le Pas en μS

void setup()
{
pinMode(Switch_in, INPUT);
pinMode(PWM_out, OUTPUT);
digitalWrite(PWM_out, LOW);
}
void loop()
{

// Génération de la rampe
while(valSwitch==1)
{

// Montée
for(int n=0;n<N;n++)
{
digitalWrite(PWM_out, HIGH); delayMicroseconds(n*Pas_us);
digitalWrite(PWM_out, LOW); delayMicroseconds((N-n)Pas_us);
}
// Descente
for(int n=N;n>0;n--)
{
digitalWrite(PWM_out, HIGH); delayMicroseconds(n
Pas_us);
digitalWrite(PWM_out, LOW); delayMicroseconds((N-n)*Pas_us);
}
digitalWrite(PWM_out, LOW);
while((valSwitch=digitalRead(Switch_in))!=0);
delay(2000);
}
}

ReSalut ,
Excusez-moi car j'ai oublié dans mon précédent message, la déclaration de la variable Switch :

#define Switch_in 2 // Entrée du switch

#define PWM_out 9 // Sortie PWM
#define N 300 // A faire varier en fonction du choix de la pente de la rampe
#define Pas_us 10 // Définit le Pas en μS

int valSwitch=0; // 0-1

void setup()
{
pinMode(Switch_in, INPUT);
pinMode(PWM_out, OUTPUT);
digitalWrite(PWM_out, LOW);
}
void loop()
{

// Lecture du switch
while((valSwitch=digitalRead(Switch_in))==0);

// Génération de la rampe
while(valSwitch==1)
{

// Montée
for(int n=0;n<N;n++)
{
digitalWrite(PWM_out, HIGH); delayMicroseconds(n*Pas_us);
digitalWrite(PWM_out, LOW); delayMicroseconds((N-n)Pas_us);
}
// Descente
for(int n=N;n>0;n--)
{
digitalWrite(PWM_out, HIGH); delayMicroseconds(n
Pas_us);
digitalWrite(PWM_out, LOW); delayMicroseconds((N-n)*Pas_us);
}
digitalWrite(PWM_out, LOW);
while((valSwitch=digitalRead(Switch_in))!=0);
delay(2000);
}
}

Tu as aussi oublié de mettre le code entre balise <code/> ce qui le rend illisible
Merci de prendre quelques minutes pour lire les bonnes pratiques du forum francophone et les appliquer.

A noter aussi, on peut corriger un message à posteriori. Donc lorsque tu oublies un morceau de code au lieu de faire un message supplémentaire il vaut mieux rouvrir le message erroné (icône crayon sous ton message) et ajouter la partie manquante cela évite de fractionner le code sur plusieurs messages.

ReSalut ,
Excusez-moi , voici le code entre balise :

#define Switch_in 2 // Entrée du switch

#define PWM_out 9 // Sortie PWM
#define N 300 // A faire varier en fonction du choix de la pente de la rampe
#define Pas_us 10 // Définit le Pas en μS

int valSwitch=0; // 0-1

void setup()
{
pinMode(Switch_in, INPUT);
pinMode(PWM_out, OUTPUT);
digitalWrite(PWM_out, LOW);
}
void loop()
{

// Lecture du switch
while((valSwitch=digitalRead(Switch_in))==0);

// Génération de la rampe
while(valSwitch==1)
{

// Montée
for(int n=0;n<N;n++)
{
digitalWrite(PWM_out, HIGH); delayMicroseconds(n*Pas_us);
digitalWrite(PWM_out, LOW); delayMicroseconds((N-n)Pas_us);
}
// Descente
for(int n=N;n>0;n--)
{
digitalWrite(PWM_out, HIGH); delayMicroseconds(nPas_us);
digitalWrite(PWM_out, LOW); delayMicroseconds((N-n)*Pas_us);
}
digitalWrite(PWM_out, LOW);
while((valSwitch=digitalRead(Switch_in))!=0);
delay(2000);
}
}

Ton programme est pas du tout indenté :frowning:

ton programme si je ne me trompe pas ne fait rien.
Du coup que veux tu comme conseille ?
De même tu parle de sortie paramétrable, mais tu n'y fais pas référence dans ton programme.

Pour faire ça, à ma connaissance il te faut un DAC, un convertisseur numérique - analogique. Le PWM ne fera pas ce que tu cherches. C'est ce que t'a dit @68tjs au message 3.

Il existe des modules DAC qui peuvent être contrôlés par un Arduino Uno, comme celui-ci

image

Mais avant de le choisir, il faut bien le spécifier : résolution, vitesse, range (je suis loin d'être un spécialiste).

Sinon, tu peux changer ton Arduino pour un ESP32 qui dispose de 2 DAC de 8 bits.

Each DAC channel can convert the digital value 0~255 to the analog voltage 0~Vref. The output voltage can be calculated as the following:

out_voltage = Vref * digi_val / 255

A priori, Vref vaut 3.3V. Si tu veux monter à 5V, il te faudra amplifier.
Voici un site qui explique comment utiliser les DAC de l'ESP32 :
https://dronebotworkshop.com/esp32-dac/

Il donne un exemple de code pour produire un signal sinusoïdal périodique. Pour une rampe, ce n'est pas vraiment plus compliqué. Il faut juste bien gérer le temps entre deux échantillons.

Le DAC peut générer 256 valeurs différentes, et tu veux que ça dure t1 secondes. Le temps entre deux échantillons est donc t1 * 1000 / 256 millisecondes. Tu fais une boucle :

unsigned int delai = t1 * 1000 / 256;
for (int i = 0; i < 256; i++) {
  dacWrite(DAC_CH1, i);
  delay(delai);
}

Le delay est le plus simple mais le moins précis pour tenir le timing (car je ne sais pas combien de temps l'ESP va prendre dans la fonction dacWrite). Il vaut mieux compter les millisecondes et générer l'échantillon au bon moment, mais c'est déjà un premier exemple.

Attention il y a maintenant des ESP32 sans DAC.
Les premiers modèles en étaient équipés.
Certains nouveaux modèles en ont, d'autres pas.

Le plus simple sera un module externe qui ne fait que ça.
Mais là aussi attention: il y a de plus en plus de modèles en 3,3 V.
Pour l'amplitude de la rampe peu importe 5 V ou 3,3V puisqu'il y aura amplification mais c'est quand même plus simple quand il n'y a pas à adapter les niveaux de commande entre le micro et les satellites comme un module DAC.

Une paire de digitalWrite() cela doit faire environ 10µs.
Il faudrait peut-être regarder du coté de la librairie digitalWriteFast ou bien écrire directement dans les registres du CPU.