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 件のコメント:
コメントを投稿