NXTとArduino間の接続は前回と同じ感じで、NXTのIN_4ポートにRS485-UARTコンバータを入れて接続しているのですが、前回のようにソフトウェアシリアルではなく、今回はArduino Megaのハードウェアシリアル1を使用して、115200bpsで通信するようにしました。
かなりいい加減なつくりですが、Arduinoを置くための台座をその場で簡単に組めちゃうところが、便利です。
ジャイロの値を取得して、RS485経由でNXTに渡して、NXTの液晶に表示(0.01度を1とした数値)しています。
以下、NXCのコード。
// RS485通信によるArduino+R1350N Gyro Shield連携 #include "NXCDefs.h" inline void WaitForMessageToBeSent() { bool sending, avail; RS485Status(sending, avail); while(sending) { Wait(MS_1); RS485Status(sending, avail); } } task main() { string rcvStr; int gyro; int status; const int STATUS_STOP = 0; const int STATUS_TURN_LEFT = 1; const int STATUS_TURN_RIGHT = 2; // S4ポートをRS485用に初期化。 UseRS485(); RS485Enable(); // RS485の通信条件を設定。 RS485Uart(HS_BAUD_115200, HS_MODE_8_DATA|HS_MODE_N_PARITY|HS_MODE_10_STOP); Wait(MS_10); // 画面消去。 ClearScreen(); // タイトル表示。 TextOut(0, LCD_LINE1, "R1350N Gyro" ); Wait(MS_10); while(true) { if (ButtonPressed(BTNLEFT, false)) { // 左ボタンを押されたら、 if (status == STATUS_STOP) { // リセットコマンドを送信。 SendRS485String("r"); WaitForMessageToBeSent(); TextOut(0, LCD_LINE2, "Send Reset."); Wait(MS_500); // 左旋回開始。 status = STATUS_TURN_LEFT; OnFwd(OUT_A, 30); OnRev(OUT_C, 30); } Wait(MS_500); } if (ButtonPressed(BTNRIGHT, false)) { // 右ボタンを押されたら、 if (status == STATUS_STOP) { // リセットコマンドを送信。 SendRS485String("r"); WaitForMessageToBeSent(); TextOut(0, LCD_LINE2, "Send Reset."); Wait(MS_500); // 右旋回開始。 status = STATUS_TURN_RIGHT; OnRev(OUT_A, 30); OnFwd(OUT_C, 30); } Wait(MS_500); } if (ButtonPressed(BTNCENTER, false)) { // 中央ボタンを押されたら、 } SendRS485String("g"); WaitForMessageToBeSent(); TextOut(0, LCD_LINE2, "Send Meas."); if (status == STATUS_TURN_LEFT) { TextOut(0, LCD_LINE1, "TURN LEFT"); if (gyro < -8500) { Off(OUT_AC); status = STATUS_STOP; TextOut(0, LCD_LINE1, "STOP"); } } if (status == STATUS_TURN_RIGHT) { TextOut(0, LCD_LINE1, "TURN RIGHT"); if (gyro > 8500) { Off(OUT_AC); status = STATUS_STOP; TextOut(0, LCD_LINE1, "STOP"); } } Wait(MS_200); // 受信処理。 if (RS485DataAvailable()) { ClearScreen(); TextOut(10, LCD_LINE2, "Received."); RS485Read(rcvStr); gyro = StrToNum(rcvStr); ClearLine(LCD_LINE3); NumOut(20, LCD_LINE3, gyro); } } }
以下、Arduino Megaのコード。
#include <Arduino.h> #include <Wire.h> #include <R1350i2c.h> // RS485ピン定義(Mega - Serial1使用) const int rs485RtsPin = 22; // 任意のpinを指定 const int rs485RxPin = 19; // 固定 const int rs485TxPin = 18; // 固定 // R1350ジャイロシールドオブジェクト R1350i2c R1350(0x9A,XTAL_7); // RS485初期化。 void RS485_initialize(long baudrate) { // Serial1初期化。 Serial1.begin(baudrate); // DTS出力ピン設定。 pinMode(rs485RtsPin, OUTPUT); // 受信(DTS=0)状態に設定。 digitalWrite(rs485RtsPin, LOW); } // RS485送信。 void RS485_write(byte data[], int count) { // DTS出力ピンを送信(DTS=1)に設定。 digitalWrite(rs485RtsPin, HIGH); // 送信。 for (int i = 0; i < count; i++) { Serial1.write(data[i]); } delayMicroseconds(70 * count); // 受信(DTS=0)状態に設定。 digitalWrite(rs485RtsPin, LOW); } void setup() { Serial.begin(115200); // R1350ジャイロ初期化。 R1350.begin(115200); // RS485初期化。 RS485_initialize(115200); delay(500); R1350.reset(); delay(500); } void loop() { short data; char c; byte sendData[2]; R1350.getData(); //data = R1350.angle() / 100; data = R1350.angle(); // RS485受信処理。 if (Serial1.available()) { c = Serial1.read(); Serial.println(c); if (c == 'r') { Serial.println("Reset..."); R1350.reset(); delay(500); } if (c == 'g') { Serial.println(data, DEC); /* sendData[0] = (byte)((data & 0xff00) >> 8); sendData[1] = (byte)(data & 0x00ff); sendData[2] = 0x03; // 送信。 RS485_write(sendData, 3); */ // DTS出力ピンを送信(DTS=1)に設定。 digitalWrite(rs485RtsPin, HIGH); // 送信。 Serial1.print(data, DEC); Serial1.write(0x03); delayMicroseconds(70 * 7); // 受信(DTS=0)状態に設定。 digitalWrite(rs485RtsPin, LOW); } } // シリアルポート受信処理。 if (Serial.available()) { c = Serial.read(); if (c == 'r') { Serial.println("Reset..."); R1350.reset(); delay(500); } if (c == 'g') { Serial.println(data, DEC); /* sendData[0] = (byte)((data & 0xff00) >> 8); sendData[1] = (byte)(data & 0x00ff); sendData[2] = 0x03; // 送信。 RS485_write(sendData, 3); */ // DTS出力ピンを送信(DTS=1)に設定。 digitalWrite(rs485RtsPin, HIGH); // 送信。 Serial1.print(data, DEC); Serial1.write(0x03); delayMicroseconds(70 * 7); // 受信(DTS=0)状態に設定。 digitalWrite(rs485RtsPin, LOW); } if (c == 't') { Serial.println("Test send."); byte testData[] = {'H', 'e', 'l', 'l', 'o', '!', 0x03}; RS485_write(testData, 7); } } }
0 件のコメント:
コメントを投稿