Interface à base de pic pour gestion d'impulsions

MAJ du 11/08/2012, 12h40 :

Salut-à-tous!

Suite à quelque divergences ou abus, ce topic a été fermé puis réouvert. Cette première page n'a pas grand intérêt (ça part en sucette), je vous invite à vous rendre directement page 2 : Interface à base de pic pour gestion d'impulsions - #20 by jfs - Français - Arduino Forum, où la discussion reprend son cours normal. Le sujet y est repris à zéro.

Il s'agit de réaliser sur circuit séparé, une sorte d'extracteur de synchro dans un signal impulsionnel pour soulager l'arduino de cette tâche trop lourde en ressources matérielles.

RDV page 2!

Cinci.

PS : merci à Jean-François pour son intervention.

-------------------- Topic d'origine ---------------

Alors voilà, j'ai réussi à faire "déborder" un mega 2560 (enfin sur le papier). Il n'a pas assez de ressources! J'ai même été jusqu'à utiliser le timer du WD, c'est pour dire!

Donc je voudrais l'alléger qu lui collant un petit PIC qui se taperait pas mal du sale boulot dans son coin. Mais j'ai rien pour programmer un pic, donc je propose à quelqu'un qui saurait faire de me programmer un PIC, je peux fournir un code pour uno qui simulerait le signal à traiter, ainsi qu'un circuit imprimé maison tout prêt pour y mettre le PIC et le tester. Pis un peu de sous aussi mais pas trop, juste de quoi payer le PIC et un pack de bière.

Objectif final : mesurer la vitesse de rotation d'un moteur de voiture (Renault11, 1987)

Entrée : Le signal à traiter provient du capteur PMH du moteur (un C2J à allumage électronique intégré) et est préamplifié dans un circuit différentiel.
Caractéristiques : TTL (0-5V) : un train de 42 impulsions bien carrées et régulières par tour moteur, sauf que deux fois par tour, il manque une dent, donc une impulsion... la fréquence des impulsions est donc égale à (42/60) fois la vitesse du moteur.

Sortie : le signal carré mais à une fréquence 8 fois supérieure qui reconstitue les dents manquantes, et une impulsion correspondant au PMH.

On doit pouvoir trouver un PIC en DIL8 ou 12 16MHz qui aurait une INT et deux timers 16 bits, non?

L'algo, je l'ai et il est super simple :

void setup{
  Timer 1 (16 bits) tourne à 2MHz en continu,
  Timer 2 (16 bits) tourne à 16MHz en mode PWM de base (de 0 à "TOP"),
    // en gros, une pin de sortie doit se mettre à 1 quand le timer est à 0 et passe à 0 un peu plus tard (quand T2 = OCR2A) ou l'inverse...
  autoriser l'INT0 sur front descendant (ou montant, sera précisé plus tard).
}
// Chaque impulsion du signal d'entrée déclenche l'interruption INT0 :
ISR(INT0) {
  relever le timer 1
  mettre le timer 1 à zéro
  si (la valeur de T1 > (2 * T1_old)) {  // dents manquantes : on est au PMH
    pin de sortie "PMH" = HIGH
  } sinon {                                // c'est une impulsion normale
    mettre la valeur de T1 dans le "TOP" de T2
    pin de sortie "PMH" = LOW    
    T1_old = T1
  }
}

// pis c'est tout!

Ensuite, le signal carré attaquera une entrée compteur 16 bits de mon mega2560, il ne me restera plus qu'à relever ce compteur toutes les 256ms (d'ailleurs, on peut utiliser le watch Dog pour générer une INT à plusieurs intervalles, dont 256ms : 4 fois par seconde).

L'idée est donc là. le code est donc très simple, mais faut mettre les mains dans le camboui des timers d'un PIC, et là... ça va me prendre une semaine pour étudier le truc, sachant que je n'ai rien pour programmer un PIC...

Quelqu'un se sent d'attaque? Je fournirai également une doc plus précise de ce que je veux (avec courbes), mais l'avantage de cet algo, c'est que le nombre de dents moteur, on s'en tape... :grin:

Merci d'avance!

PS : Ne cherchez pas d'autres solutions techniques, je VEUX un signal de fréquence 8 fois plus élevé. Car j'aurai une mesure bien plus précise (je passe à 704 impulsions par tour moteur contre 40 initialement), et ces impulsions me permettront aussi (avec l'impulsion PMH ainsi générée et en piquant le signal de primaire bobine) de calculer en teps réel l'angle d'avance à l'allumage.

Ce principe de multiplier la fréquence est d'ailleurs utilisée dans le calculateur d'allumage de ma voiture, mais c'est noyé dans de la résine, donc inaccessible. avec ma fenêtre de comptage de 256ms, au ralenti (700tr/min), je compterai 2103 impulsions, au régime max (7500tours) : 22528 impulsions, je pourrais même mesurer jusqu'à 22000tr/min... donc si le PIC le permet (en fonction des prescaler), on pourrait multiplier par 16 la fréquence au lieu de 8 (mais faudrait qu'il tourne à 40MHz pour être précis...)

La question est peut-être bête, mais pourquoi ne pas utiliser un petit atmega ?

Jean-François:
La question est peut-être bête, mais pourquoi ne pas utiliser un petit atmega ?

j'ai juste rajouté un PS... le petit atmega pourrait le faire, mai faut qu'il ait deux timers 16 bits... je vais quand même regarder ce qui se fait chez atmel, c'est vrai que je pourrais le programmer moi-même...

Super_Cinci:

Jean-François:
La question est peut-être bête, mais pourquoi ne pas utiliser un petit atmega ?

j'ai juste rajouté un PS... le petit atmega pourrait le faire, mai faut qu'il ait deux timers 16 bits... je vais quand même regarder ce qui se fait chez atmel, c'est vrai que je pourrais le programmer moi-même...

Bonsoir SuperCinci

je suis un peu du meme avis que Jean-François
pourquoi partir chez un autre fondeur ?, il doit +/- y avoir chez Atmel pour cette problématique "simple" la même chose que chez Microchip
et si tu a déjà un environnement de programmation "Atmel" ce sera surement plus simple pour toi.

ceci étant si tu ne vois qu'un candidat chez MP en 16F ou 18F, tu connais la méthode 8)

Bon, j'ai trouvé, mais qui me dit que j'arriverai facilement à programmer via arduino IDE (adresse des registres)? :

ATMEGA1284 en PDIP40, qui peut tourner à 20MHz et a deux timers 16 bits à 13€HT chez Farnell

Je pense que ça revient au même niveau prise de tête. Je vais tout de même pas utiliser un second MEGA2560 rien que pour ça.

Sinon, le PIC18F13K22 en DIP20 (donc deux fois plus petit) est parfait (64MHz pour 16MIPS), et coûte 3€HT, y'a pas photo.

Pour le sample, je suis chez free, donc ça marche pas (pas d'autre adresse mail sous la main...). Reste encore à le programmer, d'où ma demande qui reste toujours d'actualité!

Juste pour info :

Mesurer une fréquence pour déterminer un régime moteur n'est pas la meilleure solution. Cela fonctionne évidemment avec un grand nombre de pulses mais la résolution est faible.

Il faut mesurer la largeur des créneaux. Tu peut ainsi avoir 48 mesures par tour et chaque mesure est précise. Tu devras juste prendre en considération le pulse manquant qui indique le PMH et ne pas l'utiliser en mesure ou bien en divisant sa largeur par deux.

Je ne vois pourquoi se pourrir la vie à multiplier une fréquence pour ensuite la mesurer.

JLB

Désolé j'avais pas bien lu ta demande.

Etant donné que tu veux absolument une fréquence à mesurer je pense que ma proposition n'a pas de sens.

C'est dommage la fonction compte-tours aurait pu ainsi être faite avec un ATtiny45 ou même un tiny25.

JLB

Jean-François, est-ce que mon dernier message arrive à faire pardonner le message précédent où je me suis laissé emporté par un vieux réflexe d'abruti vaniteux qui ne sert à rien ni à personne ici ?

JLB

jihelbi:
Jean-François, est-ce que mon dernier message arrive à faire pardonner le message précédent où je me suis laissé emporté par un vieux réflexe d'abruti vaniteux qui ne sert à rien ni à personne ici ?

JLB

T'inquiètes, j'ai très bien compris... j'ai un besoin précis, il faut donc que j'y réponde. J'imagine que nous avons chacun notre façon de concevoir un système, mais là, je ne veux (et ne peux) pas changer le cahier des charges.

Je veux simplement en partant du signal jaune :

multiplier la fréquence par 8 ou 16 selon (c'est un choix technique, un facteur autre serait plus compliqué), tout en ayant reconstitué les créneaux manquants (en pointillés bleu). Ensuite, je compterai les impulsions sur un temps défini (et non pas mesurer la durée de l'impulsion). L'avantage, c'est que ça sera précis (rappelons-le, 704 impulsions par tour du moteur). Si je compte 3004 impulsions, ça me donne 1000tr/min, 3014 impulsions correspondent à 1003tr/min... Je suis donc à 10 impulsions près si j'affiche la vitesse moteur par pas de 5... De plus, le signal jaune me donne précisément la position des pistons et me permettra d'afficher en temps réel l'avance à l'allumage (une impulsion correspond à 0.511°).

Il y a un signal compte-tour déjà disponible sur la calculateur, mais il ne fait que deux impulsions par tour moteur et dépend du déphasage d'allumage, donc vraiment pas précis.

Par la suite, un jour peut-être je remplacerai le calculateur actuel par un fait maison, et le multiplieur de fréquence y trouvera naturellement sa place

Multiplier la fréquence ne t'apporte aucune précision supplémentaire.

Si au départ tu as 29, 30 ou 31 pulses le fait de multiplier par 10 te donnera 290, 300 ou 310. Je ne vois pas ce que tu gagnes comme précision.

Il suffit que tu mesures l'intervalle entre deux fronts montants (ou descendant si tu veux) pour connaître le temps mis pour faire un 48ème de tour. Repérer le créneau du PMH est un jeu d'enfants car l'inertie du moteur interdit une variation instantanée du régime.

Tu dis que tes impulsions sont bien précises et régulières. Mais si tu n'as pas confiance dans la précision de ces créneaux tu peux pondérer la mesure sur plusieurs créneaux.

Dans ta solution tu ne mesures le régime moteur que 4 fois par secondes. C'est très insuffisant. Ta précision sera au mieux de 1/12 ce qui est très insuffisant aussi (la multiplication de fréquence ne changera rien à cette présision qui est celle du nombre de pulses d'origine par intervalle de mesure. Donc quand tu liras 3000 tr/mn ce sera en fait entre 2750 et 3250 tr/mn.

Il faut absolument que tu reconsidère ton projet à la base en oubliant cette idée fausse que multiplier la fréquence apporte de la précision.

Ce n'est pas un point de vue, c'est une réalité objective. Si tu ne veux pas revoir ton projet tu devras te contenter d'une précision de 1/12.

JLB

jihelbi:
Multiplier la fréquence ne t'apporte aucune précision supplémentaire.
(...)
Dans ta solution tu ne mesures le régime moteur que 4 fois par secondes. C'est très insuffisant. Ta précision sera au mieux de 1/12 ce qui est très insuffisant aussi (la multiplication de fréquence ne changera rien à cette présision qui est celle du nombre de pulses d'origine par intervalle de mesure. Donc quand tu liras 3000 tr/mn ce sera en fait entre 2750 et 3250 tr/mn.

Je crois que tu te laisses un peu embarquer dans les choses. As-tu bien lu le PS du premier message? Pourquoi veux-tu absolument m'imposer TA façon de voir les choses qui est d'ailleurs fausse (je me suis aussi planté quelque part, un tour moteur donne 44 dents (- 4 manquantes), soit 352 impulsions une fois le signal régénéré et multiplié par 8 ) :

avec mon système, 2750tr/min donnent 4130 impulsions en 256ms, 3250 tr/min donnent 4881 impulsion (joli fossé!). il me suffit de diviser mon comptage d'impulsions par 1,5 (ou le multiplier par 0.66666) pour trouver la vitesse en tr/min. ma précision serait alors de +/-0.33tr/min, arrondissons à +/-0.5. Comment arrives-tu à une précision de +/-250?

Si je ne multiplie pas ma fréquence, alors 2750tr/min donnent 469 impulsions en 256ms, 3250 tr/min en donnent 545 impulsion. il me suffirait de multiplier mon comptage d'impulsions par 5,96 pour trouver la vitesse en tr/min. ma précision serait alors de +/-3tr/min. En plus, comme il manque 4 dents, certaines impulsions sont plus longues et m'induiraient en erreur.

J'ai fait ces calculs vite-fait, ils demandent à être vérifiés sur le terrain bien sûr.

Et je me répète, si j'ai pris ce choix, saches que c'est longuement réfléchi. J'ai déjà tenté une mesure de longueur d'impulsion, ça demande un lissage (en 1980, la mécanique n'était pas aussi précise qu'aujourd'hui) qui prend beaucoup de temps sur un arduino. Et je sais exactement quels signaux j'ai à disposition, et surtout ce que je veux en faire.

Comme tu n'as pas compris, j'ai rajouté en dessous les deux signaux que je veux :

Chaque impulsion obtenue dure 1/8ème de l'impulsion précédente (de toute façon, ce qui m'intéresse, ce sont les fronts descendants ou montants, pas les deux). Donc une impulsion représente 1/8ème de l'impulsion de départ, donc plus précis.

Mes 4 mesures par seconde sont justifiées par le temps disponible sur l'arduino, et après tout, ça ne concerne en rien le système à PIC : je veux faire une fonction bien précise sur un bout d'époxy, le reste du traitement se trouve à l'autre bout d'un fil (et dans un autre topic).

Reprenons : je demande une fonction précise, pas qu'on vienne tout me chambouler avec des solutions qui ne sont pas adaptées à mon projet. Si dans une usine, le patron te demande de peindre une voiture en rouge, tu auras du mal à lui faire comprendre que le vert c'est mieux.

Mais il n'existe pas de décimales aux pulses.

Dans mon exemple 29, 30 et 31 donnent une fois multiplié par 10 : 290, 300 et 310. Les valeurs intermédiaires 291,292,293 etc n'existeront jamais.

Pourquoi faire du hardware pour cela ??? Tu n'as qu'à prendre ton nombre de pulses et le multiplier par ce que tu veux (1 milliard si tu veux).

Il n'y a aucun gain de précision en multipliant une fréquence de pulses !!!!!!!!!!!!!!!!!!!!

JLB

Je ne veux rien chambouler. Tu peux bien mesurer une fréquence si tu veux même si personne ne fait ainsi.

Je veux juste te dire que la multiplication de fréquence c'est du hardware et du software qui ne sert absolument à rien.

JLB

Autre précision par l'exemple mais tu peux faire ce que tu veux.

Si tu n'avais qu'un pulse par tour tu pourrais par la mesure de temps donner un régime précis à chaque tour moteur. Par la mesure de fréquence il faudrait que tu sois à 3000 tr/mn pour avoir seulement 50 pulses par secondes. A priori il n'y a pas photo. A 900 tr/mn tu aurais 15 pulses soit une précision de 1/15.

JLB

jihelbi:
Je veux juste te dire que la multiplication de fréquence c'est du hardware et du software qui ne sert absolument à rien.

JLB

C'est bien ce que je pensais, t'as pas compris du tout... le PIC ne doit pas mesurer la fréquence, mais la multiplier (la valeur qu'il peut mesurer dans le premier timer, une fois qu'elle est transmise dans le second timer, on s'en fout). Regarde le graph que j'ai mis : c'est le nombre d'impulsions qui est multiplié, pas une valeur numérique! Si je compte mes impulsions sur la troisième courbe, tu ne crois pas que je vais compter plus ou moins d'impulsions? et pas forcément par bloc de 10... la preuve :

Si mon signal d'entrée fait 25 impulsions / sec (25Hz quoi), je le multiplie par 10 dans le pic à l'aide de ses deux timers. en sortie du pic, j'ai quoi? ben un signal qui fait 250 impulsions par seconde, non?

Bon, dans l'arduino qui est à l'autre bout du fil, si je compte les impulsions du signal d'entrée sur une fenêtre de 990ms, alors je trouve 24 (il faut une seconde complète pour trouver 25 imp). Avec cette même base de temps, je compte le signal généré par le pic : je trouve 247 impulsions. Pour savoir où j'en suis et retrouver le nombre d'impulsions de mon signal d'origine, comme la fréquence à été multipliée par 10, je divise le nombre d'impulsions par 10, et je trouve : float x = NB_Imp / 10 = 24.7

Est-ce que mon comptage n'est pas plus précis en multipliant ma fréquence avant comptage? avec 990ms, je suis très proche de la seconde, donc mon comptage devrait être très proche de 25. avec ma solution, je suis plus proche de 25 qu'en ne comptant que les impulsions de départ.

Dans mon exemple, mon moteur tourne à 34,090909... tr/min.

Comptage des impulsions d'entrée (abstraction des dents manquantes pour le coup) : je dois multiplier le nombre d'impulsions comptées par (60/44/0.99 = 1.37741) pour trouver la rotation du moteur. donc j'ai compté 24, je trouve une vitesse de 33.05784 tr/min Erreur = ~ -1,03.

Comptage des impulsions de sortie du pic : je dois maintenant multiplier par (60/44/0.99/10 = 0,137741), j'ai compté 247, je trouve 34,022027 tr/min. Erreur = ~ -0,07.

Quelle méthode est la plus précise? sachant qu'en réel, mon moteur tournant à 34.09090909... tr/min donne 24.75 impulsions par tranche de temps de 0.99s... dans le premier comptage, on a perdu 0,75 impulsions, dans le second, seulement 0,05. (0,75 x 1,37741 = 1,03305 et 0,05 x 1,37741 = 0.068882). Si t'arrives encore à me dire que je me plante, va falloir que je trouve une nouvelle forme pour te l'expliquer!

De même, il m'arrive d'utiliser le truc suivant pour arrondir un nombre avec des décimales :

float arrondi2(float x){
  float y;
  y = x*100;
  return (int(y)/100);
}

Tu vas me dire que x contenait déjà des décimales... ok, mais dans un beau signal carré où on synchronise les impulsions sur front montant, le front descendant ne correspond-il pas à une demi impulsion (0,5)?

Et un signal de période 1 seconde, est-ce que pour t = 1,4541220147 s on ne peut pas considérer le signal quand même? les impulsions contiennent une donnée importante : la période (le temps entre deux impulsions) qui s'exprime en secondes, ms, µs, ns... ne sont-ce pas des décimales, tout ça? Et c'est justement le rôle des impulsions d'un signal (hormis PWM) de donner des bases de temps. Si ta montre n'affichait pas les secondes, comment ferais-tu un oeuf à le coque? n'essaierais-tu pas d'inventer un système qui te permet de découper les minutes de ta montre et ainsi avoir le temps correct pour la cuisson?

sur mon moteur, une dent correspond à 8.182°. j'ai quand même le droit de savoir ce qu'il se passe quand il est à 45°, même si ça na correspond pas à une impulsion... c'est pas un moteur pas-à-pas... (45 degrées correspond à 5,5 dent).

essaie de comprendre : le système qui compte les impulsions existe déjà. il me faut juste un petit circuit qui adapte le signal. (vais finir pas le faire moi-même...)

Je reconnais que j'ai bien tartiné le truc, un beau pavé, alors si j'ai pris le temps de l'écrire, prends le temps de lire, merci.


A part ça, quelqu'un saurait me programmer un PIC? je viens de télécharger MPLab, pour voir si ça peut me le simuler dans un premier temps... Pis ben... J'voudrais bien programmer moi-même, mais j'ai pas de port // sur mon PC pour utiliser les montages du net.

Bon, dans l'arduino qui est à l'autre bout du fil, si je compte les impulsions du signal d'entrée sur une fenêtre de 990ms, alors je trouve 24 (il faut une seconde complète pour trouver 25 imp). Avec cette même base de temps, je compte le signal généré par le pic : je trouve 247 impulsions. Pour savoir où j'en suis et retrouver le nombre d'impulsions de mon signal d'origine, comme la fréquence à été multipliée par 10, je divise le nombre d'impulsions par 10, et je trouve : float x = NB_Imp / 10 = 24.7

Ce post relève du canular...

COMMENT LE PIC TROUVE T-IL 247 ???????????? IL NE PEUT TROUVER QUE 240 OU 250 OU 230 !!!!!!!!!!!!!!!!!!

JLB

PS: surtout ne pas craquer ! surtout ne pas craquer ! surtout ne pas craquer !..

jihelbi:
Ce post relève du canular...

COMMENT LE PIC TROUVE T-IL 247 ???????????? IL NE PEUT TROUVER QUE 240 OU 250 OU 230 !!!!!!!!!!!!!!!!!!

JLB

PS: surtout ne pas craquer ! surtout ne pas craquer ! surtout ne pas craquer !..

J'essaie de rester zen, mais t'es bougrement têtu! je remets les courbes :

Les deux premières sont identiques, c'est le signal qui sort du capteur. Moi, je veux juste que le pic me fournisse les deux autres courbes, c'est à dire un signal contenant 8 fois plus d'impulsions que celui du capteur. Regarde l'algo du premier post : où vois-tu un comptage? ben non, y'a pas besoin de compter! il suffit de mesurer la période des impulsions avec un timer à 2MHz et de générer avec cette même mesure mais sur un timer 8 fois plus rapide un signal carré... c'est pas assez clair? ]:slight_smile:

MA METHODE DE MESURE SE TROUVE DANS UN AUTRE SYSTEME QUE J'ETALERAI DANS UN AUTRE TOPIC! ICI? IL FAUT JUSTE ME PONDRE LES TROISIEME ET QUATRIEME COURBES.

compte les impulsions de la troisième courbe : tu la comptes 10 par 10? ben pas moi, et encore moins l'arduino dont on ne parle pas ici.

et je répète encore :

le PIC ne doit pas mesurer la fréquence

le pic NE COMPTE PAS LES IMPULSIONS vindédiou!

Je reconnais que j'ai bien tartiné le truc, un beau pavé, alors si j'ai pris le temps de l'écrire, prends le temps de lire, merci.

t'as lu cette phrase? T'es en train de parler d'un autre sujet, et j'imagine que si quelqu'un pouvait me rendre le service que je demande, ben il n'aura plus trop envie de se farcir tout ça...

Bon, dans l'arduino qui est à l'autre bout du fil, si je compte les impulsions du signal

C'est l'arduino qui compte les impulsions!!! et là, c'est un topic qui parle d'une interface contenant un PIC, mais pas d'arduino!

Il est des cas fortuits où l'homme le plus entreprenant est soumis à des vicissitudes des plus aléatoires...

Il n'est point besoin de réagir à l'épiphonème du docte logographe dont je tiens à dulcifier l'éloquence mordacite pour sémiologer une prose hyaline dont l'indéhiscence ne peut apparaître qu'à quelques onguligrades lignicoles à l'affut d'amphibologies gonadotropiques.

A bon entendeur adieu à ce post...

JLB

PS: J'aurais du accepter de lui faire son PIC multiplicateur. Il proposait de l'argent après tout...

Bien tenté, mais ça montre juste que tu t'es rendu compte de ta bourde et que tu n'oses même pas le dire... utiliser des mots si savants est un beau bouclier pour cacher sa bêtise.

Non, je ne paye pas l'intervenant, je le défraie, c'est pas vraiment pareil.

Quelqu'un a compris ce que je cherche et pourrait m'aiguiller?

Réouverture du sujet XD

Je précise également que j'ai indiqué à jihelbi qu'un forum est un espace ouvert où l'on partage les opinions et non pas un exutoire qui sert à imposer ses idées comme étant unique en pensant de façon unilatérale que les autres sont des ignares hébétés profonds.