Chargeur USB manuel

Bonjour,

Je réalise un chargeur USB manuel à l’aide d’un petit moteur qui fait office de générateur lorsqu’il est actionné via une manivelle. Le générateur charge une batterie 12V à l’aide d’un régulateur de charge photovoltaique. Les consommateurs sont chargés via des convertisseurs de tension (max 30V => 5V). Les convertisseur de tension sont alimentés par la batterie.
Dans ce cas de figure, si la batterie est chargée, dès qu’on branche un équipement à charger, il se charge automatiquement hors je voudrais que la charge soit rendue possible uniquement si le générateur est actionné, autrement dit si quelqu’un fait tourner la manivelle.

Pour rendre l’utilisation de la manivelle obligatoire, je pensais utiliser un ensemble relais + arduino afin d’ouvrir et de fermer le circuit de charge. Le déclencheur serait la tension aux bornes du générateur : s’il y a une tension on ouvre le circuit, si pas de tension on ferme le circuit de charge pour rendre la charge opérationnelle.

Afin de rendre le système plus convivial, je voudrais temporiser le relais afin de :
ne pas ouvrir le circuit de charge trop rapidement : il faudrait actionner le générateur au moins 30 sec. pour commencer à charger
ne pas fermer le circuit de charge trop rapidement afin d’éviter les coupures trop fréquentes : si quelqu’un “mouline” trop lentement donc tension en dessous du seuil, si on change de personne pour actionner le générateur, ce délai pourrait être de 10 sec par exemple …)

Ce montage a vocation pédagogique, je ne maîtrise pas arduino mais je saurais me débrouiller si on me met sur la piste (schema electronique pour la mesure de tension et le code associé)

La tension batterie est de 12 V
La ternsion max aux bornes du générateur est de 30V
La charge maxi serait de 3A

UG : tension aux bornes du générateur
UB : tension aux bornes de la batterie, mesurée par A0 par exemple.
S1 : relais 5V/30V

J’imagine une boucle comme ceci :

départ de la boucle
if UG < 12V
then
S1 = Ouvert
durant 10 sec
else
S1 = fermé
on retourne au départ de la boucle

Cordialement,

Karilo

Bonsoir
Comme l'indique son nom ce sous-forum est une sorte de vitrine des réalisations finies.....
Si tu observe sles messages qui y figurent tu verras que c'est bien le cas.
Reviens dans ce sous-forum présenter ta réalisation finie !!

Lit également la Règle de fonctionnement du forum qui dit entre autres ' pas de question dans les sous-forums'

Demandes au modérateur de déplacer ton message là ou il faut (lien "Report to moderator" en bas à gauche)
La bas tu aura des réponses , des pistes....

Sujet déplacé :wink:

Bonjour,

J'avance à taton dans la partie Arduino de mon projet mais ça avance : j'arrive à lire la tension aux bornes du générateur via l'entrée A0 de l'arduino via le code suivant :

// Fonction setup(), appelée au démarrage de la carte Arduino
void setup() {

  // Initialise la communication avec le PC
  Serial.begin(9600);
}

// Fonction loop(), appelée continuellement en boucle tant que la carte Arduino est alimentée
void loop() {
  
  // Mesure la tension sur la broche A0
  int valeur = analogRead(A0);
  
  // Transforme la mesure (nombre entier) en tension via un produit en croix
  float tension = valeur * (5.0 / 1023.0);
  
  // Envoi la mesure au PC pour affichage et attends 250ms
  Serial.println(tension);
  delay(250);
}

J'aimerais maintenant faire évoluer le programme pour activer ou fermer une sortie digitale (la 13 par exemple) en fonction de la tension mesurée et d'un délai mais je ne sais pas comment m'y prendre au niveau de la structure du programme, je m'explique :

  • Par défaut le PIN 13 à l'état bas
  • Le PIN 13 passe à l'état haut SI la tension mesurée est supérieure à un seuil déterminé (disons 0.5) PENDANT plus de 15 secondes.
  • Lle PIN 13 repasse à l'état bas si la tension mesurée est inférieure au seuil (le même 0.5) pendant plus de 10 secondes.
    Dire que je suis un newbie serait un euphémisme mais ça vous l'aurez compris.

Ci-joint une image du montage :

J'avance lentement (je n'ose pas ajouter "surement")
J'arrive désormais à changer l'état de ma sortie en fonction de la tension :
Code:

// Fonction setup(), appelée au démarrage de la carte Arduino
void setup() {

  // Initialise la communication avec le PC
  Serial.begin(9600);
  pinMode(13, OUTPUT);           // set pin 13 to output
}

// Fonction loop(), appelée continuellement en boucle tant que la carte Arduino est alimentée
void loop() {
  
  // Mesure la tension sur la broche A0
  int valeur = analogRead(A0);
  
  // Transforme la mesure (nombre entier) en tension via un produit en croix
  float tension = valeur * (5.0 / 1023.0);

if (tension >= 0.1 )
{   
   // pin 13 on
   digitalWrite(13, HIGH); 
  // Envoi la mesure au PC pour affichage et attends 250ms
  Serial.println(tension);
  delay(250); 
  }
else
{   
  // pin 13 off
  digitalWrite(13, LOW); 
  }
}

Je ne vois en revanche pas comment structurer la boucle relative au temps :
dès que tension > 0.5 je démarre un timer et j'active la sortie 13 qu'au bout de 15 seconde continue.
idem pour désactiver la sortie 13.

En tout cas c'est rude, c'est compliquer le chinois

Bonjour,

Il faut que tu mémorises l'état de ton système par exemple PLUS ou MOINS et tu mémorise aussi le temps en ms.

  • Si l'état à changé tu mémorises le nouvel état et le temps
  • Sinon l'état n'a pas changé
    Tu testes si la durée par rapport au temps mémorisé est supérieure à 10s
    . Si oui tu allumes ou éteint la led (suivant l'état)

Merci Kamill de m’avoir mis sur la piste.

Voici un code fonctionel mais pas forcément stable :

const byte u_generateur = A0; // on utilise le pin A0 pour lire la tension aux borne du générateur
const byte interrupteur = 13;    // on utilise le pin 13 pour commander l'interrupteur
unsigned long dateDernierChangement = 0;
const int seuil = 10;    // seuil de tension à partir duquel on autorise ou coupe la charge
const int delai_switch_on = 10000;    // delai avant d'autoriser la charge
const int delai_switch_off = 10000;    // delai avant de couper la charge
void setup() {
Serial.begin(9600);
pinMode(u_generateur, INPUT); // le pin A0 en entrée, tension générateur
pinMode(interrupteur, OUTPUT); // le pin 13 en sortie, commande interrupteur
}
void loop() 
{
  int valeur = analogRead(u_generateur); // Mesure la tension sur la broche A0
  float tension = valeur * (100 / 1023.0); // Transforme la mesure (nombre entier) en tension via un produit en croix
  unsigned long dateCourante = millis(); 
  unsigned long intervalle = dateCourante - dateDernierChangement;
  Serial.println(tension); // on envoie la tension dans le moniteur série
  delay(250); // on envoie la tension dans le moniteur série
  if (tension >= seuil && intervalle > delai_switch_on) 
    {
    digitalWrite(interrupteur,HIGH); // on coupe la charge après 5s d'inactivitées
    dateDernierChangement = dateCourante;
    }
  else if (tension <= seuil && intervalle > delai_switch_off) 
    {
    digitalWrite(interrupteur, LOW); // on coupe la charge après 5s d'inactivitées
    dateDernierChangement = dateCourante;
    }
}

Il y a de l'idée, mais si tu testes ton programme tu verras que le retard varie entre 0 et 10 secondes.
Il faut que tu réinitialises dateDernierChangement lorsque tu viens de passer en dessous ou au dessus du seuil et non pas au changement d'état de la led.

Ca donne un programme de ce genre:

void loop()
{
  static enum {PLUS, MOINS, INCONNU} etat=INCONNU;
  int valeur = analogRead(u_generateur); // Mesure la tension sur la broche A0
  float tension = valeur * (100 / 1023.0); // Transforme la mesure (nombre entier) en tension via un produit en croix
  unsigned long dateCourante = millis();
  unsigned long intervalle = dateCourante - dateDernierChangement;
  Serial.println(tension); // on envoie la tension dans le moniteur série

  if (tension >= seuil)
  {
    if (etat == PLUS)
    {
      if  (intervalle > delai_switch_on)
        digitalWrite(interrupteur, HIGH);
    }
    else
    {
      // on vient de changer d'état
      dateDernierChangement = dateCourante;
      etat = PLUS;
    }
  }
  else
  {
    if (etat == MOINS)
    {
      if (intervalle > delai_switch_off)
        digitalWrite(interrupteur, LOW);
    }
    else
    {
      // on vient de changer d'état
      dateDernierChangement = dateCourante;
      etat = MOINS;
    }
  }
  delay(250);
}

Le code que tu viens d'envoyer est parfaitement fonctionnel, chapeau bas !
Il va me falloir un temps certain pour assimiler sa structure et sa logique ...
Je te remercie pour ton aide car je n'aurais jamais pu trouver cette solution tout seul.

Content d'avoir pu t'aider

Bonjour,

Je rencontre le problème suivant :

Si le délai_switch_off est inférieur ou égal 32 sec. tout fonctionne correctement.
Si le délai_switch_off est supérieur ou égal 33 sec. la boucle reste coincée en état PLUS même si la tension est inférieure au seuil ...

const byte u_generateur = A0; // on utilise le pin A0 pour lire la tension aux bornes du générateur
const byte interrupteur = 13;    // on utilise le pin 13 pour commander l'interrupteur
unsigned long dateDernierChangement = 0;
const int seuil = 5;    // seuil de tension à partir/en-dessous duquel on autorise ou coupe la charge
const int delai_switch_on = 2000;    // delai avant d'autoriser la charge
const int delai_switch_off = 33000;    // delai avant de couper la charge
void setup() {
Serial.begin(9600);
pinMode(u_generateur, INPUT); // le pin A0 en entrée, tension générateur
pinMode(interrupteur, OUTPUT); // le pin 13 en sortie, commande interrupteur
}
void loop()
{
  static enum {PLUS, MOINS, INCONNU} etat=INCONNU;
  int valeur = analogRead(u_generateur); // Mesure la tension sur la broche A0
  float tension = valeur * (130 / 1023.0); // Transforme la mesure (nombre entier) en tension via un produit en croix
  unsigned long dateCourante = millis();
  unsigned long intervalle = dateCourante - dateDernierChangement;
  Serial.println(tension); // on envoie la valeur calculée de la tension vers le moniteur série

  if (tension >= seuil)
  {
    if (etat == PLUS)
    {
      if  (intervalle > delai_switch_on)
        digitalWrite(interrupteur, HIGH);
    }
    else
    {
      // on vient de changer d'état
      dateDernierChangement = dateCourante;
      etat = PLUS;
    }
  }
  else
  {
    if (etat == MOINS)
    {
      if (intervalle > delai_switch_off)
        digitalWrite(interrupteur, LOW);
    }
    else
    {
      // on vient de changer d'état
      dateDernierChangement = dateCourante;
      etat = MOINS;
    }
  }
  delay(250);
}

Une idée ?

Cordialement,

Bonjour,

33000 excède la capacité d'un entier qui devient négatif.
Tu peux changer le type des constantes

const unsigned long delai_switch_on = 2000;    // delai avant d'autoriser la charge
const unsigned long delai_switch_off = 33000;    // delai avant de couper la charge