コイル巻線器の製作


 Arduino NANOを使ってコイル巻線器を製作

Arduino NANO、A4988モジュール、CNCシールド4を使ってコイル巻線器を製作。



ステッピングモーターを2個使って、コイル巻線器を作ってみました。
 前記の「ステッピングモーターを回す」 で使用したArduino NANOを用いて2個のステッピングモーターを回し、 LCD表示でワイヤーの太さと巻き数を入力して稼働させるようにしました。
 最初は、もっと簡易な巻線器を考えていましたが、出来上がってみると少し大げさなものになりました。。


  コイル巻線器の完成図


完成したのコイル巻線器の写真です。






  出来上がったコイル


0.2mmのエナメル線を塩ビのボビンとボルトに巻いてみました。

1.塩ビのボビン(100均で購入)に450回巻いてみました。

2.ボルトに550回巻いてみました。



 100均のボビンは、両端の円盤(鍔)が中心部の厚さと外側の厚さが違っています。外側に行くほど 薄くなっているので巻き取りが綺麗に出来ません。
 その点、ボルトに巻く場合、両端の円盤(鍔)は均一の厚さなのでエナメル線を均等に巻くことが出来ます。





  回路図


 Arduino NANO、CNCシールドV4(HW-702)、I2C接続キャラクタLCDモジュール「ACM1602NI」を用いた回路図です。





  使用部品


 使用した部品のリストです。
 詳細は、前記の「ステッピングモーターを回す」 を参照してください。

 *Arduino NANO
 *CNCシールドV4(HW-702)
 *モータードライバーモジュールA4988 2個
 *LCDモジュール「ACM1602NI」
 *ステッピングモーター2個
 *マイクロスイッチ2個
 *スイッチ類
  ・プッシュスイッチ4個、スライドスイッチ1個、トグルスイッチ1個
 *その他CNC部品
 *3Dプリンター製作部品
 *DC電源 12V 10A




  機械的な構造について


 機械部品はCNC用の物を全てAliExpressで購入しました。

1.ワイヤーの送り出し器
 購入すると高価なのでボールペンの先を使用しました。そのためワイヤーの太さは、0.1mm~0.4mmまでしか使えません。


2.ワイヤーのテンションについて
 ワイヤーのテンションとして、バネ仕掛けのルーラー、ピアノ線、元のワイヤー巻取器の重さ等を使用しました。






3.ワイヤーの送り出し器の左右の動きのタイミングと調整。
 左右の動きのタイミングは、マイクロスイッチでモーターが反転し、ワイヤーの送り出し器が左から右へ、また、 右から左へと移動します。
 マイクロスイッチの位置調整は、巻き取るものによって調整します。
 写真の左側に見える先の尖ったもので巻き取るものの幅に合わせて位置調整をします。調整後固定します。


4.白いルーラー及び黒い部品は全て、3Dプリンターで作成しました。




  LCD表示器について


 LCD表示器で、ワイヤーの太さと巻き数を入力します。 入力表示されているのは、ワイヤーの太さが0.2mm、巻き数が450回の設定です。

*左側の赤いプッシュスイッチは、入力の際、押すと数値を増加させます。

*黒いプッシュスイッチは、入力の際、押すと数値を減少させます。

*黄色のプッシュスイッチは、入力の際、押すとカーソルを移動します。

*緑のプッシュスイッチは、入力後、押すとワイヤーの送り出し器を右側の定位置 (マイクロスイッチの位置)に移動させます。


*左上のスイッチは、電源スイッチです。

*左下のスライドスイッチは、入力設定後の巻線器のスタートスイッチです。途中で止める場合にも使用します。




  実際の巻き数の表示


 実際の巻き数を表示させたいと思い、LCDでの表示も考えましたが、 2個のステッピングモーターをステートマシンで動かしているため余分なコードは 入れたくなかったので、100均で購入した電子カウンターを改造して使うことにしました。
 円盤に磁石を付けたものを回転軸にセットし、その下にリードスイッチを設定して回転数を 計測することにしました。(この表示器は実際には必要ありませんが、なかば遊びで付けました。)

1.リードスイッチの装着
 3Dプリンターでリードスイッチを装着するケースを作成し、中にリードスイッチを入れました。


2.100均で購入した電子カウンターを改造





  スケッチプログラム


 参考にならないと思いますが、次に記載しておきます。

	
#include <Wire.h>
#include <LcdCore.h>
#include <LCD_ACM1602NI.h>

class Motor {
  int DIRpin;
  int STEPpin;
  long updateInterval;
  int motorState;
  unsigned long previousMillis;

  public:
  Motor( int pin1, int pin2, long interval) {
    DIRpin = pin1;
    STEPpin = pin2;
    pinMode(DIRpin,OUTPUT);
    pinMode(STEPpin,OUTPUT);
    updateInterval = interval;
    motorState = LOW;
    previousMillis = 0;
  }
  
  void Update(int dirState){
    digitalWrite(DIRpin,dirState);
    unsigned long currentMillis = micros();
    if((motorState == HIGH) && (currentMillis - previousMillis >= updateInterval)) {
        motorState = LOW;
        previousMillis = currentMillis;
        digitalWrite(STEPpin,motorState);
    }
    else if((motorState == LOW) && (currentMillis - previousMillis >= updateInterval)) {
        motorState = HIGH;
        previousMillis = currentMillis;
        digitalWrite(STEPpin,motorState);  
    }
  }
};

Motor motor1(2, 5, 2000);
Motor motor21(3, 6, 18146);
Motor motor22(3, 6, 9073);
Motor motor23(3, 6, 6049);
Motor motor24(3, 6, 4537);

LCD_ACM1602NI lcd(0xa0);
int buttonPin[]  = {4,7,9};
int buttonState[]  = {0,0,0};
int lastbuttonState[] = {0,0,0};
int count = 0;
int value = 0;
long Rep;
int pos = 0;
int line = 0;
unsigned long repMillis;
int rep_state = LOW;
int rep_latch = LOW;
long repInterval;
int R_val;
int F_val;
int state = 0;
int value1;
int value2;
int value3;
int value4;

void setup() {
  pinMode(buttonPin[0],INPUT);
  pinMode(buttonPin[1],INPUT);
  pinMode(buttonPin[2],INPUT);
  pinMode(8,OUTPUT);
  pinMode(10,INPUT);
  pinMode(11,INPUT);
  pinMode(12,INPUT);
  pinMode(A0,INPUT);
  
  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("WireThick=0.0");  
  lcd.setCursor(0,1);
  lcd.cursor();
  lcd.print("Rep=000");  
  lcd.cursor();
  pos=12;
  line=0;
  
  LcdSet();
  HomeMachien();
  repInterval = Rep*800;
}

void loop() {
  rep_state = digitalRead(A0);
  if(rep_state == HIGH) {
    if(rep_latch == LOW && rep_state == HIGH){
      digitalWrite(8,LOW);
      repMillis = millis();
      rep_latch = HIGH;
    }
    if(millis() - repMillis >= repInterval) {
      digitalWrite(8,HIGH);
    }else {
      motor1.Update(0);
      R_val = digitalRead(11);
      F_val = digitalRead(10);
      if((R_val == 0) && (state == 0)){
        state = 1 - state;
      }
      if((F_val == 0) && (state == 1)){
        state = 1 - state;     
      }
      if(state == 1){
        switch (value1) {
          case 1;
            motor21.Update(1);
            break;
          case 2;
            motor22.Update(1);
            break;
          case 3;
            motor23.Update(1);
            break;
          case 4;
            motor24.Update(1);
            break;
        }  
      }else{
        switch (value1) {
          case 1;
            motor21.Update(0);
            break;
          case 2;
            motor22.Update(0);
            break;
          case 3;
            motor23.Update(0);
            break;
          case 4;
            motor24.Update(0);
            break;
        }
      }
    }
  }
}
 
void LcdSet() {
  while(digitalRead(12) == LOW) {
    disp();
    buttoncheck();
    dispAct();
    
    if(pos == 4 && line == 1){
      value2 = value;  
    }else if (pos == 5 && line == 1){
      value3 = value;
    }else if (pos == 6 && line == 1){
      value4 = value;
    }
    Rep = value2*100 + value3*10 + value4;
    delay(100);
  }
}

void HomeMachien() {
  while(digitalRead(11) == HIGH) {
    motor24.Update(0);
  }
  digitalWrite(8,HIGH);
}

void dispAct() {
  for( int i = 0; i <= 2; i++) {
    if((buttonState[i] != lastbuttonState[i]) && (buttonState[i] == HIGH)) {
      buttonState[i] = 1 - buttonState[i];
      switch (i) {
        case 0:
          count++;
          if(count > 9) count = 0;
          value = count;
          break;
        case 1:
          if(count > 0) { 
            count --;
            value = count;
          }
          break;
        case 2:
          if(pos == 12 && line == 0){
            value1 = value;
            pos = 4;
            line = 1;  
          }else{
            line = 1;
            if(pos > 5)
              pos = 4;
            else  
              pos++;
          }
          value = 0;
          count = 0;
          break;
          
        default:
        lastbuttonState[i] = buttonState[i];
      }
    }
  }
  delay(100);
}

void disp() {
  lcd.setCursor(pos,line);
  lcd.cursor();
  lcd.print(value);
}

void buttoncheck() {
  for(int i = 0; i <=2; i++) {
    buttonState[i] = digitalRead(buttonPin[i]);
  }
}


						




  修正プログラム


 最初のclass Motor { }部分をヘッダーファイルにしました
以下のようなヘッダーファイルを作成して、ライブラリーに追加しスケッチを簡略化しました。

1.ヘッダーファイル StepMotorCtrl_h の作成
 以下のような宣言にしました。

#ifndef StepMotorCtrl_h
#define StepMotorCtrl_h

#include "arduino.h"

class StepMotorCtrl{
  public:
    StepMotorCtrl (unsigned int DirectionInPutPin, unsigned int StepInputPin, unsigned long Interval);

    void initialize(void);
    void Update(int dirState);

  private:
    unsigned int DIRpin;
    unsigned int STEPpin;
    unsigned long updateInterval;
    unsigned long previousMillis;
    int motorState;
};
#endif
						


2.C++ファイルStepMotorCtrl.cppの作成
 以下のようなC++ファイルにしました。

#if defined(ARDUINO) && ARDUINO >= 100
	#include "Arduino.h"
#else
	#include "WProgram.h"
	#include <pins_arduino.h>
#endif

#include "StepMotorCtrl.h"

StepMotorCtrl::StepMotorCtrl (unsigned int DirectionInputPin, unsigned int StepInputPin, unsigned long Interval){
  DIRpin=DirectionInputPin;
  STEPpin=StepInputPin;
  updateInterval=Interval;
}

void StepMotorCtrl::initialize(void){
  pinMode(DIRpin, OUTPUT);
  pinMode(STEPpin, OUTPUT);
    
  previousMillis=0;
  motorState=LOW;
}

void StepMotorCtrl::Update(int dirState){
  digitalWrite(DIRpin, dirState);
  unsigned long currentMillis = micros();
  if((motorState == HIGH)&&(currentMillis - previousMillis >= updateInterval)){
    motorState = LOW;
    previousMillis = currentMillis;
    digitalWrite(STEPpin,motorState);
  } else if((motorState == LOW)&&(currentMillis - previousMillis >= updateInterval)){
    motorState = HIGH;
    previousMillis = currentMillis;
    digitalWrite(STEPpin,motorState);
  }
}
						


なお、keywords.txtは省略しました。
 以上のファイルStepMotorCtrl.h と StepMotorCtrl.cppをArduino librariesのStepMotorCtrlホルダーに 挿入しました。

3.修正スケッチ
 このStepMotorCtrl.hを使って前記のスケッチプログラムを次のように修正しました。

#include <StepMotorCtrl.h>
#include <Wire.h>
#include <LcdCore.h>
#include <LCD_ACM1602NI.h>

StepMotorCtrl motor1(2, 5, 2000);
StepMotorCtrl motor21(3, 6, 18146);
StepMotorCtrl motor22(3, 6, 9073);
StepMotorCtrl motor23(3, 6, 6049);
StepMotorCtrl motor24(3, 6, 4537);

LCD_ACM1602NI lcd(0xa0);
int buttonPin[]  = {4,7,9};
int buttonState[]  = {0,0,0};
int lastbuttonState[] = {0,0,0};
int count = 0;
int value = 0;
long Rep;
int pos = 0;
int line = 0;
unsigned long repMillis;
int rep_state = LOW;
int rep_latch = LOW;
long repInterval;
int R_val;
int F_val;
int state = 0;
int value1;
int value2;
int value3;
int value4;

void setup() {
  motor1.initialize();
  motor21.initialize();
  motor22.initialize();
  motor23.initialize();
  motor24.initialize();

  pinMode(buttonPin[0],INPUT);
  pinMode(buttonPin[1],INPUT);
  pinMode(buttonPin[2],INPUT);
  pinMode(8,OUTPUT);
  pinMode(10,INPUT);
  pinMode(11,INPUT);
  pinMode(12,INPUT);
  pinMode(A0,INPUT);

  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("WireThick=0.0");  
  lcd.setCursor(0,1);
  lcd.cursor();
  lcd.print("Rep=000");  
  lcd.cursor();
  pos=12;
  line=0;

  LcdSet();
  HomeMachien();
  repInterval = Rep*800;
}

void loop() {
  rep_state = digitalRead(A0);
  if(rep_state == HIGH) {
    if(rep_latch == LOW && rep_state == HIGH){
      digitalWrite(8,LOW);
      repMillis = millis();
      rep_latch = HIGH;
    }
    if(millis() - repMillis >= repInterval) {
      digitalWrite(8,HIGH);
    }else {
      motor1.Update(0);
      R_val = digitalRead(11);
      F_val = digitalRead(10);

      if((R_val == 0)&&(state == 0)){
        state = 1 - state;
      }

      if((F_val == 0)&&(state == 1)){
        state = 1 - state;     
      }

      if(state == 1){
        switch (value1) {
          case 1:
            motor21.Update(1);
            break;
          case 2:
            motor22.Update(1);
            break;
          case 3:
            motor23.Update(1);
            break;
          case 4:
            motor24.Update(1);
            break;
        }  
      }else{
        switch (value1) {
          case 1:
            motor21.Update(0);
            break;
          case 2:
            motor22.Update(0);
            break;
          case 3:
            motor23.Update(0);
            break;
          case 4:
            motor24.Update(0);
            break;
        }
      }
    }
  }
}
 
void LcdSet() {
  while(digitalRead(12) == LOW) {
    disp();
    buttoncheck();
    dispAct();

    if(pos == 4 && line == 1){
      value2 = value;  
    }else if (pos == 5 && line == 1){
      value3 = value;
    }else if (pos == 6 && line == 1){
      value4 = value;
    }
    Rep = value2*100 + value3*10 + value4;
    delay(100);
  }
}

void HomeMachien() {
  while(digitalRead(11) == HIGH) {
    motor24.Update(0);
  }
  digitalWrite(8,HIGH);
}

void dispAct() {
  for( int i = 0; i <= 2; i++) {
    if((buttonState[i] != lastbuttonState[i]) && (buttonState[i] == HIGH)) {
      buttonState[i] = 1 - buttonState[i];
      switch (i) {
        case 0:
          count++;
          if(count > 9) count = 0;
          value = count;
          break;
        case 1:
          if(count > 0) { 
            count --;
            value = count;
          }
          break;
        case 2:
          if(pos == 12 && line == 0){
            value1 = value;
            pos = 4;
            line = 1;  
          }else{
            line = 1;
            if(pos > 5)
              pos = 4;
            else  
              pos++;
          }
          value = 0;
          count = 0;
          break;
        default:
          lastbuttonState[i] = buttonState[i];
      }
    }
  }
  delay(100);
}

void disp() {
  lcd.setCursor(pos,line);
  lcd.cursor();
  lcd.print(value);
}

void buttoncheck() {
  for(int i = 0; i<=2; i++) {
    buttonState[i] = digitalRead(buttonPin[i]);
  }
}
						





  Wire-movement-motorの回転スピードのコントロールを設定


 Wire-movement-motor(ワイヤー送り器用のモーター)の回転スピードをコントロールするボリュームを 設定しました。
 ArduinoのA3端子にボリュームの中間端子を接続し、若干の回転スピードをコントロールするようにしました。
 それに伴い、以下のようにヘッダーファイル StepMotorCtrl_h、StepMotorCtrl.cppとスケッチプログラムを 変更しました。

1.ヘッダーファイル StepMotorCtrl_h の変更
 以下のように変更しました。

#ifndef StepMotorCtrl_h
#define StepMotorCtrl_h

#include "arduino.h"

class StepMotorCtrl{
  public:
    StepMotorCtrl (int DirectionInPutPin, int StepInputPin, long Interval);

    void initialize(void);
    void Update(int dirState, int upturn);  //変数upturnを追加

  private:
    int DIRpin;
    int STEPpin;
    long updateInterval;
    unsigned long previousMillis;
    int motorState;
};
#endif
						


2.C++ファイルStepMotorCtrl.cppの変更
 以下のように変更しました。

#include "StepMotorCtrl.h"

StepMotorCtrl::StepMotorCtrl (int DirectionInputPin, int StepInputPin, long Interval){
  DIRpin=DirectionInputPin;
  STEPpin=StepInputPin;
  updateInterval=Interval;
}

void StepMotorCtrl::initialize(void){
  pinMode(DIRpin, OUTPUT);
  pinMode(STEPpin, OUTPUT);
    
  previousMillis=0;
  motorState=LOW;
}

void StepMotorCtrl::Update(int dirState, int upturn){
  digitalWrite(DIRpin, dirState);
  unsigned long currentMillis = micros();
  if((motorState == HIGH)&&(currentMillis - previousMillis >= updateInterval + upturn)){
    motorState = LOW;
    previousMillis = currentMillis;
    digitalWrite(STEPpin,motorState);
  } else if((motorState == LOW)&&(currentMillis - previousMillis >= updateInterval + upturn)){
    motorState = HIGH;
    previousMillis = currentMillis;
    digitalWrite(STEPpin,motorState);
  }
}
						


3.スケッチプログラムの変更
 以下のように変更しました。

#include <StepMotorCtrl.h>
#include <Wire.h>
#include <LcdCore.h>
#include <LCD_ACM1602NI.h>

StepMotorCtrl motor1(2, 5, 2000);
StepMotorCtrl motor21(3, 6, 17646);
StepMotorCtrl motor22(3, 6, 8573);
StepMotorCtrl motor23(3, 6, 5549);
StepMotorCtrl motor24(3, 6, 4037);

LCD_ACM1602NI lcd(0xa0);
int buttonPin[]  = {4,7,9};
int buttonState[]  = {0,0,0};
int lastbuttonState[] = {0,0,0};
int analogPin = A3;
int turnPlus = 0;
int count = 0;
int value = 0;
long Rep;
int pos = 0;
int line = 0;
unsigned long repMillis;
int rep_state = LOW;
int rep_latch = LOW;
long repInterval;
int R_val;
int F_val;
int state = 0;
int value1;
int value2;
int value3;
int value4;

void setup() {
  motor1.initialize();
  motor21.initialize();
  motor22.initialize();
  motor23.initialize();
  motor24.initialize();
    
  pinMode(buttonPin[0],INPUT);
  pinMode(buttonPin[1],INPUT);
  pinMode(buttonPin[2],INPUT);
  pinMode(8,OUTPUT);
  pinMode(10,INPUT);
  pinMode(11,INPUT);
  pinMode(12,INPUT);
  pinMode(A0,INPUT);

  lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("WireThick=0.0");  
  lcd.setCursor(0,1);
  lcd.cursor();
  lcd.print("Rep=000");  
  lcd.cursor();
  pos=12;
  line=0;

  LcdSet();
  HomeMachien();
  repInterval = Rep*800;
}

void loop() {
  rep_state = digitalRead(A0);
  turnPlus = analogRead(analogPin);
  if(rep_state == HIGH) {
    if(rep_latch == LOW && rep_state == HIGH){
      digitalWrite(8,LOW);
      repMillis = millis();
      rep_latch = HIGH;
    }
    if(millis() - repMillis >= repInterval) {
      digitalWrite(8,HIGH);
    }else {
      motor1.Update(0, 0);
      R_val = digitalRead(11);
      F_val = digitalRead(10);
            
      if((R_val == 0)&&(state == 0)){
        state = 1 - state;
      }
            
      if((F_val == 0)&&(state == 1)){
        state = 1 - state;     
      }
            
      if(state == 1){
        switch (value1) {
          case 1:
            motor21.Update(1, turnPlus);
            break;
          case 2:
            motor22.Update(1, turnPlus);
            break;
          case 3:
            motor23.Update(1, turnPlus);
            break;
          case 4:
            motor24.Update(1, turnPlus);
            break;
        }  
      }else{
        switch (value1) {
          case 1:
            motor21.Update(0, turnPlus);
            break;
          case 2:
            motor22.Update(0, turnPlus);
            break;
          case 3:
            motor23.Update(0, turnPlus);
            break;
          case 4:
            motor24.Update(0, turnPlus);
            break;
        }
      }
    }
  }
}
 
void LcdSet() {
  while(digitalRead(12) == LOW) {
    disp();
    buttoncheck();
    dispAct();
    
    if(pos == 4 && line == 1){
      value2 = value;  
    }else if (pos == 5 && line == 1){
      value3 = value;
    }else if (pos == 6 && line == 1){
      value4 = value;
    }
    Rep = value2*100 + value3*10 + value4;
    delay(100);
  }
}

void HomeMachien() {
  while(digitalRead(11) == HIGH) {
    motor24.Update(0, 0);
  }
  digitalWrite(8,HIGH);
}

void dispAct() {
  for( int i = 0; i <= 2; i++) {
    if((buttonState[i] != lastbuttonState[i]) && (buttonState[i] == HIGH)) {
      buttonState[i] = 1 - buttonState[i];
      switch (i) {
        case 0:
          count++;
          if(count>9) count = 0;
            value = count;
          break;
        case 1:
          if(count>0) { 
            count --;
            value = count;
          }
          break;
        case 2:
          if(pos == 12 && line == 0){
            value1 = value;
            pos = 4;
            line = 1;  
          }else{
            line = 1;
            if(pos > 5)
              pos = 4;
            else  
              pos++;
          }
          value = 0;
          count = 0;
          break;
        default:
          lastbuttonState[i] = buttonState[i];
      }
    }
  }
  delay(100);
}

void disp() {
  lcd.setCursor(pos,line);
  lcd.cursor();
  lcd.print(value);
}

void buttoncheck() {
  for(int i = 0; i<=2; i++) {
    buttonState[i] = digitalRead(buttonPin[i]);
  }
}