Go Down

Topic: Multiplexage HEX vers 1 entrée Arduino. (Read 402 times) previous topic - next topic

dbe8f

Bonjour,

Je suis nouveau sur le forum et nouveau également dans l'utilisation d'Arduino.
Je connais un peu l'électronique et je connais la programmation.

Ma question est la suivante :

J'aimerais via un dip-switch à 4 positions connaître la valeur des switchs sélectionnés avec une seule entrée Arduino afin d'économiser les entrées, est-ce possible ?

Exemple : si j'ai 0011 -> l'entrée Arduino lit 3, si j'ai 0101 -> l'entrée Arduino lit 5,...ainsi de suite pour les 16 positions possibles.

Si ce n'est pas possible, faut-il absolument 4 entrées ?
Sinon quelle autre solution y'a-t-il pour réaliser cette opération ?

Merci pour vos réponses et meilleures salutations.
dbe8f

_pepe_

Bonjour

Il est possible de connaître la position des quatre switches en utilisant des résistances afin de produire une tension mesurable par une entrée analogique.

al1fch

#2
Feb 08, 2018, 01:42 pm Last Edit: Feb 08, 2018, 01:46 pm by al1fch
Bonjour
grillé par  _pepe_ !
Possible avec une seule entrée analogique
je n'ai pas à l'instant  de lien sous la main
chercher des infos sur les réseaux R2R et les réseaux de résistances pondérées
en associant un réseau R2R et le dipswitch il est possible de produire une tension qu'il suffira d'envoyer sur une entrée analogique
(certains convertisseurs numériques / analogique sont construits autour d'un réseau R2R et d'interrupteurs electroniques)

_pepe_

#3
Feb 08, 2018, 02:02 pm Last Edit: Feb 08, 2018, 04:46 pm by _pepe_ Reason: correction valeur R0
Le réseau R2R présente l'avantage d'obtenir simplement une séquence linéaire de valeurs, mais également l'inconvénient de nécessiter un nombre résistances assez élevé.

Voici un montage qui répond au problème avec seulement 5 résistances à ±1% :



R0 = 17,4 kΩ ±1%
R1 = 10,0 kΩ ±1%
R2 = 4,75 kΩ ±1%
R3 = 2,21 kΩ ±1%
R4 = 1,00 kΩ ±1%


_pepe_

#4
Feb 08, 2018, 02:23 pm Last Edit: Feb 08, 2018, 04:47 pm by _pepe_ Reason: valeurs tableau suite à correction de R0
Voici, en fonction de la position des switches (O=ouvert / F=fermé), la tension nominale obtenue et la borne inférieure de la plage des valeurs de analogRead() correspondante :

 Switches  Tension Borne  
1  2  3  4   (V)    inf.
O  O  O  O  2,540  513
O  O  O  F  2,468  496
O  O  F  O  2,376  478
O  O  F  F  2,294  456
O  F  O  O  2,158  432
O  F  O  F  2,062  409
O  F  F  O  1,937  385
O  F  F  F  1,825  347
F  O  O  O  1,569  307
F  O  O  F  1,429  273
F  O  F  O  1,242  237
F  O  F  F  1,072  189
F  F  O  O  0,779  137
F  F  O  F  0,563   85
F  F  F  O  0,272   27
F  F  F  F  0,000    0



Le bout de code suivant devrait permettre de récupérer la position de chaque switch :

Code: [Select]
const unsigned char pinSwitches = A0;

const unsigned int seuils[] = {
  513, 496, 478, 456, 432, 409, 385, 347,
  307, 273, 237, 189, 137, 85, 27
};

unsigned char getSwitches()
{
  unsigned int tension = analogRead(pinSwitches);
  unsigned char switches = 7;
  if (tension >= seuils[switches])
    switches -= 4;
  else
    switches += 4;
  if (tension >= seuils[switches])
    switches -= 2;
  else
    switches += 2;
  if (tension >= seuils[switches])
    switches --;
  else
    switches ++;
  if (tension < seuils[switches])
    switches ++;
  return switches;
}

#define SWITCH_1(sw) ((sw) & 8)
#define SWITCH_2(sw) ((sw) & 4)
#define SWITCH_3(sw) ((sw) & 2)
#define SWITCH_4(sw) ((sw) & 1)

(non testé)

Exemple d'utilisation :

Code: [Select]
unsigned char sw = getSwitches();

Serial.print("SW1 est ");
if (SWITCH_1(sw))
  Serial.println("ON");
else
  Serial.println("OFF");

Serial.print("SW2 est ");
if (SWITCH_2(sw))
  Serial.println("ON");
else
  Serial.println("OFF");

Serial.print("SW3 est ");
if (SWITCH_3(sw))
  Serial.println("ON");
else
  Serial.println("OFF");

Serial.print("SW4 est ");
if (SWITCH_4(sw))
  Serial.println("ON");
else
  Serial.println("OFF");

dbe8f

Bonjour,

Merci à vous deux _pepe_ et afch pour vos réponses rapides et claires.

Si je résume, il n'est pas possible avec un dip-switch de passer, par exemple, par un IC avec 4 entrées et 1 sortie (genre multiplexeur 4 à 1 cmos 4050 ou autre) et d'aller directement vers une entrée numérique, il faut passer par une entrée analogique !

Il faut passer par une conversion N/A avec les résistances (au passage merci pour les 16 positions déjà calculées  :smiley-cool: ).

Dans le programme, on récupère la valeur de la tension et en fonction de celle-ci on sait qu'elle est la position des switchs.

Si c'est ça merci encore et je pense que j'ai ma réponse.

Encore une question : existe-t-il un convertisseur N/N qui donnerait justement une valeur qui pourrait être envoyée à l'Arduino (pas sûr que ma question soit très logique ou juste, enfin  :-[ ) ?

Toute bonne fin de journée et meilleures salutations.
dbe8f.

dbe8f

Super merci beaucoup, je n'avais pas vu le bout de code.

Autre question, je pense la dernière : avec les résistances c'est bien mais si on a un dip-switch à 10 entrées, cela devient difficile de mesurer précisément non ?

Dans ce cas, y'a-t-il une autre solution ?

Merci encore pour vos réponses.
dbe8f.

_pepe_

#7
Feb 08, 2018, 03:27 pm Last Edit: Feb 08, 2018, 03:53 pm by _pepe_
Il est possible de passer par un circuit qui transmette la position des quatre switches en série à une entrée numérique du micro-contrôleur.

Mais en l'absence d'une sortie délivrant un signal de synchronisation, cette entrée devra obligatoirement être une entrée série asynchrone, autrement dit l'entrée RX de l'Arduino ou bien une autre entrée émulant cette fonction.


Le circuit impliqué devra faire une conversion parallèle/série asynchrone.

Malheureusement, il n'existe pas de circuit logique réalisant cette fonction dans les séries standards (on en trouve qui, seuls, font seulement une conversion parallèle/série synchrone, c'est-à-dire cadencée par un signal d'horloge externe).

Classiquement, aujourd'hui on remplit cette fonction à l'aide d'un petit micro-contrôleur bas de gamme.


Artouste

bonjour
en complément des réponses déjà données

c'est le principe utilisé sur certains "lcd keyshield"

voir ici


_pepe_

#9
Feb 08, 2018, 03:49 pm Last Edit: Feb 08, 2018, 03:54 pm by _pepe_
avec les résistances c'est bien mais si on a un dip-switch à 10 entrées, cela devient difficile de mesurer précisément non ?
En effet, la solution que j'ai indiquée peut fonctionner parce qu'il n'y a que quatre switches et que les résistances ont une bonne précision (±1%), mais elle a des limites. La somme des erreurs commises lors de la mesure (du fait de la tolérance sur les résistances, de la précision du convertisseur et des perturbations électriques) doit rester assez faible pour ne pas aboutir à une incertitude sur la position des switches.

Dans ce cas, y'a-t-il une autre solution ?
Dans une solution de mesure analogique directe, la précision du convertisseur analogique-numérique du micro-contrôleur nous limite au mieux à 8 switches, et s'il est possible de dépasser cette limitation en réalisant une conversion par mesure du temps de charge/décharge d'un condensateur au travers des résistances, on ne peut quoi qu'il en soit pas s'affranchir du manque de précision des résistances.

La solution avec une transmission série asynchrone reste de loin la plus évidente et la plus sûre pour recevoir la position d'un nombre important de switches via une entrée unique.

schrist

Bonjour,
on peut aussi utiliser un port entré/sortie sur i2c (PCF8574)

Bonne continuation

_pepe_

on peut aussi utiliser un port entré/sortie sur i2c (PCF8574)
I2C, c'est nécessairement deux entrées-sorties (une pour les données, une autre pour leur synchronisation). Ici le sujet porte sur les solutions pour mettre plusieurs switches sur une seule entrée.

Artouste

I2C, c'est nécessairement deux entrées-sorties (une pour les données, une autre pour leur synchronisation). Ici le sujet porte sur les solutions pour mettre plusieurs switches sur une seule entrée.
un (ou des) DS2408

_pepe_

#13
Feb 08, 2018, 07:58 pm Last Edit: Feb 08, 2018, 08:00 pm by _pepe_
un (ou des) DS2408
Oui, en effet, le bus 1-Wire est une solution envisageable.

Il est plus compliqué à mettre en œuvre que l'interface série asynchrone classique (USART), mais on peut trouver des circuits spécialisés (comme celui que tu cites) et des bibliothèques  logicielles toutes faites pour les utiliser (voir par ici). Il présente également l'avantage d'être extensible, en branchant plusieurs périphériques en parallèle sur le même fil.

dbe8f

Bonjour à tous et un grand merci pour toutes vos réponses forts intéressantes et le temps que vous y avez passé.

Je suis entrain de regarder comment je pourrais utiliser le DS2408. Toutefois, j'ai lu qu'il n'est plus vraiment fabriqué ! Est-ce vrai ?

Dans l'affirmative, y'a-t-il un autre composant le remplaçant ?

Je suis également entrain de penser à une autre solution. Ce serait de mettre un bouton pousoir qui me compte le nombre d'impulsion et cela me donnerais la valeur. En fait dans mon montage, je n'ai besoin de connaître qu'une fois la valeur, elle doit être programmable et ensuite je la stocke dans l'EEPROM.

Si une fois je dois reprogrammer la valeur, je reset la valeur et j'appuie à nouveau n fois sur le bouton poussoir et ainsi de suite ! Ainsi je n'ai qu'une entrée et qu'un seul bouton + 1 pour la "Validation" et "Reset".

L'idée de tout ça, c'est que mon programme puisse être utilisé pour plusieurs composants différents. En fonction de la valeur programmée, j'exécute les parties de code correspodantes.

Cela vous semble-t-il cohérent ?

Merci pour vos réponses et bon dimanche.
Meilleures salutations.
dbe8f

Go Up