Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
A robot control board with four servo-controlled feet and a face with a distance sensor.
The control board can use Arduino nano or Obniz. The example above uses Arduino Nano 33 IoT.
Each part such as face and foot is 3D-printed.
In addition to the sonar sensor on the face and the gyro sensor on the Nano 33, remote control using the IR sensor provided on the back is possible.
It seems that I can put it on my shoulder using a robot turntable, so I will try the next Maker Faire as a robot on the shoulder.
// ============================================
// 4-Legged walking robot
// Arduino nano
// ============================================
// PORT ASSIGNMENT
// ============================================
// D2:BUZZ
// D3:SONAR ECHO D4:SONAR TRIG
// D5:SERVO FR D6:SERVO FL
// D7:SERVO RR D8:SERVO RL
// D9:SERVO TABLE
// D10:LED D11:RGB
// D12:IR
// A0:PHOTO TR A1:CHARGING
// ============================================
// FILE INCLUDE
// ============================================
#include <Servo.h>
#include <Ultrasonic.h>
Servo FRsvo; Servo FLsvo; Servo RRsvo; Servo RLsvo; // 4 legs
Servo TBL; // Turntable
Ultrasonic ultrasonic(4,3); // (Trig PIN,Echo PIN)
// ============================================
// CONTROL VALUABLES
// ============================================
long itime, itime2, itime3, itime4; // event timer
boolean tgll = true; // led tggle
int stepp = 5; // walking step
boolean autom = true; // IR controller/auto mode
// ============================================
// SETUP
int dstep = 90; int ddir = 1;
// ============================================
void setup() {
Serial.begin(9600); // Serial Monitor
pinMode(10, OUTPUT); // LED
pinMode(13, OUTPUT); // on board LED
pinMode(12, INPUT_PULLUP); // IR
pinMode(A1, INPUT);
FRsvo.attach(5); // FR leg
FLsvo.attach(6); // FL leg
RRsvo.attach(7); // RR leg
RLsvo.attach(8); // RL leg
TBL.attach(9); // TABLE control
FR(70); FL(70); RR(110); RL(110); // home position
delay(2000);
}
// ============================================
// LOOP
int inter = 1000;
int mode, Omode;
int Rstate, Rtim;
// ============================================
void loop() {
IRreceiver(); digitalWrite(10, !autom); // IR controller command decode
if(autom) { // AUTO mode
if(millis() - itime2 > 200) { itime2 = millis(); // distance sensor
ultras(); if(mode == 1) { go(0); } // walk
if(Omode != mode) {
if(mode == 0) { FR(65*tgll); FL(65*!tgll); RR(100); RL(100); noTone(2); } // short distance
else if(mode == 2) { FR(65); FL(65); RR(100); RL(100); noTone(2); } // long distance
Omode = mode;
}
}
tablecontrol();
}
if(millis() - itime > inter) { itime = millis(); tgll = !tgll; // table check
int vol = analogRead(A1); Serial.print("A1 voltage: "); Serial.println(vol);
inter = 1000; if(vol > 300) { inter = 400; } digitalWrite(13, tgll); // ON board LED
}
}
void ultras() {
int dist = ultrasonic.Ranging(CM); // Serial.print(dist); Serial.println(" cm" );
if(dist <= 13) { mode = 0; } else if(dist > 13 && dist < 30) { mode = 1; } else { mode = 2; }
}
// ============================================
// TURNTABLE control
// ============================================
void tablecontrol() {
if(inter < 1000) { // table mode
if(millis() - itime3 > 400 && mode == 2) { itime3 = millis(); // table rotation
if(ddir) { dstep += 1; if(dstep > 180) { ddir = 0; } else { TBL.write(dstep); } }
else { dstep -= 1; if(dstep < 0) { ddir = 1; } else { TBL.write(dstep); } }
}
if(millis() - itime4 > Rtim) { itime4 = millis(); // table random pose
Rtim = random(5000*2, 12000*2); ddir = !ddir;
Rstate++; if(Rstate > 7) { Rstate = 0; }
switch(Rstate) {
case 0: FR(70); FL(70); RR(110); RL(110); break; // Home
case 1: FR(0); FL(90); RR(90); RL(180); break; // Right stretch
case 2: FR(70); FL(70); RR(110); RL(110); break; // Home
case 3: FR(90); FL(90); RR(180); RL(180); break; // Rear stretch!!
case 4: FR(70); FL(70); RR(110); RL(110); break; // Home
case 5: FR(90); FL(0); RR(180); RL(90); break; // Left stretch
case 6: FR(70); FL(70); RR(110); RL(110); break; // Home
case 7: FR(0); FL(0); RR(180); RL(180); break; // ful stretch!!
}
}
}
}
// ============================================
// IR RECEIVER
// ============================================
void IRreceiver() { // command decode
char foo = IRdrcv();
if(foo) {
switch(foo) {
case '1': Serial.print("charge voltage level(0-600): ");
Serial.println(analogRead(A1)); break; // 1 light/charge sensor test
case '2': Serial.print("ultrasonic distance measurement(cm): ");
Serial.println(ultrasonic.Ranging(CM)); break; // 2 ultrasonic test
case '3': Serial.println("tone"); tone(2, 440); delay(200); noTone(2); break; // 3 buzz test
case '4': Serial.println("Rear stretch:"); FR(90); FL(90); RR(180); RL(180); break; // Rear ful stretch
case '5': Serial.println("Ful stretch:"); FR(0); FL(0); RR(180); RL(180); break; // Ful stretch
case '6': Serial.println("Front stretch:"); FR(0); FL(0); RR(90); RL(90); break; // Front stretch
case '7': Serial.println("Rear fuse:"); FR(90); FL(90); RR(120); RL(120); break; // Rear fuse
case '8': Serial.println("Ful fuse:"); FR(25); FL(25); RR(120); RL(120); break; // Ful fuse
case '9': Serial.println("Front fuse: "); FR(25); FL(25); RR(75); RL(75); break; // Front fuse
case '0': Serial.println("Home postion:"); FR(80); FL(80); RR(53); RL(53); noTone(2); break; // Square Home position
case '*': go(3); break; // * small steps
case '#': break; // #
case 'U': go(0); break; // UP forward steps
case 'D': goback(); break; // DOWN reverse steps
case 'L': go(1); break; // LEFT left direction
case 'R': go(2); break; // RIGTH right direction
case 'K': Serial.print("auto mode:"); autom = !autom;
Serial.println(autom); break; // OK auto or manual
}
}
}
// ============================================
// IR rcv
// f:38kHz unit:high = 9us/low = 17us (26us)
// (0)600/26, (1)1200/26, (2)2500/26
// || 342 ||``170`,,``||22||``22``,,,||22||````63````,,,||22||```````
// --start------- --"0"------ --"1"---------- --stop------
// 9ms 4ms 600us 600us 600us 1600us 600us total 50 to 80ms
// ============================================
char IRdrcv() {
long TStime; long sTStime; int lap[40]; int n = 0; int lgth; long ddd = 0; char moji = 0;
if(!digitalRead(12)) {
sTStime = millis(); // total length check
TStime = micros(); while(!digitalRead(12)) { if(millis() - sTStime > 100) return ddd; }
if(micros() - TStime < 4000) return ddd; // start "L" 9ms
while( digitalRead(12)) { if(millis() - sTStime > 100) return ddd; } // start space "H" 4ms
for(int n = 0; n < 32; n++) {
while(!digitalRead(12)) { if(millis() - sTStime > 100) return 0; } // data carry
TStime = micros(); while( digitalRead(12)) { if(millis() - sTStime > 100) return ddd; }
lap[n] = micros() - TStime; // data space
} while(!digitalRead(12)) { if(millis() - sTStime > 100) return 0; } // stop bit
for(int n = 0; n < 32; n++) { if(lap[n] > 1000) { bitSet(ddd, 31 - n); } } //Serial.print("data:"); Serial.println(ddd, HEX);
switch(ddd) {
case 0xFFA25D: moji = '1'; break;
case 0xFF629D: moji = '2'; break;
case 0xFFE21D: moji = '3'; break;
case 0xFF22DD: moji = '4'; break;
case 0xFF02FD: moji = '5'; break;
case 0xFFC23D: moji = '6'; break;
case 0xFFE01F: moji = '7'; break;
case 0xFFA857: moji = '8'; break;
case 0xFF906F: moji = '9'; break;
case 0xFF9867: moji = '0'; break;
case 0xFF6897: moji = '*'; break;
case 0xFFB04F: moji = '#'; break;
case 0xFF18E7: moji = 'U'; break; // "^"
case 0xFF4AB5: moji = 'D'; break; // "v"
case 0xFF10EF: moji = 'L'; break; // "<-"
case 0xFF5AA5: moji = 'R'; break; // "->"
case 0xFF38C7: moji = 'K'; break; // "ok"
} Serial.print("["); Serial.print(moji); Serial.print("]");
} return moji;
}
// ============================================
// 0<----- | ----->180
// 25 90
// 75---120
// 45--90
void FR(int posi) { FRsvo.write(180-posi); } // 0, 25, 90
void FL(int posi) { FLsvo.write(posi); } // 0, 25, 90 80 Home
void RR(int posi) { RRsvo.write(180-posi); } // 75, 120, 75-30, 120-30, 180
void RL(int posi) { RLsvo.write(posi); } // 75, 120, 75-30, 120-30, 180 53 Home
// ============================================
int go(int dir) { // 1:left 2:rite
tone(2, 200 + 200*stepp);
stepp += 1; if(stepp > 5) { stepp = 0; }
if(!dir) mogaki(stepp,0,0); // normal steps
else if(dir == 1) mogaki(stepp, 0, 1); // right direction
else if(dir == 2) mogaki(stepp, 1, 0); // left direction
else if(dir == 3) mogaki(stepp, 1, 1); // small steps
}
int goback() {
tone(2, 2000 + 200*stepp);
stepp -= 1; if(stepp < 0) { stepp = 5; }
mogaki(stepp,1,1);
}
void mogaki(int para, int lt, int rt) {
Serial.print("step:"); Serial.println(para);
switch(para) {
case 0: FL(90); FR(25); // - ^ (-) ^
RL(75); RR(120); // (-) v - v
break;
case 1: FL(25); FR(25); // (^) ^ ^ (^)
RL(75-30); RR(120); // - v - v
break;
case 2: FL(25); FR(90); // ^ (-) ^ -
RL(120-30); RR(120); // (v) v v (v)
break;
case 3: FL(25); FR(90); // ^ - ^ (-)
RL(120); RR(75); // v (-) v -
break;
case 4: FL(25); FR(25); // ^ (^) (^) ^
RL(120); RR(75-30); // V - V -
break;
case 5: FL(90); FR(25); // (-) ^ - ^
RL(120); RR(120-30); // V (V) (V) V
break;
}
}
Masahiro Mizuno
20 projects • 32 followers
Chief Prototypist. 20+ years R&D experience in wide range of technology.
Comments