2~3年前秋月にコパルのSPG27-1101が安価で出ていたので、使い道も考えずに纏め買いして、ジャンクボックスの肥しになっていました。 で、バタフライバリコンでこれを使ってリモートで、と当然考え、これのドライバをESP8266とDRV8835で作ってみました。
SPG27のスペックシートを見ると12Vでの動作が出ていたので、つい「12Vで動かす必要がある」と思い込んでいましたが、DRV8835のVMmaxが12Vです。 気にしないで、12V加えていましたが、 突然動かなくなって、ESP8266もUSB入力を受け付けなくなってしまうものが幾つか出てきました(壊れている!)。
回路はいたって簡単で、外部からDC電源を供給して、内部で3.3VのVccをICに供給、モーターには外部からのDCを供給するようになっています。
壊れそうなところは無いので、最初原因が分からず色々考えていましたが、DRV8835のVM maxが一番怪しい!という事で、電圧を5V位まで落としてみましたが、StepperMotorはちゃんと動いてくれます(トルクが少し落ちているかもしれませんが)。 また、動かなくなることも今のところないようなので、結論として、12Vが拙かった!
ちょっとした勘違いで、可愛そうなESP8288とDRV8835を幾つかお見送りしてしまいました。Amen...
SPG27-1101は基本ステップ角度3°で、これに5:1のギアでMLAのバタフライバリコンを動かしています(0.6°/step)が、100pF程度のバタフライバリコンだと、まだ粗い感じがあります。
マルチバンドのMLAの場合は、多分、固定コンデンサと小容量のバタフライバリコンの組み合わせ、等を考える必要があるのでしょうね。 この時、固定コンデンサの切り替えをリレーで行うとすると数十Aの高周波電流を許容するリレーをどうするか?が問題になりそう。
備忘録としてfritzingのBreadboardとPCBのコピー、それにsketchを添付しておきます。
// For use of DRV8835+SPG27-1101
// Author Ken Yamada, JA2IYJ
// WeMos D1 mini
// Date: 2019 July 3rd. V0.5 Initial version.
// July 11th V1.0 Zero_sensor added and bandled to the workable protype hardware.
// 2020 Nov. 11 v2.0 MAX_sensor added.
// 2021 Apr. 23 Modified for Butterfly Capacitor ... No need of Max/Min Stopper.
// 2021 May. 19 EEPROM.write/read/commit added to set initial and current Position.
// 2021 Sept. 3 Changed Up/Dwn/Init pin to reflect PCB alignment. Motor runs at 5V.
// Above 11V, DRV8835 might die and kills ESP8266 too.
//
#include <Stepper.h>
#include <EEPROM.h>
#include <ESP8266WiFi.h>
#define EEPROM_SIZE 2 // sizeof(int)=2 byte.
#define TRUE 1
#define FALSE 0
#define MOTOR_1 16 //15 DRV8825のピン配置に合わせて変更 5/22
#define MOTOR_2 14 //12
#define MOTOR_3 12 //13
#define MOTOR_4 13 //14
// digital address それぞれをボタンにアサイン
#define UP_BUTTON 0 // 黄色
#define DOWN_BUTTON 4 // 白
#define INIT_BUTTON 2 // Position 0 setting (GPIO16 has a built-in pull-down resistor.)
#define STEPS_PER_REV 120 // SPG27-1101 specification
#define MAX_POS 155 // 90deg/3deg step, 5:1 gear = 30 x 5 + α
// stepPerRotate は素のモーターの一回転当たりのstep数の様です(ギアの事汎用では顧慮できないもんね)
//const int stepsPerRotate = 20;// SPG20-1332ス テップ数 = 480 ギア比1:24 hence 20
const int stepsPerRotate = 12;// SPG27-1101 ステップ数 = 120 ギア比1:5 hence 24 でも12でないと動かない! 何故?
int curPosition;
int initPosition;
boolean toggle1 = FALSE;
boolean toggle2 = FALSE;
Stepper myStepper(stepsPerRotate, MOTOR_1, MOTOR_2, MOTOR_3, MOTOR_4);
void setup(){
Serial.begin(115200);
Serial.println("\n Setup ...");
// WiFiを使用しないので、省電力化の為に下の3行
WiFi.mode(WIFI_OFF);
WiFi.forceSleepBegin();
delay(1);
//EPROM.begin(EEPROM_SIZE);
//initPosition = EEPROM.read(0);
//curPosition = initPosition;
Serial.print("\n curPosition = ");
Serial.println( curPosition );
pinMode(UP_BUTTON, INPUT_PULLUP); // 手動制御用のUp/Down ボタン High
pinMode(DOWN_BUTTON, INPUT_PULLUP); // 手動制御用のUp/Down ボタン High
pinMode(INIT_BUTTON, INPUT_PULLUP); // One time.
myStepper.setSpeed(2000); // 2500位まではOKの様です。
//myStepper.setSpeed(50); // make it slow
Serial.println("\n End of Setup ...");
}
void loop(){
Serial.println(" Start Loop ---");
// 初期設定の時に容量最大値の位置を0に設定する。
#if 0
if( digitalRead(INIT_BUTTON) == LOW) {
EEPROM.begin(EEPROM_SIZE);
EEPROM.write(0, 0);
EEPROM.commit();
Serial.println( " Wrote EEPROM -> 0 ");
delay(500);
}
#endif
// Up button
if( digitalRead(UP_BUTTON) == LOW ){
Serial.println("Up button 1");
// while( digitalRead(UP_BUTTON) == LOW && toggle1 == TRUE && curPosition < MAX_POS){
while( digitalRead(UP_BUTTON) == LOW ){
myStepper.step(1);
curPosition++;
yield(); // Soft WDT reset が出ない様にするため。
delay(50);
}
}
// Down button
if ( digitalRead(DOWN_BUTTON) == LOW ){
Serial.println("Down button 1");
// while( digitalRead(DOWN_BUTTON) == LOW && toggle2 == TRUE && curPosition > 0 ){
while( digitalRead(DOWN_BUTTON) == LOW ){
myStepper.step(-1);
curPosition--;
yield(); // Soft WDT reset が出ない様にするため。
delay(50);
}
}
stopMotor();
#if 0
if (curPosition != initPosition ){
EEPROM.write(0, curPosition);
EEPROM.commit();
initPosition = curPosition;
Serial.print( "Save curPosition = ");
Serial.println( curPosition );
}
delay(10);
#endif
Serial.println(" End of Main loop ...");
delay(10);
}
void stopMotor() {
digitalWrite(MOTOR_1, LOW);
digitalWrite(MOTOR_2, LOW);
digitalWrite(MOTOR_3, LOW);
digitalWrite(MOTOR_4, LOW);
}
#if 0
int moveAbsPos2(long pos){
if (pos < maxPosition) {
myStepper.step(currentPosition - pos);
currentPosition = pos;
} else {
return -1;
}
}
int incrementPosBy(long pos){
if (currentPosition + pos < maxPosition) {
myStepper.step(pos);
currentPosition = currentPosition+pos;
} else {
return -1;
}
}
int decrementPosby(long pos){
if (currentPosition - pos > 0 ){
myStepper.step(-pos);
currentPosition = currentPosition - pos;
} else {
return -1;
}
}
#endif