走行方向をOLED・音声合成LSIで通知、圧電スピーカによる効果音に「スター・ウォーズ」R2-D2を使いました。
●同ブログ関連記事:【障害物回避ロボットカー ESP32 RemoteXY操作】
動画
回路図
構成部品
上面 |
●ATP3012R5-PU(小型ロボットの音声)
●サーボモーター SG90
●超音波距離センサー HC-SR04(障害物検知)
側面 |
●モバイルバッテリー 5000mAh(ESP32開発ボード電源)
内部 |
●デュアルモータードライバDRV8835
●TA7368使用小型アンプキット
●スピーカー(音声)
●圧電スピーカ(効果音)
●リチウムポリマー電池 3.7V(モーター電源)
●SSD1306 OLED
底面 |
●タミヤ ダブルギヤボックス(70168)
●タミヤ ボールキャスター(70144)
●タミヤ ユニバーサルプレート
●マイクロスイッチ(障害物検知)
モータ |
●ノイズ対策
モータ電源端子⊕⊝間 セミコン104モータ電源端子⊕-モータ金属ケース セミコン104
モータ電源端子⊝-モータ金属ケース セミコン104
Arduino IDE
プログラム
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <ESP_Adafruit_SSD1306.h>
#include <AquesTalk.h>
#define OLED_RESET 4 // 21Pin SDA , 22PIN SCL
#define ServoPin 15 // Servo モータ
#define LEDPin 16
#define SpeakPin 17 //スピーカ
#define LM1Pin 33 // AIN1 左モーター DRV8835
#define LM2Pin 32 // AIN2 左モーター
#define RM1Pin 26 // BIN1 右モーター
#define RM2Pin 25 // BIN2 右モーター
#define echoPin 27 // Echo Pin
#define trigPin 14 // Trigger Pin
#define swPin 23 // Sw Pin
Adafruit_SSD1306 display(OLED_RESET);
AquesTalk atp; //インスタンス定義 変数名は任意
int PWM=150; //モーター回転数制御
int Distance = 0, rightDistance = 0, leftDistance = 0, middleDistance = 0;
int sw ;
void Go(){
ledcWrite(0, PWM);
ledcWrite(1, 0);
ledcWrite(2, PWM);
ledcWrite(3, 0);
display.clearDisplay(); // Clear the buffer.
display.setTextColor(WHITE);
display.setTextSize(6);
display.setCursor(30,10);
display.println( "GO" );
display.display();
delay(10);
}
void Left(){
ledcWrite(0, 0);
ledcWrite(1, PWM);
ledcWrite(2, PWM);
ledcWrite(3, 0);
display.clearDisplay(); // Clear the buffer.
display.setTextColor(WHITE);
display.setTextSize(4);
display.setCursor(15,20);
display.println( "LEFT" );
display.display();
delay(10);
}
void Stop(){
ledcWrite(0, 0);
ledcWrite(1, 0);
ledcWrite(2, 0);
ledcWrite(3, 0);
display.clearDisplay(); // Clear the buffer.
display.setTextColor(WHITE);
display.setTextSize(4);
display.setCursor(15,20);
display.println( "STOP" );
display.display();
delay(10);
}
void Right(){
ledcWrite(0, PWM);
ledcWrite(1, 0);
ledcWrite(2, 0);
ledcWrite(3, PWM);
display.clearDisplay(); // Clear the buffer.
display.setTextColor(WHITE);
display.setTextSize(4);
display.setCursor(0,20);
display.println( "RIGHT" );
display.display();
delay(10);
}
void Back(){
ledcWrite(0, 0);
ledcWrite(1, PWM);
ledcWrite(2, 0);
ledcWrite(3, PWM);
display.clearDisplay(); // Clear the buffer.
display.setTextColor(WHITE);
display.setTextSize(4);
display.setCursor(10,20);
display.println( "BACK" );
display.display();
delay(10);
}
void L(){
Left();
atp.Synthe("hidari");
delay(750);
Stop();
}
void GO(){
Go();
atp.Synthe("zensin");
}
void R(){
Right();
atp.Synthe("migi");
delay(750);
Stop();
}
void LEFT(){
Left();
atp.Synthe("sasetu");
}
void STOP(){
Stop();
atp.Synthe("sutoppu");
}
void RIGHT(){
Right();
atp.Synthe("usetu");
}
void BACK(){
Back();
atp.Synthe("bakku");
}
void Auto() {
swon();
ledcWrite(6, 57); //(-45)
delay(350);
rightDistance = Distance_test();
if( rightDistance <= 30) {
Left();
Tone();
atp.Synthe("hidari");
delay(200);
swon();
Go();
}
swon();
ledcWrite(6, 42); //(-90)
delay(350);
rightDistance = Distance_test();
if( rightDistance <= 20) {
Left();
Tone();
atp.Synthe("hidari");
delay(100);
swon();
Go();
}
swon();
ledcWrite(6, 73); // ( 0 )
delay(700);
Distance = Distance_test();
if( Distance <= 30) {
Search();
}
swon();
ledcWrite(6, 88); // (+45)
delay(350);
leftDistance = Distance_test();
if(leftDistance <= 30) {
Right();
Tone();
atp.Synthe("migi");
delay(200);
Go();
}
swon();
ledcWrite(6, 106); // (+90)
delay(350);
leftDistance = Distance_test();
if(leftDistance <= 20) {
Right();
Tone();
atp.Synthe("migi");
delay(100);
swon();
Go();
}
swon();
ledcWrite(6, 73); //( 0 )
delay(700);
Distance = Distance_test();
if( Distance <= 30) {
Search();
}
swon();
Go();
}
void Search() {
Stop();
digitalWrite(LEDPin,HIGH);
R2d2_tone();
atp.Synthe("kakunin");
if(rightDistance > leftDistance) {
Back();
delay(1000);
digitalWrite(LEDPin,LOW);
atp.Synthe("usetu");
Right();
delay(1000);
Go();
}
else if(rightDistance < leftDistance) {
Back();
delay(1000);
digitalWrite(LEDPin,LOW);
atp.Synthe("sasetu");
Left();
delay(1000);
Go();
}
else if((rightDistance <= 30) || (leftDistance <= 30)) {
Back();
atp.Synthe("sagari masu");
delay(2000);
Right();
delay(750);
}
else {
swon();
Go(); //GO
}
}
void swon() {
sw = digitalRead(swPin ) ; //スイッチの状態を読む
if(sw== LOW){
Back();
atp.Synthe("kiken sagarimasu");
delay(3000);
Right();
delay(750);
}
}
// HC-SR04
int Distance_test() {
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(20);
digitalWrite(trigPin, LOW);
float Fdistance = pulseIn(echoPin, HIGH);
Fdistance= Fdistance / 58;
return (int)Fdistance;
}
void R2d2_tone(){
const int NOTE_NONE = NOTE_MAX;
int melody[] = {
NOTE_A, NOTE_G, NOTE_E, NOTE_C, NOTE_D, NOTE_B, NOTE_F, NOTE_C,
NOTE_A, NOTE_G, NOTE_E, NOTE_C, NOTE_D, NOTE_B, NOTE_F, NOTE_C
};
int noteOctaves[] = {
7, 7, 7, 7, 7, 7, 7, 8,
7, 7, 7, 7, 7, 7, 7, 8
};
int noteDurations[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
};
for (int thisNote = 0; thisNote < 16; thisNote++) {
ledcWriteNote(4, (note_t)melody[thisNote], noteOctaves[thisNote]);
int pauseBetweenNotes = 1000 / noteDurations[thisNote] * 0.1 ;
delay(pauseBetweenNotes);
ledcWriteTone(4, 0); // stop the tone playing:
}
}
void Tone() {
digitalWrite(LEDPin,HIGH);
ledcWriteTone(4, 800);
delay(100);
digitalWrite(LEDPin,LOW);
ledcWriteTone(4, 0);
}
void setup() {
pinMode(LM1Pin, OUTPUT); // AIN1
pinMode(LM2Pin, OUTPUT); // AIN2
pinMode(RM1Pin, OUTPUT); // BIN1
pinMode(RM2Pin, OUTPUT); // BIN2
pinMode(SpeakPin, OUTPUT); // スピーカ
pinMode(ServoPin, OUTPUT); // Servo
pinMode( echoPin, INPUT );
pinMode( trigPin, OUTPUT );
pinMode( swPin, INPUT );
ledcSetup(0,490,8); // モータ 0CH 490Hz 8bit=0-255(PWM)
ledcSetup(1,490,8);
ledcSetup(2,490,8);
ledcSetup(3,490,8);
ledcSetup(4,5000,13); //スピーカ 4CH 5000Hz 13biT=0-8192(PWM)
ledcSetup(6, 50, 10); // 5ch 50 Hz 10bit=0-1023(PWM)
ledcAttachPin(LM1Pin, 0); // モータ 0CH
ledcAttachPin(LM2Pin, 1);
ledcAttachPin(RM1Pin, 2);
ledcAttachPin(RM2Pin, 3);
ledcAttachPin(SpeakPin, 4); //スピーカ 4CH
ledcAttachPin(ServoPin, 6); //サーボ 5ch
Wire.begin(21,22); // (SDA,SCL)
display.begin(SSD1306_SWITCHCAPVCC, 0x78>>1); // OLED ADDRESS
Serial.begin(9600);
pinMode( LEDPin, OUTPUT);
delay(500);
Go();
}
void loop() {
Auto();
}
0 件のコメント:
コメントを投稿