Go Down

Topic: Déphasage via potentiomètre d'un signal PWM  (Read 909 times) previous topic - next topic

bauvaisis

#30
Jul 21, 2020, 08:36 pm Last Edit: Jul 21, 2020, 10:03 pm by bauvaisis


J'ai réussi à fabriquer ce fameux signal lu avec l'analyseur logique ! ca me parrait pas mal , on a bien les 20Hz et les 63.3% de RC ! Reste plus qu'à tester sur le montage en réel pour voir si le "phasage est bon "

:) merci beaucoup pour l'aide en tout cas , je vous tiendrai informé si le résultat est satisfaisant !

dfgh


bauvaisis

Oui avec plaisir :) J'aurais des news d'ici ce weekend :)

bauvaisis

Bonsoir ;)

Je reviens donner des news ;) Le signal est effectivement bon , contrôlé à l'oscilloscope pro mais impossible d'obtenir une synchro parfaite entre le signal vilo fabriqué par un outillage de simulation de capteur et mon signal arduino pour l'aac.

Les fréquences ne sont pas exactement pareil , il suffit qu'il y ait un 20.1Hz au lieu de 20 et ça créer un décalage dans le temps .... Je me suis torturé l'esprit pour essayer de trouver une solution.

J'ai peut-être une dernière idée avant de baisser les bras:

Il faudrait que dans un premier temps l'arduino fasse une lecture de l'état du signal vilo (donc choisir une entrée logique je pense) afin de faire un comptage qui s'incrémente à chaque impulsion (dents de vilo). Et "préprogrammer " des états logiques à 5V selon le comptage en cours.

Je ne sais pas si c'est possible ... Il y a 58 dents sur la roue dentée du vilo. 1 tour aac = 2 tours vilo. Donc 1 cycle complet = 116 impulsions carré de 5V.

Exemple:  il faut que j'envoie un signal 5V pendant tant de millisecondes lorsque le compteur est à 30 , 60 et 90.

et le compteur revient à 0 lorsqu'il arrive à 116. (car l'histoire de la double dent manquante cause un décalage sur plusieurs cycles si on ne le prends pas en compte)


A voire si c'est réalisable , je fouille encore :D

bonne soirée :)

dfgh

#34
Jul 30, 2020, 12:19 am Last Edit: Jul 30, 2020, 12:21 am by dfgh
hello

testes ce code, il est en phase et synchro à toutes fréquences
pas de timer, juste des interruptions
(j'entends des cris au loin...) :)
inter 0 pour suivre la fréquence . (je n'ai commenté que l'assembleur)
inter 1 pour être en phase
pour les deux dents manquantes, il n'y aura pas de signal non plus

c'est bien ce que tu veux?

Code: [Select]
#define maskAND 0b11111110
#define maskOR  0b00000001
const byte VILO = 2;
const byte AAC  = 8;

void setup()
{
  pinMode(AAC, OUTPUT);
  pinMode (VILO, INPUT);
  PORTB &= maskAND;
  attachInterrupt(1,isr1, RISING);
  attachInterrupt(0,isr0, CHANGE);sei();
}
void loop()
{
}
void isr1()
{
  PORTB |= maskOR;
}
void isr0()
{
  asm("SBIC 0x05,0");//saut 1 ligne si bit 0 de port B est à 0
  asm("jmp suite");  //sinon saut en etiquette suite
  asm("SBI 0x05,0"); //bit 0 du port B passe à 1
  asm("jmp fin");    //saut en fin
  asm("suite:");     //etiquette suite
  asm("CBI 0x05,0"); //bit 0 du port B passe à 0
  asm("fin:");       //etiquette fin
}

bauvaisis

salut dfgh :)

Merci encore et toujours pour ton soutien :)

Dons si j'ai bien compris ton script , à chaque impulsion positive lu sur le signal vilo (pour chaque dent du vilo)  , il va me créer en direct une impulsion (signal aac) ?


Enfaite la subtilité de conception de ce moteur réside dans le fait que ce n'est pas une synchro à proprement parler du type 1dent vilo = 1 impulsion aac. ca aurait limite était plus simple ...

Dans mon cas j'ai 58 dents sur le vilo et seulement 3 cibles (grosses dents) sur l'aac ! Donc si je résume pour 1 cycle complet :
 2 tours de vilo = 58 * 2 = 116 impulsions au total
 1 tour d'aac = 3 grosses cibles = 3 longues impulsions.


Tout ca pour dire qu'il est impossible de mettre en phase exactement dent pour dent.

Pendant la durée d'une seule impulsions AAC , on a presque 39 impulsions vilo . C'est ça que j'aimerais "synchroniser" .

C'est pour cela que j'avais pensé au comptage des dents de 0 à 116 et de dire " lorsqu'on arrive au comptage de la dent # 20 par exemple , il faut envoyer un signal jusqu'au comptage de la dent 59 et rebelote entre la dent 70 jusqu'à la dent 109 etc... (c'est un exemple)


Je ne sais pas si ce que j'explique est assez clair :) mais en tout cas c'est un cas plutôt complexe ... :)

un grand merci ;)

68tjs

hello
 juste des interruptions
(j'entends des cris au loin...) :)
Bizarre je n'entend rien :) .

Une question sur l'usage des interruptions et le temps qu'elles prennent dans le cadre de synchronisation (je reste dans le sujet).

Est-ce que l'usage de la fonction arduino "attachInterupt" qui appelle une fonction et utilise la macro ISR ne prend pas de cycles horloge que l'usage direct de la macro ISR.

Qualitativement je dis oui puisqu'il y a plus d'actions à faire, mais quantitativement je suis incapable de chiffrer et de conclure si c'est négligeable ou pas.
L'occupation mémoire doit aussi être différente.

Cordialement
Ceux qui savent qu'ils ne savent rien en connaisse autant que ceux qui croient tout savoir et qui n'en connaissent pas plus qu'eux.
Pierre DAC.

dfgh

#37
Jul 30, 2020, 06:07 pm Last Edit: Jul 30, 2020, 06:15 pm by dfgh
hello
@68tjs: je pense comme toi, mais je n'ai pas pris le temps de regarder.
Vileroi nous a passé un petit prg our calculer le nombre de cycles, je l'ai sauvegardé. dès que j'ai le temps je ferai un test.
Nota: Vileroi n'est pas diplomate, il a raison dans son raisonnement et utilisation du PWM.
(juste la façon de le dire...)

@Bauvaisis:
alors, pour m'en sortir j'ai d'abord créé un signal vilebrequin à 200 Hz et avec les deux dents manquantes
Code: [Select]
//vilebrequin: fréquence 200HZ
#define PULS                       8//portB_0
#define top_Synchro                9//portB_1
int   compteur           =         0;
int   compteur_dents     =         0;
long   tampon            =       148;
bool  isr                =     false;

void setup()
{
  pinMode(PULS,OUTPUT); digitalWrite(PULS, HIGH);
  pinMode(top_Synchro,OUTPUT); digitalWrite(top_Synchro, HIGH);
  cli();
  TCCR2A = 0b00000000; //
  TCCR2B = 0b00000001; //
  TIMSK2 = 0b00000001; //
  sei();
  isr = true;
}

void loop()
{

}

ISR (TIMER2_OVF_vect)
{
  if (isr)
  {
    TCNT2 = 15;
    if (compteur++ >= tampon )
    {
      compteur = 0;
      asm("SBIC 0x05,0");
      asm("jmp suite");
      compteur_dents++;
      if (compteur_dents == 62) {compteur_dents = 0;asm("SBI 0x05,1");asm("jmp fin");}
      if (compteur_dents == 61) {asm("jmp fin");}
      if (compteur_dents == 60) {asm("jmp fin");}
      if (compteur_dents == 59) {asm("CBI 0x05,1");asm("jmp fin");}
      //if (compteur_dents == 58) {asm("jmp fin");}
      asm("SBI 0x05,0");
      asm("jmp fin");
      asm("suite:");       
      asm("CBI 0x05,0");
      asm("fin:");
    }
  }
}


téléversé dans un uno ou nano, pas d'importance
en D8, il sort le signal du villebrequin
en D9, il sort un bit de synchro à chaque tour de volant ( pendant l'absence de dents)

cette platine est raccordée à une deuxième qui fabrique le signal des 3 périodes sur deux tours

donc le D8 entre sur D2 et le D9 entre sur D3

Code: [Select]
//signal AAC
#define maskAND 0b11111110
#define maskOR  0b00000001
const byte VILO = 2;
const byte AAC  = 8;
int compteur_periode=0;
int compte_tour_vilo=0;
void setup()
{Serial.begin(1000000);
  pinMode(AAC, OUTPUT);
  pinMode (VILO, INPUT);
  PORTB &= maskAND;
  attachInterrupt(1,isr1, RISING);
  attachInterrupt(0,isr0, CHANGE);sei();
}
void loop()
{
}
void isr1()
{Serial.println(compte_tour_vilo);
  if((compte_tour_vilo++ %2)){compte_tour_vilo=0;
  //compteur_periode=27;//de 0 à 53 pour retarder le signal 66/27 / synchro
  compteur_periode=53;//laisser 53 pour avoir le départ signal synchronisé
  PORTB &= maskAND;}
}
void isr0()
{
  if (compteur_periode++ >=52)
  {
  asm("SBIC 0x05,0");//saut 1 ligne si bit 0 de port B est à 0
  asm("jmp suite");  //sinon saut en etiquette suite
  asm("SBI 0x05,0"); //bit 0 du port B passe à 1
  compteur_periode=0;
  asm("jmp fin");    //saut en fin
  asm("suite:");     //étiquette suite
  asm("CBI 0x05,0"); //bit 0 du port B passe à 0
  compteur_periode=27;//
  asm("fin:");       //étiquette fin
}
}


n'ayant pas la précision, j'ai prévu deux lignes dont l'une devra être commentée

//compteur_periode=27;//de 0 à 53 pour retarder le signal 66/27 / synchro
  compteur_periode=53;//laisser 53 pour avoir le départ signal synchronisé

celle que je n'ai pas commentée fait une synchro sur le top synchro envoyé
par la platine vilebrequin (un tour sur deux ). il faut lui laisser une valeur de 53.

si tu utilises l'autre ligne, tu feras varier la valeur de 0 à 53.
ce qui retardera d'autant la synchro du signal AAC

sur la copie d'écran jointe:
 la trace du haut est le top synchro tous les tours.
la trace du milieu est la trace du vilebrequin avec les deux dents manquantes.
la trace du bas est le signal AAC avec ses trois périodes de 66/33 sur 2 tours vilebrequin

ne pas oublier de relier les deux GND des platines.

en attente de ton retour

bauvaisis

Bizarre je n'entend rien :) .
:)  :)  :)

Je viens de me taper une demi heure de lecture sur la fonction interruption avec ISR. Je pense avoir compris le principe pour le déclenchement de cette routine selon le "mode" .

Merci vraiment à vous 2 !

@dfgh : impressionant, les signaux ont l'air super à premiere vue sur la photo !! Je vais reproduire tout ca et brancher mon petit analyseur logique!

Je vous tiens informé rapidement !!

bauvaisis

#39
Jul 30, 2020, 07:16 pm Last Edit: Jul 30, 2020, 07:35 pm by bauvaisis
Impressionnant ! les signaux sont magnifiques :)



super taf :)

J'ai plus qu'à déterminer la valeur de "compteur_periode=" idéal pour que cela se synchronise comme je le souhaite :)  voire meme rajouter une fonction map qui gere mon petit potar, ca je suis capable :D :D

J'ai un potar dans le garage , quand je lui mets du 5V au cul, il me sort une plage entre 4.785V et 5.004V.

Ajouter ce bout de script pourrait fonctionner ?

Code: [Select]
void loop()
{
int pot = analogRead(A0);   // Lecture de la valeur de sortie sur la pin Analogique A0 (0 à 1023)
float tension = pot * 5 / 1023;   // Conversion en Tension (vcc = 5V DC)
int tensionsup = tension * 1000;
int compt_period = map(tensionsup, 4795, 5000, 0, 53);  // Création d'une proportionalité entre la valeur de sortie du potentiomètre ( 0v à 5v )   
}
void isr1()
{Serial.println(compte_tour_vilo);
  if((compte_tour_vilo++ %2)){compte_tour_vilo=0;
  //compteur_periode=27;//de 0 à 53 pour retarder le signal 66/27 / synchro
  compteur_periode= compt_period;//laisser 53 pour avoir le départ signal synchronisé
  PORTB &= maskAND;}
}



Un grand grand merci a vous 2 pour votre temps et surtout votre patience :D :D :D

je reviens rapidement aux news mais je sent qu'on voit la lumière au bout du tunnel :)

bonne soirée a tous !

bauvaisis

Juste une dernière question par curiosité : est il possible de facilement "inverser" le signal de sortie finale ? etat 0 en 1 et 1 en 0 ?

merci :)

dfgh

3 lignes à changer
Code: [Select]
void isr1()
{Serial.println(compte_tour_vilo);
  if((compte_tour_vilo++ %2)){compte_tour_vilo=0;
  //compteur_periode=27;//de 0 à 53 pour retarder le signal 66/27 / synchro
  compteur_periode=53;//laisser 53 pour avoir le depart signal synchronisé
  //PORTB &= maskAND;}
  PORTB |= maskOR;}
}
void isr0()
{
  if (compteur_periode++ >=52)
  {
  asm("SBIC 0x05,0");//saut 1 ligne si bit 0 de port B est à 0
  asm("jmp suite");  //sinon saut en etiquette suite
  asm("SBI 0x05,0"); //bit 0 du port B passe à 1
  //compteur_periode=0;
  compteur_periode=27;
  asm("jmp fin");    //saut en fin
  asm("suite:");     //etiquette suite
  asm("CBI 0x05,0"); //bit 0 du port B passe à 0
  compteur_periode=0;
  //compteur_periode=27;//
  asm("fin:");       //etiquette fin
}
}

//compteur_periode=0;
  compteur_periode=27;[/b]
  asm("jmp fin");    //saut en fin
  asm("suite:");     //etiquette suite
  asm("CBI 0x05,0"); //bit 0 du port B passe à 0
  compteur_periode=0;
  //compteur_periode=27;//

dans isr1
////PORTB &= maskAND;}
  PORTB |= maskOR;}

dans isr0

//compteur_periode=0;
  compteur_periode=27;

  asm("jmp fin");    //saut en fin
  asm("suite:");     //etiquette suite
  asm("CBI 0x05,0"); //bit 0 du port B passe à 0
  compteur_periode=0;
  //compteur_periode=27;//


bauvaisis

Super :) cela fonctionne parfaitement ! vraiment mille merci  ! Avec mon pauvre niveau de base en arduino je n'aurais absolument pas été capable d'en arriver la !

Je vous dirai si le test grandeur nature fonctionne, mais la je n'y voit aucune raison :)

excellente soirée a tous ;)

Go Up