工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

DIYSMDリワークステーション

コンポーネントと消耗品

>
SparkFun Arduino Pro Mini 328-5V / 16MHz
× 1
Adafruit標準LCD-16x2白地に青
× 1
lcdi2cモジュール
× 1
プッシュボタン付きロータリーエンコーダー
× 1
ホットエアガンハンドル
× 1
ホットエアガンハンドルホルダー+ノズル
× 1
BTA12-600B
× 1
IRFZ44
× 1
MCP602
× 1
MOC3052
× 1
4N25
× 1
ブリッジ整流器
× 1
ブザー
× 1
FR107高速整流ダイオード
× 1
0.01 uFコンデンサ、400V
× 1
コンデンサ100nF
× 6
スルーホール抵抗、39オーム
× 1
スルーホール抵抗、33kohm
× 2
抵抗330オーム
× 1
抵抗220オーム
× 1
抵抗1kオーム
× 3
スルーホール抵抗、470オーム
× 1
500kマルチターンポテンショメータ
× 1
抵抗10kオーム
× 3

必要なツールとマシン

>
はんだごて(汎用)

アプリとオンラインサービス

>
Arduino IDE
Autodesk Eagle

このプロジェクトについて

イントロ:DIYSMDリワークステーション

このチュートリアルでは、Arduinoやその他の一般的なコンポーネントを使用してホットエアガンコントローラーを作成する方法を学ぶことができます。このプロジェクトでは、PIDアルゴリズムを使用して必要な電力を計算し、分離されたTriacドライバーによって制御されます。

このプロジェクトでは、858Dと互換性のあるハンドルを使用しています。 Kタイプの熱電対、700ワットの230 VACヒーター、24VDCファンを備えています。

このコントローラーは、市販のコントローラーに比べて効率的で信頼性が高く、簡単に作成できます。

ステップ1:配線

下の写真に示されている完全なスキーマ。

<図>


I2C LCDモジュールの配線:

I2Cモジュール<--------------> Arduino Pro Mini

GND <-----------------------> GND <---------> GND

VCC <------------------------> VCC <---------> 5V

SDA <-------------------------------------------> A4

>

SCL <-------------------------------------------> A5。

ロータリーエンコーダモジュールの配線:

エンコーダ<----------------------> Arduino

GND <---------------------------> GND

+ <--------------------------------> NC(接続されていません、コードはarduinoの組み込み入力プルアップを使用します)

SW <-----------------------------> D5

DT <------------------------------> D3

CLK <----------------------------> D4。

ハンドルの配線: (7線)

3ピンコネクタ-(緑、黒、赤)

赤い線<----------------------->熱電対+

緑のワイヤー<-------------------->リードスイッチ

黒線<--------------------->共通アース。

2ピンコネクタ-(青、黄)

青いワイヤー<-------------------------->ファン+0

黄色のワイヤー<------------------------>ファン-(またはGND)

2ビッグピンコネクタ-(白、茶色)

白いワイヤー<----------------------->ヒーター

茶色のワイヤー<---------------------->ヒーター(極性なし)

注:

熱風ガンハンドルの配線は、ワンドの種類によって異なる場合があります。そのため、写真の配線図を参照し、配線の経路をたどってそれぞれのピンを見つけてください。

ステップ2:回路図

回路は主に3つの部分で構成されています。

インターフェース部分:

これは、I2Cモジュールを備えた1602 LCDディスプレイと、プッシュボタンを備えたロータリーエンコーダで構成されています。ディスプレイには、設定温度、現在の温度、ファン速度、適用電力、およびハンドルの現在のステータスが表示されます。エンコーダーは、さまざまな入力や、オプションやコントロールをナビゲートするために使用されます。

センサーパーツ:

温度検知用のK型熱電対とハンドルの位置を決定するためのリードスイッチで構成されています。熱電対の電圧は、オペアンプによって増幅され、arduinoで測定可能な電圧レベルになります。オペアンプのゲインは200Kトリムポットによって制御されます。

コントローラー部分:

この回路には主に2つのコントローラーがあります。 1つは、MOSFETを備えた単純なPWMファン速度コントローラーです。もう1つはヒーター用の絶縁コントローラーです。これは、光結合DIACによって駆動されるトライアックで構成され、ヒーターに供給される波のサイクル数を制御することによって行われます。 4N25オプトカプラーはAC波形との同期を維持するのに役立ちます。

ステップ3:PCB

このプロジェクトの回路は少し複雑なので、ドットPCBよりもプリント基板を使用することをお勧めします。独自のPCBを作成したい場合は、プロジェクトの最後にイーグルファイルを添付しました。ただし、PCB製造会社に依頼したい場合は、JLCPCBに注文できます

。 Easy EDAの設計は、次のリンクから表示できます:https://easyeda.com/ManojBR/harws1-1

ステップ4:コードとライブラリ

このプログラムはプロジェクトの最も重要な部分であり、 sfrwmaker に感謝します。 プログラムを書く。プログラムは PIDアルゴリズムを使用します 設定温度を維持するために電力を制御します。これは、1秒あたりにハンドルに送られる波のサイクル数を制御することによって機能します。

コントローラをオンにすると、ワンドはオフ状態になります。 エンコーダーを回転させる 温度とファン速度を調整できます。 短押し エンコーダのはファン速度と設定温度調整を切り替えます。

ホットエアガンは、ホルダーから持ち上げられるとすぐに加熱を開始し、準備完了を示し、設定温度に達すると短いビープ音を鳴らします。ホルダーに戻すとすぐに加熱がオフになります。ただし、ファンは安全な温度に達するまで吹き続けます。温度が50°Cを下回ると、短いビープ音が鳴り、COLDが表示されます。

ホットエアガンがオフの場合、コントローラーはセットアップモードに入ります。 エンコーダが長押しの場合 。

セットアップモードには、[調整]、[調整]、[保存]、[キャンセル]、[構成のリセット]オプションがあります。

注: easyEDA のPCBを使用している場合 次に、リードスイッチのピン番号をピン番号に変更する必要があります。 8 およびブザーピンからピン番号6へ

コードを正しく機能させるには、Commoncontrols-masterライブラリとtime-masterライブラリをインストールする必要があります。

注意: ファームウェアをフラッシュするときは、コントローラーを電源コンセントに接続しないでください。ファンの非絶縁型電源装置は、ラップトップに損傷を与える可能性があります。

プロジェクトページからスケッチソースコードをダウンロードします。

ステップ5:セットアップ

温度の読み取り値は、妥当な読み取り値を取得するために元の値で校正する必要があります。したがって、これを行うには、次の手順に従う必要があります。

まず、セットアップモードに移動して[調整]オプションを選択します。調整モードでは、内部温度(0-1023)が画面に表示されます。エンコーダーを回転させて、熱風ガンに適用される電力を手動で選択します。ガンを400度に加熱します。温度と分散が低くなると、コントローラーがビープ音を鳴らします。次に、トリムポットを調整して、内部温度を約900(内部単位)に設定します。エンコーダーを長押ししてメニューに戻ります

次に、セットアップモードに移動し、[調整]オプションを選択します。キャリブレーションポイントを選択します:200、300、または400度、エンコーダーを押します。ホットガンは希望の温度に達し、ビープ音を鳴らします。エンコーダーを回転させて、実際の温度を入力します。次に、別の参照ポイントを選択し、すべてのキャリブレーションポイントに対してこのプロセスを繰り返します。

この長押しの後、メイン画面に移動し、もう一度セットアップモードに移動して、[保存]を選択します。

これで、熱風リワークステーションが完成しました。

ステップ6:ビデオ!

ビデオでコントローラーの動作を見てください。

コードを書いてくれてありがとうsfrwmaker。

LCSCのサポートに感謝します。 LCSC Electronicsは、中国で最も急成長している電子部品のサプライヤーの1つです。 LCSCは、2011年の設立以来、多種多様な本物の在庫品の提供に取り組んできました。アジアからのより優れた部品を全世界に提供することを目指しています。詳細については、https://lcsc.com/

をご覧ください。

自宅で独自のPCBを作成する必要がある場合は、次のチュートリアルを確認してください:https://www.instructables.com/id/PCB-Making-1/

ありがとうございます。

コード

  • ファームウェア1.4
ファームウェア1.4 C / C ++
アクティブ/パッシブブザーのサポート。 BUZZER_ACTIVEパラメータを変更してください
ロータリーエンコーダーを増やす必要はもうありません。値が1ずつ変化します。
 / * * atmega328ICに基づくホットエアガンコントローラー*バージョン1.4 * 2020年12月5日リリース* /#include  #include  #include  #include  #include  #include  #include  const uint16_t temp_minC =100; //コントローラーが正確にチェックできる最低温度constuint16_t temp_maxC =500; //可能な最大温度定数uint16_ttemp_ambC =25; //平均周囲温度constuint16_t temp_tip [3] ={200、300、400}; //キャリブレーションの温度基準点constuint16_t min_working_fan =100; //可能な最小のファン速度constuint8_t AC_SYNC_PIN =2; //コンセント220v同期ピン。変更しないでください!const uint8_t HOT_GUN_PIN =7; //ホットガンヒーター管理pinconstuint8_t FAN_GUN_PIN =9; //ホットガンファン管理ピン。変えないで! const uint8_t TEMP_GUN_PIN =A0; //ホットガンの温度チェックpinconstuint8_t R_MAIN_PIN =3; //ロータリーエンコーダのメインピン。変更しないでください!const uint8_t R_SECD_PIN =4; //ロータリーエンコーダのセカンダリpinconstuint8_t R_BUTN_PIN =5; //ロータリーエンコーダボタンpinconstuint8_t REED_SW_PIN =8; //リードスイッチpinconstuint8_t BUZZER_PIN =6; //ブザーpinconstbool BUZZER_ACTIVE =true; // + 5vが供給されると、アクティブなブザーがビープ音を鳴らします// ------------------------------------- - - - 設定データ - - - - - - - - - - - - - - - - - - - - - - ----- / * EEPROMの構成レコードの形式は次のとおりです。* uint32_tIDを1ずつインクリメントするたびに* struct cfg構成データ、8バイト*バイトCRCチェックサム* / structcfg {uint32_tキャリブレーション; // 3つの温度ポイントでパックされたキャリブレーションデータuint16_ttemp; //内部単位でのIRONのプリセット温度uint8_tファン; //プリセットファン速度0〜255 uint8_t off_timeout; //自動スイッチオフタイムアウト}; class CONFIG {public:CONFIG(){can_write =false; buffRecords =0; rAddr =wAddr =0; eLength =0; nextRecID =0; uint8_t rs =sizeof(struct cfg)+ 5; //設定レコードの合計サイズ//適切なレコードサイズを選択します。レコードサイズは2の累乗である必要があります。つまり、(record_size =8; record_size  recID){minRecID =recID; minRecAddr =addr; } if(maxRecID  eLength)wAddr =0; } else {wAddr =minRecAddr; } can_write =true;} void CONFIG ::getConfig(struct cfg&Cfg){memcpy(&Cfg、&Config、sizeof(struct cfg));} void CONFIG ::updateConfig(struct cfg&Cfg){memcpy(&Config、&Cfg、sizeof( struct cfg));} bool CONFIG ::saveConfig(struct cfg&Cfg){updateConfig(Cfg); save();を返します。 //新しいデータをEEPROMに保存します} bool CONFIG ::save(void){if(!can_write)return can_write; if(nextRecID ==0)nextRecID =1; uint16_t startWrite =wAddr; uint32_t nxt =nextRecID; uint8_t summ =0; for(uint8_t i =0; i <4; ++ i){EEPROM.write(startWrite ++、nxt&0xff);合計<<=2;合計+ =nxt; nxt>> =8; } uint8_t * p =(byte *)&Config; for(uint8_t i =0; i  EEPROM.length())wAddr =0; nextRecID ++; //次のレコードを書き込む準備をしますreturntrue;} bool CONFIG ::load(void){bool is_valid =readRecord(rAddr、nextRecID); nextRecID ++; return is_valid;} bool CONFIG ::readRecord(uint16_t addr、uint32_t&recID){uint8_t Buff [record_size]; for(uint8_t i =0; i  =0; --i){ts <<=8; ts | =Buff [byte(i)]; } recID =ts; memcpy(&Config、&Buff [4]、sizeof(struct cfg)); trueを返します。 } return false;} // ------------------------------------------クラスHOT GUN CONFIG ---------------------------------------------- class HOTGUN_CFG:public CONFIG {public:HOTGUN_CFG(){} void init(void); uint16_t tempPreset(void); //内部単位でのプリセット温度uint8_tfanPreset(void); //プリセットファン速度0〜255 uint16_t tempInternal(uint16_t temp); //人間が読める温度を内部値に変換しますuint16_ttempHuman(uint16_t temp); //温度を内部単位から摂氏に変換しますvoidsave(uint16_t temp、uint8_t fanSpeed); //プリセット温度を内部ユニットに保存し、ファン速度を無効にしますvoid applyCalibrationData(uint16_t tip [3]); void getCalibrationData(uint16_t tip [3]); void saveCalibrationData(uint16_t tip [3]); void setDefaults(bool Write); // EEPROMプライベートからのデータのロードに失敗した場合は、デフォルトのパラメータ値を設定します:uint16_t t_tip [3]; const uint16_t def_tip [3] ={587、751、850}; //基準温度での内部センサー読み取り値のデフォルト値constuint16_t min_temp =50; const uint16_t max_temp =900; const uint16_t def_temp =600; //デフォルトのプリセット温度constuint8_t def_fan =64; //デフォルトのプリセットファン速度0〜255 const uint16_tambient_temp =0; const uint16_tambient_tempC =25;}; void HOTGUN_CFG ::init(void){CONFIG ::init(); if(!CONFIG ::load())setDefaults(false); // EEPROMからのデータのロードに失敗した場合は、デフォルト値で構成データを初期化しますuint32_t cd =Config.calibration; t_tip [0] =cd&0x3FF; cd>> =10; // ADCの読み取り値は10ビットであるため、キャリブレーションパラメータごとに10ビットt_tip [1] =cd&0x3FF; cd>> =10; t_tip [2] =cd&0x3FF; //チップのキャリブレーションが正しいかどうかを確認しますif((t_tip [0]> =t_tip [1])||(t_tip [1]> =t_tip [2])){setDefaults(false); for(uint8_t i =0; i <3; ++ i)t_tip [i] =def_tip [i]; } return;} uint32_tキャリブレーション; // 3つの温度ポイントでパックされたキャリブレーションデータuint16_ttemp; //内部単位でのIRONのプリセット温度uint8_tファン; //プリセットファン速度0〜255 uint8_t off_timeout; //自動スイッチオフタイムアウトuint16_tHOTGUN_CFG ::tempPreset(void){return Config.temp;} uint8_t HOTGUN_CFG ::fanPreset(void){return Config.fan;} uint16_t HOTGUN_CFG ::tempInternal(uint16_t t){//人間が読み取れる温度を内部値に変換t =strike(t、temp_minC、temp_maxC); uint16_t left =0; uint16_t right =1023; //内部単位での最大温度値uint16_ttemp =map(t、temp_tip [0]、temp_tip [2]、t_tip [0]、t_tip [2]); if(temp>
(left + right)/ 2){temp-=(right-left)/ 4; } else {temp + =(right-left)/ 4; } for(uint8_t i =0; i <20; ++ i){uint16_t tempH =tempHuman(temp); if(tempH ==t){return temp; } uint16_t new_temp; if(tempH > 1; } t_tip [0] =tip [0]; t_tip [1] =tip [1]; if(tip [2]> max_temp)tip [2] =max_temp; t_tip [2] =tip [2];} void HOTGUN_CFG ::getCalibrationData(uint16_t tip [3]){tip [0] =t_tip [0]; tip [1] =t_tip [1]; tip [2] =t_tip [2];} void HOTGUN_CFG ::saveCalibrationData(uint16_t tip [3]){if(tip [2]> max_temp)tip [2] =max_temp; uint32_t cd =tip [2]&0x3FF; cd <<=10; //チップキャリブレーションデータを1つの32ビットワードにパックします:値あたり10ビットcd | =tip [1]&0x3FF; cd <<=10; cd | =tip [0]; Config.calibration =cd; t_tip [0] =tip [0]; t_tip [1] =tip [1]; t_tip [2] =tip [2];} void HOTGUN_CFG ::setDefaults(bool Write){uint32_t c =def_tip [2]&0x3FF; c <<=10; c | =def_tip [1]&0x3FF; c <<=10; c | =def_tip [0]&0x3FF; Config.calibration =c; Config.temp =def_temp; Config.fan =def_fan; if(書き込み){CONFIG ::save(); }} // ------------------------------------------ class BUZZER- -------------------------------------------------- --class BUZZER {public:BUZZER(byte buzzerP、bool active =true){buzzer_pin =buzzerP; this-> active =active; } void init(void); void shortBeep(void); void lowBeep(void); void doubleBeep(void); void failedBeep(void);プライベート:byte buzzer_pin; bool active;}; void BUZZER ::init(void){pinMode(buzzer_pin、OUTPUT); if(active){digitalWrite(buzzer_pin、LOW); } else {noTone(buzzer_pin); }} void BUZZER ::shortBeep(void){if(active){digitalWrite(buzzer_pin、HIGH); delay(80); digitalWrite(buzzer_pin、LOW); } else {tone(buzzer_pin、3520、160); }} void BUZZER ::lowBeep(void){if(active){digitalWrite(buzzer_pin、HIGH); delay(160); digitalWrite(buzzer_pin、LOW); } else {tone(buzzer_pin、880、160); }} void BUZZER ::doubleBeep(void){if(active){digitalWrite(buzzer_pin、HIGH); delay(160); digitalWrite(buzzer_pin、LOW); delay(150); digitalWrite(buzzer_pin、HIGH); delay(160); digitalWrite(buzzer_pin、LOW); } else {tone(buzzer_pin、3520、160); delay(300);トーン(buzzer_pin、3520、160); }} void BUZZER ::failedBeep(void){if(active){digitalWrite(buzzer_pin、HIGH); delay(170); digitalWrite(buzzer_pin、LOW); delay(10); digitalWrite(buzzer_pin、HIGH); delay(80); digitalWrite(buzzer_pin、LOW); delay(100); digitalWrite(buzzer_pin、HIGH); delay(80); digitalWrite(buzzer_pin、LOW); } else {tone(buzzer_pin、3520、160); delay(170);トーン(buzzer_pin、880、250); delay(260);トーン(buzzer_pin、3520、160); }} // ------------------------------------------ class lcd DSPLay forはんだごて-----------------------------クラスDSPL:保護されたLiquidCrystal_I2C {パブリック:DSPL(void):LiquidCrystal_I2C(0x27、16、 2){} void init(void); void clear(void){LiquidCrystal_I2C ::clear(); } void tSet(uint16_t t、bool摂氏=true); //設定温度を表示しますvoidtCurr(uint16_t t); //現在の温度を表示しますvoidtInternal(uint16_t t); //現在の温度を内部単位で表示しますvoidtReal(uint16_t t); //キャリブレーションモードで実際の温度を摂氏で表示しますvoidfanSpeed(uint8_t s); //ファンの速度を表示しますvoidappliedPower(uint8_t p、bool show_zero =true); //適用電力を表示(%)void setupMode(uint8_t mode); void msgON(void); //メッセージを表示します: "ON" void msgOFF(void); void msgReady(void); void msgCold(void); void msgFail(void); //「失敗」メッセージを表示しますvoidmsgTune(void); //「Tune」メッセージをプライベートに表示します:bool full_second_line; // 2行目がメッセージchartemp_unitsでいっぱいかどうか。 const uint8_t custom_symbols [3] [8] ={{0b00110、//次数0b01001、0b01001、0b00110、0b00000、0b00000、0b00000、0b00000}、{0b00100、//ファン記号0b01100、0b01100、0b00110、0b01011、0b11001 、0b00000}、{0b00011、//電源記号0b00110、0b01100、0b11111、0b001 10、0b01100、0b01000、0b10000}};}; void DSPL ::init(void){LiquidCrystal_I2C ::begin(); LiquidCrystal_I2C ::clear(); for(uint8_t i =0; i <3; ++ i)LiquidCrystal_I2C ::createChar(i + 1、(uint8_t *)custom_symbols [i]); full_second_line =false; temp_units ='C';} void DSPL ::tSet(uint16_t t、bool Celsius){char buff [10]; if(摂氏){temp_units ='C'; } else {temp_units ='F'; } LiquidCrystal_I2C ::setCursor(0、0); sprintf(buff、 "Set:%3d%c%c"、t、(char)1、temp_units); LiquidCrystal_I2C ::print(buff);} void DSPL ::tCurr(uint16_t t){char buff [6]; LiquidCrystal_I2C ::setCursor(0、1); if(t <1000){sprintf(buff、 "%3d%c"、t、(char)1); } else {LiquidCrystal_I2C ::print(F( "xxx"));戻る; } LiquidCrystal_I2C ::print(buff); if(full_second_line){LiquidCrystal_I2C ::print(F( "")); full_second_line =false; }} void DSPL ::tInternal(uint16_t t){char buff [6]; LiquidCrystal_I2C ::setCursor(0、1); if(t <1023){sprintf(buff、 "%4d"、t); } else {LiquidCrystal_I2C ::print(F( "xxxx"));戻る; } LiquidCrystal_I2C ::print(buff); if(full_second_line){LiquidCrystal_I2C ::print(F( "")); full_second_line =false; }} void DSPL ::tReal(uint16_t t){char buff [6]; LiquidCrystal_I2C ::setCursor(11、1); if(t <1000){sprintf(buff、 ">%3d%c"、t、(char)1); } else {LiquidCrystal_I2C ::print(F( "xxx"));戻る; } LiquidCrystal_I2C ::print(buff);} void DSPL ::fanSpeed(uint8_t s){char buff [6]; s =map(s、0、255、0、99); sprintf(buff、 "%c%2d%c"、(char)2、s、 '%'); LiquidCrystal_I2C ::setCursor(11、1); LiquidCrystal_I2C ::print(buff);} void DSPL ::applyPower(uint8_t p、bool show_zero){char buff [6]; if(p>
 99)p =99; LiquidCrystal_I2C ::setCursor(5、1); if(p ==0 &&!show_zero){LiquidCrystal_I2C ::print(F( "")); } else {sprintf(buff、 "%c%2d%c"、(char)3、p、 '%'); LiquidCrystal_I2C ::print(buff); }} void DSPL ::setupMode(byte mode){LiquidCrystal_I2C ::clear(); LiquidCrystal_I2C ::print(F( "setup")); LiquidCrystal_I2C ::setCursor(1,1); switch(mode){case 0://チップキャリブレーションLiquidCrystal_I2C ::print(F( "calibrate"));壊す;ケース1:// LiquidCrystal_I2C ::print(F( "tune"));を調整します。壊す;ケース2:// LiquidCrystal_I2C ::print(F( "save"));を保存します壊す;ケース3:// LiquidCrystal_I2C ::print(F( "cancel"));をキャンセルします壊す;ケース4://デフォルトを設定LiquidCrystal_I2C ::print(F( "reset config"));壊す;デフォルト:ブレーク; }} void DSPL ::msgON(void){LiquidCrystal_I2C ::setCursor(10、0); LiquidCrystal_I2C ::print(F( "ON"));} void DSPL ::msgOFF(void){LiquidCrystal_I2C ::setCursor(10、0); LiquidCrystal_I2C ::print(F( "OFF"));} void DSPL ::msgReady(void){LiquidCrystal_I2C ::setCursor(10、0); LiquidCrystal_I2C ::print(F( "Ready"));} void DSPL ::msgCold(void){LiquidCrystal_I2C ::setCursor(10、0); LiquidCrystal_I2C ::print(F( "Cold"));} void DSPL ::msgFail(void){LiquidCrystal_I2C ::setCursor(0、1); LiquidCrystal_I2C ::print(F( "-==Failed ==-"));} void DSPL ::msgTune(void){LiquidCrystal_I2C ::setCursor(0、0); LiquidCrystal_I2C ::print(F( "Tune"));} // ---------------------------------- --------クラスの履歴---------------------------------------- ------------#define H_LENGTH 16class HISTORY {public:HISTORY(void){len =0; } void init(void){len =0; } uint16_t last(void); uint16_t top(void){return queue [0]; } void put(uint16_t item); //履歴に新しいエントリを配置しますuint16_taverage(void); //平均値を計算しますfloatdispersion(void); //数学の分散を計算しますprivate:volatile uint16_t queue [H_LENGTH];揮発性バイト長; //キューの揮発性バイトインデックス内の要素の数。 //現在の要素の位置、リングバッファを使用}; void HISTORY ::put(uint16_t item){if(len  =H_LENGTH)index =0; //リングバッファを使用します}} uint16_t HISTORY ::last(void){if(len ==0)return 0; uint8_t i =len-1; if(index)i =index-1; return queue [i];} uint16_t HISTORY ::average(void){uint32_t sum =0; if(len ==0)return 0; if(len ==1)return queue [0]; for(uint8_t i =0; i > 1; //平均合計を丸めます/ =len; return uint16_t(sum);} float HISTORY ::dispersion(void){if(len <3)return 1000; uint32_t sum =0; uint32_t avg =average(); for(uint8_t i =0; i > 1; update(value); return(emp_data + round_v)/ emp_k;} void EMP_AVERAGE ::update(int32_t value){uint8_t round_v =emp_k>> 1; emp_data + =value-(emp_data + round_v)/ emp_k;} int32_t EMP_AVERAGE ::read(void){uint8_t round_v =emp_k>> 1; return(emp_data + round_v)/ emp_k;} // -------------------------------------- ----温度を維持するためのクラスPIDアルゴリズム----------------------- / * PIDアルゴリズム* Un =Kp *(Xs --Xn)+ Ki * summ {j =0; j <=n}(Xs-Xj)+ Kd(Xn-Xn-1)、*ここで、Xs-はセットアップ温度、Xn-n-反復ステップの温度*このプログラムでは、対話式が使用されます。* Un =Un-1 + Kp *(Xn-1-Xn)+ Ki *(Xs-Xn)+ Kd *(Xn-2 + Xn-2 * Xn-1)*最初のステップ:* U0 =Kp *( Xs-X0)+ Ki *(Xs-X0); Xn-1 =Xn; * * PID係数の履歴:* 10/14/2017 [768、32、328] * 11/27/2019 [2009、1600、20] * 04/27/2020 [50、16、50] * / class PID { public:PID(void){Kp =50; Ki =16; Kd =50; } void resetPID(int temp =-1); // PIDアルゴリズムの履歴パラメータをリセットします//適用される電力を計算しますlongreqPower(int temp_set、int temp_curr); int changePID(uint8_t p、int k); //設定または取得(パラメーター<0の場合)PIDパラメーターprivate:void debugPID(int t_set、int t_curr、long kp、long ki、long kd、long delta_p); int temp_h0、temp_h1; //以前に測定された温度boolpid_iterate; //反復プロセスを使用するかどうかlongi_summ; // Kiの要約に分母の長い累乗を掛けたもの; //べき乗法に分母longKp、Ki、Kdを掛けたもの; // PIDアルゴリズム係数に分母を掛けたものconstbyte denominator_p =11; // 2の一般​​的な係数分母の累乗(11は2048で除算することを意味します)}; void PID ::resetPID(int temp){temp_h0 =0;パワー=0; i_summ =0; pid_iterate =false; if((temp>
 0)&&(temp <1000))temp_h1 =temp; else temp_h1 =0;} int PID ::changePID(uint8_t p、int k){switch(p){ケース1:if(k> =0)Kp =k; Kpを返します。ケース2:if(k> =0)Ki =k; Kiを返します。ケース3:if(k> =0)Kd =k; Kdを返します。デフォルト:ブレーク; } return 0;} long PID ::reqPower(int temp_set、int temp_curr){if(temp_h0 ==0){//温度がプリセット温度に近づいたら、PIDをリセットし、反復式を準備しますif((temp_set --temp_curr )<30){if(!pid_iterate){pid_iterate =true;パワー=0; i_summ =0; }} i_summ + =temp_set --temp_curr; //最初に、反復プロセスではなく、直接式を使用しますpower =Kp *(temp_set --temp_curr)+ Ki * i_summ; //温度が近い場合は、PID反復プロセスを準備します} else {long kp =Kp *(temp_h1-temp_curr); long ki =Ki *(temp_set --temp_curr); long kd =Kd *(temp_h0 + temp_curr-2 * temp_h1); long delta_p =kp + ki + kd;パワー+ =delta_p; //パワーに分母を掛けたままにします! } if(pid_iterate)temp_h0 =temp_h1; temp_h1 =temp_curr; long pwr =power +(1 <<(denominator_p-1)); //分母で削除する力を準備し、結果を丸めますpwr>> =denominator_p; //分母で削除returnpwr;} // --------------------- D9ピンの高周波PWM信号の計算--------- ---------------- --------------- class FastPWM_D9 {public:FastPWM_D9(){} void init(void); void Duty(uint8_t d){OCR1A =d; } uint8_t fanSpeed(void){return OCR1A; }}; void FastPWM_D9 ::init(void){pinMode(9、OUTPUT); digitalWrite(9、LOW); noInterrupts(); TCNT1 =0; TCCR1B =_BV(WGM13); //モードを位相と周波数の正しいpwmとして設定し、タイマーを停止しますTCCR1A =0; ICR1 =256; TCCR1B =_BV(WGM13)| _BV(CS10); //トップ値=ICR1、プリスケール=1 TCCR1A | =_BV(COM1A1); // OCR1A上のXORD9、D10から切り離されたOCR1A =0; //ピン9の信号をオフにします。 Interrupts();} // ---------------------ハードウェアの電源をオンにするために完全な正弦波形状を使用する熱風ガンマネージャー--------- ------クラスHOTGUN:public PID {public:typedef enum {POWER_OFF、POWER_ON、POWER_FIXED、POWER_COOLING} PowerMode; HOTGUN(uint8_t HG_sen_pin、uint8_t HG_pwr_pin); void init(void); bool isOn(void){return(mode ==POWER_ON || mode ==POWER_FIXED); } void setTemp(uint16_t temp){temp_set =contramp(temp、0、int_temp_max); } uint16_t getTemp(void){return temp_set; } uint16_t getCurrTemp(void){return h_temp.last(); } uint16_t tempAverage(void){return h_temp.average(); } uint8_t powerAverage(void){return h_power.average(); } uint8_t applyPower(void){return actual_power; } void setFanSpeed(uint8_t f){fan_speed =strike(f、min_working_fan、max_fan_speed); } uint8_t getFanSpeed(void){return fan_speed; } uint16_t tempDispersion(void){return h_temp.dispersion(); } bool isCold(void){return h_temp.average() =period){cnt =0; last_period =millis(); //現在の時間を保存して、外部割り込みをチェックしますif(!active &&(actual_power> 0)){digitalWrite(gun_pin、HIGH);アクティブ=true; }} else if(cnt> =actual_power){if(active){digitalWrite(gun_pin、LOW);アクティブ=false; }} if(!active){e_sensor.update(analogRead(sen_pin)); } return(cnt ==0); //電源期間の終了(期間AC電圧形状)} void HOTGUN ::switchPower(bool On){switch(mode){case POWER_OFF:if(hg_fan.fanSpeed()==0){//電源が供給されていないファンif(On)//!FAN &&On mode =POWER_ON; } else {if(On){if(isGunConnected()){// FAN &&On &&connected mode =POWER_ON; } else {// FAN &&On &&!connected shutdown(); }} else {if(isGunConnected()){// FAN &&!On &&connected if(isCold()){// FAN &&!On &&connected &&cold shutdown(); } else {// FAN &&!On &&connected &&!cold mode =POWER_COOLING; } } } } 壊す; case POWER_ON:if(!On){mode =POWER_COOLING; } 壊す; case POWER_FIXED:if(hg_fan.fanSpeed()){if(On){// FAN &&オンモード=POWER_ON; } else {// FAN &&!On if(isGunConnected()){// FAN &&!On &&connected if(isCold()){// FAN &&!On &&connected &&cold shutdown(); } else {// FAN &&!On &&connected &&!cold mode =POWER_COOLING; }}}} else {//!FAN if(!On){//!FAN &&!On shutdown(); } } 壊す; case POWER_COOLING:if(hg_fan.fanSpeed()){if(On){// FAN &&On if(isGunConnected()){// FAN &&On &&接続モード=POWER_ON; } else {// FAN &&On &&!connected shutdown(); }} else {// FAN &&!On if(isGunConnected()){if(isCold()){// FAN &&!On &&connected &&cold shutdown(); }} else {// FAN &&!On &&!connected shutdown(); }}} else {if(On){//!FAN &&オンモード=POWER_ON; }}} h_power.init();} //このルーチンは、熱風ガンの温度を必要な値に近づけるために使用されますvoid HOTGUN ::keepTemp(void){// uint16_t temp =analogRead(sen_pin); //熱風ガンの温度を確認します// uint16_t temp =emulateTemp(); uint16_t temp =e_sensor.read(); //熱風ガン温度の平均値h_temp.put(temp); ...このファイルは切り捨てられています。ダウンロードして完全な内容を確認してください。
Github
https://github.com/ManojBR105/ARDUINO-SMD-REWORK-STATIONhttps://github.com/ManojBR105/ARDUINO-SMD-REWORK-STATION

回路図

これは、コントローラーに必要な電圧を供給するための電源回路です。 hot_air_gunsch_l627KvauMg.sch

製造プロセス

  1. 液晶ディスプレイ(LCD)
  2. DIYサーモカムを作る
  3. Raspberry Pi2ウェザーステーション
  4. ラズベリーパイウェザーステーション
  5. 所持しているポートレート–更新
  6. Weather Station V 2.0
  7. UVCボックスDIYUV滅菌器
  8. Nokia 5110LCDのDIYシンプル20kHzArduinoオシロスコープ
  9. LCDアニメーションとゲーム
  10. 128x64LCDディスプレイ上のDIY10Hz-50kHzオシロスコープ
  11. ローカル気象台