Hardware components | ||||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
|
"SHAKEY" - robot shaking face by alternately flowing a current on coil generated on PCB - was made to be implemented on Arduino UNO.
This time I reworked it to be self-contained by implemented ATMEGA 328p + FTDI on one board. It become self standing. You can connect directly to the PC and write your programs.
Furthermore, I mounted an infrared receiver, you are able to instruct the operation from infrared controller.
I connected the Grove Speech Recognizer to the infrared controller through UART. You can control MULTIPLE SHAKEY robots by voice.
All 3D print data is on Thingiverse.
These are electric components I used this time.
para.h
// ============================================
// Tone
// ============================================
#define o1 0x10 // short base note 1
#define o2 0x20 // short base note 2
#define o3 0x30 //
#define o4 0x40 //
#define o5 0x50 //
#define o6 0x60 //
#define o7 0x70 //
#define v1 0x10|0x80 // with vivrato
#define v2 0x20|0x80 // with vivrato
#define v3 0x30|0x80 // with vivrato
#define v4 0x40|0x80 // with vivrato
#define v5 0x50|0x80 // with vivrato
#define v6 0x60|0x80 // with vivrato
#define v7 0x70|0x80 // with vivrato
#define zzz 0xff // no action
#define nT 0 // no tone
#define C 1
#define Cs 2
#define D 3
#define Ds 4
#define E 5
#define F 6
#define Fs 7
#define G 8
#define Gs 9
#define A 10
#define As 11
#define B 12
// ============================================
// Tone
boolean tglv = true; // vivrato tgl
int viv = 0; // vivrato on/off switch
float vvv; // vivrato depth
int freq; // sound frequency
int octo; // oct control (base short note)
boolean stgl = true; // face swing tgl
int unitt = 40; // tempo
// ============================================
long oto[] = { // divide 0 to 7 times(3bit)
0, // 0 notone
2093*2, // 1 C
2217*2, // 2 Cs
2349*2, // 3 D
2489*2, // 4 Ds
2637*2, // 5 E
2794*2, // 6 F
2960*2, // 7 Fs
3136*2, // 8 G
3322*2, // 9 Gs
3520*2, // 10 A
3729*2, // 11 As
3951*2 // 12 B 5bit(0-16)
};
Music.ino
// ============================================
// Dance of the Reed Flutes data "a(ov1) b(ov2)(short) c(ov3) d(ov4) e(ov5) f(ov6) g(ov7)"
// ============================================
// <I>
const PROGMEM int xcountI[] = { 12, 12, 12, 12, 12, 12, 12, 12 }; // count[8]
const PROGMEM int xtoneIa[] = { C|o1, G|o1, G|o1, G|o1, C|o1, G|o1, G|o1, G|o1 }; // toneA
const PROGMEM int xtoneIb[] = { nT, G|o2, nT, G|o2, nT, G|o2, nT, G|o2 }; // toneB
const PROGMEM int xtoneIc[] = { nT, nT, nT, nT, nT, nT, nT, nT }; // toneC
const PROGMEM int xtoneId[] = { nT, nT, nT, nT, nT, nT, nT, nT }; // toneD
// <A> | | | | | | | |
const PROGMEM int xcountA[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 12, 12 }; // count [16]
const PROGMEM int xtoneAa[] = { C|o6, B|o5, C|o6, B|o5, C|o6, nT, B|o5, nT, D|o6, nT, C|o6, E|o6, G|o6, C|o7, E|v7, zzz }; // toneA
const PROGMEM int xtoneAb[] = { E|o4, D|o4, E|o4, D|o4, E|o4, nT, D|o4, nT, F|o4, nT, E|o4, G|o4, C|o4, E|o4, G|v4, zzz }; // toneB
const PROGMEM int xtoneAc[] = { nT, zzz, B|o2, zzz, nT, zzz, C|o2, zzz, nT, zzz, D|o2, zzz, zzz, zzz, nT, E|o2 }; // toneC
const PROGMEM int xtoneAd[] = { B|o1, zzz, B|o1, zzz, C|o1, zzz, C|o1, zzz, D|o1, zzz, D|o1, zzz, zzz, zzz, E|o1, E|o1 }; // toneD
// <B> | | | | | | | |
const PROGMEM int xcountB[] = { 6, 6, 6, 6, 6, 6, 6, 6, 12, 6, 6, 12, 12 }; // count [13]
const PROGMEM int xtoneBa[] = { F|o7, E|o7, F|o7, E|o7, D|o7, C|o7, G|o6, E|o6, C|o6, zzz, C|o7, B|v6, zzz }; // toneA
const PROGMEM int xtoneBb[] = { A|o5, G|o5, A|o5, G|o5, F|o5, E|o5, C|o5, E|o5, Gs|o5, zzz, zzz, F|v5, zzz }; // toneB
const PROGMEM int xtoneBc[] = { nT, zzz, F|o2, zzz, nT, zzz, G|o2, zzz, nT, G|o2, zzz, nT, G|o2 }; // toneC
const PROGMEM int xtoneBd[] = { F|o1, zzz, F|o1, zzz, G|o1, zzz, G|o1, zzz, G|o1, G|o1, zzz, G|o1, G|o1 }; // toneD
void DanceoftheRead() { humming(xcountI, xtoneIa, xtoneIb, xtoneIc, xtoneId, 8); // Dance of the Reed Flutes data Intro
humming(xcountA, xtoneAa, xtoneAb, xtoneAc, xtoneAd, 16); // Dance of the Reed Flutes data 1
humming(xcountB, xtoneBa, xtoneBb, xtoneBc, xtoneBd, 13); } // Dance of the Reed Flutes data 2
// ============================================
// Lady Madonna data "a(ov1) b(ov2)(short) c(ov3) d(ov4) e(ov5) f(ov6) g(ov7)"
// ============================================
// <C>
const PROGMEM int xcountC[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 6, 6, 6, 6 }; // count [16x6]
const PROGMEM int xtoneCa[] = { Cs|o5, Cs|o5, zzz, B|o4, B|o4, A|o4, zzz, zzz, Cs|o5, Cs|o5, B|o4, nT, C|o4, A|o4, zzz, zzz, zzz, zzz }; // toneA
const PROGMEM int xtoneCb[] = { B|o1, A|o2, Cs|o1, Cs|o2, D|o2, D|o1, D|o1, D|o1, B|o1, A|o2, Cs|o1, zzz, Cs|o2, zzz, D|o2, D|o1, D|o1, D|o1 }; // toneB
const PROGMEM int xtoneCc[] = { nT, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz }; // toneC
const PROGMEM int xtoneCd[] = { nT, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz }; // toneD
// <D>
const PROGMEM int xcountD[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 36 }; // count [13x6]
const PROGMEM int xtoneDa[] = { Cs|o6, Cs|o6, E|o6, Cs|o6, Fs|o6, E|o6, Cs|o6, A|o5, zzz, G|o5, B|o5, A|o5, zzz, A|v6 }; // toneA
const PROGMEM int xtoneDb[] = { B|o1, A|o2, Cs|o1, Cs|o2, D|o2, D|o1, E|o2, E|o1, F|o1, F|o2, Cs|o1, G|o2, A|o2, E|v5 }; // toneB
const PROGMEM int xtoneDc[] = { nT, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, zzz, E|v7 }; // toneC
const PROGMEM int xtoneDd[] = { A|o4, nT, A|o4, nT, A|o4, nT, A|o4, nT, A|o4, nT, A|o4, nT, A|o4, A|v4 }; // toneD
void LadyMaddonna() { humming(xcountC, xtoneCa, xtoneCb, xtoneCc, xtoneCd, 18); // Lady Maddonna
humming(xcountD, xtoneDa, xtoneDb, xtoneDc, xtoneDd, 14); }
// ============================================
// The Imperial March data "a(ov1) b(ov2)(short) c(ov3) d(ov4) e(ov5) f(ov6) g(ov7)"
// ============================================
// <1> | | | | | | ||
const PROGMEM int count1[] = { 16, 16, 16, 13, 3, 16, 13, 3, 32 }; // count
const PROGMEM int tone1a[] = { A|o3, A|o3, A|o3, F|o3, C|o4, A|o3, F|o3, C|o4, A|v3 }; // toneA
const PROGMEM int tone1b[] = { E|o2, E|o2, E|o2, zzz, zzz, E|o2, zzz, zzz, E|v2 }; // toneB
const PROGMEM int tone1c[] = { B|o1, B|o1, B|o1, B|o2, zzz, B|o1, B|o2, zzz, B|v1 }; // toneC
const PROGMEM int tone1d[] = { A|o1, zzz, zzz, Gs|o2, zzz, A|o1, Gs|o2, zzz, E|v1 }; // toneD
// <2> | | | | | | ||
const PROGMEM int count2[] = { 16, 16, 16, 13, 3, 16, 13, 3, 32 }; // count
const PROGMEM int tone2a[] = { E|o4, E|o4, E|o4, F|o4, C|o4, Gs|o3, F|o3, C|o4, A|v3 }; // toneA
const PROGMEM int tone2b[] = { A|o2, A|o2, A|o2, Gs|o1, zzz, A|o2, Gs|o1, zzz, C|v2 }; // toneB
const PROGMEM int tone2c[] = { C|o1, C|o1, C|o1, C|o2, zzz, C|o1, C|o2, zzz, E|v1 }; // toneC
const PROGMEM int tone2d[] = { A|o1, nT, nT, Gs|o2, nT, A|o1, Gs|o2, nT, A|v1 }; // toneD
// <3> | | | | | |
const PROGMEM int count3[] = { 16, 13, 3, 16, 8, 8, 4, 4, 8, 8 }; // count
const PROGMEM int tone3a[] = { A|o4, A|o3, A|o3, A|o4, Gs|o4, G|o4, Fs|o4, F|o4, Fs|o4, nT }; // toneA
const PROGMEM int tone3b[] = { C|o2, C|o2, zzz, C|o2, C|o2, zzz, Ds|o2, zzz, zzz, nT }; // toneB
const PROGMEM int tone3c[] = { E|o1, E|o1, zzz, E|o1, E|o1, zzz, A|o1, zzz, zzz, nT }; // toneC
const PROGMEM int tone3d[] = { A|o1, zzz, zzz, zzz, zzz, zzz, Fs|o1, zzz, zzz, nT }; // toneD
// <4> | | | | |
const PROGMEM int count4[] = { 8, 16, 8, 8, 4, 4, 8, 8, 8, 8 }; // count
const PROGMEM int tone4a[] = { As|o3, Ds|o4, D|o4, Cs|o4, C|o4, B|o3, C|o4, nT, Fs|o4, nT }; // toneA
const PROGMEM int tone4b[] = { nT, A|o2, A|o2, zzz, E|o2, zzz, zzz, zzz, zzz, nT }; // toneB
const PROGMEM int tone4c[] = { nT, Ds|o1, Ds|o1, zzz, A|o1, zzz, zzz, zzz, zzz, nT }; // toneC
const PROGMEM int tone4d[] = { nT, A|o1, A|o1, zzz, C|o2, zzz, zzz, zzz, zzz, nT }; // toneD
// <5> | | | | ||
const PROGMEM int count5[] = { 8, 16, 13, 3, 16, 13, 3, 32 }; // count
const PROGMEM int tone5a[] = { F|o3, Gs|o3, F|o3, C|o4, A|o3, F|o3, C|o4, A|v3 }; // toneA
const PROGMEM int tone5b[] = { nT, zzz, zzz, zzz, A|o1, zzz, zzz, E|v2 }; // toneB
const PROGMEM int tone5c[] = { nT, C|o1, C|o1, zzz, E|o2, zzz, zzz, C|v1 }; // toneC
const PROGMEM int tone5d[] = { nT, Gs|o2, F|o2, zzz, C|o1, zzz, zzz, A|v1 }; // toneD
void ImperialMarch1() { humming(count1, tone1a, tone1b, tone1c, tone1d, 9); } // The Imperial March data 1/3
void ImperialMarch2() { humming(count2, tone2a, tone2b, tone2c, tone2d, 9); } // The Imperial March data 2/3
void ImperialMarch3() { humming(count3, tone3a, tone3b, tone3c, tone3d, 10); // The Imperial March data 3/3
humming(count4, tone4a, tone4b, tone4c, tone4d, 8);
humming(count5, tone5a, tone5b, tone5c, tone5d, 8); }
// ============================================
// Theme from Close Encouters of the Third Kind "a(ov1) b(ov2)(short) c(ov3) d(ov4) e(ov5) f(ov6) g(ov7)"
// ============================================
// <6> | | | | | | | | |
const PROGMEM int count6[] = { 16, 16, 16, 16, 16, 16, 16, 16, 64 }; // count
const PROGMEM int tone6a[] = { A|o6, B|o6, G|o6, G|o5, D|o5, zzz, zzz, zzz, D|v5 }; // toneA
const PROGMEM int tone6b[] = { nT, zzz, zzz, zzz, A|o4, B|o4, G|o4, G|o3, D|v3 }; // toneB
const PROGMEM int tone6c[] = { nT, zzz, zzz, zzz, zzz, zzz, zzz, zzz, A|v3 }; // toneC
const PROGMEM int tone6d[] = { nT, zzz, zzz, zzz, zzz, zzz, zzz, zzz, D|v2 }; // toneD
void CloseEncounters() { humming(count6, tone6a, tone6b, tone6c, tone6d, 9); } // Theme from Close Encounters of the Third Kind
// ============================================
// play music (viv / oct 2, 1, 0 / note 3, 2, 1, 0 )
long Ttime; //
// ============================================
void humming(const int *countn, const int *tonena, const int *tonenb, const int *tonenc, const int *tonend, int len) {
for(int n = 0; n < len; n++) { Ttime = millis();
if(part == 0) { stone(pgm_read_word_near(tonena + n)); } // part0
else if(part == 1) { stone(pgm_read_word_near(tonenb + n)); } // part1
else if(part == 2) { stone(pgm_read_word_near(tonenc + n)); } // part2
else { stone(pgm_read_word_near(tonend + n)); } // part3
if(!viv) { magOnwT(0, 50, stgl); stgl = !stgl; } // swing tgl
while(millis() - Ttime < unitt * pgm_read_word_near(countn + n)) {
if(viv && freq != 0) {
if(tglv) { tone(10, freq - vvv); magOnwT(0, 50, tglv); } //
else { tone(10, freq); magOnwT(0, 50, tglv); } tglv = !tglv; // vivrato tgl
}
} //
} noTone(10);
}
void stone(int ddd) {
if(ddd == 00) { noTone(10); viv = 0; } else if(ddd == zzz) { } // nT/zzz
else { noTone(10); delay(2); tone(10, frqcalc(ddd)); } //
if(octo > 4 && !viv) { delay(120); noTone(10); } // Cut off, Base(1 or 2) short note
}
long frqcalc(int dd) {
freq = oto[min(dd & 0x0f, 12)]; octo = 7 - ((dd & 0x70) >> 4);
if(octo < 7) { for (int k = 0; k < octo; k++) { freq /= 2; } } else { freq = 0; }
viv = bitRead(dd, 7); // vibrato switch
vvv = freq * 0.01; // vibrato depth
return freq; // note frequency
}
SHAKEY.ino
// ============================================
// Base design http://simblee.com
// Language Reference http://arduino.cc/en/Reference/HomePage
// 24kRAM, 128kROM
// ============================================
// PIN ASSIGN
// ============================================
// D2:IR input
// A3:Light Sensor (analogRead(3))
// D5:Driver Enable
// D6:Driver Phase
// D11:RGB
// D10:BUZZ
// boarddefs.h in IR remote master
// avoid timer confrict between tone() and IR
// #else
// Arduino Duemilanove, Diecimila, LilyPad, Mini, Fio, Nano, etc
// ATmega48, ATmega88, ATmega168, ATmega328
// #define IR_USE_TIMER1 // tx = pin 9 << send pin
// //#define IR_USE_TIMER2 // tx = pin 3 << send pin
// ============================================
// FILE INCLUDE
// ============================================
#include "FastLED.h" // RGB LED
#include "para.h" //
#include <avr/pgmspace.h>
#include "IRremote.h" // IR remote controll
IRrecv irrecv(2); // create instance of 'irrecv' receive @D2
decode_results results; // create instance of 'decode_results'
CRGB leds[2]; // RGB LED buffer
// ============================================
// Variables
// ============================================
int part = 0; // part 0 to 3rd
boolean tgll = true;
// ============================================
// SET UP
// ============================================
void setup() {
Serial.begin(9600); // Serial.begin(115200);
pinMode(2, INPUT); // IR receive
pinMode(3, INPUT); // Light Sensor
pinMode(5, OUTPUT); digitalWrite(5, 0); // Coil Drive Enable
pinMode(6, OUTPUT); // Coil Drive Phase
pinMode(10, OUTPUT); // BUZZ
irrecv.enableIRIn(); // Start IR receiver
FastLED.addLeds<NEOPIXEL, 11>(leds, 2); // FastLED setup for RGB LEDs
col(0, 10, 0); // RGB LED
}
// ============================================
// LOOP (SPIDER: or BALL:)
// ============================================
void loop() {
if(irrecv.decode(&results)) {
switch(results.value) {
case 0xFFA25D: Serial.print("1:"); ImperialMarch1(); break;
case 0xFF629D: Serial.print("2:"); ImperialMarch2(); break;
case 0xFFE21D: Serial.print("3:"); ImperialMarch3(); break;
case 0xFF22DD: Serial.print("4:"); CloseEncounters(); break;
case 0xFF02FD: Serial.print("5:"); DanceoftheRead(); break;
case 0xFFC23D: Serial.print("6:"); LadyMaddonna(); break;
case 0xFFE01F: pi(Fs|o4); Serial.print("7:"); for (int k = 0; k < 10; k++) { lolo( 50, 10); } break; // 1 mmm
case 0xFFA857: pi(G|o4); Serial.print("8:"); for (int k = 0; k < 10; k++) { lolo( 50, 30); } break; // 2
case 0xFF906F: pi(Gs|o4); Serial.print("9:"); for (int k = 0; k < 10; k++) { lolo( 50, 60); } break; // 3 mmm
case 0xFF9867: pi(A|o4); Serial.print("0:"); for (int k = 0; k < 10; k++) { lolo( 50, 100); } break; // 4
case 0xFF6897: pi(As|o4); Serial.print("*:"); break;
case 0xFFB04F: pi(B|o4); Serial.print("#:"); break; // 17
case 0xFF18E7: pi(C|o5); Serial.print("UP:"); col(10, 20, 0); part = 0; break; // 11
case 0xFF4AB5: pi(Cs|o5); Serial.print("DN:"); col( 0, 20, 0); part = 1; break; // 12
case 0xFF10EF: pi(D|o5); Serial.print("LT:"); col(20, 0, 0); part = 2; break; // 13
case 0xFF5AA5: pi(Ds|o5); Serial.print("RT:"); col( 0, 0, 20); part = 3; break; // 14
case 0xFF38C7: pi(E|o5); Serial.print("OK:"); col(10, 10, 10); part = 0; break; // 15
} irrecv.resume(); // receive the next value
noTone(10);
}
}
// ============================================
// Motion (5:coil enable, 6:coil phase)
// ============================================
void pi(int ddd) { tone(10, frqcalc(ddd)); delay(50); noTone(10); delay(50); }
void lolo(int magt, int fret) { magOnwT(A|o4, magt, 1); delay(fret); magOnwT(A|o5, magt, 0); delay(fret); }
void magOnwT(int ddd, int tt, boolean ns) { digitalWrite(6, ns); // phase
digitalWrite(5, 1); if(ddd != 0) { tone(10, frqcalc(ddd)); delay(20); noTone(10); } delay(tt); digitalWrite(5, 0); // delay/off
}
// ============================================
// NEO PIXEL
// ============================================
void col(int x, int y, int z) { leds[0] = CRGB(x, y, z); leds[1] = leds[0]; FastLED.show(); }
Masahiro Mizuno
20 projects • 32 followers
Chief Prototypist. 20+ years R&D experience in wide range of technology.
Comments