2022年6月29日水曜日

【Arduino】 モータードライバーの放熱 【19日目】


モータードライバーが、数十秒で触れないくらいに熱くなります。

いろいろ調べてみたら、どうやらそんなものって可能性が高いみたいなので、冷却パーツをアレしました。


Amazonでポチリました

左から、ヒートシンク、冷却ファン(25mm角、5V)、+000の精密プラスドライバー、です


電流値の制限(?)

可変抵抗(?)を回すと電流値を制限できるようなことがどこかに書いてあった気がしたので、手持ちの +00の精密ドライバーを使ってみましたが回せず。(先端が入ってない?)

今回買った +000 のでも回せずで、謎は深まった。

なお、ピンセットで回したら少し動いた…


ヒートシンクと冷却ファンを取り付けました

上が取り付け前で、下が取り付け後です。

チップの表面が 8 * 16mm に対して、ヒートシンクが 22 * 22mm (高さ15mm)です。なんかそれっぽい。

冷却ファンは 25 * 25mm (厚さ10mm)で、マスキングテープで固定しました。タミヤのマスキングテープまじで優秀です。

肝心の冷却性能ですが、ヒートシンクは全く熱くならず、効いてるのか効いてないのか分からない…。

ファンは微風ですが、無いよりはずいぶん良いような雰囲気がします。気分的に。プーン、って音がして振動があるので、山洋だったりNidecだったりの同等品に替えたいところです。




2022年6月26日日曜日

【Arduino】 NEMA 17 の加減速制御ができた (ステッピングモーター) 【17日目】


NEMA 17 (ステッピングモーター)の加減速制御ができました

モータードライバーが直ぐに結構熱くなるのが懸念点


ソースコード

長いですが、以下に貼り付けます。

「とりあえず動いた」レベルで堅牢性などは不明です。

また、コーディング標準的に Arduino として適切ではない可能性もあります。

加減速から定速に移行する時に弱い衝撃があるので、滑らかにつなげる処理があった方が良いのかも知れません。(難しそう)


※修正 (2022.6.28、v1.2.1)

一部に間違いがあり、rpm が指定の半分になっていました。

赤字の太字で修正します。(4行)


StepperMotor_v1.2.0.ino

// https://www.norwegiancreations.com/2014/12/arduino-tutorial-stepper-motor-with-easydriver/ ← A3967の配線図とサンプルコード

#include "A3967.h"

// ピンアサイン
int m_pinM1 = 2;
int m_pinM2 = 3;
int m_pinDdirection = 4;
int m_pinStep = 5;

// モータードライバークラス
A3967 a3967(A3967::MicloStepTypes::EighthStep, m_pinM1, m_pinM2, m_pinDdirection, m_pinStep);

void setup()
{
    // 初期化
    a3967.Init();

    // シリアルポートの開始
    Serial.begin(9600);

    // 以下、回転動作
    a3967.Step(true, 400, 4);
    delay(1000);

    a3967.Step(false, 300, 3);
    delay(1000);
}

void loop()
{
    Test14();
}

void Test14()
{
    int maxRpm = 600;
    int rotationNumToComplete = 10;
    a3967.Accelerate(true, 0, maxRpm, rotationNumToComplete, A3967::MicloStepTypes::EighthStep);
    a3967.Accelerate(true, maxRpm, maxRpm + 1, rotationNumToComplete + 5);
    //a3967.Step(true, maxRpm, 20);
    a3967.Accelerate(true, maxRpm + 1, maxRpm, rotationNumToComplete + 5);
    a3967.Accelerate(true, maxRpm, 0, rotationNumToComplete - 2);
    delay(1000);
}


A3967.h

#include <Arduino.h>
#include "RotateCalcUtil.h"

#ifndef A3967_h
#define A3967_h

class A3967
{
public:
    // enum
    enum class MicloStepTypes { FullStep, HalfStep, QuarterStep, EighthStep };

    // コンストラクタ
    A3967(MicloStepTypes micloStep, int pinM1, int pinM2, int directionPin, int stepPin);

    // 初期化
    void Init();

    // 回転動作
    void Step(bool isClockwise, int rpm, int rotationNum, A3967::MicloStepTypes micloStepType);
    void Step(bool isClockwise, int rpm, int rotationNum);

    // 加減速動作
    void Accelerate(bool isClockwise, int rpmFrom, int rpmTo, float rotationNumToComplete, A3967::MicloStepTypes micloStepType);
    void Accelerate_01(bool isClockwise, int rpmFrom, int rpmTo, float rotationNumToComplete);
    void Accelerate(bool isClockwise, int rpmFrom, int rpmTo, float rotationNumToComplete);

private:
    // 定数
    const int BASE_STEPS_PER_ROTATION = 200;

    // 処理クラス
    RotateCalcUtil* rotateCalcUtil;

    // メンバー変数
    A3967::MicloStepTypes m_micloStepType = A3967::MicloStepTypes::EighthStep;
    int m_pinM1 = 2;
    int m_pinM2 =3;
    int m_pinDirection = 4;
    int m_pinStep = 5;

    // 1周のステップ数の取得
    int GetStepsPerRotation(A3967::MicloStepTypes micloStepType);

    // マイクロステップモードの書き込み
    void WrtiteMicloStepMode(A3967::MicloStepTypes micloStepType);
};

#endif


A3967.cpp

#include "A3967.h"

#include <Arduino.h>
#include "RotateCalcUtil.h"

/// コンストラクタ
A3967::A3967(A3967::MicloStepTypes micloStepType, int pinM1, int pinM2, int pinDirection, int pinStep)
{
    // 引数の保存
    m_micloStepType = micloStepType;
    m_pinM1 = pinM1;
    m_pinM2 = pinM2;
    m_pinDirection = pinDirection;
    m_pinStep = pinStep;

    // 処理クラスの生成
    rotateCalcUtil = new RotateCalcUtil();
}

/// 初期化
void A3967::Init()
{
    // ピンモードの設定
    pinMode(m_pinM1, OUTPUT);
    pinMode(m_pinM2, OUTPUT);
    pinMode(m_pinDirection, OUTPUT);
    pinMode(m_pinStep, OUTPUT);

    // マイクロステップモードの書き込み
    A3967::WrtiteMicloStepMode(m_micloStepType);
}

/// 回転動作
void A3967::Step(bool isClockwise, int rpm, int rotationNum, A3967::MicloStepTypes micloStepType)
{
    // 引数の保存
    m_micloStepType = micloStepType;

    // マイクロステップモードの書き込み
    A3967::WrtiteMicloStepMode(m_micloStepType);

    // 実際の回転動作
    A3967::Step(isClockwise, rpm, rotationNum);
}
void A3967::Step(bool isClockwise, int rpm, int rotationNum)
{
    // 1周のステップ数の取得
    int stepsPerRotation = A3967::GetStepsPerRotation(m_micloStepType);

    // 必要なステップ数
    int steps = stepsPerRotation * rotationNum;

    // 1ステップの時間の計算
    int microSecPerStep = rotateCalcUtil->CalcMicroSecPerStep(rpm, stepsPerRotation);
            
    //Serial.print("Step.microSecPerStep : ");
    //Serial.println(microSecPerStep);

    // 回転方向の指定
    if(isClockwise == true) { digitalWrite(m_pinDirection, HIGH); }
    else  { digitalWrite(m_pinDirection, LOW); }

    // 回転動作
    int microSecPerStepA;
    for(int i = 0; i < steps; i++)
    {
        //@@@@
        int microSecPerStepA = rotateCalcUtil->CalcMicroSecPerStep(rpm, stepsPerRotation);

        // 書き込み
        digitalWrite(m_pinStep, HIGH);
        //delayMicroseconds(microSecPerStep);
        delayMicroseconds(microSecPerStep / 2);
        digitalWrite(m_pinStep, LOW);
        //delayMicroseconds(microSecPerStep);
        delayMicroseconds(microSecPerStep / 2);
    }
}

/// 加減速動作
void A3967::Accelerate(bool isClockwise, int rpmFrom, int rpmTo, float rotationNumToComplete, A3967::MicloStepTypes micloStepType)
{
    // 引数の保存
    m_micloStepType = micloStepType;

    // マイクロステップモードの書き込み
    A3967::WrtiteMicloStepMode(m_micloStepType);

    // 実際の加減速動作
    A3967::Accelerate(isClockwise, rpmFrom, rpmTo, rotationNumToComplete);
}
void A3967::Accelerate_01(bool isClockwise, int rpmFrom, int rpmTo, float rotationNumToComplete)
{
    // 1周のステップ数の取得
    int stepsPerRotation = A3967::GetStepsPerRotation(m_micloStepType);

    // 必要なステップ数
    int steps = stepsPerRotation * rotationNumToComplete;

    // 1ステップの時間の計算(開始時と終了時)
    int microSecPerStep_From = rotateCalcUtil->CalcMicroSecPerStep(rpmFrom, stepsPerRotation);
    int microSecPerStep_To = rotateCalcUtil->CalcMicroSecPerStep(rpmTo, stepsPerRotation);

    // 差分の計算
    long microSecPerStep_Delta = 0;
    {
        int diff = microSecPerStep_To - microSecPerStep_From;
        microSecPerStep_Delta = (diff * (long)1000) / (long)steps;
    }

    // 回転方向の指定
    if(isClockwise == true) { digitalWrite(m_pinDirection, HIGH); }
    else  { digitalWrite(m_pinDirection, LOW); }

    // 加減速動作
    int microSecPerStep = microSecPerStep_From;
    long accumulation = 0;
    long temp = 0;
    for(int i = 0; i < steps; i++)
    {
        digitalWrite(m_pinStep, HIGH);
        delayMicroseconds(microSecPerStep);
        digitalWrite(m_pinStep, LOW);
        delayMicroseconds(microSecPerStep);

        // 差分の確認と適用
        accumulation += microSecPerStep_Delta;
        if(accumulation < (long)-1000 || (long)1000 < accumulation)
        {
            temp = accumulation / (long)1000;
            microSecPerStep += temp;
            accumulation -= temp * (long)1000;
        }
    }
}
void A3967::Accelerate(bool isClockwise, int rpmFrom, int rpmTo, float rotationNumToComplete)
{
    // 1周のステップ数の取得
    int stepsPerRotation = A3967::GetStepsPerRotation(m_micloStepType);

    // 必要なステップ数
    int steps = stepsPerRotation * rotationNumToComplete;

    // 差分の計算
    long rp1000000m_Delta = (long)0;
    {
        int diff = rpmTo - rpmFrom;
        rp1000000m_Delta = ((long)diff * (long)1000000) / ((long)steps - (long)1);
    }

    // 回転方向の指定
    if(isClockwise == true) { digitalWrite(m_pinDirection, HIGH); }
    else  { digitalWrite(m_pinDirection, LOW); }

    // 加減速動作
    int microSecPerStep;
    int rpm = rpmFrom;
    long accumulation = 0;
    long temp = 0;
    for(int i = 0; i < steps; i++)
    {
        // 差分の確認と適用
        if(i != 0)
        {
            accumulation += rp1000000m_Delta;
            if(accumulation < (long)-1000000 || (long)1000000 < accumulation)
            {
                temp = accumulation / (long)1000000;
                rpm += temp;
                accumulation -= temp * (long)1000000;
            }
        }

        // 1ステップの時間の計算
        microSecPerStep = rotateCalcUtil->CalcMicroSecPerStep(rpm, stepsPerRotation);

        //Serial.print("Accelerate.microSecPerStep : ");
        //Serial.println(microSecPerStep);

        // 書き込み
        digitalWrite(m_pinStep, HIGH);
        //delayMicroseconds(microSecPerStep);
        delayMicroseconds(microSecPerStep / 2);
        digitalWrite(m_pinStep, LOW);
        //delayMicroseconds(microSecPerStep);
        delayMicroseconds(microSecPerStep / 2);
    }
}

//-- 以下、privateメソッド

/// 1周のステップ数の取得
int A3967::GetStepsPerRotation(A3967::MicloStepTypes micloStepType)
{
    // 1回転のステップ数(ベース)
    int stepsPerRotation = A3967::BASE_STEPS_PER_ROTATION;

    // マイクロステップの場合は係数を適用
    if (micloStepType == A3967::MicloStepTypes::HalfStep)
    {
        stepsPerRotation = stepsPerRotation * 2;
    }
    else if (micloStepType == A3967::MicloStepTypes::QuarterStep)
    {
        stepsPerRotation = stepsPerRotation * 4;
    }
    else if (micloStepType == A3967::MicloStepTypes::EighthStep)
    {
        stepsPerRotation = stepsPerRotation * 8;
    }

    // 返す
    return stepsPerRotation;
}

/// マイクロステップモードの書き込み
void A3967::WrtiteMicloStepMode(A3967::MicloStepTypes micloStepType)
{
    if(m_micloStepType == A3967::MicloStepTypes::FullStep)
    {
        digitalWrite(m_pinM1, LOW);
        digitalWrite(m_pinM2, LOW);
    }
    else if(m_micloStepType == A3967::MicloStepTypes::HalfStep)
    {
        digitalWrite(m_pinM1, HIGH);
        digitalWrite(m_pinM2, LOW);
    }
    else if(m_micloStepType == A3967::MicloStepTypes::QuarterStep)
    {
        digitalWrite(m_pinM1, LOW);
        digitalWrite(m_pinM2, HIGH);
    }
    else
    {
        digitalWrite(m_pinM1, HIGH);
        digitalWrite(m_pinM2, HIGH);
    }
}


RotateCalcUtil.h

#ifndef RotateCalcUtil_h
#define RotateCalcUtil_h

class RotateCalcUtil
{
public:
    // コンストラクタ
    RotateCalcUtil();

    // 1ステップの時間の計算
    int CalcMicroSecPerStep(int rpm, int stepsPerRotation);

private:
};

#endif


RotateCalcUtil.cpp

#include "RotateCalcUtil.h"

#include <Arduino.h>

/// コンストラクタ
RotateCalcUtil::RotateCalcUtil()
{
    // 何もしない
}

/// 1ステップの時間の計算
int RotateCalcUtil::CalcMicroSecPerStep(int rpm, int stepsPerRotation)
{
    if(rpm < 10) { rpm = 10; }
    long rp1000s = (rpm * (long)1000) / (long)60;               // 1000秒あたりの回転数
    long stepsPer1000Sec = rp1000s * stepsPerRotation;          // 1000秒あたりのステップ数
    long microSecPerStep = (long)1000000000 / stepsPer1000Sec;  // 1ステップあたりのマイクロ秒
    int ret = (int)microSecPerStep;                             // 型変換
    return ret;
}




2022年6月25日土曜日

【Arduino】 IDE を Visual Studio Code に変更した 【16日目】

@2022/6/25


Visual Studio Code (VSCode) とは

マイクロソフト社が、統合開発環境である Visual Studio 譲りの入力支援を使用できるエディタとしてリリースしています。

拡張機能(プラグイン)をインストールすれば Arduino の統合開発環境として使用できます。

Visual Studio Code (Wikipedia)


利点

入力支援が非常に強力です (快感)


懸念点

設定に手間がかかり、場合によっては難解なこともあるかもしれません。

また、環境の変化(Arduino側のバージョンアップなど)により、再設定等が必要になる可能性もあります。


設定方法

ベースとさせてもらったページ

VSCodeでArduinoの開発をする方法

上記に補足する形で記載します


VSCode のインストール

https://visualstudio.microsoft.com/ja/downloads/


C/C++ for Visual Studio Code のインストール

左端の列の一番下のボタンから拡張機能をインストールします。

これに関してはインストールしたきりで、手動での特段の設定は行わないで大丈夫でした。(多分)

インストールした結果は↓の様になりました。

→ C/C++ IntelliSense, debugging, and code browsing
→ Popular extensions for C++ development in Visual Studio Code
→ UI Themes for C/C++ extension

※必須でないものも含まれているかも知れません


C_Cpp.default.includePath の設定

UIで実施できるようになっていました


文字化け

以前は Arduino IDE の出力する日本語が文字化けしていたようですが、2022年6月時点では何もしないで大丈夫でした


フォルダーの右クリック

インストーラを走らせることで設定できます。

変更した設定内容は保持されていました。

Windowsの右クリックメニューに「VSCodeで開く」を追加する

※「ファイルではなく」「フォルダーを」右クリックして開く必要がある




2022年6月24日金曜日

【Arduino】 NEMA 17 が回った (ステッピングモーター) 【14日目】


NEMA 17 (ステッピングモーター) が回りました

NEMA 17ステッピングモーターは3Dプリンターなどによく使われています

なので、入手が容易なのだと思われます


配線図とコードは下記を参照しました

配線図:3つ目の画像

コード:最初のコード


モータードライバー(A3967)のピンアサイン(?)

ステップ角は既定だと「Eighth Step」(マイクロステップ駆動?) になっているぽいです


モーターのピンアサイン(?)

全くの謎だったので総当たりで…

「B」側は、入れ替えても動作に変化がないのですが、個人的に非常に謎です


今まで使っていたDCジャック

なんか動作が不安定だと思ったら、これに乗っているチップがめちゃ熱くなってました

仕方がないので、どこかで見た気がした Arduino の VIN から駆動用の電力を取るのをやってみたら上手くいきました


Arduinoのピンアサイン(?)


Arduino IDE のエディター

入力補助があまりにアレなのでここで一旦コーディングを中断しました

Visual Studio Code (VS Code) にプラグインを入れて開発できるぽいので、先にその環境を作ってみようと思います




2022年6月23日木曜日

【Arduino】 モータードライバーのピンをはんだ付け 【13日目】


そんな装備で大丈夫か?


まずはブレッドボードにピンを立てると良いらしい


基盤を被せる


なんとかなった、のか?

基盤が少し溶けている疑惑がある

あと、視力が厳しい…


横から見たらガタガタだったけど、どうにか抜き差しできる




2022年6月22日水曜日

【Arduino】 はんだごてを発掘 【7日目(2)】


はんだごてを発掘

なぜか油まみれだったので掃除が必要でしたが、通電したら熱くなったので大丈夫そうです。

「goot」というシールが貼ってあり、今回買った「はんだ」「はんだ吸い取り線」と同じメーカーでした。




2022年6月16日木曜日

【Arduino】 NEMA 17 を買った (ステッピングモーター) 【7日目(1)】


Amazonから荷物が届きました


左上から反時計回りに、ステッピングモーター、モータードライバー、はんだ、はんだ吸い取り線、です


ステッピングモーターは「NEMA 17」規格のものです。3Dプリンターでよく使われています。今回は薄型のものを買いました


モータードライバーは「A3967」搭載のものを選びました。入力電圧が7.2Vでいけるらしいので。ピンは自分ではんだ付けせなあかんらしい。2個入りだった


「はんだ」と「はんだ吸い取り線」は日本製です


はんだごては家のどこかにあるので頑張って探します。

30年以上ぶりのはんだ付けにチャレンジです。




(Arduino) 駆動部のたたき台 【5日目】


手持ちの部品で駆動部のたたき台を作ってみた

プーリはGT2規格で20歯です。6mm幅のGT2ベルトが使用できます。タイミングプーリー、アイドラープーリー関わらず、ボルトで締めこめばそこそこ固定できそうです。Amazonで買いました。

ボルト関係はM5で、ボルトはM5*60です。その他にワッシャ、スプリングワッシャ、ナット、スペーサー(3mm、4mm)を使用しています。モノタロウで買いました。

スペーサーは、本来は締めこむときの隙間調整に用います。今回はユルユルにしてブッシュやベアリングの代用にしようと思っています。

※部品は、以前にレーザー加工機(Fabool Laser Mini)を改修したときの残りです




2022年6月13日月曜日

【Arduino】 ステッピングモーターをばらしてみた 【4日目(2)】


モーター (間違って買った12Vの28BYJ-48) をばらしてみた


思ってたよりギヤが小さく、モーターが大きい


出力軸が独特 (平面取りが対向している) なんだよなぁ…




【Arduino】 お寿司を食べて容器をゲット 【4日目(1)】


お寿司を食べて容器をゲット


サイズぴったり


残念ながら蓋は閉まらず





2022年6月12日日曜日

【Arduino】 ステッピングモーターの加減速制御ができました 【3日目】


ステッピングモーターの加減速制御ができました

Stepperクラスのコンストラクタの第一引数を大きくすると、なぜか最高回転数が上がる…

そして、なぜかドレミファインバーターの音に似ている




【Arduino】 概要的に参考になった動画 【2日目(3)】


電子工作の概要(?)


マイコンの概要(?)


パーツの買い方


「いったいどうなってるんや。わけ分らんぞ」ってなってる時にすんごい助かった




【Arduino】 アキバでいろいろゲット 【2日目(2)】


所用の帰りに秋葉原に寄って買ってきたものたち

えー、モーターは電圧違いのものを買ってしまった

モーターのドライバーに至っては挫折して帰ってきた…

店員さんは思ったよりは親切だったんですが


電池ボックスが100円くらいで、モーターは300円くらい

ギヤは500円くらいです

電子工作の部品って安いんですねぇ


ちなみに、プラレールの動力部は結構ごついです


とりあえず、外部電源を不要にできた

移動体に搭載が可能ぽく思えてきた




【Arduino】 バッテリーをゲット 【2日目(1)】


実家から強奪した充電池(単3)

じゃなくて「余ってるのがあったら貸して」って言ったらくれたやつ

なんか微妙に高そう


手持ちのモバイルバッテリー

消費電流が小さいと自動でスリープしてしまうバッテリーが多いらしい

黒いバッテリーが使えた

新しく買う場合は「IoT対応モバイルバッテリー」にすれば良いらしい




【Arduino】 ステッピングモーターを回してみた 【1日目(2)】


USBケーブルが届かないので手持ちのもの(黒)を投入


こんな感じ (ステッピングモーターにしか興味がない模様)


回転が遅いですね…




【Arduino】 入門キットをポチった 【1日目(1)】


4700円くらいでした


ステッピングモーターにしか興味がない模様


Amazon で買いました

https://www.amazon.co.jp/gp/product/B06XF2HZGT/

(ELEGOO Arduino用UNO R3スターターキット レベルアップ チュートリアル付 mega2560 r3 nanoと互換 [並行輸入品])