Sujet : Mixage de voies et liaisons I²C entre carte Arduino

Bonjour,

Je suis tout nouveau ici. Je vais donc faire rapidement une présentation. Je pratique l'électronique depuis mes 14 ans, j'en ai maintenant 34. Oui, je suis un vieux de la bielle ! J'ai accéder aux composant programmé un peu tard alors, veuillez excuser mes questions idiotes. J'ai décidé de plaqué les Pics, car ils me demandais beaucoup de travaille de carte pour finalement pas obtenir grand chose. C'est par hasard que j'ai découvert, il y a peu les Arduino. Depuis, nombre de mes projets sont sur les rails.

Maintenant que cette présentation est fini, je vais en venir au problème.
Je suis en train de créer un rov et si j'ai largement évoluer dans le monde des submersible c'est que j'en ai fais des tests et des mesures. Je ne parlerais donc pas de cette partie là. Pendant une discussion entre confrères du monde des subs, j'ai compris que l'intérêt d'avoir un tout mini sub complet et piloter par câble était une approche particulière. À ce moment précis, les détails techniques se dessinais devant moi.

Il me fallait avoir un joystick comme celui que l'on trouve sur une radio-commande. J'en ai trouvé grâce à inter-nenette et je me suis penché sur les possibilités. Je dois donc mixés des voies pour piloter deux moteurs avec un seul joystick. Mes joystick ont des potentiomètre de 5K variant ainsi de 0V à 5V en fonction de leurs position. Ensuite ça se complique et c'est à ce point que j'ai besoin d'aide.

Ma commande, ici on va dire maître, est une carte Arduino Méga. Elle a tout les boutons, joysticks et écran LCD piloter par liaison I2C. Pour être très exacte, c'est un module LCD03 de Davantech. Il fonctionne parfaitement et je suis très heureux de l'utilisé. Je n'aurais donc pas à revenir dessus, en principe.

Ensuite, partira un câble composé d'un +5, d'un 0V, d'un SDA et d'un SCL. Une résistance sur SDA et SCL au pull-up de façon constante. C'est le principe de l'I2C.

Et au bout de ce câble, une autre carte Arduino méga. Peut-être une nano. Enfin pour les essais, c'est une méga. Cette carte là me pilotera des sorties tout ou rien, des captures analogiques et enfin pour finir des servos et variateurs donc PWM.

Mon problème est très simple. Si je pousse le manche en avant, je mixe mes voies 1 et 2 vers une PWM représentative de l'emplacement du manche. Les deux moteurs vont tourné dans un sens contra-rotatif. Le ROV part en avant. On à la même à l'envers et enfin, on mixe pour tourner à droite et à gauche.

Comment dois-je m'y prendre (hors trame I2C) pour que le mixage proportionnel aux commande s'opère ?
Faut-til analysé la position des deux potars puis en fonction commandé le pilotage des moteurs, ou bien un calcul de la valeur numérique, recopie des potard suffit pour piloter au bout les variateurs ?


Ensuite, j'ai commencé à étudier mes trames.
Cas 1, le maître envoie en permanence des trames vers l'autre Arduino. Dans ce cas [Start Bit] [Appel de la carte en écriture] [Ack] [Moteur 1] [Moteur 2] [Serv 1] [Serv2] [Serv 3] [Eclairage] [Aquitement pression] [Stop Bit]

Cas 2, le maître passe après la commande en réception pour remonter les défauts. Dans ce cas  [Start Bit] [Appel de la carte en lecture] [Ack] [Pression actuel] [Fuite] [Température] [Luminosité] [Stop Bit]

Pour info, chaque crochet vaut 8 bits à la suite. est-ce que je ne risque pas d'avoir une séquence un peu longue ainsi ? Existe-il une meilleure possibilité ?

Autant de questions que je me pose dans ce cas précis.

Bon et bien, j'espère que je n'ai pas trop demander du premier coup. Je pense y allé pas à pas, commencé par piloter mes cartes, l'une l'autre et dans quel cas chacune à ses priorités.

Merci pour votre attention.
Microbulle.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

2

Re : Mixage de voies et liaisons I²C entre carte Arduino

Salut,

Ca ressemble fort au projet du radeau que j'ai fait il y a quelques années (http://www.pobot.org/-Radeau-environnemental-.html), hormis le fait que mon radeau ne va pas sous l'eau (en temps normal en tout cas wink) et qu'il est piloté par liaision radio bi-directionnelle et pas par liaison filaire.

Concernant le mixage dont tu parles, j'ai procédé un peu différemment de ce que tu envisages. En fait, le dialogue entre le poste de contrôle à terre et le radeau se compose d'une trame aller avec les ordres (moteurs de propulsion, moteur du treuil, commandes des relais,...) et d'une trame retour avec les mesures (capteurs embarqués, GPS, cap, tensions batteries,...). La commande des divers moteurs est exprimée sous forme d'un encodage ASCII donnant le niveau de puissance et le sens. J'utilise en entrée la position du joystick en X et Y telle qu'elle est retournée par l'OS (le poste de contrôle est un PC portable), mais ce serait pareil en utilisant un ADC qui numériserait la tension au curseur du potentiomètre. Ensuite, il s'agit d'un calcul à 2 balles pour passer de la position X/Y du joystick aux deux consignes moteur, selon une loi telle que celle que tu décris.

C'est trivial si on réalise que :
- la position en Y (axe avant-arrière du joystick) représente la vitesse de déplacement du radeau, et donc la médiane des vitesses des deux moteurs,
- la position en X représente la vitesse de rotation du radeau sur lui-même, et donc le biais de la vitesse de chaque moteur par rapport à la médiane, qu'il suffit donc d'ajouter pour un des moteurs et de retrancher pour l'autre.
Bien entendu le résultat des opérations médiane +/- biais est à borner par les bornes maxi et mini des consignes à envoyer.

On peut faire plus sophistiqué, avec une loi trigonométrique, mais personne n'y verra une différence à l'usage, alors pas la peine de se faire des noeuds à la tête wink

Je ne m'embête pas avec l'aspect contra-rotatif des hélices à ce niveau, car l'inversion est gérée au niveau du câblage des moteurs. Ca présente l'avantage de ne pas mélanger les problèmes et de ne rien avoir à changer si un jour je passe des hélices aux roues à aubes par exemple smile

Concernant l'usage que tu veux faire de l'I2C, attention : ça ne "porte" qu'à quelques 10aines de centimètres. Pour aller au-delà (jusqu'à une 20aine de mètres), il faut ajouter des buffers de ligne. Je décrit tout cela dans un des articles de la rubrique consacrée au radeau, car la sonde immergée utilise une liaison I2C longue avec le radeau.

Pour une liaison longue distance comme ce que tu veux faire, il serait beaucoup plus simple à mon avis de passer par une liaison RS232 ou RS422. Je ne l'ai pas fait dans mon cas car les 2 UARTs disponibles sur le MCU utilisé étaient déjà occupés par la liaison radio et le GPS externe.

Cordialement

Eric

Re : Mixage de voies et liaisons I²C entre carte Arduino

Bonjour,

Wah, je suis surpris de l'idée passé par une liaison bi-directionnel. Mais bon, si tu y est arrivé, c'est peut-être une solution. Dans mon cas, bien que j'adore travaillé avec des ondes radio, j'ai un impératif de ne pas en utilisé à cause des expos.

Le choix délibéré du câble sera de 10 mètres environs. Donc il faudra que j'amplifie le signal... Donnée que je n'avais pas ! Je vais regardé ça de plus prêt et passé peut-être par une solution alternative.

En effet, sur la carte méga, j'ai vue plusieurs tx/rx. Est-ce que j'ai pas intérêt à passé par une tx/rx de l'une vers l'autre tx/rx de la uno qui sera embarqué ? Je n'ai pas essayer et j'ai pas non plus le retour sur expérience à ce sujet. L'i2C je le pratique régulièrement donc je sait à quoi m'attendre.

Si j'applique ce dernier cas, je dirais que ça me soulage beaucoup la situation. Ma télécommande mallette, aura un grand nombre de boutons. A ce moment la, écran, boutons seront sur I2C, alors que les potentiomètres resterons sur l'analogique. Les autres sorties me servirons pour divers diodes et équipements. Enfin, je fais un départ en Tx/Rx vers l'autre Arduino.

Pensez-vous que c'est jouable ?

Pour la partie commande triviale, c'est vrai que j'avais pas raisoné ainsi et je n'avais pas non plus connaissance de la partie trigonométrique. Je vais essayer bien sûr. Mais avant, il faut que je travaille sur les trames.

Au niveau des trames en Tx/Rx comment ça se comporte ? Comment s'organiser dedans ? trame 1 : moteur choisi, trame 2 : sens, trame 3 puissance ? Quelle vitesse avons nous afin  de ne pas perdre le contrôle ? Quelle distance on peut accepté entre les deux cartes ? Il me reste beaucoup de questions du coup...

Dans tous les cas de figure, si je passe par RS232, je suis content des informations qui me sont données. J'espère progressé encore et faire évolué mon système pour faire piloter les visiteurs, pour peu qu'ils veuillent savoir comment ça se passe en pilotage.

Merci donc pour tout ça, bon dimanche.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

4

Re : Mixage de voies et liaisons I²C entre carte Arduino

Microbulle a écrit:

Wah, je suis surpris de l'idée passé par une liaison bi-directionnel

Le but est de faire tout passer (commandes, télé-mesures, statuts,...) sur un même canal. C'est quand même la moindre des choses dès qu'on utilise un réseau, qu'il soit sur un support série, I2C, Ethernet,...

Microbulle a écrit:

Mais bon, si tu y est arrivé, c'est peut-être une solution. Dans mon cas, bien que j'adore travaillé avec des ondes radio, j'ai un impératif de ne pas en utilisé à cause des expos.

En fait la liaison radio n'est qu'une simple liaison série "dématérialisée". Des deux côtés on s'interface avec le Rx/Tx (soit du MCU, soit du port COM du PC). Donc ce n'est pas plus compliqué que de tirer un câble entre les deux protagonistes. De toute manière, la radio ne serait pas applicable dans ton cas car la pénétration dans l'eau est très faible (cf les radio-modélistes qui font du sous-marin : ils ne peuvent évoluer que dans des bassins de faible profondeur, comme les piscines)

Microbulle a écrit:

Le choix délibéré du câble sera de 10 mètres environs. Donc il faudra que j'amplifie le signal... Donnée que je n'avais pas ! Je vais regardé ça de plus prêt et passé peut-être par une solution alternative.

A moins que tu ne tiennes vraiment à l'I2C, ou alors que tu aies besoin d'adresser plusieurs dispositifs remote (ce qui n'est pas ton cas, puisqu'il n'y a qu'un seul ROV au bout du fil), je te conseille fortement d'utiliser une liaison série RS232. L'I2C n'est pas fait pour de telles distances, même si on peut y arriver (je l'ai fait) via des extenders.

En effet, sur la carte méga, j'ai vue plusieurs tx/rx. Est-ce que j'ai pas intérêt à passé par une tx/rx de l'une vers l'autre tx/rx de la uno qui sera embarqué ?

Personnellement, c'est ce que je ferais (alors que je connais également l'I2C). Par contre pour de telles longueurs il est fortement conseillé de convertir le niveau TTL en RS232 et vice-versa. Transporter une com sérier TTL (donc en 0/5V ou 0/3V) sur un câble de 10 mètres va la dégrader, surtout s'il y a des générateurs de parasites dans les environs.

Ca se fait de manière totalement transparente via des MAX232. Le top serait du RS422 (RS232 avec signaux symétrisés), car on devient encore plus immune aux parasites. A voir si dans ton cas d'utilisation tu risques de te trouver dans des milieux perturbés (attention, dans les salons, tu as pas mal de parasites générés par tous les variateurs d'éclairages et autres dispositifs qui commutent ou hachent la tension secteur, sans parler des com HT utilisées pour les talkie-walkie des organisateurs et équipes de sécurité).

Au cas où tu optes pour le 422, il existe exactement les même circuits de conversion que pour le RS232. Un petit coup de Google te les donneras. Faire un tour sur le site de Maxim-Dalas, qui fabrique les MAX232 cités plus haut, devrait te donner la réponse très rapidement. Ils ont aussi énormément de notes d'application pour aider à faire ses choix et à mettre en oeuvre leurs produits.

Si j'applique ce dernier cas, je dirais que ça me soulage beaucoup la situation. Ma télécommande mallette, aura un grand nombre de boutons. A ce moment la, écran, boutons seront sur I2C, alors que les potentiomètres resterons sur l'analogique. Les autres sorties me servirons pour divers diodes et équipements. Enfin, je fais un départ en Tx/Rx vers l'autre Arduino.

Pensez-vous que c'est jouable ?

Je ne comprends pas très bien ce que tu veux dire.

Histoire de te donner des indications de pistes, je vais détailler ce que j'ai fait. Pour le radeau j'avais deux types de consignes à envoyer :
- des valeurs binaires (état des switchs de la commande)
- des valeurs pseudo-continues (consignes de puissance des moteurs).

C'est la même chose en gros que ton problème, puisque les signaux analogiques doivent être convertis en numérique pour pouvoir être transmis, que ce soit en I2C, en série, ou autre. Si tu envisages de transmettre directement la tension de sortie des potentiomètres via le câble, attends-toi à des gros problème, car le transport d'un signal analogique sur de telles longueurs n'est pas une chose simple.

Donc pour résumer, ce que je te suggère au niveau de ton poste de contrôle, est de faire les choses suivants :
- capturer l'état des switchs via des I/O et la position des potentiomètres via des ADC. Tout cela te donne des valeurs numériques : un ou plusieurs octets pour refléter l'état de tous les switchs, à raison d'un bit pour chacun pour faire  compact, et un octet par moteur pour encoder sa consigne
- construire une trame qui contient l'ensemble
- envoyer cette trame sur la câble
- cycler avec une récurrence adaptée à la réactivité souhaitée (dans la pratique, compte tenu de l'inertie du ROV, une période de 100ms est largement suffisante, pas besoin de descendre plus bas)

Au niveau du ROV :
- on décode les trames à chaque réception, et on en extrait les consignes pour les switchs et les moteurs
- on applique cela à l'électronique environnante
- on construit une trame de réponse, avec au minimum un rapport de bon fonctionnement, et si on a des capteurs embarqués, avec les valeurs qu'on en aura collecté entre deux itérations
- on renvoie le tout vers le poste de contrôle

Dans cette architecture, le ROV est en esclave du poste de contrôle et n'émet pas spontanément, mais uniquement en réponse aux trames de contrôle reçue.

Dans mon projet, pour ne pas saturer la bande radio et pour être certain de tenir la récurrence imposée par le poste de contrôle, je ne renvoyais pas systématiquement l'intégralité des valeurs des capteurs embarqués, mais je les répartissais sur les réponses successives, de manière à avoir tout renvoyé sur un cycle de 1 seconde. En effet, les paramètres mesurés, que ce soit la position, le cap, les températures,...) ont des constantes de temps largement supérieures à cet ordre, et donc ça ne sert à rien de renvoyer comme un malade des valeurs qui seront identiques la plupart du temps d'une trame sur la suivante.

Au niveau des trames en Tx/Rx comment ça se comporte ? Comment s'organiser dedans ? trame 1 : moteur choisi, trame 2 : sens, trame 3 puissance ?

Comme décrit plus haut, tout est dans une trame unique, qui est une bête struct C au niveau programme.

Quelle vitesse avons nous afin  de ne pas perdre le contrôle ?

Cf plus haut. Une trame de contrôle toutes les 100ms est largement suffisant.

Quelle distance on peut accepté entre les deux cartes ?

Tout dépend du type de communication. En I2C de base, quelques 10aines de centimètres. Avec les extenders je suis allé jusqu'à 15 mètres. Avec du RS232 ou RS422 ça peut aller jusqu'à plusieurs 100aines de mètres.

Bonne continuation

Eric

Re : Mixage de voies et liaisons I²C entre carte Arduino

Plop,

Je viens de voir ton nouveau message. Je dois avoué que je ne comprends pas !

Pourquoi utilisé un max 232 ?

Est-ce que cela veut dire que la carte n'est pas capable de faire du RS 232 et qu'il faille interfacé ?

Autre chose, l'I2C, deux fils et basta. Là, si c'est du pure série, bien que le fait de passé en bi-directionnel séparer je vais en avoir carrément plus. Pas glop pour mon modèle si petit !

Donc je suis dans l'impasse !

A propos, j'ai pas su trouvé de schéma série utilisant du RS232 mais je ne suis pas doué en recherche. Donc pas forcément la bonne piste sous la main.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

6

Re : Mixage de voies et liaisons I²C entre carte Arduino

Microbulle a écrit:

Pourquoi utilisé un max 232 ?

Est-ce que cela veut dire que la carte n'est pas capable de faire du RS 232 et qu'il faille interfacé ?

Exact.

Les I/O Rx/Tx sont en niveau TTL (càd 0-5V ou 0-3.3V) et pas en RS232 (càd -12V/+12V). Si on veut connecter cela sur un port RS232 (de PC ou d'autre chose) il faut ajouter l'étage de conversion de niveau.

Il existe des shields Arduino qui font cela (je ne suis pas du tout un spécialiste de l'Arduino, mais c'est Google qui vient de me le dire via une recherche "Arduino RS232").

Microbulle a écrit:

Autre chose, l'I2C, deux fils et basta. Là, si c'est du pure série, bien que le fait de passé en bi-directionnel séparer je vais en avoir carrément plus. Pas glop pour mon modèle si petit !

Je pense que tu fais erreur : une liaison série c'est aussi 2 fils : Rx et Tx (+ la masse comme pour l'I2C). Pourquoi penses-tu qu'il y en a plus ?

A propos, j'ai pas su trouvé de schéma série utilisant du RS232 mais je ne suis pas doué en recherche. Donc pas forcément la bonne piste sous la main.

Il y a un petit site que je connais ( smile ) où on peut trouver un article écrit par un mec que je connais ( smile smile ) et qui explique précisément tout cela : http://www.pobot.org/S-ouvrir-au-monde.html

On peut tomber dessus en saisissant "MAX232" dans le champ "recherche" du site en question.

Google est toujours ton ami... si tu ne trouves pas sur le site POBOT pour commencer wink

Re : Mixage de voies et liaisons I²C entre carte Arduino

Re ^^

Bon en fait j'ai effectivement dit une énormité et je m'en excuse d'avance !

3 Fils et basta wink

Bon, ce qui c'est passé c'est que je tombais sur des trucs de PC toussa toussa ! Et forcément là, je ne veux pas communiqué avec un PC, donc je n'ai pas su trouvé...

Si je résume, donc on est déjà au niveau TTL, mon rov, lui aura de toute facon du 5V embarqué nimi, à voir si un jour il y aura du 12V. Mais c'est moins sûr !

Si je comprends bien, le TX de la méga sera branché sur le RX de la nano. Puis le RX de la méga sera branché sur le TX de la méga. La masse sera de toute façon commune. Je rajouterais que c'est la même alimentation. Corrige moi si je dis une bêtise, on est jamais de deux paire d'yeux pour voir les erreurs wink

Ensuite, faut-il que je sécurise mon câble avec des résistances au pull-up / pull-down ? Le MAX 232 en a dedans. Je peux toujours en ajouter.

Niveau moteur et anti-parasitage. Des capas de découplages viendrons sur mes moteurs. Donc pas de soucis de ce cotés là.

Maintenant, si j'ai juste au niveau du schéma, je vais cherché des codes pour communication entre arduino. But du jeu, on appuie sur un bouton et hop c'est la diode en face qui s'allume.

Ah tien, une dernière petite chose. Si à 10 mètre c'est un peu trop faible, un transistor, quelques résistances et hop je réajuste / inverse mon signal wink Pratique non ?

Bon et bien, avec toutes ces infos, comme dit l'indien d'Amérique "Yapuka" !

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

8

Re : Mixage de voies et liaisons I²C entre carte Arduino

Microbulle a écrit:

Bon en fait j'ai effectivement dit une énormité et je m'en excuse d'avance !

Ca arrive même aux meilleurs big_smile

Microbulle a écrit:

Bon, ce qui c'est passé c'est que je tombais sur des trucs de PC toussa toussa ! Et forcément là, je ne veux pas communiqué avec un PC, donc je n'ai pas su trouvé...

Même entre deux PC il suffit de 2 files (+ la masse). Les autres signaux ne sont connectés que si on utilise du handshaking hardware, ce qui est extrêmement rare. Ca se faisait autrefois, car les procs étaient lents, et  font on avait donc pas mal de chances de ne pas avoir le temps de traiter les données au rythme où elles arrivent. Actuellement, même sur des MCU le pb arrive quasiment jamais.

Microbulle a écrit:

Si je résume, donc on est déjà au niveau TTL, mon rov, lui aura de toute facon du 5V embarqué nimi, à voir si un jour il y aura du 12V. Mais c'est moins sûr !

Je ne pige pas trop : les moteurs sont alimentés en combien et comment ?

Dans tous les cas, 10m en TTL 5V c'est chercher les emm...des. Met un MAX de chaque côté si tu veux un bon conseil. Puur te dire : dans le radeau, le module GPS est en tête de mât (soit 1 petit mètre au-dessus du point), et j'ai quand même préféré passer en RS232 entre lui et la carte de contrôle qui est au niveau du pont. Ca évite toute mauvaise surprise causée par un quelconque truc qui rayonne dans les environs.

Si je comprends bien, le TX de la méga sera branché sur le RX de la nano. Puis le RX de la méga sera branché sur le TX de la méga. La masse sera de toute façon commune.

Tu as tout compris

Je rajouterais que c'est la même alimentation.

Pas obligatoirement, voire surtout pas. Si c'est la même alimentation, ça veut dire que tout est alimenté par la surface. Encore une fois, les perturbateurs alentour vont se faire une joie de polluer ta ligne d'alim en 5V et tu va tout récupérer au niveau du MCU.

Je ne sais pas comment tu alimentes le ROV, mais il y a deux options :
- embarquer une batterie 12V (ou plus) pour les moteurs et faire le 5V local à partir de là (avec un bon filtrage pour nettoyer les parasites créés par les moteurs)
- descendre le 12V depuis la surface. C'est plus simple, car on n'est pas contraint par le volume et le poids des batteries, mais il va y avoir des pertes tout au long des 10m de câbles (effet Joule). Sauf si les moteurs consomment 3 fois rien (est-ce le cas), ou bien si la section des fils d'alim et de masse sont sur-dimensionnés afin d'offrir une résistance minimale

Il existait un site nommé ExploBotique il y a quelques années (je crois que je l'ai référencé dans un de mes articles consacrés au radeau), tenu par des fous furieux des ROVs (des gars des parages de Toulon, qui exploraient des résurgences à -40m et plus avec des ROVs construits en éléments PVC haute pression pour plomberie piscine). Je crois qu'ils alimentaient leurs moteurs en... 100V, de manière à avoir une intensité faible malgré des moteurs puissants. Tu n'as peut-être pas besoin d'aller jusque là, mais ne travailler qu'en 5V est tout sauf une bonne idée.

Ensuite, faut-il que je sécurise mon câble avec des résistances au pull-up / pull-down ?

Il n'y a pas de pull-up/down sur les liaisons série.

Niveau moteur et anti-parasitage. Des capas de découplages viendrons sur mes moteurs. Donc pas de soucis de ce cotés là.

Souviens-toi qu'on n'est jamais assez généreux sur ce plan-là. Il en faut au minimum 3 par moteur.

Maintenant, si j'ai juste au niveau du schéma, je vais cherché des codes pour communication entre arduino. But du jeu, on appuie sur un bouton et hop c'est la diode en face qui s'allume.

Les articles dans les parages de celui qui je t'ai indiqué précédemment devraient répondre à tes questions : ils contiennent le code source et tout ce qu'il faut pour compiler. Attention : ce n'est pas de l'Arduino, mais du code C AVR natif (trop facile sinon wink ). D'après ce que j'en sais, la lib Arduino contient de quoi faire en sorte qu'envoyer ou recevoir des données via une liaison série se résume à un appel de fonction.

La rançon de cela, c'est que le code généré est 5 à 10 fois plus gros (et moins rapide souvent) que si on écrit soi-même ce dont on a besoin (et rien d'autre). Si tu analyses l'article cité et les sources qui l'accompagnent, tu pourras constater que malgré les apparences c'est beaucoup moins compliqué qu'il n'en a l'air. Sans parler de la situation où ça ne marche plus dans les coulisses, où si on veut faire des choses non prévues par la lib. C'est pour cela que je n'aime pas trop l'Arduino en fait.

Ah tien, une dernière petite chose. Si à 10 mètre c'est un peu trop faible, un transistor, quelques résistances et hop je réajuste / inverse mon signal wink Pratique non ?

J'ai bien peur que tu n'idéalises les choses. Pas si simple que cela, car il n'y a pas que l'atténuation du signal qui perturbe, mais aussi les effets capacitifs des fils de grande longueur (c'est pour cela que l'I2C de base est limité en distance) et la superposition des parasites créés par l'environnement. Et tout cela ne se traite malheureusement pas avec avec un transistor et quelques résistances.

S'il y a une chose que j'aie retenue (entre autres), c'est que dans ce domaine, il ne faut pas chercher à corriger un problème, mais faire en sorte qu'il n'apparaisse pas.

Bon et bien, avec toutes ces infos, comme dit l'indien d'Amérique "Yapuka" !

Bon courage wink

Re : Mixage de voies et liaisons I²C entre carte Arduino

En fait, je ne vais pas avoir beaucoup le choix.

Je vais mettre une petite caméra embarqué. Le souci est qu'elle est en 12V. Je n'ai pas la place matériel de mettre une batterie dedans... sniff ! Je vais donc devoir alimenté de dehors. Donc 12V -> 5V -> arduino. Le 12V restera quand même pour la caméra.

Ensuite, je peux aussi la retirer mais alors, je perds une fabuleuse idée d'avoir un mini rov avec sa caméra et son bras manipulateur. Dommage !

Donc, comme ce rov me sert de prototype, a la limite, j'envisage tel que et je ferais les modifications qui s'impose.

Dans l'ensemble, je suis assez d'accord avec toi. Il vaut mieux éliminer le problème que de chercher à le laisser.

Bon donc maintenant, l'idée est de trouvé le schéma le plus épuré pour utilisé des max232.
A propos le datasheet mentionne des capas à ajouter. Sniff ! Je vais encore devoir faire une platine qui va me prendre de la place sad

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

10

Re : Mixage de voies et liaisons I²C entre carte Arduino

Ce n'est pas un pb d'avoir le 12V. Je suppose que tes moteurs l'utilisent aussi. Et il vaut mieux amener une tension élevée et la réduire sur place (surtout qu'on trouve maintenant des DC/DC au format des TO220 style 7805). Au moins tu garantis la propreté de l'alim de tes cartes.

Bon donc maintenant, l'idée est de trouvé le schéma le plus épuré pour utilisé des max232.

Il n'y a pas bcp de latitude à ce niveau, aucun des composants additionnels n'étant facultatif.

Je vais encore devoir faire une platine qui va me prendre de la place

Il y a déjà une Arduino si j'ai bien compris. Alors ce n'est pas la place d'un MAX232 et de quelques capas qui vont y changer grand-chose. Surtout qu'on peut toujours opter pour le CMS.

11

Re : Mixage de voies et liaisons I²C entre carte Arduino

Oui, c'est pas faux pour les CMS...

Je voulais dire qu'un ROV aquatique n'a pas autant de possibilités que dans un ROV terrestre. Mais bon, je connais ma faculté d'intégration, je suis bien capable de faire rentré un PC dans une boite d'alumette. Si, si ! En le démontant en pièce et en le passant au mixeur big_smile

Je plaisante, je plaisante mais bon, pour l'heure, une modification de dernière minute me contraint à repousser le montage des deux cartes.

Bon puisque l'affaire est lâcher, que je ne vais pas vous masqué ce que je fais, je vais me permettre de vous donner quelques images du bazar.

Ça c'est le plan
https://lh6.googleusercontent.com/-Ff0n … G_0125.JPG

Les gabarits
https://lh4.googleusercontent.com/-h4ma … G_0126.JPG

Un montage provisoire pour voir si tout va bien
https://lh6.googleusercontent.com/-VWDy … G_0127.JPG

Le collage
https://lh6.googleusercontent.com/-mK_A … G_0128.JPG

L'assemblage quasiment fini. Il me reste des détails mais à cette étape, la trappe démontable est étanche
https://lh6.googleusercontent.com/-DwNC … G_0373.JPG

Mes deux sous-marins à cotés
https://lh5.googleusercontent.com/-4Xf9 … G_0375.JPG

Bon, à noté que le sous-marin qui est derrière est plus gros et qu'il est radio-commandé. Là, c'est plus un petit jaune pour faire découvrir aux publique dans les période d'expositions.

Tout à été réalisé en lexan et si l'aspect est poli, c'est que je voulais une coque sans trop de défaut. Il reste beaucoup à faire, donc je ne m'attarderais pas pour le moment à gratté plus. Avant peinture de toute façon, je serais contraint de gratté beaucoup.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

12

Re : Mixage de voies et liaisons I²C entre carte Arduino

Ce qu'on voit à l'arrière, c'est le pupitre de commande ?

13 Dernière modification par Microbulle (02-04-2012 09:12)

Re : Mixage de voies et liaisons I²C entre carte Arduino

A l'arrière, c'est mon oscilloscope roll

Ma télécommande sans fil et une FF9, quand à celle de mon rov est dans une valise. Je ferais une image dans quelques jours, quand j'aurais fini l'implantation de tous les boutons big_smile

Petit Edit avec un début de schéma coté télécommande:
https://lh4.googleusercontent.com/-8eli … mamnde.png

Bon, j'ai pas représenté les boutons pour me concentré sur le max 232 et tel que devrais être le montage. En théorie roll

Il ne faut pas hésité à me corriger s'il y a des choses qui ne sont pas bonne. J'ai pas l'habitude d'utiliser des max 232...

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

14

Re : Mixage de voies et liaisons I²C entre carte Arduino

Microbulle a écrit:

A l'arrière, c'est mon oscilloscope roll

oops :-(

Il ne faut pasa hésité à me corriger s'il y a des choses qui ne sont pas bonne. J'ai pas l'habitude d'utiliser des max 232...

Ça a l'air correct à première vue

15

Re : Mixage de voies et liaisons I²C entre carte Arduino

Ok, donc demain, je m'attaque au schéma du minimog 02. La partie réceptrice.

Je parlerais d'un autre problème précis.

Bon ben, si déjà la c'est juste j'ai pas trop perdu la main en schéma.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

16

Re : Mixage de voies et liaisons I²C entre carte Arduino

Plop,

Je viens de réussir une liaison TX -> RX et RX <- TX entre deux cartes sur une liaison courte.

Maintenant, je suis en train de bosser sur le protocole. A ce propos, j'ai pas mal d'interrogations. Je pense faire quelque-chose comme ceci:

<fonction:valeur>
<option:valeur>
etc...

J'ai peur qu'avec un tableau de char on ne puisse pas utilisé les < et >. Dans ce cas, je trouverais d'autres drapeaux tel que [ ou ] mais je trouve que c'est moins pratique...

S'il y a des idées la dessus, un protocole existant facile à utilisé dans notre cas présent, je veux bien étudier le cas.

Merci.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

17

Re : Mixage de voies et liaisons I²C entre carte Arduino

Ne jamais transposer au monde du micro-contrôleur ce qu'on fait sur des machines où on se vautre dans les Goctets et les GHertz. Le XML et autres balises bavardes, c'est à oublier, car outre le volume inutile qu'on transporte pour rien, il faut aussi le décoder à l'arrivée.

Comme tu sais exactement quelles sont les informations qui sont échangées, pas besoin de mettre des identificateurs. Il suffit de prendre la structure C qui reflète la trame, et l'envoyer telle quelle octet par octet. A l'arrivée on sait ce qu'on doit recevoir et donc on range les octets au fur et à mesure dans une structure de données identique, et le tour est joué.

Les choses peuvent se compliquer si on a d'un côté un PC et de l'autre un µP, mais ce n'est pas ton cas. Et même si c'est le cas (exemple du radeau), il suffit de connaitre la manière donc chacun représente les données en mémoire pour s'en sortir sans difficulté.

Ne pas se laisser égarer par le terme "protocole". Comme dans la vraie vie, un protocole n'est qu'un accord entre deux parties pour pouvoir se comprendre mutuellement. On n'est pas obligé d'y coller du XML et autres trucs qu'adorent les gaspilleurs d'octets et de cycles CPU smile

18

Re : Mixage de voies et liaisons I²C entre carte Arduino

Wah, tu me rassure un bon peu là wink

Alors, voila ce que j'ai fait en code réception, j'essaie avec la liaison série USB et la console. Si si ça fonctionne big_smile

//Carte Uno sous-marin

char commande[32];


void setup() {

  Serial.begin(9600); //Lancer le mode série
  pinMode(13, OUTPUT);
}

void loop() {

  if(readCommande() != 0) {
    
    Serial.println(commande);
    
    if(strcmp(commande, "<on>")==0) {
      digitalWrite(13, HIGH);
    }
    if(strcmp(commande, "<off>")==0) {
      digitalWrite(13, LOW);
    }
  }
  delay(20);
}

int readCommande() {
  if(!Serial.available()) {
    return 0;
  }
  
  int i=0;
  
  while(Serial.available()) {
    commande[i]=Serial.read();
    i++;
  }
  
  commande[i] = 0;
  return i;
}

Il me semble que je me suis basé sur un code du club, mais je me rappelle plus ou je l'ai glané. J'ai trouve une parade sur mes if, mais il me faudra un parseur je pense.

Si je le XML plus, je pourraît alors faire ceci:
- Moteur1;1.5ms
- Moteur2;2ms

Je prévoie au retour la possibilité de l'acknowledge. Cas atypique de trames qui doivent se suivre et de synchronisés.

Pour le retour,
- Sonde1;10 (ici une température en °C)
- Sonde2;0,5 (ici une profondeur par colonne de pression)
- Secu1,0 (ici 0 si pas de voie d'eau, 1 si une voie d'eau est détecté)...

Comment modifier le code que j'ai au dessus ?

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

19

Re : Mixage de voies et liaisons I²C entre carte Arduino

Plop,

Bon je suis arrivé à faire un quelque-chose. Mais seule une commande sur deux passe. Je pense que je vais avoir besoin d'un coup de main pour arrivé à quelque-chose de plus stable / fiable. Sans quoi pas question de faire navigué le moindre engin.

Je me suis basé sur 2 portions pour faire une commande complète à savoir: Commande;Valeur ce qui me donne :

/*
  Carte Uno intégré au sous-marin MINIMOG 02
  
  Réception depuis une commande filaire type série.
  Emission vers une commande filaire type série.
  
  Le principe commande en deux mots : [cmd];[val]
*/

/* VARIABLES ET DEFINITIONS */
char commande[32];  

/* SETUP */
void setup() {

  Serial.begin(9600); //Lancer le mode série
  pinMode(13, OUTPUT);  //Placer la pin 13 en sortie
}

/* LOOP */
void loop() {
  
  //Si il y a une réception de donnée sur RX
  if(readCommande() != 0) {
    
    //Serial.println(commande);  //Pour le débug
    
    executeCommande();  //Execute la commande
    /*
    //si il a été reçu <on>
    if(strcmp(commande, "<on>")==0) {
      digitalWrite(13, HIGH);  //Mettre la sortie 13 à 1
    }
    //si il a été reçu <off>
    if(strcmp(commande, "<off>")==0) {
      digitalWrite(13, LOW);  //Mettre la sortie 13 à 0
    }
    */
  }
  delay(120);  //Laisser suffisament de temps pour exécuter le programme
}

/* FONCTIONS */

//Fonction qui exécute la commande
void executeCommande() {
  
  char * parse[2];  //Créer un tableau de caractère pour deux valeurs
  int val = 0;          //Valeur forcé à 0
  
  parse[0] = strtok(commande, ";");  //Commande
  parse[1] = strtok(NULL, ";");      //Valeur
  
  //Si c'est ca commande Out13
  if(strcmp(parse[0], "Out13") == 0) {
    //Convertir les mots en 0 ou 1 selon les valeurs données
    (strcmp(parse[1], "HIGH") == 0) ? val = HIGH : val = LOW;
    //Assigner à la sortie correspondante la valeur donné
    digitalWrite(13, val);
  }
  
  //Les autres commandes
}

//Fonction de réception de données série
int readCommande() {
  //Si il n'y a aucune donnée reçu sur RX
  if(!Serial.available()) {
    return 0;  //Retourner 0 - Abandon
  }
  
  //Tant que on a des caractères
  int i=0;
  while(Serial.available()) {
    //Charger dans le tableau de caractère global
    //les caractères reçu.
    commande[i]=Serial.read();
    i++;
  }
  
  //Plus de caractères, on place un 0
  commande[i] = 0;
  
  //Retourner si il y a 0 caractères ou s'il y en a plus d'un
  return i;
}

En espérant trouve dans la partie executeCommande() comment améliorer ça !

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

20

Re : Mixage de voies et liaisons I²C entre carte Arduino

Pourquoi tiens-tu absolument à envoyer des commandes en ASCII ? Une vitesse moteur et son sens peuvent être codés sur 2 octets (1 pour le sens, l'autre pour la vitesse entre 0 et 255), et là tu en prends une bonne 10aine.

La lib Arduino doit permettre de lire des données binaires je suppose. Ei tu envoies par exemple 2 octets pour un moteur, 2 pour l'autre, 2 pour coder l'état de 16 relais, tu a une trame de 6 octets seulement à la base. Côté interprétation, il suffit de lire les octets un par un, de ranger le résultat dans des variables. Une fois que tu as lu la trame, tu utilises ce que tu as stocké dans les variables pour piloter les moteurs, les relais,...

Comparer des chaînes de caractère sur un µP est du ressort des membres de la tribu des gaspilleurs de cycles CPU, mais pas des "real programmers" smile Je ne dis pas qu'on n'y est pas obligé parfois,

21 Dernière modification par Microbulle (05-04-2012 21:49)

Re : Mixage de voies et liaisons I²C entre carte Arduino

Pourquoi l'ascii. Et bien par ce que je dois gérer la vitesse de rotation en fonction des potentiomètres. Comme avec une télécommande classique...

Sinon, je me casserais pas la tête, crois moi.

A tu un autre codage pour ce type de carte, est-ce qu'un autre membre peut se penché sur le cas et faire évoluer mon code ?

Par ce que là, je patauge, j'en ai bien peur roll

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

22

Re : Mixage de voies et liaisons I²C entre carte Arduino

Plop,

Changement de cap !

J'ai décidé à la vue de ton message de faire un protocole et de m'y tenir, ça m'évitera de coder et de flasher des cartes pour rien ! Ce c'est qu'une fois le concept validé que je passerais à un code Arduinien.

Je pense tout codé en octet. 1 octet pour la sélection du servo, un octet pour son sens de rotation et sa vitesse.

Mettons que j'ai 5 servos:
Servo 1 adresse 0x01
Servo 2 adresse 0x02
Servo 3 adresse 0x03
Servo 4 adresse 0x04
Servo 5 adresse 0x05

Et mes lights:
Light 1 adresse 0x06
Light 2 adresse 0x07

Et mon lock pression:
Lock pression adresse 0x08

Ensuite un second octet pour le sens et sa vitesse.
Si on prends le milieu entre 0x00 et 0xFF, on a 255/2 soit 127,5. Je ne vais pas m'amusé avec les virgules, donc on prendra entre 0 et 254 soit 254/2 soit 127 points.

Si je suis sur 127, soit 0x7F, j’enverrais au sevo une impulsion de 1,5ms le servo est au neutre. T'inquiète pas pour les moteurs, les variateurs fonctionnent de la même façon que les servos.
Si je vais à 0, soit 0x00, j'enverrais 1ms, soit -90° de rotation.
Si, au contraire, j'envoie 254, soit 0xFE, j'enverrais 2ms, soit 90° de rotation.

Une solution annexe est de partir avec 1ms de base et de rajouter 0,x ou x est égale à un codage de 0 à 9.
C'est à dire que pour la position centrale, soit 0°, j'aurais 1,[0x05]ms.
Pour aller à gauche, -90°, j'aurais 1,[0x00]ms.
Pour aller à droite, 90°, j'aurais 1,[0x09]ms. Mais pas totalement 2ms.

Peut-on envoyer dans 1 octet un chiffre à virgule ?

Si je reprends mon protocole, je devrais avoir ceci:
0x01;0x7F [attente 10µs] 0x02;0x7F ...

Pour les ordres de retour, je propose de codé de la même façon. Attention toutefois, le capteur de pression remonte une valeur à virgule. Donc même problème qu'avec les 1, quelque-chose.

J'espère que cette fois-ci tout est bon, sinon, je pense éviter de passé par une liaison série et je met le projet en stand by en attendant de trouver mieux ! Ce que je ne peux pas admettre !

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

23

Re : Mixage de voies et liaisons I²C entre carte Arduino

Opla !
J'avance un peu dans la connexion série. C'est loin d'être simple mais pas insurmontable.

Je suis en train d'étudier un protocole similaire au mien. Il est basé sur interruption ce qui est parfait dans mon cas. Tout étant constituer d'octets, j'aurais la trame suivante:
[Start][Lenght][Data 1][Data 2][Data x][End]

Au démarrage, je force chaque sorties avec des valeurs de base leurs correspondant. Ici c'est des PWM allant de 1 à 2ms.
On entre dans la boucle et toute les 18 à 20ms on prends chaque sorties les une derrières les autres et on écrit ce que l'on a dans les variables.

A partir de là, si on reçois quelque-chose sur RX, on passe en mode interruption, et on y reste le temps qu'on a pas reçu toute la trame. Attention, un timer est quand même mis par sécurité afin de ne pas rester sur une erreur d'envoie. Charger la variable avec la donnée reçu. Revenir de l'interruption vers le programme principal.

Je pense codé sur 3 octets mes pulses. En effet, un octet pour choisit la sortie, un octet pour le premier chiffre, et un octet pour se second chiffre. Ainsi: si j'ai 1ms, 0x01 0x01 , 0x00.
Si j'ai 1,5ms, 0x01 0x01 , 0x05.
Et pour 2 ms : 0x01 0x02 , 0x00.

Pour mes lights c'est beaucoup plus simple bien sûr. Grâce au lenght, je peux lui dire je te place tel sortie à 0x01 ou 0x00. En 2 octets...

Et bien maintenant, je vais commencer à travailler une une ébauche en espérant que ce soit faisable sans trop de cafouillage.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink

24

Re : Mixage de voies et liaisons I²C entre carte Arduino

Microbulle a écrit:

Peut-on envoyer dans 1 octet un chiffre à virgule ?

Oui, en travaillant en ce qu'on appelle virgule fixe.

Par exemple, imagine que tu veuilles envoyer une valeur décimale avec 1 décimale. Eh bien, il suffit de multiplier par 10, et d'envoyer l'entier résultant. Le décodage se passe en divisant par 10. Ca marche bien entendu pour n'importe quelle précision, mais toutes les valeurs sont exprimées avec le même nombre de décimales. En fait, c'est comme si on parlait en 10èmes ou en 100èmes, au lieu de l'unité concernée.

Si on veut être au top question performances, il faut éviter les puissances de 10 et leur préférer les puissances de 2. Au lieu de travailler en 10èmes on travaillera en 8èmes ou en 16èmes. Pourquoi ? Parce qu'une multiplication ou une division par une puissance de 2 n'est rien d'autre qu'un décalage de n bits dans un sens ou dans l'autre selon qu'on multiplie ou qu'on divise. Ce genre d'opération est très rapide sur un MCU (1 seul cycle d'horloge sur un AVR par exemple)  alors que l'arithmétique en puissance de 10 est extrêmement lente, car il n'y a pas de FPU sur ce genre de processeur et ces opérations prennent donc un nombre de cycles d'horloge énorme.

J'ai vu que tu as fini par laisser tomber l'encodage ASCII. C'est une sage décision, qui économisera non seulement de la bande passante sur la communication, mais surtout du temps de calcul pour passer des valeurs numériques à la représentation textuelle et vice-versa. Et ce genre de chose sur un µP ça coûte un bras. Donc à éviter comme la peste si on peut.

25

Re : Mixage de voies et liaisons I²C entre carte Arduino

Oui, j'ai mis de coté l'ascii. Par contre j'ai pas avancé d'un poil concernant la programmation. Je suis bloqué sur le protocole à adopté et pire, comment le codé proprement.

Tu me dira, librairie avr->code à la mano et zou. Je te répondrais bêtement oui. Mais !
Là ou je ne gère pas, c'est qu'autant avec un PIC je pouvais me permettre de foncé à la mano car j'en connaissait les moindres recoins, autant sous avr / arduino, je ne suis pas sûr du tout que ça le face.

Est-ce que le soft fourni par Arduino permet de faire cela ?
Est-ce que je peux avor un peu d'aide pour constituer le code directement sous avr ?
Vaut-il pas mieux que je développe une lib afin de faire profiter mes deux cartes, vue que je fais du bi-directionnel ?

Au final, je peux mettre à disposition aux communautés le travail du développement  de la librairie, c'est une façon de faire avancer tout le monde.
Par contre je ne me lance pas seul. Par ce que je pense que si je le fait seul, je vais y passé beaucoup de temps pour finalement pas avoir le temps de développer l'engin qui demande beaucoup de mécanique.

Mon appel est lancé. Si j'ai un peu d'aide, ici par exemple, des personnes compétentes en Arduino et qui puis est en codage sous avr, alors je suis prêt à commencer. Quitte à passer par mail (plus rapide que par forum) ou même dans le forum. Peut importe ! ce qui est important c'est que ce soit bien développé, portable entre cartes et surtout que ça serve à tous. Y compris à Pobot, bien sûr.

Dans ce cas, en restant sur des octets du type 0x00 à 0xFF, il faut adopter un code unique. Moi je veut gérer autant l'information numérique pour piloter 1 à 16 servos (cas d'un hexapode) que de piloter un sous-marin avec une pince, des variateurs, le tout fonctionnant à la facon des servos 1ms à 2ms avec toutes les valeurs nécessaires à leurs positionnement.

Je pense avoir des trames ressemblant à (Start bit / Type / Lenght / Data(s) / CR16 / Stop Bit).
Type :
0x00 -> Entrée tout ou rien sur 1 data (0x00 = 0v / 0x01 = 5v)
0x01 -> Sortie tout ou rien sur 1 data (0x00 = Éteint / 0x01 = Allumer)
0x02 -> PWM sur 2 data (Data1 = temps du front haut et Data2 = total du créneau)
0x03 -> Servo ou Variateur (PWM sur 20ms) 1 Data (si on adopte le coup du décalage pour les chiffres à virgules (Variable entre 1ms et 2ms / possibilité de donné un angle)
0x04 -> Urgence (Ce cas prendra 1 bit et est nécessaire au retour si une avarie ou une grave anomalie est détecter) 0x00 = RAS / 0x01 = Urgence

Lenght:
0x01 = 1 data
0x02 = 2 data
...
0x10 = 10 data

J'ai pas trouvé d'exemple de CR16, je veux bien un coup de main la dessus.

Enfin, dans mon cas, si urgence il y a, on stoppe les moteurs, on force à la vidange du ballast, on place un message sur l'ecran via le mode 0x04 0x01.

Comment doit-on gérer entre chaque data ?
Est-ce que je met tout en brut 0x000x000x01CR160x01 ou bien 0x00,0x00,0x01,CR16,0x01 ou bien 0x00 pause 0x00 pause 0x01 pause CR16 pause 0x01 ?

Voila ou j'en suis pour le moment. Merci pour votre aide aussi qui m'a permis d'avancer un peu.

Bon ben, comme d'ab, à défaut d'avoir la science infuse, j'infuse la science wink