Description
Cette note d'application explique comment obtenir des mesures d'inclinaison à partir d'un capteur d'inclinaison électrolytique et d'un conditionneur de signaux. Elle couvre les schémas et le code pour chaque protocole disponible sur les conditionneurs de signaux de The Fredericks Company. Tous les exemples montrent le code et les circuits avec un Arduino Uno, il y aura donc des différences dans le code si l'on utilise d'autres plateformes. Chaque exemple fournit une sortie brute du capteur dans une variété d'unités. Chacune de ces unités peut être convertie en degrés à l'aide des méthodes expliquées dans la note d'application 1005.
Analogue
Les deux 1-6200-007 et 1-6200-012 Les conditionneurs de signaux ont des sorties analogiques. Sur le 1-6200-007, les deux axes et la température sont sortis des broches XA, YA et T respectivement. La connexion à l'Arduino nécessite des connexions directes du conditionneur de signaux aux broches d'entrée analogique de l'Arduino.
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
Les mesures PWM sont disponibles sur l'écran 1-6200-007 conditionneur de signaux. Avec le PWM, les angles d'inclinaison x et y peuvent être lus à partir des broches numériques XP et YP du conditionneur de signaux. Il n'y a pas de sortie PWM pour la température, qui devra donc être lue à partir de la broche analogique. Un schéma de cette configuration est présenté à la figure 2.
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.
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 :
- Vitesse d'horloge maximale de l'esclave, qui est de 20Mhz sur le 1-6200-005.
- 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).
- 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
Il est également possible de connecter 1-6200-005 Les conditionneurs de signaux sont regroupés dans un bus SPI. Un bus SPI permet à tous les dispositifs SPI de partager les connexions CLK, MISO et MOSI. Chaque esclave dispose cependant de sa propre connexion SS, ce qui permet au maître de sélectionner l'esclave avec lequel il souhaite communiquer. Le nombre de dispositifs SPI que vous pouvez utiliser simultanément est limité par le nombre de connexions SS indépendantes que vous pouvez établir. La figure 4 montre le schéma de 2 capteurs sur un bus SPI avec les broches D9 et D10 utilisées comme signaux SS.
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(); }
Les définitions de toutes les commandes RS-232 sont disponibles sur la fiche technique du conditionneur de signaux.
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.