설명
이 애플리케이션 노트에서는 전해 기울기 센서 및 신호 조절기에서 기울기 측정을 얻는 방법을 설명합니다. The Fredericks Company의 신호 컨디셔너에서 사용할 수 있는 각 프로토콜에 대한 회로도와 코드를 다룹니다. 모든 예제는 Arduino Uno가있는 코드와 회로를 보여 주므로 다른 플랫폼을 사용할 때 코드에 차이가 있습니다. 각 예제는 센서의 원시 출력을 다양한 단위로 제공합니다. 이들 유닛들 중 임의의 것은 애플리케이션 노트(1005)에 설명된 방법들을 사용하여 각도로 변환될 수 있다.
아날로그
Both the 1-6200-007 및 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.
그림 1 아날로그를 사용하여 아두이노에 1-6200-007을 연결하기위한 회로도
1-6200-012 신호 컨디셔너는 아날로그 온도 출력이 없으므로 RS-232를 사용하여 온도를 읽어야 합니다. 1-6200-012에서 의 온도 읽기 온도에 대한 자세한 내용은 RS-232섹션을 참조하십시오.
회로를 조립하면 아두이노의 analogRead() 함수를 사용하여 데이터를 읽을 수 있습니다. 이 예는 다음과 같습니다.
x = 아날로그 읽기 (A0); y = 아날로그 읽기 (A1); 온도 = 아날로그 읽기 (A2);
이 코드의 결과는 아날로그 핀의 전압을 나타내는 원시 값이 됩니다. 이 측정의 해상도는 전압을 읽는 데 사용되는 하드웨어에 따라 달라집니다. 아두이노 우노에서 아날로그 핀은 10비트해상도를 가지고 있습니다.
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.
그림 2 PWM을 사용하여 아두이노에 1-6200-007연결회로 연결하기 위한 회로도
PWM 출력은 PWM 핀뿐만 아니라 Arduino의 모든 디지털 핀에 연결할 수 있습니다. 이 예제에서는 핀 D7과 D8이 비PWM 핀을 모두 사용합니다.
Arduino로 PWM 신호를 읽는 것이 펄스In() 기능으로 수행하는 것이 가장 좋습니다. 펄스In() 함수는 펄스가 높거나 낮은 상태에서 지속되는 시간을 시간입니다. 이 경우, 우리는 높은 상태를 시간 것입니다.
x = 펄스인 (XPIN, 높음); y = 펄스인(YPIN, HIGH); 온도 = 아날로그 읽기 (A0); char res[50]; 스프린트 (res, "X: %i, Y: %i, 온도: %i", x, y, 온도); 직렬.println(res)
결과는 마이크로초 단위로 펄스의 길이가 될 것입니다. pulseIn() 기능은 10μs만큼 짧은 펄스를 판독할 수 있으며, 이는 최대 8ms 펄스의 측정이 10비트 출력과 유사한 정확도를 갖는다는 것을 의미합니다. 이 정확도는 장치를 읽는 장치가 더 작은 펄스를 감지할 수 있다면 더 높을 것입니다.
SPI
SPI는 1-6200-005 신호 컨디셔너에서 사용할 수 있는 동기 연속 통신 프로토콜입니다. 이 프로토콜은 MISO(슬레이브 아웃 마스터), MOSI(마스터 아웃 슬레이브 인), CLK(직렬 시계), SS(슬레이브 선택)의 4개의 연결을 사용하여 마스터/슬레이브 기술에서 작동합니다. 마스터는 MOSI(1-6200-005에 IN로 표시됨)를 통해 슬레이브에 명령을 보내고, 슬레이브는 MISO(1-6200-005에 OUT로 표시됨)를 통해 응답합니다. CLK는 슬레이브의 통신을 동기화하는 마스터가 만든 시계입니다. SS는 슬레이브를 활성화하는 데 사용됩니다. 이 핀은 SPI가 한 버스에서 여러 장치를 지원하는 방법입니다(자세한 내용은 "SPI Bus" 섹션을 참조하십시오).
아두이노 우노는 MOSI, MISO 및 CL에 미리 정의된 핀을 가지고 있습니다. 다음은 다음 표에 표시됩니다.
MOSI | D11 |
미소 | D12 |
CLK | D13 |
아두이노에 연결하기 위한 회로도는 그림 3에 도시되어 있다.
그림 3 1-6200-005를 SPI와 함께 아두이노에 연결하기 위한 회로도
센서와 통신하기 위해 아두이노의 SPI 라이브러리를 사용합니다. SPI.begin()은 SPI 라이브러리를 초기화합니다(그러나 통신을 열지 않음). 이 회로에는 하나의 SPI 장치만 있기 때문에 핀 10(SS)이 LOW로 설정되어 해당 핀으로 제어되는 슬레이브가 가능합니다. 이 전체 프로그램에 대 한 LOW로 설정 됩니다. 이 회로에서 슬레이브를 비활성화할 이유가 없습니다.
void setup() { SPI.begin(); // initialize SPI digitalWrite(10, LOW); // enable slave 1 }
라이브러리를 초기화되었으므로 신호 컨디셔너와의 연결을 열어야 합니다. SPI.begin트랜잭션() 함수를 사용하여 수행됩니다. 이 함수는 SPISettings 개체인 하나의 인수를 수행합니다. 이 개체는 연결을 만드는 데 필요한 모든 정보를 제공합니다. SPISettings 개체에는 세 가지 인수가 있습니다.
- 1-6200-005에서 20Mhz인 슬레이브의 최대 클럭 속도입니다.
- 두 번째 인수는 SPI 인터페이스가 가장 중요한 비트 또는 최소 중요 비트 먼저를 사용할지 여부를 결정합니다. 1-6200-005의 경우 가장 중요한 비트 퍼스트(또는 MSBFIRST)입니다.
- 세 번째 인수는 SPI 모드를 결정합니다. 1-6200-005의 경우 SPI 모드 2(CPOL=1, CPHA=0)가 사용됩니다.
// 오픈 SPI 통신 SPI.begin트랜잭션(SPISettings(200000000, MSBFIRST, SPI_MODE2));
SPI.transfer() 함수는 데이터를 보내고 받는 데 사용됩니다. 동시에 명령을 보내고 MISO 핀에서 읽는 모든 것을 반환합니다. 슬레이브는 항상 응답하는 데 1 클럭 주기가 소요됩니다. 따라서 각 명령의 결과는 다음 주기까지 수신되지 않습니다. 예를 들어 아래 코드에서 X 축 낮은 바이트 요청을 보내는 함수는 이 지연으로 인해 X 축 높은 바이트 값을 반환합니다.
0x39 명령은 좋은 측정을 얻는 데 필수적입니다. 이 명령은 보드에 기울기의 새로운 측정을 하도록 지시합니다. 아래 코드에서는 처음에 한 번, 그리고 저온 비트가 수신되는 if 문 끝에 다시 한 번 전송됩니다.
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.
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.
그림 4 1-6200-005의 두 대를 아두이노와 SPI 버스로 연결하는 회로도. 각 장치에 대한 별도의 /SS 연결 주
이 코드는 단일 SPI 장치의 코드와 매우 유사합니다. SS 핀은 통신되는 슬레이브를 제어하도록 변경됩니다.
// 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
2개의 SPI 슬레이브를 동시에 활성화하고 메시지가 전송되면 신호가 방해되고 응답이 제대로 읽지 않습니다.
RS-232
RS-232(TIA-232)는 일반적인 직렬 통신 프로토콜이다. RS-232의 3선 버전은 1-6200-006 및 1-6200-012 신호 컨디셔너모두에서 사용할 수 있습니다. RS-232를 연결하는 것은 부지를 함께 연결하고 각 Rx를 다른 장치의 Tx에 연결하는 것으로 구성됩니다.
이 응용 프로그램에서는 Arduino의 SoftwareSerial 라이브러리를 사용하여 사용할 가상 직렬 포트를 만듭니다. 이 라이브러리는 센서와 통신하는 데 필요한 포트의 신호를 반전할 수 있는 기능을 제공합니다. 또한 하드웨어 직렬 포트를 다른 용도로 사용할 수 있습니다. RS-232의 회로를 만들려면 D10(가상 RX 핀)을 OUT 및 D11(가상 TX)에 IN에 연결하기만 하면 됩니다. 이는 그림 5에 표시됩니다.
그림 5 RS-232및 소프트웨어 시리얼 라이브러리와 아두이노에 1-6200-006연결 회로도
SoftwareSerial를 사용하면 다음 코드로 가상 직렬 포트를 초기화할 수 있습니다.
SoftwareSerial Sensor(10, 11, true); //RX, TX, inverse void setup() { Sensor.begin(9600); //RX, TX, invert }
UART TTL 직렬 포트(예: Arduino)가 있는 장치에는 반전된 직렬 연결이 필요하거나 통신할 수 없습니다. Arduino를 사용하면 가상 직렬 포트를 만들 때 세 번째 인수로 수행됩니다(반전된 신호에 대해 "true").
먼저 RS-232를 통해 기울기를 읽으려면 원하는 데이터에 대한 명령을 보낸 다음 포트에서 데이터를 읽습니다. x 축, y축 및 온도 값을 읽을 수 있는 코드는 다음과 같습니다.
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(); }
모든 RS-232 명령의 정의는 신호 조절기의 데이터시트에서 사용할 수 있습니다.
이 코드의 응답은 8바이트 문자 배열로, 새로운 라인 및 캐리지 반환 문자(0x0a, 0x0d)로 종료됩니다. 문자열이 아니므로 문자열로 변환해야 할 가능성이 큽입니다. 필요한 경우 int로 변환할 수도 있습니다.
// 샤어 배열을 문자열로 변환 x[b - 2] = '\0'; // 문자열을 16비트 int로 변환 xInt = 아토이 (x);
위의 코드는 새 줄 문자를 null 문자로 대체하여 마지막 문자 직후 문자열을 종료합니다. 이렇게 하려면 b 변수를 사용 하 여 필요 하므로 측정을 받은 후 즉시 수행 해야 할 수 있습니다. b 변수를 사용하지 않고 이를 달성하기 위해 종료 문자도 배열 끝에 배치할 수 있지만 후행 공간과 문자를 남깁니다.
RS-485
RS-485(TIA-485)는 장거리 및 전기 적으로 시끄러운 환경에서 잘 작동하는 직렬 통신 표준입니다. 1-6200-008 신호 컨디셔너에서 사용할 수 있습니다. Arduino Uno자체적으로 RS-485를 지원하지 않지만 변환기를 사용하여 RS-485 제품에 대한 통신을 용이하게 할 수 있습니다.
대부분의 RS-485 컨버터에서 DI(데이터 인) 및 RO(수신)는 각각 Rx 및 Tx입니다. 변환기가 RS-485 데이터를 보내고 받을 때 RE(사용 지원 수신) 및 DE(데이터 사용) 제어; 일반적으로 함께 연결하고 전환할 수 있습니다(높은 데이터를 전송하고 데이터를 수신하기 위해 낮음). 컨버터의 A 및 B 연결은 신호 컨디셔너에서 A와 B에 연결됩니다. 이 회로에 대한 회로는 그림 6으로 표시됩니다.
그림 6 RS-485와 아두이노에 1-6200-008연결 에 대한 회로도. 중개자로 사용되는 RS-485 컨버터
신호 컨디셔너와 통신하는 데 사용되는 RS-485 명령은 다음 형식을 사용합니다.
*xxyy #
*는 각 명령을 시작하는 시작 문자입니다. xx는 명령이 전송되는 주소입니다. 기본적으로 1-6200-008에서 99가 됩니다. yy는 명령 자체입니다. #은 명령의 끝을 신호합니다. 예를 들어 주소 99에서 x 축 기울기를 읽는 명령은 *9911#입니다. 사용 가능한 모든 명령은 1-6200-008 데이터 시트에서 찾을 수 있습니다.
RS-232에서 RS-485 컨버터 인라인을 사용하면 이러한 명령을 RS-232로 변환기로 보낼 수 있습니다. 그런 다음 변환기가 RS-485를 사용하여 신호 컨디셔너로 전송됩니다. 설정 기능은 RS-232 신호 컨디셔너와 동일합니다. 아래 코드는 이 구성을 사용하여 신호 컨디셔너에서 데이터를 읽는 방법을 보여 주며 다음과 같습니다.
// 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 }
RS-232와 마찬가지로 응답은 새 줄및 캐리지 리턴으로 종료되는 문자 배열이 됩니다. 배열을 문자열로 처리하려면 null 문자('\0')를 부더야 합니다.
주소가 있는 RS-485
최대 32 1-6200-008 신호 컨디셔너를 단일 버스에 연결할 수 있습니다. 그런 다음 신호 컨디셔너는 주소를 할당할 수 있으며 각 센서가 응답 여부를 결정할 수 있는 방법을 제공합니다. 센서가 서로의 변속기를 방해하기 때문에 여러 센서를 동일한 주소로 연결하지 않는 것이 중요합니다.
기본적으로 신호 컨디셔너의 주소는 99입니다. 변경하려면 해당 주소와 연결된 유일한 장치인지 확인합니다. 그런 다음 xx81Azz #명령을 사용하여 xx가 현재 주소이고 zz가 새 주소인 경우 를 사용합니다. 예를 들어:
Sensor.print("*9981A01#"); // 주소 변경 99에서 01로 변경
주소가 변경되면 99로 시작하는 명령을 사용하여 센서에 액세스할 수 없습니다. 대신 새 주소 01은 모든 명령에서 99를 대체합니다. 예를 들어 제품 정보를 읽는 명령은 위의 명령을 실행한 후 *9980#에서 *0180#으로 변경됩니다.
각 센서에 고유한 주소가 할당되면 회로에 연결할 수 있습니다. 각 신호 컨디셔너는 추가 구성 요소 나 연결없이 동일한 버스에 연결할 수 있습니다. 이를 보여주는 회로도는 그림 7을 참조하십시오.
그림 7 RS-485를 가진 아두이노에 (4) 1-6200-008 신호 컨디셔너를 연결하기 위한 회로도
여러 개의 주소가 지정된 RS-485 센서에서 읽는 프로그램의 예가 아래에 있습니다. 이 코드는 8 - 11을 해결 4 센서에 연결된 회로에 대해 작성됩니다.
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 } }
응답은 16비트 번호에 대한 ASCII 문자를 포함하는 8바이트 문자 배열입니다.