ArduinoでRCサーボ4台を動かして「ひょっこりモグラタワー」を作ってみた
モグラ叩きの動きをいろいろと試しているうち,RCサーボの動きが「ひょっこり」に見えてきました(^^;;。そこで,急ごしらえではあるのですがRCサーボ4台で動く「ひょっこりモグラタワー」なるものを作ってみました。[外観]PCの梱包用ダンボールで組んでみたタワーと「元祖モグラ叩きゲーム」から外したモグラ4匹です。左右にひょっこり出てきます(^^)。[機材]Arduino で動くRaspberry Pi PicoとI2C接続のサーボコントローラです。MPU : Raspberry Pi PicoServo Controller : PCA9685 (16ch)RC Servo : SG-90 (超廉価版)モグラはサーボアームにホットボンドで直結です。[動画]簡単なプログラムで動かしてみました。一斉に動くと結構揺れます(^^;;;;;.じわっと動く動作の後にランダムな動きを試してみましたが,,イマイチですかね,,。[プログラム] つたない例ですが,ま,動いていますのでメモしておきます(^^;;;;。1)サーボコントローラのPCA9685の設定などは今まで通りです。→ 16chのRCサーボコントロールモジュール(AE-PCA9685)を使ってモグラを出そうと試作中/* PCA9685 for 16ch Servo controll OSC:25MHz MODE1_REG:0x00 PRESCALE__REG:0xFE LED0_ON_L, ON_H, OFF_L, OFF_H ---> LED15 0x06 0x07 0x08 0x09 ---> 0x42,43,44,45 Raspberr Pi Pico, I2C (SDA:GP4, SCL:GP5) */#include <Wire.h>#define PCA9685 0x40void I2C__write (byte reg, byte val){ Wire.beginTransmission(PCA9685); Wire.write(reg); Wire.write(val); Wire.endTransmission();}void setup() { Wire.begin(); // set prescale for 50Hz, OSC:25MHz // prescale:25000000/(4096*50)-1 I2C__write (0x00, 0b00010001); // MODE1 sleep mode on I2C__write (0xFE, 121); // set prescale for 50Hz I2C__write (0x00, 0b00100001); // sleep off and auto inc.}2)サーボのポジション設定を角度から行ったりするルーチンです。→16chのRCサーボコントローラー(PCA9685)に角度からのポジション設定ルーチンを追加void setPos_all(int dv){ // Set all Servo for (byte i=0; i<4; i++){ setPosition (i, dv); }}void setPos_slow(byte ch, int sdv, int edv){ if (edv > sdv){ for (int i=sdv; i<edv+1 ;i++){ setPosition (ch, i); delay(20); } } else { for (int i=sdv; i>edv-1 ;i--){ setPosition (ch, i); delay(20); } }}/* Set servo position PCA9685:50Hz, 20ms(4095) SG-90 Servo Degree Duty cycle Pulse length 0 0.5 ms 102 90 1.45ms 297 180 2.4 ms 491*/void setPosition (byte ch, int pos){ if (ch<16 && pos<181){ unsigned int plen=(unsigned int)pos*216/100+102; // pulse length Wire.beginTransmission(PCA9685); Wire.write(ch*4+0x06); // set register of servo ch. Wire.write(0x00); // ON_L Wire.write(0x00); // ON_H Wire.write(lowByte(plen)); // OFF_L Wire.write(highByte(plen)); // OFF_H Wire.endTransmission(); delay(20); }} 3)loop部です。 長ったらしくいろいろ動きを試していますが,,ま,メモとして(^^;;;;;;。void loop() { setPos_all(90);delay(1000); // ALL L-> M-> R-> M setPos_all(45);delay(1000); setPos_all(90);delay(1000); setPos_all(135);delay(1000); setPos_all(90);delay(1000); // One by One, R:0->3, L: 0->3 for (byte i=0; i<4; i++){ setPosition (i, 45);delay(500); } for (byte i=0; i<4; i++){ setPosition (i, 135);delay(500); } setPos_all(90);delay(1000); // One by One, R<->L for (byte i=0; i<3; i=i+2){ setPosition (i, 45);delay(500); setPosition (i+1,135);delay(500); } for (byte i=0; i<3; i=i+2){ setPosition (i, 135);delay(500); setPosition (i+1,45);delay(500); } setPos_all(90);delay(1000); // One by One, R_step<->L_step for (byte i=0; i<4; i++){ setPosition (i, 90-11*(i+1));delay(500); } for (byte i=4; i>0; i--){ setPosition (i-1, 90+11*i);delay(500); } setPos_all(90);delay(1000); // Move slowly 0:L, 3:R setPos_slow(0, 90, 45); setPos_slow(0, 45, 90); setPos_slow(3, 90,135); setPos_slow(3,135, 90); // Move random long rseed=analogRead(26)*millis(); randomSeed(rseed); for (byte i=0; i<20; i++){ int rd[]={45,135}; setPosition (random(4), rd[random(2)]);delay(500); }} 私の本題のモグラ叩きから横道にそれていますけど,サーボ直結は楽なのにプログラムで色々できてなにか楽しいですね(^^)。これはこれとして,「ひょっこり」の動きもいろんな場面で使えそうです。