AN 1006 : Obtenir des mesures des conditionneurs de signaux TFC

Description

This Application Note explains how to obtain tilt measurements from an electrolytic tilt sensor and signal conditioner. It covers schematics and code for each protocol available on signal conditioners from The Fredericks Company. All examples will show code and circuits with an Arduino Uno, so there will be differences in code when using other platforms. Each example will provide a raw output from the sensor in a variety of units. Any of these units can be converted to degrees using the methods explained in Application Note 1005.

Analogue

Both the 1-6200-007 et 1-6200-012 signal conditioners have analog outputs. On the 1-6200-007, both axes and the temperature are output from pins XA, YA, and T respectively. Connecting to the Arduino requires direct connections from the signal conditioner to the analog input pins of the Arduino. Wiring Schematic for the 1-6200-007 and 1-6200-012 analog signal conditioners with an Arduino Uno

Figure 1 Schéma de connexion de 1-6200-007 à Arduino en utilisant des

Notez que le conditionneur de signal 1-6200-012 n'a pas de sortie analogique de température, donc la température doit être lue en utilisant le RS-232. Voir la section sur le RS-232 pour plus d'informations sur la lecture de la température à partir du 1-6200-012.

Une fois le circuit assemblé, les données peuvent être lues à l'aide de la fonction analogRead() d'Arduino. Un exemple de cette fonction est présenté ci-dessous :

x = analogRead(A0) ;
y = analogRead(A1) ;
température = analogRead(A2) ;

Le résultat de ce code sera une valeur brute qui représente la tension sur les broches analogiques. La résolution de cette mesure dépendra du matériel utilisé pour lire la tension ; sur un Arduino Uno, les broches analogiques ont une résolution de 10 bits.

PWM

PWM measurements are available on the 1-6200-007 signal conditioner. With PWM, the x and y tilt angles can be read from the digital XP and YP pins on the signal conditioner. There is no temperature PWM output, so that will have to be read from the analog pin. A schematic for this setup is shown in figure 2. Wiring Schematic for the 1-6200-007 PWM signal conditioners with an Arduino Uno

Figure 2 Schéma pour la connexion de 1-6200-007 à Arduino en utilisant PWM

Notez que les sorties PWM peuvent être connectées à n'importe quelle broche numérique de l'Arduino, et pas seulement aux broches PWM. Dans cet exemple, les broches D7 et D8 sont utilisées, toutes deux non-PWM.

La meilleure façon de lire un signal PWM avec un Arduino est d'utiliser la fonction pulseIn(). La fonction pulseIn() indique la durée d'une impulsion, qu'elle soit à l'état haut ou bas. Dans ce cas, nous allons chronométrer l'état haut.

x = pulseIn(XPIN, HIGH) ;
y = pulseIn(YPIN, HIGH) ;
température = analogRead(A0) ;

char res [50] ;
sprintf(res, "X : %i, Y : %i, Température : %i", x, y, température) ;
Serial.println(res)

Le résultat sera la durée de l'impulsion en microsecondes. La fonction pulseIn() peut lire des impulsions aussi courtes que 10 µs, ce qui signifie que sa mesure de l'impulsion jusqu'à 8 ms aura une précision similaire à une sortie de 10 bits. Cette précision sera plus élevée si l'appareil qui la lit peut détecter des impulsions plus petites.

SPI

SPI est un protocole de communication série synchrone disponible sur le conditionneur de signal 1-6200-005. Le protocole fonctionne sur une technique maître/esclave utilisant 4 connexions : MISO (Master In Slave Out), MOSI (Master Out Slave In), CLK (Serial Clock), et SS (Slave Select). Le maître enverra des commandes à l'esclave via MOSI (marqué IN sur le 1-6200-005), et l'esclave répondra via MISO (marqué OUT sur le 1-6200-005). Le CLK est une horloge créée par le maître qui synchronise la communication de l'esclave. SS est utilisé pour activer un esclave ; cette broche est la façon dont SPI supporte plusieurs appareils sur un bus (voir la section "Bus SPI" pour plus d'informations).

L'Arduino Uno a des broches prédéfinies pour les MOSI, MISO et CL. Elles sont indiquées dans le tableau suivant :

MOSI D11
MISO D12
CLK D13

Le schéma de connexion à l'Arduino est présenté à la figure 3. Wiring Schematic for the 1-6200-005 SPI signal conditioners with an Arduino Uno

Figure 3 Schéma de connexion de 1-6200-005 à Arduino avec SPI

Pour communiquer avec le capteur, nous utiliserons la bibliothèque SPI d'Arduino. SPI.begin() initialisera la bibliothèque SPI (cependant, il n'ouvrira pas de communication). Comme ce circuit ne possède qu'un seul dispositif SPI, la broche 10 (SS) sera mise sur LOW, ce qui permettra à l'esclave contrôlé par cette broche de fonctionner. Elle restera sur LOW pendant tout le programme ; il n'y a aucune raison de désactiver l'esclave dans ce circuit.

void setup() {
    SPI.begin(); // initialize SPI
    digitalWrite(10, LOW); // enable slave 1
}

Maintenant que nous avons initialisé la bibliothèque, nous devons ouvrir la connexion avec le conditionneur de signal. Cela se fait à l'aide de la fonction SPI.beginTransaction(). Cette fonction prend un argument, un objet SPISettings. Cet objet fournira toutes les informations nécessaires pour créer la connexion. L'objet SPISettings a trois arguments :

  1. Vitesse d'horloge maximale de l'esclave, qui est de 20Mhz sur le 1-6200-005.
  2. Le deuxième argument détermine si l'interface SPI utilisera le bit le plus significatif ou le bit le moins significatif en premier. Pour le 1-6200-005, il s'agit du bit le plus significatif en premier (ou MSBFIRST).
  3. Le troisième argument détermine le mode SPI ; pour le 1-6200-005, le mode SPI 2 (CPOL=1, CPHA=0) est utilisé.
// communication ouverte du SPI
SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE2)) ;

La fonction SPI.transfer() est utilisée pour envoyer et recevoir des données. Elle enverra simultanément la commande et retournera tout ce qu'elle lira à partir de la broche MISO. Notez que l'esclave prendra toujours un cycle d'horloge pour répondre ; par conséquent, le résultat de chaque commande ne sera pas reçu avant le cycle suivant. Par exemple, dans le code ci-dessous, la fonction qui envoie la demande de l'octet inférieur de l'axe X renvoie la valeur de l'octet supérieur de l'axe X en raison de ce délai.

Notez que la commande 0x39 est essentielle pour obtenir de bonnes mesures. Cette commande indique au tableau d'obtenir une nouvelle mesure d'inclinaison. Dans le code ci-dessous, elle est envoyée une fois au début, et une autre fois à la fin de l'instruction if, où le bit de basse température est reçu.

    SPI.transfer(0x39); // update sensor data
    delay(1); // wait for SPI response
    res = SPI.transfer(0x31); // get status, request high x byte
    delay(1); // wait for SPI response

    if (res == 0x2A) { // verify sensor data updated successfully
        high = SPI.transfer(0x32); // get high x byte, request low x byte
        delay(1); // wait for SPI response
        low = SPI.transfer(0x33); // get low x byte, request high y byte
        x = (high << 8) | low; // merge low and high bytes into int

        delay(1); // wait for SPI response
        high = SPI.transfer(0x34); // get high y byte, request low y byte
        delay(1); // wait for SPI response
        low = SPI.transfer(0x35); // get low y byte, request high temperature byte
        y = (high << 8) | low; // merge low and high bytes into int

        delay(1); // wait for SPI response
        high = SPI.transfer(0x36); // get high temp byte, request low temp byte
        delay(1); // wait for SPI response
        low = SPI.transfer(0x39); // get low temperature byte, update sensor data
        temperature = (high << 8) | low; // merge low and high bytes into int
    }

    SPI.endTransaction(); // close the SPI communication

Note that the responses will be in separate high and low bytes. The code above converts these to 16-bit integers using the expression (high << 8) | low.

Bus SPI

It is also possible to connect 1-6200-005 signal conditioners together in an SPI bus. An SPI Bus allows all SPI devices to share the CLK, MISO, and MOSI connections. Each slave, however, gets its own SS connection, allowing the master to select which slave it wants to communicate with. The number of SPI devices you can use at once is limited by the number of independent SS connections you can make. Figure 4 shows the schematic for 2 sensors on an SPI bus with pins D9 and D10 used as the SS signals. Wiring Schematic for the 1-6200-005 SPI Bus signal conditioners with an Arduino Uno

Figure 4 Schéma de connexion de deux 1-6200-005 à Arduino avec un bus SPI. Notez les connexions /SS séparées pour chaque appareil

Ce code est très similaire à celui du dispositif SPI unique ; notez que les broches SS sont modifiées pour contrôler avec quel esclave on communique.

// open SPI communication

    SPI.beginTransaction(SPISettings(20000000, MSBFIRST, SPI_MODE2));
    digitalWrite(10, LOW); // enable the slave controlled by D10

    SPI.transfer(0x39); // request status
    delay(1);
    res = SPI.transfer(0x31); // get status, request high x byte
    delay(1);

    if (res == 0x2A) {
        hi = SPI.transfer(0x32); // get high x byte, request low x byte
        delay(1);
        lo = SPI.transfer(0x33); // get low x byte, request high y byte
        x = (hi << 8) | lo;

        delay(1);
        hi = SPI.transfer(0x34); // get high y byte, request low y byte
        delay(1);
        lo = SPI.transfer(0x35); // get low y byte, request high temperature byte
        y = (hi << 8) | lo;

        delay(1);
        hi = SPI.transfer(0x36); // get high temperature byte, request low temperature byte
        delay(1);
        lo = SPI.transfer(0x39); // get low temperature byte
        temperature = (hi << 8) | lo;
    }

    digitalWrite(10, HIGH); // disable the slave controlled by D10
    digitalWrite(9, LOW); // enable the slave controlled by D9

    SPI.transfer(0x39); // request status
    delay(1);
    res = SPI.transfer(0x31); // get status, request high x byte
    delay(1);

    if (res == 0x2A) {
        hi = SPI.transfer(0x32); // get high x byte, request low x byte
        delay(1);
        lo = SPI.transfer(0x33); // get low x byte, request high y byte
        x = (hi << 8) | lo;

        delay(1);
        hi = SPI.transfer(0x34); // get high y byte, request low y byte
        delay(1);
        lo = SPI.transfer(0x35); // get low y byte, request high temperature byte
        y = (hi << 8) | lo;

        delay(1);
        hi = SPI.transfer(0x36); // get high temperature byte, request low temperature byte
        delay(1);
        lo = SPI.transfer(0x39); // get low temperature byte
        temperature = (hi << 8) | lo;
    }

    digitalWrite(9, HIGH); // disable the slave controlled by D9
    SPI.endTransaction(); // close the SPI communication

Notez que si 2 esclaves SPI sont activés en même temps et qu'un message est envoyé, les signaux interféreront et la réponse ne sera pas correctement lue.

RS-232

RS-232 (TIA-232) est un protocole de communication série commun. Une version 3 fils de RS-232 est disponible sur les conditionneurs de signaux 1-6200-006 et 1-6200-012. La connexion RS-232 consiste à relier les masses entre elles et à relier chaque Rx au Tx de l'autre appareil.

Dans cette application, nous utiliserons la bibliothèque SoftwareSerial d'Arduino pour créer un port série virtuel à utiliser. Cette bibliothèque nous donne la possibilité d'inverser les signaux sur le port, ce qui est nécessaire pour communiquer avec le capteur. Elle permet également de garder le port série matériel disponible pour d'autres utilisations. Pour créer le circuit pour RS-232, il suffit de connecter D10 (notre broche RX virtuelle) à OUT et D11 (notre TX virtuel) à IN. C'est ce que montre la figure 5.

Figure 5 Schéma pour la connexion 1-6200-006 à Arduino avec RS-232 et la bibliothèque SoftwareSerial

En utilisant SoftwareSerial, vous pouvez initialiser le port série virtuel avec le code suivant :

SoftwareSerial Sensor(10, 11, true); //RX, TX, inverse
void setup() {
    Sensor.begin(9600); //RX, TX, invert
}

Notez que les appareils dotés de ports série TTL UART (comme l'Arduino) nécessitent une connexion série inversée, sinon ils ne pourront pas communiquer. Avec un Arduino, cela se fait avec le troisième argument lors de la création du port série virtuel ("true" pour un signal inversé).

Pour lire le tilt par RS-232, envoyez d'abord la commande pour les données que vous voulez, puis lisez les données du port. Le code pour lire les valeurs de l'axe des x, de l'axe des y et de la température se trouve ci-dessous :

Sensor.print('x'); // send command for x axis tilt
delay(50); // delay to give time for response
b = 0;
while (Sensor.available() != 0 && b < 8) {
    x[b++] = Sensor.read(); // read received bytes into char array
}

Sensor.print('y'); // send command for y axis tilt
delay(50);
b = 0;
while (Sensor.available() != 0 && b < 8) {
    y[b++] = Sensor.read();
}

Sensor.print('t'); // send command for temperature
delay(50);
b = 0;
while (Sensor.available() != 0 && b < 8) {
    temperature[b++] = Sensor.read();
}

The definitions of all RS-232 commands are available on the datasheet for the signal conditioner.

La réponse de ce code sera un tableau de caractères de 8 octets, terminé par des caractères de saut de ligne et de retour chariot (0x0a, 0x0d). Il ne s'agira pas d'une chaîne de caractères, il faudra donc très probablement la convertir en une chaîne de caractères. Si nécessaire, il peut également être converti en int.

// convertir un tableau de caractères en chaîne de caractères
    x[b - 2] = '\0' ;

   // convertir une chaîne de caractères en 16 bits int
    xInt = atoi(x) ;

Le code ci-dessus remplace le caractère de nouvelle ligne par le caractère nul, terminant la chaîne immédiatement après le dernier caractère. Cela nécessite l'utilisation de la variable b, donc il faudra probablement le faire immédiatement après avoir reçu la mesure. Pour y parvenir sans utiliser la variable b, le caractère de terminaison peut également être placé à la fin du tableau, mais cela laissera des espaces et des caractères de fin de chaîne.

RS-485

RS-485 (TIA-485) est une norme de communication série qui fonctionne bien sur de longues distances et dans des environnements électriquement bruyants. Elle est disponible sur le conditionneur de signal 1-6200-008. L'Arduino Uno ne prend pas en charge la norme RS-485 en soi, mais un convertisseur peut être utilisé pour faciliter la communication avec n'importe lequel de nos produits RS-485.

Sur la plupart des convertisseurs RS-485, les DI (Data In) et RO (Receive Out) sont respectivement les Rx et Tx. Le RE (Receive Enable) et le DE (Data Enable) contrôlent quand le convertisseur enverra et recevra des données RS-485 ; ils peuvent généralement être connectés et basculés ensemble (haut pour envoyer des données, bas pour recevoir des données). Les connexions A et B du convertisseur se connectent à A et B du conditionneur de signal. Le schéma de ce circuit est illustré à la figure 6.

Figure 6 Schéma pour la connexion de 1-6200-008 à Arduino avec RS-485. Convertisseur RS-485 utilisé comme intermédiaire

Les commandes RS-485 utilisées pour communiquer avec le conditionneur de signal utilisent le format suivant :

*xxyy#

Le * est le caractère de départ, qui commence chaque commande. xx est l'adresse à laquelle la commande est envoyée. Par défaut, ce sera 99 le 1-6200-008. yy est la commande elle-même. Le # signale la fin de la commande. Par exemple, la commande de lecture de l'inclinaison de l'axe des x à l'adresse 99 est *9911#. Toutes les commandes disponibles se trouvent sur la fiche technique du 1-6200-008.

Avec le convertisseur RS-232 à RS-485 en ligne, ces commandes peuvent être envoyées au convertisseur avec RS-232. Le convertisseur les enverra ensuite au conditionneur de signal avec le RS-485. La fonction de configuration sera la même que pour le conditionneur de signal RS-232. Le code ci-dessous montre comment cette configuration peut être utilisée pour lire les données du conditionneur de signal :

// x axis tilt
    digitalWrite(9, HIGH); // enable transmission
    Sensor.print("*9911#"); // send x axis command
    digitalWrite(9, LOW); // enable reception
    delay(25); // wait for sensor to respond
    b = 0;
    while (Sensor.available()) {
        x[b++] = Sensor.read(); // store response in a char array
    }

    // y axis tilt
    digitalWrite(9, HIGH); // enable transmission
    Sensor.print("*9921#"); // send y axis command
    digitalWrite(9, LOW); // enable reception
    delay(25);
    b = 0;
    while (Sensor.available()) {
        y[b++] = Sensor.read(); // store response in char array
    }

    // temperature
    digitalWrite(9, HIGH); // enable transmission
    Sensor.print("*9941#"); // send temperature command
    digitalWrite(9, LOW); // enable reception
    delay(25);
    b = 0;
    while (Sensor.available()) {
        temperature[b++] = Sensor.read(); // store response
    }

Comme pour le RS-232, la réponse sera un tableau de caractères terminé par une nouvelle ligne et un retour chariot. Si vous souhaitez traiter le tableau comme une chaîne de caractères, vous devrez ajouter le caractère nul ('\0').

Adressée RS-485

Il est possible de connecter jusqu'à 32 conditionneurs de signaux 1-6200-008 à un seul bus. Les conditionneurs de signaux peuvent ensuite se voir attribuer des adresses, ce qui permet à chaque capteur de déterminer s'il doit répondre. Notez qu'il est important d'éviter de connecter plusieurs capteurs avec la même adresse, car les capteurs interféreraient avec les transmissions des autres.

Par défaut, l'adresse du conditionneur de signal sera 99. Pour le modifier, assurez-vous qu'il s'agit du seul appareil connecté avec cette adresse. Ensuite, utilisez la commande *xx81Azz#, où xx est l'adresse actuelle et zz la nouvelle adresse. Par exemple :

Sensor.print("*9981A01#") ; // changement d'adresse de 99 à 01

Une fois l'adresse modifiée, vous ne pourrez plus accéder au capteur en utilisant des commandes qui commencent par 99. Au lieu de cela, la nouvelle adresse 01 remplacera la 99 dans toutes les commandes. Par exemple, la commande de lecture des informations sur les produits passera de *9980# à *0180# après l'exécution de la commande ci-dessus.

Une fois qu'une adresse unique a été attribuée à chaque capteur, ils peuvent être reliés au circuit. Chaque conditionneur de signal peut être connecté au même bus sans aucun composant ou connexion supplémentaire. Voir la figure 7 pour un schéma montrant cela.

Figure 7 Schéma de connexion des (4) conditionneurs de signal 1-6200-008 à un Arduino avec RS-485

Un exemple de lecture de programme à partir de plusieurs capteurs RS-485 adressés est donné ci-dessous. Ce code est écrit pour un circuit connecté à 4 capteurs, adressés 8 - 11.

char addr[4][3] = {"08", "09", "10", "11"};
for (int i = 0; i < 4; i++) { // run this code for every address
    // x axis tilt
    digitalWrite(9, HIGH); // enable transmission
    sprintf(cmd, "*%2s11#", addr[i]); // create x axis command
    Sensor.print(cmd); // send x axis command
    digitalWrite(9, LOW); // enable reception
    delay(25); // wait for sensor to respond
    b = 0;
    while (Sensor.available()) {
        x[b++] = Sensor.read(); // store response from sensor in a char array
    }

    // y axis tilt
    digitalWrite(9, HIGH); // enable transmission
    sprintf(cmd, "*%2s21#", addr[i]); // create command
    Sensor.print(cmd); // send command
    digitalWrite(9, LOW); // enable reception
    delay(25);
    b = 0;
    while (Sensor.available()) {
        y[b++] = Sensor.read(); // store response
    }

    // temperature
    digitalWrite(9, HIGH); // enable transmission
    sprintf(cmd, "*%2s41#", addr[i]); // create command
    Sensor.print(cmd); // send command
    digitalWrite(9, LOW); // enable reception
    delay(25);
    b = 0;
    while (Sensor.available()) {
        temperature[b++] = Sensor.read(); // store response
    }
}

Les réponses seront des tableaux de caractères de 8 octets contenant les caractères ASCII pour un nombre de 16 bits.