Ganponブログ

趣味の模型作り、ドライブ、旅行など
since Mar.2017

Arduino UNOでATtiny85に書き込んで遊ぶ(その2)

2023-09-27 20:01:42 | Arduino

2023-09-27
前回はマイコンプログラムの最初に動かすプログラムの定番「L チカ」でLEDを点滅させました。
今回は、ネット上からプログラムをダウンロードしてミニゲーム機を作ってみます。

参考にしたのは、

1. 【自作】ゲームボーイ風!!携帯ゲーム機をArduinoで電子工作方法・手順【Arduboy】

2. ATtiny85を使った ちびゲーム機を自作しよう。 1回目「紹介と準備」

プリント基板にパーツを取り付け、ダウンロードしたプログラムを書き込みます。
すんなり動いてくれると思いきや、OLEDモジュールに何も表示されません。
ボタンを押すと圧電ブザーから音がするのみです。

OLEDモジュールのSSD1306の動作確認用プログラムでは正しく表示されます。

色々調べている中で、上記のご両人が利用した先のプログラムと現在入手できるものが異なっている様です。

▼何も表示されないプログラム。
表示されるプログラムに記述がある「#include <ssd1306xled.h> 」が有りません。
その代わり「#include "TinyDriver.h"」が有ります。

▼表示されるプログラム

▼入手先はここです。

 ネットで事例紹介がある方は、現在プログラムが変わっている様で、画像表示されない原因は判りません。
しかし、別の入手先からダウンロードしたプログラムで何とか完成です。

▼マイコンへの書き込み時に足を曲げない様に気を付けてソケットに差しますが、ゼロプレッシャーソケットを追加取付けしました。
製作した基板は何れケースに入れたいですが、今回はここまでで終了です。

Arduino UNOでATtiny85に書き込んで遊ぶ(その1)

2023-09-25 20:49:46 | Arduino

2023-09-25
手配していた部品が届いたので、
8ピンAVRマイコン ATtiny85にプログラムを描き込んで遊びます。

【手順】
1. Arduino IDEのメニューから ファイル/スケッチ例/11.ArduinoISP/ArduinoISPを開きます。

2. Arduino UNOをUSBケーブルでパソコンに接続。

3. スケッチArduinoISPをArduinoUNOに書き込みます。
これで、ArduinoUNOをAVRライターにする事が出来ました。

4. 次に、ArduinoUNOを経由してATtiny85にブートローダを書き込みます。
マイコン起動時に、外部からプログラムをメモリに読み込むプログラムの事をブートローダと言います。
ATtiny85をArduino言語で動かすために、あらかじめブートローダを書き込んであげる必要があります。
ただし、書き込むのは一度だけでOKです。

5. ツール/ボードで「ATtiny45/85(Optiboot)」を選択。(*1)
Chipは「ATtiny85」を選択。
Clock Souceは「8MHz(internal)」を選択。
シリアルポートは「ArduinoUNO」が接続されているCOMポートを選択。
書き込み装置は「Arduino as ISP」を選択。

6. ATtiny85をArduinoUNOに接続します。
ツール/ブートローダを書き込むをクリックしてATtiny85に書き込みます。

7. ArduinoからATtiny85に動作確認用のLチカを書き込みます。
この時、いつもの「マイコンボードに書き込む」ではなく、
スケッチ/書込装置を使って書き込む」で、実行します。

1秒ごとにLEDが点滅すれば成功です。

【スケッチ:LEDチカ】

  void setup() {
    pinMode(4, OUTPUT); // D4
  }

  void loop() {
    digitalWrite(4, HIGH);
    delay(1000);
    digitalWrite(4, LOW);
    delay(1000);
  }

【回路】

(*1) : ツール/ボードで「ATtiny45/85(Optiboot)」が無い場合は、ATtiny85をボードに追加しておきます。
   詳細は省きますが、ネットをググると何個か見つかるはずです。

 


JQ6500 MP3 Player Moduleを使ってみた

2021-12-12 16:54:45 | Arduino

2021-12-12
RC可動戦車などの効果音はDFPlayer miniを使っているが、microSDカードも必要でした。
DFPlayer miniが3個で800円程度。microSDカードが1個570円程度。1set合計833円程度です。
最近、JQ6500音声モジュール基板(MP3)というものを知りました。
これは、内蔵のメモリー(2MBらしい)にデータを描き込んで使用でき、お手軽です。
使ってみたのは非正規品ですが2個788円(16PT)、1個当たり390円程度で利用できます。

▼JP6500にデータを描き込むにはアップローダープログラムが必要です。

  1. JQ6500 MP3 Player Module を開きます。
  2. ページ内の下方の、English Language MusicDownload.exe Uploader for JQ6500-16P
    English Language MusicDownload.exe v1.2a をクリックして、
    Zipファイルをダウンロードし、適当な場所に解凍します。
  3. 開いたプログラムのFILESタブがMP3ファイルの選択画面、FLASHタブがアップロード画面です。
  4. JQ6500とWindowsPCをUSBケーブルで接続。
    デバイスとして認識されてないので不安でしたが、書込みは問題なく出来るようです。
  5. FILESタブをクリックし、Chose files...ボタンをクリックして、コピー元のファイルを選択してセットします。

  6. 次に、FLASHタブをクリックし、FLASHボタンをクリックしてJP6500にアップロードさせます。


    この時、メモリーは初期化され、新たに書込みされているようです。
  7. 下図の回路で、マイコン無しで動作させることができるので、
    購入したユニットが正常に動作するか、正常に描き込まれているかを確認することができます。
    電源電圧はDC3.2~5Vです。
    K1からK5までの5個の端子に各々プッシュスイッチを接続することで、
    マイコン無しでも5個のMP3音源を再生できます。
    描き込んだファイルが3個だけの場合、S4、S5を押して再生されるファイルは1番目のファイルでした。

Arduinoでコントロールすることも可能ですが、詳しいコマンドの説明が見つかりません。
サンプルプログラムを参考に試行錯誤で動作させてみました。
Arduino IDEでプログラムを書き込み、動作させるにはJQ6500_Serial Arduino Library をダウンロードします。
http://sparks.gogo.co.nz/JQ6500_Serial.zip をダウンロードします。
Zipファイルのダウンロードは「安全ではありません」と警告されますが、各自の責任でダウンロードしてください。
ダウンロードしたZipファイルは、Arduino IDEで「Zip形式のライブラリーをインストール」で処理します。
これで、File/スケッチ例/JQ6500Serial/FullDemoなどを利用できるようになります。

ArduinoとJQ6500の接続はスケッチの内容を確認。
JQ6500のTX(10pin)をArduinoの8pinに、
JQ6500のRX(9pin)をArduinoの9pinに1kΩを介して接続します。
//   Arduino Pin 8 is connected to TX of the JQ6500
//   Arduino Pin 9 is connected to one end of a  1k resistor, 
//     the other end of the 1k resistor is connected to RX of the JQ6500
//   If your Arduino is 3v3 powered, you can omit the 1k series resistor
SoftwareSerial mySerial(8, 9);
JQ6500_Serial mp3(mySerial);

▼サンプルスケッチを参考に、下記のスケッチを作成しました。
5個のMP3ファイルを順に再生するだけのプログラムです。
上手く動作したので、取り敢えずArduinoで動作する確認はできました。
mp3ファイルですが、001abc.mp3の様に3桁の数字で始まるファイル名で登録する。
指示、再生は数字の若い順で何番目という具合になる様です。

JQ6500_TEST_5files.ino  1/1
1: /* JQ6500_TEST_5files
2: test controls of the JQ6500 module.
3: 2021/12/12
4: 5 files simple play test
5: */
6:
7: #include "Arduino.h"
8: #include "SoftwareSerial.h"
9: #include "JQ6500_Serial.h"
10:
11: // Create the mp3 module object,
12: // Arduino Pin 8 is connected to TX of the JQ6500
13: // Arduino Pin 9 is connected to one end of a 1k resistor,
14: // the other end of the 1k resistor is connected to RX of the JQ6500
15: // If your Arduino is 3v3 powered, you can omit the 1k series resistor
16:
17: SoftwareSerial mySerial(8, 9);
18: JQ6500_Serial mp3(mySerial);
19: int fnum ;
20:
21: void setup() {
22: Serial.begin(9600);
23: mySerial.begin(9600);
24: mp3.setVolume(20);
25: }
26:
27: void loop() {
28: for (fnum = 1 ; fnum <= 5 ; fnum++) {
29: mp3.playFileByIndexNumber(fnum);
30: delay(3000);
31: }
32: delay(3000);
33:
34: for (fnum = 5 ; fnum >= 1 ; fnum--) {
35: mp3.playFileByIndexNumber(fnum);
36: delay(3000);
37: }
38: }
39:

注)7,8,9行目の #includeの後に <***.h>で記述した場合、
  <***.h>ごと消える現象が有るため、"***.h"で表示しています。

未だ未確認な点が多くあり、上記内容に誤った解釈が有るか判りませんが、
取り敢えず動作させた所までを備忘録として残します。

 

 

 

 


ArduinoでRC可動戦車(2)スケッチ

2020-07-21 23:18:33 | Arduino

ArduinoでRC可動戦車(2)のスケッチが、上手く動かないとの事で、
確認したところ、一部が欠落していました。
訂正しても、上手く書き換わってくれないので、こちらに改めて表記しました。

 

 

// PS3BT_arduino_battle_tank_2dcmotor
#include <AFMotor.h>
#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif

USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます

//モーターシールドの3,4のモーターを使用する
AF_DCMotor motor3(3, MOTOR12_64KHZ); //右側モータ
AF_DCMotor motor4(4, MOTOR12_64KHZ); //左側モータ

int pos_y;
int pos_x;
int motor_sp;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 0; //超低速

void setup() {
  Usb.Init();
  Serial.begin(115200);
  while (!Serial); // シリアルポートが接続するのを待つ
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));

  motor3.run(RELEASE);
  motor4.run(RELEASE);
}

void loop() {
  Usb.Task();
  if (PS3.PS3Connected) {
    //スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
    //左スティック上下の値(最上部0、中央127、最下部255)を読み込む
    pos_y = PS3.getAnalogHat(LeftHatY);
    pos_x = PS3.getAnalogHat(LeftHatX);

    //左スティックがセンター付近は停止
    if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
      motor3.setSpeed(0);
      motor3.run(RELEASE);
      motor4.setSpeed(0);
      motor4.run(RELEASE);
    }

    //前進
    else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
      //左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
      motor_sp = map(pos_y, 137, 0, 0, 255);
      motor3.setSpeed(motor_sp);
      motor3.run(FORWARD);
      motor4.setSpeed(motor_sp);
      motor4.run(FORWARD);
    }

    //後進
    else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
      motor_sp = map(pos_y, 137, 255, 0, 255);
      motor3.setSpeed(motor_sp);
      motor3.run(BACKWARD);
      motor4.setSpeed(motor_sp);
      motor4.run(BACKWARD);
    }

    //前進右旋回
    else if ( pos_y < 117 && pos_x > 137) {
      motor_sp = map(pos_y, 117, 0, 0, 255);
      motor3.setSpeed(motor_sp0);
      motor3.run(FORWARD);
      motor4.setSpeed(motor_sp);
      motor4.run(FORWARD);
    }

    //前進左旋回
    else if ( pos_y < 117 && pos_x < 117) {
      motor_sp = map(pos_y, 117, 0, 0, 255);
      motor3.setSpeed(motor_sp);
      motor3.run(FORWARD);
      motor4.setSpeed(motor_sp0);
      motor4.run(FORWARD);
    }

    //後進右旋回
    else if ( pos_y > 137 && pos_x > 137) {
      motor_sp = map(pos_y, 137, 255, 0, 255);
      motor3.setSpeed(motor_sp0);
      motor3.run(BACKWARD);
      motor4.setSpeed(motor_sp);
      motor4.run(BACKWARD);
    }

    //後進左旋回
    else if ( pos_y > 137 && pos_x < 117) {
      motor_sp = map(pos_y, 117, 0, 0, 255);
      motor3.setSpeed(motor_sp);
      motor3.run(BACKWARD);
      motor4.setSpeed(motor_sp0);
      motor4.run(BACKWARD);
    }

    //右超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {

      motor3.setSpeed(motor_sp1);
      motor3.run(BACKWARD);
      motor4.setSpeed(motor_sp1);
      motor4.run(FORWARD);
    }

    //左超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {

      motor3.setSpeed(motor_sp1);
      motor3.run(FORWARD);
      motor4.setSpeed(motor_sp1);
      motor4.run(BACKWARD);
    }
  }
}


ArduinoとPS4コントローラで戦車を動かす

2019-07-10 10:07:09 | Arduino

2019-07-10
追記する事が有ったのでブログを更新しました。

ペアリング完了(BTドングルのMACアドレスをPS4コントローラに書き込み)後に、スケッチの下記の部分を書き換えることで、次回からのPSボタンのみで起動が出来る様になります。

  【変更前】
/* You can create the instance of the PS4BT class in two ways */
// This will start an inquiry and then pair with the PS4 controller - you only have to do this once
// You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode
PS4BT PS4(&Btd, PAIR);
// After that you can simply create the instance like so and then press the PS button on the device
//PS4BT PS4(&Btd);
 
  【変更後】
/* You can create the instance of the PS4BT class in two ways */
// This will start an inquiry and then pair with the PS4 controller - you only have to do this once
// You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode
//PS4BT PS4(&Btd, PAIR);
// After that you can simply create the instance like so and then press the PS button on the device
PS4BT PS4(&Btd);
 
しかし、これではBTドングルとPS4コントローラがひも付きで1対1になります。
私はコントローラ1台で複数のBTドングルとペアリングしたいので、面倒でも起動はSHAREボタンとPSボタンを同時でペアリングする様にしています。


2019-07-08
これまでPS3コントローラを使ってArduinoで模型戦車を動かしてきました。
しかし、PS3コントローラとArduinoのペアリングには最初にUSBケーブルでコントローラとUSBシールドを接続してBluetoothドングル(以下BTドングル)のMACアドレスをPS3コントローラに書き込む必要が有ります。
この為、複数の戦車に対してはBT
ドングルを差し替えて使用する事になります。
BT
ドングルを差し替えるのはかなり面倒で、戦車毎にBTドングルとコントローラを持つことになります。 

【備忘録】
 BTトングルのMACアドレスはシリアルモニタでArduino IDEのシリアルモニタで確認できます。
 その準備としてsetting.hの一部を書き換えておく必要が有ります。

 1. librariesフォルダ内のUSB_Host_Shield_Library_2.0フォルダへ移動

 2. settings.h をテキストエディタで開く
 3. ENABLE_UHS_DEBUGGING の値を 0から1 に変更する。

////////////////////////////////////////////////////////////////////////////////
// DEBUGGING
////////////////////////////////////////////////////////////////////////////////
/* Set this to 1 to activate serial debugging */
#define ENABLE_UHS_DEBUGGING 0 ←この0を1に書き換える
 
 4. SHAREボタンとPSボタンを同時してペアリングをさせます。
  確認出来たら、0に戻しておくこと。
   1のままだとプログラムを書き込んだ時にメモリー量が大幅に増加します。

 


PS4コントローラの場合は、この工程が要らない様なので試してみます。

先ず、PS4コントローラを手に入れます。
PS3コントローラはAmazonで1500円程度で互換品が手に入りますが、PS4コントローラは互換品でも倍以上です。
それならばと言う事で、互換品とほぼ同価格の純正品の中古を手配しました。

Arduino IDEで以前作成したスケッチ(プログラム)のPS3BTに関わる部分をPS4BTに書き換えます。
プログラム容量は殆ど変化しないので、私のスケッチでも使えそうです。

コントローラとArduinoに接続したUSBシールドとペアリングの方法は、
1. SHAREボタンとPSボタンを同時に3秒ほど押す。
2. コントローラのインジケータが白く高速点滅し、ペアリング完了すると青色点灯して操縦可能になります。

次に2台目の戦車とのペアリングの確認をします。
その前に1台目の戦車の電源を切り、PS4コントローラの青色点灯が消灯するまで待ちます。
準備が出来たら、2台目の戦車を起動して、PS4コントローラのSHAREボタンとPSボタンを同時押しして白く高速点滅させます。
暫くすると、青色点灯に変わりペアリングが成功し操縦可能になります。
上手くペアリングできないときは、先にPS4コントローラをペアリングモード(白色高速点滅)にしてから戦車の電源を入れると上手くいく場合が有ります。

一度、ペアリングできると次からのペアリング開始までの時間は短くなります。

動画では青色点灯が白っぽく映っています。

 

 

 

 

 


RC可動戦車 【番外編】 Arduino スティックVRのカーブ

2019-06-03 14:10:31 | Arduino
PS3コントローラのスティックを操作して戦車の速度制御をしていますが、
微速走行し易くする改良を試みます。
スティックのVRはBカーブだと思われるので、Aカーブにしたいと思います。
VRを取り換える以外の方法を考えていましたが、Arduinoのスケッチで何とかしたいです。
 
PS3コントローラの左スティックの値を読み取り、モータ速度に変換しています。
 
Arduino関数:map(value, fromLow, fromHigh, toLow, toHigh) 
       value: 変換したい数値 
       fromLow: 現在の範囲の下限 
       fromHigh: 現在の範囲の上限 
       toLow: 変換後の範囲の下限 
       toHigh: 変換後の範囲の上限 

一例として、中央(127)から最上部(0)の値をモータースピード0から255に変換しています。
(但し、中央部分の±10は読み取らせていないので、127ではなく117にしています。)
 motor_speed = map(pos_y, 117, 0, 0, 255);
 
これを下記の様に変更します。
 motor_speed = map(pow(pos_y,2), 13689, 0, 0, 255);
(補足)pow(pos_y,2)はpos_yの2乗、 13689は117の2乗。
2乗して扱う事で疑似Aカーブにします。
 
この理論で実際に試してみます。
結果は。。。。
 


RC可動戦車 【番外編】 Arduinoメモリ不足対策

2019-05-21 10:40:29 | Arduino

2019-05-21
これまで製作したRC可動戦車のArduinoのスケッチ(プログラム)がメモリー容量ギリギリで不安定動作をすることが有り、対応策を検討しています。
今回のブログはArduino初心者の開発の覚書であり、あまり参考にはならないかもしれません。

対策1. スケッチサイズをコンパクトにする。
工夫してみましたが、私の知識ではこれ以上のダウンサイジングは難しいです。

対策2. メモリ容量の大きいArduinoを使う。
1/35スケールの戦車に内蔵する前提で対策2ができるArduinoは知りません。
Arduino Mega 2560では形状サイズが大きすぎます。

対策3. 作業を分割する。
Arduinoを2台使い、シリアル通信で相互データをやり取りして、作業分割を実施する。
通信方法はいろいろありそうですが、簡単な方法で試してみます。

概略:
 メインユニット:PS3コントローラの命令を受信して、モータ、LEDを動作させる。
 サブユニット :赤外線発光LED、受光素子にてIRバトルの発光、受光をする。
         MP3プレーヤーで効果音発生をする。
 ArduinoのRX、TXピンで両者間の通信をシリアルで実施。
 当然ですが、双方のデータ転送速度は揃えておきます。(9600bpsにしました)
 手持ちのArduinoの都合から、5Vと3.3VのPro Miniを使用するため、電圧レベル整合が必要です。
 通常はレベル変換モジュールなどを介入させるのでしょうが、簡略的に2KΩの抵抗を入れて接続しました。
 これはDFplayerとの通信ラインに1kΩを挿入する方法で実績が有ります。

 追加仕様:エンジン始動音、アイドリング音を発生。
      走行時のエンジン音などは、音源を取得出来ていないので見送り。
      今回、アイドリング音発生のためにリピート再生をさせるのでDFplayerのライブラリーを変更。
      DFPlayer_Mini_Mp3.hでは上手くリピート再生できなかったので、DFRobotDFPlayerMini.hに変更。
      DFRobotDFPlayerMini.hの方が使用するメモリサイズが大きいが、今回はゆとりが出来たので採用。

 

 

 



 


Arduinoをはじめよう(小型化2)

2018-12-01 01:43:54 | Arduino

2018-11-30
プログラムサイズはIDEの環境を再セットアップしたところサイズダウンできました。
赤外線受信も何とか実装して、童友社のバトルタンクJRをバトルが出来るようになりました。

【赤外線バトル信号送信機能付きArduino NANOのスケッチ】 

/*
PS3BT_arduino_NANO_tank_TB6612_FIRE_IR_D5RB
モータドライバはTB6612
A4ピンでサーボモータ(砲身上下)を動かす
A5ピンでサーボモータ(砲塔旋回)を動かす 連続回転改造サーボ
砲撃時のリコイルアクション
A1,A2,A3ピンでLED点灯
irremote PIN3 赤外線発光(砲撃)システム
A0ピンに赤外線受光モジュール出力を接続し、被弾処理を追加
最大30720バイトのフラッシュメモリのうち、スケッチが26886バイト(87%)を使っています。
最大2048バイトのRAMのうち、グローバル変数が1342バイト(65%)を使っていて、ローカル変数で706バイト使うことができます。
PWM速度制御していなかったのを訂正。 後進系は1/2速度
*/

#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
//#include <Usb.h> // needed by Arduino IDE

USB Usb;
BTD Btd(&Usb);
PS3BT PS3(&Btd);
//PS3BT PS3(&Btd, 0x00, 0x1B, 0xDC, 0xF2, 0x54, 0x32); //for Dongke A
/*シリアルモニタにBluetooth DongleのアドレスがSerial.printされる。
書き出された6個のコードをスケッチを変更し、
ドングルを指した状態でArduinoに書き込む(電源は切らない)
ドングルを抜いてUSBケーブルでPS3コントローラを接続する(電源は切らない)
ケーブルを抜いてドングルを指し直す(Arduinoを再起動する)
PS3コントローラのPS ボタンを押してペアリングする。
*/

#include <IRremote.h>
IRsend irsend;
int RECV_PIN = A0 ; //赤外線受光部をPIN A0に
IRrecv irrecv(RECV_PIN);
decode_results results; //受信信号を格納する
const long sign_hit = 0x4CB0FADD;
int cnt = 0 ;

//#include <Servo.h>
//Servo myservo;
#include <VarSpeedServo.h>
VarSpeedServo myservo;
VarSpeedServo myservo_1;
int servo_pos = 90;
const int servo_sp = 50;
const int servo1_sp = 50;
const int d_time = 20;
int ch = 0;
int val = 0;
int pos_y;
int pos_x;
int pos_ry;
int pos_rx;
int PWMA = 5; // Aモータ PWM 左側モータ
int AIN1 = 4; // Aモータ IN1 ( 9ピンはUSBホストシールド使用
int AIN2 = 2; // Aモータ IN2
int BIN1 = 8; // Bモータ IN1
int BIN2 = 7; // Bモータ IN2
int PWMB = 6; // Bモータ PWM 右側モータ( 10ピンはUSBホストシールド使用

int motor_speed;
//int motor_sp; //モータスピード  max=255

//const int LED_1 = A1; //主砲 D3にLED_IRとパラ接続
const int LED_2 = A2; //機銃
const int LED_3 = A1 ; //ブレーキランプ
//const int LED_4 = ; //主砲準備中
const int LED_8 = A3; //ヘッドランプ
const int SVCH1 = A4; //servo 1
const int SVCH2 = A5; //servo 2

void setup() {
irrecv.enableIRIn(); // Start the receiver
pinMode(RECV_PIN, INPUT) ; // 赤外線受信モジュールに接続ピンをデジタル入力に設定
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
// pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
// pinMode(LED_4, OUTPUT);
pinMode(LED_8, OUTPUT);
pinMode(SVCH1, OUTPUT);
pinMode(SVCH2, OUTPUT);
myservo.attach(SVCH1); //servo1 砲身上下
myservo.write(servo_pos);
myservo_1.attach(SVCH2); //servo2 砲塔旋回
myservo_1.write(servo_pos);

Serial.begin(115200);
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1); //halt
}
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}

void loop() {
Usb.Task();
if (irrecv.decode(&results)) { // 受信コードの値が
if (results.value == sign_hit) { // 0x4CB0FADDだったら被弾
Serial.println("HIT!");
Hit();
}
irrecv.resume();
}

if (PS3.PS3Connected) {
//スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
//左スティック上下の値(最上部0、中央127、最下部255)を読み込む
pos_y = PS3.getAnalogHat(LeftHatY);
pos_x = PS3.getAnalogHat(LeftHatX);
pos_ry = PS3.getAnalogHat(RightHatY);
pos_rx = PS3.getAnalogHat(RightHatX);

/*
砲身 UP/DOWN
スティックが下(20未満)の時は1ずつ下に動く。
スティックが上(235より上)の時1ずつ上に動く。
スティックを中間に戻すと、サーボはその位置で停止。
ボタン(SQUARE)を押すと90°にセット。
*/
if (pos_ry > 235 && servo_pos < 179 ) { // UP
servo_pos++;
myservo.write(servo_pos, servo_sp, true);

} else if (pos_ry < 20 && servo_pos > 1 ) { //DOWN
servo_pos--;
myservo.write(servo_pos, servo_sp, true);

} else if (PS3.getButtonClick(SQUARE)) { //90°
servo_pos = 90;
myservo.write(servo_pos, servo_sp, true);
// delay(d_time);
}

//砲塔旋回
if (pos_rx > 235) { //右旋回
myservo_1.write(0, servo1_sp);

} else if (pos_rx < 20) { //左旋回
myservo_1.write(180, servo1_sp);

} else { //停止
myservo_1.write(90, servo1_sp);
}
//delay(d_time);

//砲撃 + リコイル
if (PS3.getButtonClick(R1) && ch == 0 ) {
int khz = 38; // 38kHz carrier frequency for the NEC protocol
unsigned int irSignal[] = {4100, 1000, 2000, 2050, 1000}; // vs BATTLE TANK jr T-72 40MHz
// AnalysIR Batch Export (IRremote) - RAW
irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);

irrecv.enableIRIn(); // 受信を再開する  

//digitalWrite(LED_1, HIGH);
motor_run(255, 0, 1, 0, 1, 1);
ch = 20000; //約5秒間は砲撃不可
delay(70);

motor_run(0, 0, 0, 0, 0, 1);
delay(20);

//digitalWrite(LED_1, LOW);
motor_run(255, 1, 0, 1, 0, 1);
delay(130);
} else {
if (ch > 0) {
ch--;
// digitalWrite(LED_4, HIGH); //装填中
} else {
// digitalWrite(LED_4, LOW); //砲撃可
}
}

//銃撃
if ( PS3.getButtonClick(L1)) {
for ( int i = 0; i < 5 ; i++) {
val++;

digitalWrite(LED_2, HIGH);
delay(50);
digitalWrite(LED_2, LOW);
delay(50);
}
}

//ヘッドライト
if (PS3.getButtonClick(RIGHT)) { //点灯
digitalWrite(LED_8, HIGH);
}

if (PS3.getButtonClick(LEFT)) { //消灯
digitalWrite(LED_8, LOW);
}


//左スティックがセンター付近は停止(ブレーキ)
if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
motor_run(0, 1, 1, 1, 1, 1);
}

//前進
else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
//左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
motor_speed = map(pos_y, 117, 0, 0, 255);
motor_run(motor_speed, 1, 0, 1, 0, 0);
}

//後進
else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
motor_speed = map(pos_y, 137, 255, 0, 255);
motor_speed = motor_speed / 2;
motor_run(motor_speed, 0, 1, 0, 1, 0);
}

//前進右旋回
else if ( pos_y < 117 && pos_x > 137) {
motor_speed = map(pos_y, 117, 0, 0, 255);
//motor_speed = motor_speed / 2;
motor_run(motor_speed, 1, 0, 0, 0, 0);
}

//前進左旋回
else if ( pos_y < 117 && pos_x < 117) {
motor_speed = map(pos_y, 117, 0, 0, 255);
//motor_speed = motor_speed / 2;
motor_run(motor_speed, 0, 0, 1, 0, 0);
}

//後進右旋回
else if ( pos_y > 137 && pos_x > 137) {
motor_speed = map(pos_y, 137, 255, 0, 255);
motor_speed = motor_speed / 2;
motor_run(motor_speed, 0, 1, 0, 0, 0);
}

//後進左旋回
else if ( pos_y > 137 && pos_x < 117) {
motor_speed = map(pos_y, 137, 255, 0, 255);
motor_speed = motor_speed / 2;
motor_run(motor_speed, 0, 0, 0, 1, 0);
}

//右超信地旋回
else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
motor_speed = map(pos_x, 137, 255, 0, 255);
motor_speed = motor_speed / 2;
motor_run(motor_speed, 1, 0, 0, 1, 0);
}

//左超信地旋回
else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
motor_speed = map(pos_x, 117, 0, 0, 255);
motor_speed = motor_speed / 2;
motor_run(motor_speed, 0, 1, 1, 0, 0);
}
}
}

void motor_run(int D0, int D1, int D2, int D3, int D4, int D5) {
/* D0 : モータスピード
D1 : モータA(左)CH1 , D2 : モータA(左)CH2 1 = HIGH / 0 = LOW
D3 : モータB(右)CH1 , D4 : モータB(右)CH2 1 = HIGH / 0 = LOW
D5 : LED_3 ON/OFF 1 = HIGH / 0 = LOW
*/
analogWrite(PWMA, D0);
analogWrite(PWMB, D0);
digitalWrite(AIN1, D1);
digitalWrite(AIN2, D2);
digitalWrite(BIN1, D3);
digitalWrite(BIN2, D4);
digitalWrite(LED_3, D5);
}


// ====被弾====
void Hit() {
motor_run(255, 0, 1, 0, 1, 0);
delay(100);
motor_run(0, 1, 1, 1, 1, 1);
delay(50);
motor_run(160, 1, 0, 1, 0, 0);
delay(80);
motor_run(0, 1, 1, 1, 1, 1);
delay(50);

cnt++;
if ( cnt >= 5 ) {
motor_run(0, 1, 1, 1, 1, 0);
delay(10000);
cnt = 0;
} else {
delay(1000);
}
}

 


モータードライバICアールエスコンポーネンツのオンライン販売サイトでも購入できます。
規格ごとに検索ソートがかけられ商品選択がしやすく、業者価格での部品購入が可能です。 


 

2018-11-16
前回の(小型化1)から2週間経過している。
その間、MEGA搭載戦車の赤外線バトルシステムの実験やNANO+サーボドライバPCA9685のテストをしました。

左からArduino MEGA、UNO、NANOです。

先日、発注していたミニUSBホストシールドがお届け予定日から2日遅れではあるが2週間で深川から届きました。
早速、ユニバーサル基板にヘッダーを取付け配線をします。
数ヶ所迷うところが有りますが、ネットなどで情報を入手しながら進めます。
ミニUSBホストシールドはArduino Pro Miniとは結合が良いのですが、NANOにはプラグインできず配線する必要が有りました。

 

デジタルPINが足りません。
PIN D3は赤外線発光用にリザーブ
PIN D2,D4~D8は2個のDCモータのPWM制御用に使います。
PIN D9~D13はミニUSBホストシールドで使います。
2個のサーボモータと、6個のLEDはサーボドライバPCA9685で動かす予定でしたが、小型化のためPCA9685は使うのを見送ります。
従ってLEDと、赤外線受光モジュールの信号入力ピンが足りません。

なんて、ずっと悩んでいましたが、解決方法をネットで発見しました。
テキスト「Arduinoをはじめよう」にも182頁に〔補足〕として書かれていました。
アナログ入力ピンをデジタルピンとして使えます。

早速、回路を組み、スケッチを書いて確認します。
使えました。
これで、何とかなりそうです。

Arduino NANO + ミニUSB ホストシールド + モータドライバ 接続回路図です。
赤外線受光部は未取付けです。

組み立てたものを比較してみます。
床面積的には同じくらいでしょうか。
以前のタイプが3階建てでしたが、今回は平屋なので高さは抑えることが出来ました。

画像左側がコンパクト化したArduino NANO版です。

赤外線受光モジュールを組み込み、被弾処理をするスケッチも書きましたが、スケッチのサイズが許容量の10%オーバーと言う事で実行できませんでした。
赤外線受光システム無しだと、「最大30720バイトのフラッシュメモリのうち、スケッチが27878バイト(90%)を使っています。」で、何とかクリアー。
MEGAはフラッシュメモリのサイズが8倍有るため実行できますが、UNOやNANO等では難しいです。



一部追記 2019-11-07


Arduinoをはじめよう(小型化1)

2018-11-13 16:33:31 | Arduino

2018-10-31
Arduino NANOが届いた。
ELEGOO製が3個で1,450円。
同社のUNO R3 ボードは1,100円。
サイズは1/3程度、価格は1/2程度。
助かります。(使いこなせれば。。。。。)

早速、1個を組立て(ピンヘッダを基板にはんだ付けするだけ)、「Lチカ」のスケッチを書き込みます。

???書き込めない。
エラーメッセージが、

ネットで調べると、
「ツール」→「プロセッサ」→「【ATmega328P】を【ATmega328P(Old Bootloader)】に設定変更すると書ける。」との事。
やってみる。
その通りでした。

そして、スケッチを書き込んで動作確認。
ここまではOK

 


ArduinoでRC可動戦車(8)

2018-11-09 12:25:20 | Arduino

2018-11-09
Arduino MEGA 2560を入手できたので、LED出力をPIN22以降に移設します。
サーボ出力もPIN46に移設。
更に砲塔旋回用のサーボをPIN44に接続。
砲塔旋回用サーボは連続回転するように改造済みです。

新たに、赤外線バトルシステムの導入を模索。
赤外線リモコンの値を読み取り、送信する方法に関して、ネットの記事などを参考に試行錯誤してみます。
手持ちのアオシマのVSタンクは難しいですが、童友社のバトルタンクJRの信号はなんとか処理できました。
使用するライブラリーはIRremoteです
読み取ったコードをスケッチに組み込み、実験してみたところ上手く動いてくれました。

IRremoteは、UNOでは赤外線LEDを接続するのはPIN3が指定ですが、MEGAでは上手く作動しません。
解決策を探していると、PIN9でいけそうな情報を入手。
PIN9はUSBシールドと干渉する可能性があるが、試してみたところ支障なく動作します。

これでバトルタンク試作で確認したかったことは、ほぼ出来ました。
今後は小型化に挑戦して、1/35スケールの戦車に搭載したいです。

Arduino PS3 Bluetooth controlled tank ver.5

【赤外線バトル信号送信機能付きArduino MEGA 2560のスケッチ】 

/*
PS3BT_arduino_MEGA2560_tank_2dcmotor_TB6612_FIRE_IR_D
モータドライバはTB6612
46ピンでサーボモータ(砲身上下)を動かす
44ピンで連続回転サーボモータ(砲塔旋回)を動かす
砲塔旋回モータを追加
砲撃時のリコイルアクション+LED点灯、銃撃時のLED点滅(5回)の機能を追加
IRremote(MEGAはPIN9, UNOその他はPIN9)で赤外線対戦システムを組込(砲撃のみ)
*/

#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <Usb.h> // needed by Arduino IDE

#include <IRremote.h>
IRsend irsend;

//#include <Servo.h>
//Servo myservo;
#include <VarSpeedServo.h>
VarSpeedServo myservo;
VarSpeedServo myservo_1;
int servo_pos = 90;
const int servo_sp = 50;
const int servo1_sp = 50;
const int d_time = 20;
int ch = 0;
int val = 0;
int pos_y;
int pos_x;
int PWMA = 5; // ← 11 Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9 Aモータ IN1 ( 9ピンはUSBホストシールド使用
int AIN2 = 2; // ← 8 Aモータ IN2
int BIN1 = 8; // ← 7 Bモータ IN1
int BIN2 = 7; // ← 6 Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ( 10ピンはUSBホストシールド使用

int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 255; //超高速

const int LED_1 = 22; //主砲
const int LED_2 = 24; //機銃
const int LED_3 = 26; //ブレーキランプ
const int LED_4 = 28; //主砲準備中
const int LED_8 = 36; //ヘッドランプ

USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます

void setup() {
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(PWMB, OUTPUT);
pinMode(LED_1, OUTPUT);
pinMode(LED_2, OUTPUT);
pinMode(LED_3, OUTPUT);
pinMode(LED_4, OUTPUT);
pinMode(LED_8, OUTPUT);

myservo.attach(46); //servo ピン46 (9-11ピンは使えない。)
myservo_1.attach(44); //servo_1 ピン44
myservo.write(servo_pos);
myservo_1.write(servo_pos);
Serial.begin(115200);
while (!Serial); // Wait for serial port to connect - used on Leonardo,
Teensy and other boards with built-in USB CDC serial connection
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1); //halt
}
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}

void loop() {
Usb.Task();
if (PS3.PS3Connected) {
//スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
//左スティック上下の値(最上部0、中央127、最下部255)を読み込む
pos_y = PS3.getAnalogHat(LeftHatY);
pos_x = PS3.getAnalogHat(LeftHatX);

/*
砲身 UP/DOWN
スティックが下(20未満)の時は1ずつ下に動く。
スティックが上(235より上)の時1ずつ上に動く。
スティックを中間に戻すと、サーボはその位置で停止。
ボタン(SQUARE)を押すと90°にセット。
*/
if ((PS3.getAnalogHat(RightHatY) > 235) && (servo_pos < 179 )) { // UP
servo_pos++;
myservo.write(servo_pos, servo_sp, true);
} else if ((PS3.getAnalogHat(RightHatY) < 20) && (servo_pos > 1 )) { //DOWN
servo_pos--;
myservo.write(servo_pos, servo_sp, true);
} else if (PS3.getButtonClick(SQUARE)) { //90°
servo_pos = 90;
myservo.write(servo_pos, servo_sp, true);
delay(d_time);
}

//砲塔旋回 (連続回転サーボ) loop処理の関係で停止まで最大1回転する
if (PS3.getAnalogHat(RightHatX) < 137 && PS3.getAnalogHat(RightHatX) > 117) { //停止
myservo_1.write(90, servo1_sp);
} else if (PS3.getAnalogHat(RightHatX) > 235) { //右旋回
myservo_1.write(0, servo1_sp);
} else if (PS3.getAnalogHat(RightHatX) < 20) { //左旋回
myservo_1.write(180, servo1_sp);
}

//砲撃 + リコイル動作 + 赤外線砲撃信号発光
if (PS3.getButtonClick(R1) && ch == 0 ) {
int khz = 38; // 38kHz carrier frequency for the NEC protocol
unsigned int irSignal[] = {4068, 1028, 2024, 2088, 964}; // vs BATTLE TANK jr T-72 40MHz
/* unsigned int irSignal[] = {4048,1068,2048,2008,1044};
vs BATTLE TANK jr エイブラムス 27MHz
AnalysIR Batch Export (IRremote) - RAW
*/
irsend.sendRaw(irSignal, sizeof(irSignal) / sizeof(irSignal[0]), khz);

Serial.println("FIRE");
digitalWrite(LED_1, HIGH);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_sp0);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_sp0);
ch = 20000; //約5秒間は砲撃不可
delay(70);

digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 0);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMA, 0);
delay(20);

digitalWrite(LED_1, LOW);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_sp1);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_sp1);
delay(130);
} else {
if (ch > 0) {
ch--;
digitalWrite(LED_4, HIGH); //装填中
} else {
digitalWrite(LED_4, LOW); //砲撃可
}
}

//銃撃
if ( PS3.getButtonClick(L1)) {
for ( int i = 0; i < 5 ; i++) {
val++;
Serial.print("L1 : ");
Serial.println(PS3.getButtonClick(L1));
Serial.println("DA ");
Serial.println(val);
digitalWrite(LED_2, HIGH);
delay(50);
digitalWrite(LED_2, LOW);
delay(50);
Serial.println("");
}
}

//ヘッドライト
if (PS3.getButtonClick(RIGHT)) { //点灯
digitalWrite(LED_8, HIGH);
} else if (PS3.getButtonClick(LEFT)) { //消灯
digitalWrite(LED_8, LOW);
}

//左スティックがセンター付近は停止(ブレーキ)
if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, 0);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
analogWrite(PWMA, 0);
digitalWrite(LED_3, HIGH); //ブレーキランプ点灯
}

//前進
else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
//左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
digitalWrite(LED_3, LOW);
}

//後進
else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
motor_speed = map(pos_y, 137, 255, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_speed);
digitalWrite(LED_3, LOW);
}

//前進右旋回
else if ( pos_y < 117 && pos_x > 137) {
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
digitalWrite(LED_3, LOW);
}

//前進左旋回
else if ( pos_y < 117 && pos_x < 117) {
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
digitalWrite(LED_3, LOW);
}

//後進右旋回
else if ( pos_y > 137 && pos_x > 137) {
motor_speed = map(pos_y, 137, 255, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
digitalWrite(LED_3, LOW);
}

//後進左旋回
else if ( pos_y > 137 && pos_x < 117) {
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_speed);
digitalWrite(LED_3, LOW);
}

//右超信地旋回
else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_sp1);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_sp1);
digitalWrite(LED_3, LOW);
}

//左超信地旋回
else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_sp1);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_sp1);
digitalWrite(LED_3, LOW);
}
}
}

ArduinoでRC可動戦車(6)

2018-11-05 21:03:58 | Arduino

2018-11-04
arduinoでサーボの使い方(プログラミング)が上手くいかなかったが、やっと思ったように動くようになった。
以下、考えに誤りがあるかもしれませんが、改善した内容を記録します。

【改善前】

    if (PS3.getAnalogHat(RightHatY) < 20) {                      // UP
      for ( servo_pos; servo_pos < 180; servo_pos++) {
        myservo.write(servo_pos, servo_sp, true);
      }
    }

  スティックを上下に倒すとサーボが回転し、離すと止まる様にしたいが、
  このスケッチだと、for文が実行中はスティックを戻しても
  (PS3.getAnalogHat(RightHatY))の値は125にならず20未満のまま。
  for文の中でスティック情報を読み取る様にしても、
  for文が実行中はスティックの値が変化せず、スティックを戻しても止まらない。

【改善後】 for文をやめ、loop1回ごとでカウントup/downをする様に変更。

    if ((PS3.getAnalogHat(RightHatY) < 20) && (servo_pos < 179 )) {  // UP
      servo_pos++;
      myservo.write(servo_pos, servo_sp, true);
    }
 
    if ((PS3.getAnalogHat(RightHatY) > 235) && (servo_pos > 1 )) {  //DOWN
      servo_pos--;
      myservo.write(servo_pos, servo_sp, true);
    }
 
    if (PS3.getButtonClick(SQUARE)) {                   //90°
      servo_pos = 90;
      myservo.write(servo_pos, servo_sp, true);
      delay(d_time);
    }
 
 

【今後の課題】

1. 現状ではアナログ出力の制限から砲塔旋回はDCモータの設定だが、できればサーボで動かすようにしたい。

2. 1/35 戦車模型に組み込むには小型化が必須。

 

【現時点の最新スケッチ】  

/*
PS3BT_arduino_tank_2dcmotor_TB6612_FIRE_C2
モータドライバはTB6612
3ピンでサーボモータ(砲身上下)を動かす Ver.3
砲塔旋回モータを追加
砲撃時のリコイルアクション+LED点灯、銃撃時のLED点滅(5回)の機能を追加
出力8本のGPIOを使用し、LED点灯をさせる
*/

#include
#include
#ifdef dobogusinclude
#include
#endif
#include // needed by Arduino IDE
#include
MaxGPIO max;
//#include
//Servo myservo;
#include
VarSpeedServo myservo;
int servo_pos = 90;
const int servo_sp = 50;
const int d_time = 20;
int ch = 0;
int val = 0;
int pos_y;
int pos_x;
int PWMA = 5; // ← 11 Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9 Aモータ IN1 ( 9ピンはUSBホストシールド使用
int AIN2 = 2; // ← 8 Aモータ IN2
int BIN1 = 8; // ← 7 Bモータ IN1
int BIN2 = 7; // ← 6 Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ ( 10ピンはUSBホストシールド使用

int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 255; //超高速

USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます

void setup() {
pinMode(PWMA, OUTPUT);
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(PWMB, OUTPUT);

myservo.attach(3); //servo1 ピン3 (9-11ピンは使えない)
myservo.write(servo_pos);

Serial.begin(115200);
while (!Serial); // Wait for serial port to connect - used on Leonardo,
Teensy and other boards with built-in USB CDC serial connection
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while (1); //halt
}
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}

void loop() {
Usb.Task();
if (PS3.PS3Connected) {
//スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
//左スティック上下の値(最上部0、中央127、最下部255)を読み込む
pos_y = PS3.getAnalogHat(LeftHatY);
pos_x = PS3.getAnalogHat(LeftHatX);

/*
砲身 UP/DOWN
スティックが下(20未満)の時は1ずつ下に動く。
スティックが上(235より上)の時1ずつ上に動く。
スティックを中間に戻すと、サーボはその位置で停止。
ボタン(SQUARE)を押すと90°にセット。
*/
if ((PS3.getAnalogHat(RightHatY) < 20) && (servo_pos < 179 )) { // UP
servo_pos++;
myservo.write(servo_pos, servo_sp, true);
}

if ((PS3.getAnalogHat(RightHatY) > 235) && (servo_pos > 1 )) { //DOWN
servo_pos--;
myservo.write(servo_pos, servo_sp, true);
}

if (PS3.getButtonClick(SQUARE)) { //90°
servo_pos = 90;
myservo.write(servo_pos, servo_sp, true);
delay(d_time);
}

//砲塔旋回
if (PS3.getAnalogHat(RightHatX) > 235) { //右旋回
max.write(5, HIGH);
max.write(6, LOW);
} else if (PS3.getAnalogHat(RightHatX) < 20) { //左旋回
max.write(5, LOW);
max.write(6, HIGH);
} else { //停止
max.write(5, LOW);
max.write(6, LOW);
}

//砲撃
//リコイル
if (PS3.getButtonClick(R1) && ch == 0 ) {
Serial.println("FIRE");
max.write(0, HIGH);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_sp0);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_sp0);
ch = 20000; //約5秒間は砲撃不可
delay(70);

digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, 0);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMA, 0);
delay(20);

max.write(0, LOW);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_sp1);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_sp1);
delay(130);
} else {
if (ch > 0) {
ch--;
max.write(3, HIGH); //装填中
} else {
max.write(3, LOW); //砲撃可
}
}

//銃撃
if ( PS3.getButtonClick(L1)) {
for ( int i = 0; i < 5 ; i++) {
val++;
Serial.print("L1 : ");
Serial.println(PS3.getButtonClick(L1));
Serial.println("DA ");
Serial.println(val);
max.write(1, HIGH);
delay(50);
max.write(1, LOW);
delay(50);
Serial.println("");
}
}

//ヘッドライト
if (PS3.getButtonClick(RIGHT)) { //点灯
max.write(7, HIGH);
}

if (PS3.getButtonClick(LEFT)) { //消灯
max.write(7, LOW);
}

//左スティックがセンター付近は停止(ブレーキ)
if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, 0);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, HIGH);
analogWrite(PWMA, 0);
max.write(2, HIGH); //ブレーキランプ点灯
}

//前進
else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
//左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
max.write(2, LOW);
}

//後進
else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
motor_speed = map(pos_y, 137, 255, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_speed);
max.write(2, LOW);
}

//前進右旋回
else if ( pos_y < 117 && pos_x > 137) {
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
max.write(2, LOW);
}

//前進左旋回
else if ( pos_y < 117 && pos_x < 117) {
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
max.write(2, LOW);
}

//後進右旋回
else if ( pos_y > 137 && pos_x > 137) {
motor_speed = map(pos_y, 137, 255, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_speed);
max.write(2, LOW);
}

//後進左旋回
else if ( pos_y > 137 && pos_x < 117) {
motor_speed = map(pos_y, 117, 0, 0, 255);
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_speed);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_speed);
max.write(2, LOW);
}

//右超信地旋回
else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, motor_sp1);
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, motor_sp1);
max.write(2, LOW);
}

//左超信地旋回
else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, motor_sp1);
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, motor_sp1);
max.write(2, LOW);
}
}
}


ArduinoでRC可動戦車(5)

2018-10-31 00:19:01 | Arduino

2018-10-30
出力ピン不足で行き詰っていたら、ネットでUSBボスとシールドのGPIOが利用できることを知った。
早速、デジタル8個のデジタル出力を利用する。
前作に対して、Arduinoの3ピンはサーボ用に戻し、ヘッドライト、ストップランプ、砲撃、銃撃の4個のLEDを操作します。
因みに、このGPIOは3.3V出力なので注意が必要です。

Arduino PS3 Bluetooth controlled tank ver.3

 

【変更後のスケッチ】

/*
  PS3BT_arduino_tank_2dcmotor_TB6612_FIRE_A
  モータドライバはTB6612
  3ピンでサーボモータを動かす Ver.2
  砲撃時のリコイルアクション+LED点灯、銃撃時のLED点滅(5回)の機能を追加
  出力8本のGPIOを使用し、LED点灯をさせる
*/
#include
#include
#ifdef dobogusinclude
#include
#endif
#include // needed by Arduino IDE
#include
MaxGPIO max;
#include
Servo myservo;
int servo_pos = 90;
int val = 0;
int pos_y;
int pos_x;
int PWMA = 5; // ← 11  Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9  Aモータ IN1  ( 9ピンはUSBホストシールド使用
int AIN2 = 2; // ← 8  Aモータ IN2
int BIN1 = 8; // ← 7  Bモータ IN1
int BIN2 = 7; // ← 6  Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ ( 10ピンはUSBホストシールド使用
int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 255; //超高速
USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます
void setup() {
  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  myservo.attach(3); //servo1 ピン3  (9-11ピンは使えない)
  myservo.write(servo_pos);
  Serial.begin(115200);
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop() {
  Usb.Task();
  if (PS3.PS3Connected) {
    //スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
    //左スティック上下の値(最上部0、中央127、最下部255)を読み込む
    pos_y = PS3.getAnalogHat(LeftHatY);
    pos_x = PS3.getAnalogHat(LeftHatX);
    //砲撃
    //リコイル
    if (PS3.getButtonClick(R1) ) {
      Serial.println("FIRE");
      max.write(0, HIGH);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp0);
      delay(70);
      max.write(0, LOW);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
      delay(95);
    }

    //サーボ UP/DOWN
    if (PS3.getButtonClick(DOWN) ||
        PS3.getAnalogHat(RightHatY) > 137 ||
        PS3.getAnalogHat(RightHatY)
      servo_pos = (int)( ( (float)PS3.getAnalogHat(RightHatY) / 255.0f ) * 180.0f);
      myservo.write(servo_pos);
      delay(20);
    }
    if (PS3.getButtonClick(UP)) {
      myservo.write(0);
      delay(20);
    }
    if (PS3.getButtonClick(DOWN)) {
      myservo.write(255);
      delay(20);
    }
    //銃撃
    if ( PS3.getButtonClick(L1)) {
      for ( int i = 0; i < 5 ; i++) {</span>
        val++;
        Serial.print("L1 : ");
        Serial.println(PS3.getButtonClick(L1));
        Serial.println("DA ");
        Serial.println(val);
        max.write(1, HIGH);
        delay(50);
        max.write(1, LOW);
        delay(50);
        Serial.println("");
      }
    }
    //ヘッドライト
    if (PS3.getButtonClick(RIGHT)) {
      max.write(7, HIGH);
    }
    if (PS3.getButtonClick(LEFT)) {
      max.write(7, LOW);
    }

    //左スティックがセンター付近は停止
    if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
      analogWrite(PWMA, 0);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, 0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      max.write(2, HIGH);
    }
    //前進
    else if (pos_y < 117 && pos_x > 117 && pos_x
      //左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
      max.write(2, LOW);
    }
    //後進
    else if ( pos_y > 137 && pos_x > 117 && pos_x
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
      max.write(2, LOW);
    }
    //前進右旋回
    else if ( pos_y < 117 && pos_x > 137) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
      max.write(2, LOW);
    }
    //前進左旋回
    else if ( pos_y
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
      max.write(2, LOW);
    }
    //後進右旋回
    else if ( pos_y > 137 && pos_x > 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
      max.write(2, LOW);
    }
    //後進左旋回
    else if ( pos_y > 137 && pos_x
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
      max.write(2, LOW);
    }
    //右超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp1);
      max.write(2, LOW);
    }
    //左超信地旋回
    else if ( pos_y > 117 && pos_y
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
      max.write(2, LOW);
    }
  }
}
 

 

 

 

 

 
 

ArduinoでRC可動戦車(4)

2018-10-30 13:28:08 | Arduino

2018-10-29
砲撃時のリコイルアクション+LED点灯、銃撃時のLED点滅(5回)の機能を追加しました。
残念ながら、現在のシステムでは出力ピンの空きは3から9までの7個です。
DCモータ1個に+、-、PWMの3個が2セットで6個と、LEDに1個で残りゼロです。

砲塔旋回、砲身上下などの機能を追加するにはどうするか?

Arduino PS3 Bluetooth controlled tank ver.2

【使用パーツ】
1.Aruduino UNO R3(ELEGOO)
2.USBホストシールド 2.0 for Arduino(互換品)
3.KKHMF デュアル・モータードライバ モジュール TB6612FNG
4.DD昇圧コンバータ(IN:
DC3V / OUT:DC5V):100均モバイルバッテリから移植
 モータドライブ用電源に使用
5.Lipoバッテリ DC3.7V 350mAh(DD昇圧コンバータ用)
6.006Pアルカリ電池(Arduino外部電源用)
7.タミヤ タンク工作基本セット[70108]
8.タミヤ ツインモーターギヤーボックス [70097]
9.タミヤ ユニバーサルプレートセット [70098]

(注意)DC5Vコンバータ出力電流値は0.8A(実測)でした。
    100均のモバイルバッテリのDDコンバータの使用は自己責任です。

【直近の問題点】
1.006Pアルカリ電池はもったいないので、他の電源供給方法を検討したい。
 この電圧が6Vまで下がってくると暴走します。


2018-10-30
009Pアルカリ電池の代替案を実施。
容量不足で使わなかったDDコンバータを使い、同じ3.7VのLipoバッテリからモータ用とは別のコンバータで5Vを作成。
Arduino外部入力(Vin)へ接続します。(実測電流値0.1A以下)
コンバータを分けることで、モータ駆動時のラッシュ電流などで5Vが一瞬低下してArduinoが動作不良するのを回避します。
動作テストの結果も良好なので、この方法で解決です。(100μFコンデンサ実装だけでは回避できない)

 

【ver.2のスケッチ】

/*
  PS3BT_arduino_tank_2dcmotor_TB6612
  モータドライバはTB6612
  サーボモータを動かす Ver.2
*/
#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
const int LED = 3; //砲撃 LED 3ピン
int val = 0;
int pos_y;
int pos_x;
int PWMA = 5; // ← 11  Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9  Aモータ IN1  ( 9ピンはUSBホストシールド使用
int AIN2 = 2; // ← 8  Aモータ IN2
int BIN1 = 8; // ← 7  Bモータ IN1
int BIN2 = 7; // ← 6  Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ ( 10ピンはUSBホストシールド使用
int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 255; //超高速
USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます
void setup() {
  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(LED, OUTPUT);
  Serial.begin(115200);
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}
void loop() {
  Usb.Task();
  if (PS3.PS3Connected) {
    //スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
    //左スティック上下の値(最上部0、中央127、最下部255)を読み込む
    pos_y = PS3.getAnalogHat(LeftHatY);
    pos_x = PS3.getAnalogHat(LeftHatX);
    //砲撃
    //リコイル
    if (PS3.getButtonClick(R1) ) {
      Serial.println("FIRE");
      digitalWrite(LED, HIGH);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp0);
      delay(70);
      digitalWrite(LED, LOW);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
      delay(95);
    }
    //銃撃
    if ( PS3.getButtonClick(L1)) {
      for ( int i = 0; i < 5 ; i++) {
        val++;
        Serial.print("L1 : ");
        Serial.println(PS3.getButtonClick(L1));
        Serial.println("DA ");
        Serial.println(val);
        digitalWrite(LED, HIGH);
        delay(50);
        digitalWrite(LED, LOW);
        delay(50);
        Serial.println("");
      }
    }
    //左スティックがセンター付近は停止
    if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
      analogWrite(PWMA, 0);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, 0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
    }
    //前進
    else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
      //左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進
    else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //前進右旋回
    else if ( pos_y < 117 && pos_x > 137) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //前進左旋回
    else if ( pos_y < 117 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進右旋回
    else if ( pos_y > 137 && pos_x > 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進左旋回
    else if ( pos_y > 137 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //右超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp1);
    }
    //左超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
    }
  }
}


 
 

ArduinoでRC可動戦車(3)

2018-10-30 00:59:36 | Arduino
2018-10-27
モータドライバーを従来よく使っていたTB6612に変えます。
こちらの方が電圧降下が少なく、より低い電圧で扱えます。
実装はArduino用ユニバーサル基板を使い、積み重ねます。
入力は3.7V350mAHのLipoバッテリで、100均のモバイルバッテリの中身の昇圧コンバータで5Vを作ります。
 
モータドライブシールドを止めたので、スケッチを書き換えます。
特にUSBホストシールドが9ピンと10ピンを使っているので、競合しない様に他のピンに振り替えます。
この競合の事は知らなかったのですが、基板組立後の動作確認時に誤動作を繰り返すことから判りました。
 
【変更後のスケッチ】
// PS3BT_arduino_tank_2dcmotor_TB6612
// 空きデジタルPIN2でLEDを点灯/消灯
//モータドライバはTB6612
#include <PS3BT.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
USB Usb;
BTD Btd(&Usb); //そうしたBluetooth Dongleの事例を作成する必要があります
PS3BT PS3(&Btd); //これで事例が作成されます
//PS3BT PS3(&Btd, 0x00, 0x15, 0x83, 0x3D, 0x0A, 0x57);
// これにはBluetoothアドレスも格納されます
// これはスケッチを実行するときにドングルから取得できます
int pos_y;
int pos_x;
int PWMA = 5; // ← 11  Aモータ PWM 左側モータ
int AIN1 = 4; // ← 9  Aモータ IN1  ( 9ピンはUSBホストシールド使用
int AIN2 = 3; // ← 8  Aモータ IN2
int BIN1 = 8; // ← 7  Bモータ IN1
int BIN2 = 7; // ← 6  Bモータ IN2
int PWMB = 6; // ← 10 Bモータ PWM 右側モータ ( 10ピンはUSBホストシールド使用
int motor_speed;
const int motor_sp1 = 128; //超信地旋回速度
const int motor_sp0 = 0; //超低速
const int LED = 2;
int btn;
int i ;
 
void setup() {
  Usb.Init();
  Serial.begin(115200);
  while (!Serial); // シリアルポートが接続するのを待つ
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); //halt
  }
  Serial.print(F("\r\nPS3 Bluetooth Library Started"));
  pinMode(PWMA, OUTPUT);
  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);
  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);
  pinMode(PWMB, OUTPUT);
  pinMode(LED, OUTPUT);
  // turn on servo
  //servo0.attach(9);
  //servo1.attach(10);
}
void loop() {
  Usb.Task();
  if (PS3.PS3Connected) {
    //スティックの中央は127だけどピタリと止まらないので+-10ほど余裕を持たせる。
    //左スティック上下の値(最上部0、中央127、最下部255)を読み込む
    pos_y = PS3.getAnalogHat(LeftHatY);
    pos_x = PS3.getAnalogHat(LeftHatX);
    pos_rx = PS3.getAnalogHat(RightHatX);
    //LED点灯
    if (PS3.getButtonClick(UP)) {
      digitalWrite(LED, HIGH);
    }
    //LED消灯
    if (PS3.getButtonClick(DOWN)) {
      digitalWrite(LED, LOW);
    }
    //サーボUP
    //    if (PS3.getButtonClick(TRIANGLE)) {
    //      servo0.write(168);
    //      delay(20);
    //    }
    //サーボDOWN
    //    if (PS3.getButtonClick(CROSS)) {
    //      servo0.write(12);
    //      delay(20);
    //    }
    //サーボ右回転
    //    if (pos_rx > 137) {
    //      servo1.write(168);
    //      delay(20);
    //    }
    //サーボ左回転
    //    if (pos_rx < 117 ) {
    //      servo1.write(12);
    //      delay(20);
    //    }
    //左スティックがセンター付近は停止
    if (pos_x >= 117 && pos_x <= 137 && pos_y >= 117 && pos_y <= 137) {
      analogWrite(PWMA, 0);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, 0);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
    }
    //前進
    else if (pos_y < 117 && pos_x > 117 && pos_x < 137) {
      //左スティック中央(127)から最上部(0)の値をモーターのスピード0から255に変換
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進
    else if ( pos_y > 137 && pos_x > 117 && pos_x < 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //前進右旋回
    else if ( pos_y < 117 && pos_x > 137) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //前進左旋回
    else if ( pos_y < 117 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進右旋回
    else if ( pos_y > 137 && pos_x > 137) {
      motor_speed = map(pos_y, 137, 255, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_speed);
    }
    //後進左旋回
    else if ( pos_y > 137 && pos_x < 117) {
      motor_speed = map(pos_y, 117, 0, 0, 255);
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_speed);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_speed);
    }
    //右超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x > 137) {
      digitalWrite(AIN1, HIGH);
      digitalWrite(AIN2, LOW);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, LOW);
      digitalWrite(BIN2, HIGH);
      analogWrite(PWMB, motor_sp1);
    }
    //左超信地旋回
    else if ( pos_y > 117 && pos_y < 137 && pos_x < 117) {
      digitalWrite(AIN1, LOW);
      digitalWrite(AIN2, HIGH);
      analogWrite(PWMA, motor_sp1);
      digitalWrite(BIN1, HIGH);
      digitalWrite(BIN2, LOW);
      analogWrite(PWMB, motor_sp1);
    }
  }
}