diff --git a/DigitalReadSerialX8.cpp b/DigitalReadSerialX8.cpp new file mode 100644 index 0000000..c5c0624 --- /dev/null +++ b/DigitalReadSerialX8.cpp @@ -0,0 +1,34 @@ +/* +DigitalReadSerialX8.cpp +(C)2013 kou029w - MIT License +*/ +#if defined(ARDUINO) && ARDUINO >= 100 +#include +#else +#include +#endif +#include "DigitalReadSerialX8.h" + +template<> +void DigitalReadSerialX8(HardwareSerial& serial, uint8_t minPin); +#ifdef __AVR_ATmega32U4__ +template<> +void DigitalReadSerialX8(Serial_& serial, uint8_t minPin); +#endif + +template +void DigitalReadSerialX8(T& serial, uint8_t minPin=12){ + if(!serial) return; + for(int i=minPin; i= 100 +#include +#else +#include +#endif + +template void DigitalReadSerialX8(T& serial, uint8_t minPin); + +#endif diff --git a/Motor.cpp b/Motor.cpp new file mode 100644 index 0000000..c7e7958 --- /dev/null +++ b/Motor.cpp @@ -0,0 +1,61 @@ +/* +Motor.cpp +(C)2013 kou029w - MIT License +*/ +#include "Motor.h" + +Motor::Motor(){ + _pin1 = -1; + _pin2 = -1; +} + +void Motor::mode(uint8_t mode){ + if(_pin1 != -1) digitalWrite(_pin1, (mode>>0)&1); + if(_pin2 != -1) digitalWrite(_pin2, (mode>>1)&1); +} + +void Motor::mode(uint8_t mode, uint8_t speed){ + switch(mode){ + case GO: + if(_pin1 != -1) analogWrite(_pin1, speed); + if(_pin2 != -1) digitalWrite(_pin2, LOW); + break; + case BACK: + if(_pin1 != -1) analogWrite(_pin1, ~speed); + if(_pin2 != -1) digitalWrite(_pin2, HIGH); + break; + default: + if(_pin1 != -1) digitalWrite(_pin1, (mode>>0)&1); + if(_pin2 != -1) digitalWrite(_pin2, (mode>>1)&1); + break; + } +} + +void Motor::speed(int speed){ + if(speed>=0) mode(GO, speed); + else mode(BACK, -speed); +} + +void Motor::attach(uint8_t pin1){ + _pin1 = pin1; + _pin2 = -1; + pinMode(_pin1, OUTPUT); + digitalWrite(_pin1, LOW); +} + +void Motor::attach(uint8_t pin1, uint8_t pin2){ + _pin1 = pin1; + _pin2 = pin2; + pinMode(_pin1, OUTPUT); + pinMode(_pin2, OUTPUT); + digitalWrite(_pin1, LOW); + digitalWrite(_pin2, LOW); +} + +void Motor::detach(){ + mode(STOP); + pinMode(_pin1, INPUT); + pinMode(_pin2, INPUT); + _pin1 = -1; + _pin2 = -1; +} diff --git a/Motor.h b/Motor.h new file mode 100644 index 0000000..6783d68 --- /dev/null +++ b/Motor.h @@ -0,0 +1,75 @@ +/* +Motor.h - モータードライバ(1ピン/2ピン)のためのライブラリ + +## 概要 ## +このライブラリは、1ピンあるいは2ピンを占有するモータードライバのためのシンプルなライブラリです。 +PWM対応ピンが1つしか必要ないのがこのライブラリの特徴です。 +ただし、その副作用として、GOとBACKの速度に差があることがあります。 + +## 使い方 ## +例: + #include "Motor.h" + Motor motor; + void setup(){ + // motor.attach(pin1, pin2); + motor.attach(5, 6); + } + void loop(){ + // motor.mode(GO); //正転 + motor.mode(GO, 100); //0-255(ここでは、100)のスピードで正転 + delay(1000); + motor.mode(STOP); //停止 + delay(1000); + } + +注意: +使用するモータードライバの動作は、 +1ピンの場合: + 動作 |pin1 + -----+----- + STOP | L + GO | H + +2ピンの場合: + 動作 |pin1 |pin2 + ----------+-----+----- + STOP | L | L + GO | H | L + BACK | L | H + STOP/BRAKE| H | H + +でなければなりません。また、 + void Motor::mode(char mode, byte speed); + void Motor::speed(int speed); + +これらを使用する場合、pin1はPWM対応でなければなりません。 + +## ライセンス ## +(C)2013 kou029w - MIT License +*/ + +#ifndef Motor_h +#define Motor_h +#if defined(ARDUINO) && ARDUINO >= 100 +#include +#else +#include +#endif + +enum { STOP = 0, GO = 1, BACK = 2, BRAKE = 3 }; + +class Motor{ +public: + Motor(); + void mode(uint8_t mode); + void mode(uint8_t mode, uint8_t speed); + void speed(int speed); + void attach(uint8_t pin1); + void attach(uint8_t pin1, uint8_t pin2); + void detach(); +private: + char _pin1; + char _pin2; +}; + +#endif diff --git a/README.md b/README.md index 11b3da7..05d4d7a 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,21 @@ Servomotor for steering - ステアリング用サーボモーター Servomotor for lance - ランス用サーボモーター +### 車体仕様 ### +* ホイールベース : 約150mm +* 車重 : 1kg以下 +* 車体材料 : タミヤ ユニバーサルプレートL +* 使用ギアボックス : タミヤ ハイスピードギアボックスHE +* ギア比 : 11.6:1 +* 使用モーター : 上記ギアボックスに付属するもの +* 使用サーボモーター : enRoute DHCM(ステアリング用)/Savox SC-0352(ランス用) + +### 回路仕様 ### +* 動作電圧 : 7.2V以上 +* 使用マイコン : Atmel AVR (Arduino) +* 使用センサーアレイ : SG-2BC x 8 (ロボラボ講習会のもの) +* 使用ロータリーエンコーダー : 公式マイコンカーキットのものを使用 + ### Software ### [count/mark] | @@ -51,28 +66,8 @@ steering - ステアリングの動作 lance - ランスの動作 -### 車体仕様 ### -* ホイールベース : 約150mm -* 車重 : 1kg以下 -* 車体材料 : タミヤ ユニバーサルプレートL -* 使用ギアボックス : タミヤ ハイスピードギアボックスHE -* ギア比 : 11.6:1 -* 使用モーター : 上記ギアボックスに付属するもの -* 使用サーボモーター : enRoute DHCM(ステアリング用)/Savox SC-0352(ランス用) - -### 回路仕様 ### -* 動作電圧 : 7.2V以上 -* 使用マイコン : Atmel AVR (Arduino) -* 使用センサーアレイ : SG-2BC x 8 (ロボラボ講習会のものを踏襲) -* 使用ロータリーエンコーダー : 公式マイコンカーキットのものを使用 - ### ソフトウェア仕様 ### -基本的には半蔵2.1までの機能を包含します。 - * 使用言語 : Arduino 1.0 ## ライセンス ## -MIT Licence - ---------------- -(C)2013 kou029w +(C)2013 kou029w - MIT Licence \ No newline at end of file diff --git a/SerialUtil.cpp b/SerialUtil.cpp new file mode 100644 index 0000000..9d1e650 --- /dev/null +++ b/SerialUtil.cpp @@ -0,0 +1,49 @@ +/* +SerialUtil.cpp +(C)2013 kou029w - MIT License +*/ + +#include +#include "SerialUtil.h" + +template<> +String inputLine(String str, HardwareSerial& serial); +template<> +String getStr(size_t size, HardwareSerial& serial); +#ifdef __AVR_ATmega32U4__ +template<> +String inputLine(String str, Serial_& serial); +template<> +String getStr(size_t size, Serial_& serial); +#endif + +// serialから文字列を一行('\r'まで)入力 (str:入力がないとき返す文字列) +template +String inputLine(String str, T& serial){ + if(!serial) return str; + String result = ""; + for(;;){ + if(serial.available()){ + char c = serial.read(); + if(c == '\r') break; + result += String(c); + } + } + if(result != "") return result; + return str; +} + +// serialから文字列を入力 +template +String getStr(size_t size, T& serial){ + if(!serial) return String(""); + String str = ""; + for(size_t i = 0; i + +template +String inputLine(String str, T& serial); + +template +String getStr(size_t size, T& serial); + +#endif diff --git a/ServoTest.cpp b/ServoTest.cpp new file mode 100644 index 0000000..dd3d370 --- /dev/null +++ b/ServoTest.cpp @@ -0,0 +1,122 @@ +/* +ServoTest.cpp +(C)2013 kou029w - MIT License +*/ + +#include +#include +#include "ServoTest.h" +#include "SerialUtil.h" + +//#ifdef Servo_h +template<> +class ServoTestClass; +#ifdef __AVR_ATmega32U4__ +template<> +class ServoTestClass; +#endif +//#endif + +template +void ServoTestClass::_setAndPrint(SERVO& servo, const char* servoName, S& serial){ + static unsigned long lastTime; + lastTime = _time; + _time = millis(); + serial.print("delay("); + serial.print(_time - lastTime); + serial.println(");"); + + serial.print(servoName); + switch(_mode){ + case ATTACH_MODE: + serial.print(".attach("); + serial.print(_val); + servo.attach(_val); + break; + case DETACH_MODE: + serial.println(".detach("); + servo.detach(); + break; + case WRITE_MODE: + serial.print(".write("); + serial.print(_val); + servo.write(_val); + break; + case WRITE_MICROSEC_MODE: + serial.print(".writeMicroseconds("); + serial.print(_val); + servo.writeMicroseconds(_val); + break; + } + serial.println(");"); +} + +template +void ServoTestClass::operator()(S& serial){ + // using namespace servotest; + char _helpdoc[] = "" + "/*\n" + "## help ##\n" + "default\n" + " Format : \"angle + 'a/b'\"\n" + " Example: \"90a\" => servoA.write(90)\n" + "\n" + "[t] attach\n" + " Format : \"'t' + pin + 'a/b'\"\n" + " Example: \"t8b\" => servoB.attach(8)\n" + "\n" + "[d] detach\n" + " Format : \"'d' + 'a/b'\"\n" + " Example: \"db\" => servoB.detach()\n" + "\n" + "[u] write-microseconds\n" + " Format : \"'u' + us + 'a/b'\"\n" + " Example: \"u1500a\" => servoA.writeMicroseconds(1500)\n" + "*/\n"; + _time = millis(); + SERVO _servoA; + SERVO _servoB; + _servoA.attach(9); + _servoB.attach(10); + serial.println("servoA.attach(9);"); + serial.println("servoB.attach(10);"); + + /* Main loop */ + for(;;){ + _mode = NONE; + _val = 0; + serial.println("/*-- [q] quit [h] help --*/"); + while(_mode == NONE){ + char c = getStr(1, serial)[0]; + switch(c){ + case 'h': + serial.print(_helpdoc); + break; + case 'q': + _servoA.detach(); + _servoB.detach(); + return; + case 't': + _mode = ATTACH_MODE; + break; + case 'd': + _mode = DETACH_MODE; + break; + case 'u': + _mode = WRITE_MICROSEC_MODE; + break; + case '0'...'9': + _val = _val * 10 + c - '0'; + break; + case 'a': + if(_mode == NONE) _mode = WRITE_MODE; + _setAndPrint(_servoA, "servoA", serial); + break; + case 'b': + if(_mode == NONE) _mode = WRITE_MODE; + _setAndPrint(_servoB, "servoB", serial); + break; + } + } + } +} diff --git a/ServoTest.h b/ServoTest.h new file mode 100644 index 0000000..e875aed --- /dev/null +++ b/ServoTest.h @@ -0,0 +1,41 @@ +/* +ServoTest.h - サーボの動作を確認するためのライブラリ + +## 概要 ## +このライブラリは、シリアルモニター上からサーボの動作を確認するためのシンプルなライブラリです。 + +## 使い方 ## +例: + #include + #include "ServoTest.h" + void setup(){ + Serial.begin(9600); + ServoTest(Serial); + } + void loop(){ + } + +## ライセンス ## +(C)2013 kou029w - MIT License +*/ + +#ifndef ServoTest_h +#define ServoTest_h + +#include +#include +#include "SerialUtil.h" + +template +class ServoTestClass{ + public: + void operator()(S& serial); + private: + void _setAndPrint(SERVO& servo, const char* servoName, S& serial); + enum mode_e {ATTACH_MODE, DETACH_MODE, WRITE_MODE, WRITE_MICROSEC_MODE, NONE} _mode; + unsigned long _time; + int _val; + char* _helpdoc; +}; + +#endif diff --git a/hanzo3.ino b/hanzo3.ino index 8b13789..9ea3301 100644 --- a/hanzo3.ino +++ b/hanzo3.ino @@ -1 +1,22 @@ +/* +競技用ランサーロボット +半蔵 3.0 +(C)2013 kou029w - MIT License +*/ +#include +#include "ServoTest.h" +//#include "SerialUtil.h" +#ifdef __AVR_ATmega32U4__ +ServoTestClass ServoTest; +#else +ServoTestClass ServoTest; +#endif + +void setup(){ + Serial.begin(9600); + ServoTest(Serial); +} + +void loop(){ +}