PILOTAGE DES 8 SORTIES DU PORT //

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 14 oct. 2009 à 14:19
saigneurdushi Messages postés 45 Date d'inscription samedi 3 mai 2003 Statut Membre Dernière intervention 25 janvier 2011 - 4 janv. 2011 à 05:50
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/50692-pilotage-des-8-sorties-du-port

saigneurdushi Messages postés 45 Date d'inscription samedi 3 mai 2003 Statut Membre Dernière intervention 25 janvier 2011
4 janv. 2011 à 05:50
Si c'est une question de longueur de code, essayer python !! :-)
flamt Messages postés 19 Date d'inscription mardi 11 mars 2003 Statut Membre Dernière intervention 21 mai 2010
12 mai 2010 à 20:45
j'arrive après la bataille, mais je te soutiens!
ton code si "mauvais" soit il, m'à bien aidé.

A l'autre zigoto, je ferais remarqué que ça fait peut être 20 ans que l'usb à remplacé toutes les autres Connectique mais que pour tester, piloter et interfacer des micro-contrôleurs on est bien heureux de toujours avoir la solution économique en temps et en sous du port série.

pour améliorer ton code:
si tu as l'octé : "1000 1100" << "0001 1000" <= deviens ça
"1000 1100" >> "0100 0110"

bref l'opérateur décale d'un rang les bits à gauche ou à droite (ce qui reviens à multiplier ou diviser par 2 la valeur de ton octé en décimal...)
il y à aussi l'utilisation de masques qui peut être utile avec les opérateurs & et ||, si tu veux aller plus loin.

anecdote: l'opérateur << consomme très peu de temps machine.
Plutôt que de diviser par 2 utilise la pour des super programmes super puissant et tout et tout... ^^.
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
3 nov. 2009 à 09:03
Désolé de te contredire Shorzy, mais j'ai bel et bien été courtois et constructif en essayant d'orienter le contributeur et signaler quelques bévues de son code. Cela n'avait strictement rien de personnel, même si j'ai dit que ce code n'apprenait rien et ne remplissait pas les objectifs voulus pour être utilisable par d'autres (hormi un seul appel de fonction, c'est à dire une seule ligne, la plus intéressante pourtant qu'il a omis de commenter, celle concernant l'appel de ioperm() avec des valeurs "magiques").
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
2 nov. 2009 à 11:17
j ai utiliser ce principe de cablage , avec des leds de 3v et une resistance par led dont je ne me souviens pas la valeur , et mon montage d essais un indemontable car scelle par de la colle a chaud pour tout isoler



/ \
\ 13 12 11 10 9 8 7 6 5 4 3 2 1 /
\ /
\ 25 24 23 22 21 20 19 18 17 16 15 14 /
\______________________________________________________/



borne 2 +led 1 borne 18 masse led 1
borne 3 +led 2 borne 18 masse led 2
borne 4 +led 3 borne 19 masse led 3
borne 5 +led 4 borne 19 masse led 4
borne 6 +led 5 borne 20 masse led 5
borne 7 +led 6 borne 20 masse led 6
borne 8 +led 7 borne 21 masse led 7
borne 9 +led 8 borne 21 masse led 8

Voila le montage de base ; apres pour l utilisation de relais je compte passer par des micro relais qui commanderont un autre jeux de relais via une alimentation normale 12v

bonne journee
shorzy Messages postés 94 Date d'inscription jeudi 23 novembre 2000 Statut Membre Dernière intervention 1 juin 2013
2 nov. 2009 à 07:51
T'es Relou VERDY_P !!!

CEDPIC voulais faire partager un programme qui l'a bien aidé.
Je lui dis bravo, et merci !!!

Je voulais justement savoir comment faire ce genre de choses avec un PC. (pour piloter, par Ex. une maquette de Train, éclairage, aiguillage...)

Je ne te félicite pas VERDY_P pour ta courtoisie ni pour ton manque de jugement.
(n'importe qui, verrait qu'ici, les port USB ne sont pas applicables !!!)

PS:
Tu as un schéma de raccordement Elec CEDPIC ???
kinkek Messages postés 7 Date d'inscription jeudi 17 juillet 2008 Statut Membre Dernière intervention 13 janvier 2012
29 oct. 2009 à 21:50
j 'ai eu peur quand je ai vus ces quelques lignes,
heureusement c'est un petit programme destiné à fonctionner sur linux
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
21 oct. 2009 à 06:46
Je ne nie pas l'intérêt pour toi de faire ça, c'est juste que je me demande quel est l"intérêt pour les autres, puisque le code n'apprend rien; la seule chose intéressante est en fait uniquement l'utilisation de la fonction ioperm() pour demander à ouvrir un port I/O, car cette fonction est mal connue;

Mais le reste ne contitue pas une bonne utilisation du codage binaire, de la façon de nommer des variables, ou de structurer un programme; car tu te rends bien compte que le code est inutilement verbeux (et d'autres plus ont l'ont dit).

Que ce soit un port parallèle ou autre chose, n'a aucune importance, ni même que tu utilises ce code pour piloter un dispositif externe; allez, un peu de recherche et tu trouveras comment énumérer les ports de Windows disponibles, comment trouver leurs adresses (je n'ai pas demandé ici de faire une interface complète avec des boutons, tu te trompes, ce n'est d'ailleurs pas le sujet de ton code); mais on pouvait se passer ici des scanf() pour lire des variables, de la façon bizarre de présenter le code (tu mets les commentaires au mauvais endroit, tu sautes des lignes entre la déclaration d'une fonction et l'accolade ouvrante, tu mets trop de lignes pour juste déclarer des varaibles similaires, de même type et de même rôle. Dans le cadre d'un vrai programme, avec ce style là, tu aurais des pages et des pages de code pour faire trop peu de chose, et tu ne te mets pas à l'abri de nombreuses fautes de frappe.

En attendant je t'invite à étudier l'opérateur binaire "<<" pour transformer un numéro de bit en puissance de 2 (toutes les variables d0 à d7 sont inutiles).

Et puis tant qu'à faire passe à autre chose que le port parallèle (ou même le port série) car ces ports physiques sont en voie de disparition totale (une évolution qui s'est faite maintenant depuis de nombreuses années) : même pour ce type de montage, tout le monde est passé au port USB, qui offre bien plus de possibilités, est plus fiable, plus pratique, et bien plus rapide (par exemple les programmateurs d'EEPROM qui utilisaient le port série ne se vendent plus, ils sont tous passés au port USB, et n'ont jamais été vendus sur le port parallèle à cause du gros manque de fiabilité, hormi avec un cable de moins de 2 mètres, et de sa lenteur extrème, très inférieure même aux ports série, à cause justement du problème du câble et de la désynchronisation des bits à courte distance, même avec un câble de bonne qualité mais très cher, alors que le port USB, ou même Firewire/IEEE1394 les transporte en série sur des distances bien plus élevées avec un protocole au point et un câble bien meilleur marché)

Courage.
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
19 oct. 2009 à 17:30
Merci pour cet encouragement , je comprend mieux pourquoi des personnes ne connaissant rien a la programation ne progresse pas , car quand on met en ligne son premier code en attend plustot des conseil que des reproches ce code a ete fait dans un but de piloter 8 relais via un pc sous linux ce qui fonctionne tres bien , a l heure actuelle j ai fait expres d'occulter les autre ports car comme tu dis on peu aussi s'en servir et serviront en entree et non en sortie , merci de ce commentaire non instructif je soushaite une chose c'est de te recroiser sur un forum ou tu ne maitrise pas quelque chose je me ferais un plaisir de te descendre , mon truc c'la videosurveillance , l'alarme baser sur de l 'automate des mtu et autre je t'encourage a ne pas poster sur mes commentaire et reste dans ton petit monde ou on ne doit qu'etre le meilleur , rappel toi a t' debut et repense a ton premier jet , un commentaire comme celui la pourrait etre decourageant pour un ado qui ce chercherait , de plus tui a l air si fort j attend de voir ta proposition tourner sur mon pc sous une distribution linux , avec une rampe la prise DB25 deja cable , de pmlus l utilisation de la Db25 a ete volontaire car le bute etais de piloter un jeux de micro relais /led a faible cout , j attend ton code et puisque tu a l air ci bon propose moi une version avec 8 boutons graphique afin de ne plus rentrer la valeur des bouton en mode console , le sforum et ce genre de site son la pour s'entraider etv non pour ce faire descendre , a bonne entendeur salut et j espere que tu aura l'honneteter de proposer un code qui fontionne pour me montre ce que j aurai du faire sans connaissance que je suis merci
verdy_p Messages postés 202 Date d'inscription vendredi 27 janvier 2006 Statut Membre Dernière intervention 29 janvier 2019
19 oct. 2009 à 14:40
1) Le port parallèle (prises au format DB25) est une espèce en voie de disparition, beaucoup de PC n'en ont plus du tout depuis longtemps (c'est le cas de la quasi-totalité des PC portables depuis des années), de la même façon qu'ont disparu aussi les ports série DB9 : ces ports ont remplacé par les ports USB, nettement plus rapides et avec des câbles plus pratiques (ou par l'éventuel port FireWire/IEEE1394).

2) Le port parallèle a plus que 8 bits (il y a aussi les bits dits de contrôle), et ces bits ne sont pas nécessairement en sortie mais peuvent être programmés (chacun séparément) en entrée (dans ce cas ce qu'on sort est tout bonnement ignoré) : ton code n'en tient pas compte et suppose que le port est actuellement en mode sortie. Il ne suffit pas de faire un "outp" vers un port pour que ça marche, surtout sur Windows où les ports sont virtualisés.

3) L'adresse du port parallèle n'est pas nécessairement 0x378, on trouve aussi 0x3FB ou d'autres. connaitre l'adresse était facile au temps de MSDOS (il y a 20 ans) avec une fonction BIOS, mais aujourd'hui ce n'est plus si simple, car il faut aller chercher l'info dans les paramètres du pilote (l'info du BIOS peut être fausse ou inexistante). De plus à cause de la virtualisation, la seule façon propre pour être sûr d'adresser le port est d'utiliser l'API Windows de partage.

4) Le port peut être restreint pour des raisons de sécurité

5) Tout accès à un port sans droit d'administrateur, et pour un port inexistant provoquera une exception de sécurité de Windows (même chose sous Linux d'ailleurs...)

Bref ton code devrait plutôt commencer par recherche la liste des pilotes déclarés dans le système pour les ports, permettre de sélectionner le port, ensuite l'ouvrir avec les API concernées afin de le réserver à ton utilisation, ensuite émettre les données.

Mais personne n'utilisera un programme qui demande d'entrer 8 numéros sur une interfaces de commande juste pour émettre un bit ! Ton programme ne sert à rien, et n'apprends rien, il révèle même de mauvaises pratiques (programmation d'il y a plus de 20 ans) en plus du fait qu'il est très mal écrit et inutilement long pour faire finalement une seule chose, c'est-à-dire une seule instruction de l'assembleur x86 : "OUTP 0x378,octet" (qui justement aujourd'hui n'est plus correcte). Il ne sert même pas de démonstration sur le calcul binaire, ni de démonstration de la façon de coder un programme.

Si vraiment tu veux faire de l'assembleur, ce sera pour programmer des pilotes de périphériques ou un code noyau, mais ce code est très loin de cet objectif.

Peut-être faut-il retourner programmer sur le Commodore 64 que tu auras retrouvé dans la cave, car c'est à peu près le niveau de ce programme et bien le seul endroit où ce genre de programme sera encore utile.
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
14 oct. 2009 à 18:18
merci
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2009 à 18:11
> ... par la suite j étendrais à 16 sorties avec une carte port // en pci

Il te suffit d'ajouter un:
#define NB_OUT 8 // ou 16

Puis de remplacer:
for (i = 0; i < 8; ++i)
par
for (i = 0; i < NB_OUT; ++i)
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
14 oct. 2009 à 18:01
Tu ma bien aider a optimiser ce code , je voulais juste te dire a quoi sa va me servir , c'est un projet personnel , je m en sert a l heure actuelle pour faire allumer et eteindre 8 led , mais aux final c pour gerer de eclairages et autre sur une maquette ,sa faisait 3 semaine que ce code etait fini pour moi et j avais decider de le mettre en ligne car ce site ma beaucoup aider , maintenant je cherche a passer du mode console en mode graphique , par la suite j eteindrais a 16 sortie avec un carte port // en pci , merci de ton aide
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
14 oct. 2009 à 17:52
niquel j ai poster trop to tout a l heure ce dernier code que je n avias pas vu marche nickel sur le pupitre de controle que j ai fabriquer , merci de ton aide
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
14 oct. 2009 à 17:49
J ai modifier le code je vais continuer a chercher car o niveau des sortie j ai des erreur les boutons ne corespondent plus en sortie ,les valeur binaire envoyer au port ne correpond plus a l attente ,
merci quand meme sa ma fait decouvrir des chose que je n avais pas encore vu
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2009 à 17:44
Bon allez cette fois j'ai testé.
Inutile de faire un tableau, une seule boucle for suffit dans le do..while.
La fonction puissance a été optimisé, puisque ce sont uniquement des puissances de 2, on peut faire des décalages de bit.

#include <stdio.h>
#include
#include <sys/io.h>
#define ADRESSEBASE 0x378

int puissance2(int nb)
{
if (nb <= 0)
return 1;

return 2 << (nb - 1);
}

int main(void)
{
int bin = 0;
int input = 0;
int i = 0;

if (ioperm(ADRESSEBASE, 2, 1))
{
perror("Erreur d'obtention des droits");
return (1);
}

printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
do
{
printf(" Bouton ON=1 Bouton OFF=0\n");
bin = 0;
for (i = 0; i < 8; ++i)
{
printf("Quel valeur affecte a b%d: ", i + 1);
scanf("%d", &input); bin +input 1 ? puissance2(i) : 0;
}
printf("Arret : ");
scanf("%d", &input);

outb(bin, ADRESSEBASE);

printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
}
while (input != 1);

if (ioperm(ADRESSEBASE, 2, 0))
{
perror("Erreur de fermeture");
return(1);
}

return (1);
}
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2009 à 17:25
Je l'ai fait à la va-vite, sans tester. Il reste encore des chose à améliorer, comme faire une seule et unique boucle, et un seul printf+scanf en début de while.
cedpic Messages postés 8 Date d'inscription samedi 8 août 2009 Statut Membre Dernière intervention 2 novembre 2009
14 oct. 2009 à 17:23
merci des remarques qui sont constructive je vais modifier mon code , c'est mon premier ;
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2009 à 14:21
(Grrr, à quand la fonction "éditer").

Remplacer:
for (i = 0; i < 9; ++i)
bin += d[i];
par:
bin = 0;
for (i = 0; i < 8; ++i)
bin += d[i];
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2009 à 14:20
Remplacer:
for (i = 0; i < 9; ++i)
bin += d[i];
par:
for (i = 0; i < 8; ++i)
bin += d[i];
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2009 à 14:19
Inutilement verbeux. Pourquoi ne pas utiliser des variables plutôt que des tonnes de variables ?
Ca pourrait donner un truc de ce genre (attention non testé):

#include <stdio.h>
#include
#include <sys/io.h>
#define ADRESSEBASE 0x378

int puissance(int a, int b)
{
if (b <= 1)
return 1;

return a * puissance(a, b - 1);
}

int main(void)
{
/* initialisation de la valeur du port db25 */
int bin = 0;
int b[9] = {0};
int d[9] = {0};
int i = 0;

if (ioperm(ADRESSEBASE, 2, 1))
{
perror("Erreur d'obtention des droits");
return (1);
}

printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
do
{
printf(" Bouton ON=1 Bouton OFF=0\n");
printf("Quel valeur affecte a b1:");scanf("%d", &b[0]);
printf("Quel valeur affecte a b2:");scanf("%d", &b[1]);
printf("Quel valeur affecte a b3:");scanf("%d", &b[3]);
printf("Quel valeur affecte a b4:");scanf("%d", &b[4]);
printf("Quel valeur affecte a b5:");scanf("%d", &b[5]);
printf("Quel valeur affecte a b6:");scanf("%d", &b[6]);
printf("Quel valeur affecte a b7:");scanf("%d", &b[7]);
printf("Quel valeur affecte a b8:");scanf("%d", &b[8]);
printf("Arret :");scanf("%d", &b[8]);
/* attribution des valeurs datas selon le bouton et sa position */
for (i = 0; i < 9; ++i)
d[i] = b[i] == 1 ? puissance(2, i) : 0;

for (i = 0; i < 9; ++i)
bin += d[i];

outb(bin, ADRESSEBASE);

printf("Valeur en entree: %d\n", inb(ADRESSEBASE));
}
while (b[8] != 1);

if(ioperm(ADRESSEBASE, 2, 0))
{
perror("Erreur de fermeture");
return(1);
}

return (1);
}
Rejoignez-nous