Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Stasiun Pengerjaan Ulang SMD DIY

Komponen dan persediaan

SparkFun Arduino Pro Mini 328 - 5V/16MHz
× 1
Adafruit LCD Standar - 16x2 Putih di Atas Biru
× 1
modul lcd i2c
× 1
Rotary Encoder dengan Tombol Tekan
× 1
Pegangan Pistol Udara Panas
× 1
Hot Air Gun Handle Holder + Nozzle
× 1
BTA12-600B
× 1
IRFZ44
× 1
MCP602
× 1
MOC3052
× 1
4N25
× 1
Penyearah jembatan
× 1
Buzzer
× 1
FR107 dioda penyearah cepat
× 1
0,01 uF kapasitor, 400V
× 1
Kapasitor 100 nF
× 6
Melalui Resistor Lubang, 39 ohm
× 1
Melalui Resistor Lubang, 33 kohm
× 2
Resistor 330 ohm
× 1
Resistor 220 ohm
× 1
Resistor 1k ohm
× 3
Melalui Resistor Lubang, 470 ohm
× 1
potensiometer multi-putaran 500rb
× 1
Resistor 10k ohm
× 3

Alat dan mesin yang diperlukan

Besi solder (generik)

Aplikasi dan layanan online

Arduino IDE
Autodesk Eagle

Tentang proyek ini

Intro:Stasiun Pengerjaan Ulang SMD DIY

Dalam tutorial ini Anda dapat mempelajari cara membuat pengontrol pistol udara panas menggunakan Arduino dan komponen umum lainnya. Dalam proyek ini, algoritma PID digunakan untuk menghitung daya yang dibutuhkan dan dikendalikan oleh driver Triac yang terisolasi.

Proyek ini menggunakan pegangan yang kompatibel dengan 858D. Dilengkapi termokopel tipe K, pemanas 700 watt 230 VAC, dan kipas 24 VDC.

Kontroler ini efisien dan andal dibandingkan dengan yang komersial dan mudah dibuat.

Langkah 1:Pengkabelan

Skema lengkapnya terlihat pada gambar di bawah ini.


Pengkabelan untuk modul LCD I2C:

Modul I2C<-------------> Arduino Pro Mini

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

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

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

SCL<------------------------------------------->A5.

Pengkabelan untuk modul rotary encoder:

Pembuat Enkode<---------------------->Arduino

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

+<-------------------------------->NC(Tidak Terhubung, kode menggunakan input pull-up arduino)

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

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

CLK<---------------------------->D4.

Pengkabelan pegangan: (7 kawat)

Konektor 3pin - (Hijau, Hitam, Merah)

Kabel merah<---------------------->Termokopel +

Kabel hijau<-------------------->Saklar Buluh

Kabel hitam<--------------------->Hal yang sama.

Konektor 2 pin - (Biru, Kuning)

Kabel biru<--------------------------> Kipas +0

Kabel kuning<------------------------>Kipas - (atau GND)

2 Konektor pin besar -(Putih, Coklat)

Kabel putih<-----------------------> Pemanas

Kawat coklat<----------------------> Pemanas (tanpa polaritas)

CATATAN:

Kabel pegangan pistol udara panas mungkin berbeda untuk berbagai jenis tongkat. Jadi, lihat diagram pengkabelan di foto dan ikuti jalur kabel untuk menemukan masing-masing pin.

Langkah 2:Diagram Sirkuit

Sirkuit terdiri dari 3 bagian terutama.

Bagian Antarmuka:

Ini terdiri dari layar LCD 1602 dengan modul I2C dan encoder putar dengan tombol tekan. Layar menunjukkan suhu yang disetel, suhu saat ini, kecepatan Kipas dan daya yang diterapkan serta status pegangan saat ini. Encoder digunakan untuk berbagai input dan untuk menavigasi melalui opsi dan kontrol.

Bagian Sensor:

Ini terdiri dari termokopel tipe-K untuk penginderaan suhu dan sakelar buluh untuk menentukan posisi pegangan. Tegangan termokopel diperkuat oleh op-amp ke level tegangan yang dapat diukur oleh arduino. Penguatan op-amp dikendalikan oleh pot trim 200K.

Bagian Pengontrol:

Ada terutama 2 pengontrol di sirkuit ini. Salah satunya adalah pengontrol kecepatan Kipas PWM sederhana dengan MOSFET. Yang lainnya adalah pengontrol terisolasi untuk pemanas. Ini terdiri dari TRIAC yang digerakkan oleh DIAC opto-coupled dan dilakukan dengan mengontrol jumlah siklus gelombang yang dikirimkan ke pemanas. Optocoupler 4N25 membantu menjaga sinkronisasi dengan bentuk gelombang AC.

Langkah 3:PCB

Rangkaian proyek ini agak rumit, Jadi saya sarankan Anda menggunakan papan cetak daripada PCB titik. Jika Anda ingin membuat PCB sendiri, saya telah melampirkan file elang di akhir proyek. Namun, jika Anda ingin menyelesaikannya oleh perusahaan manufaktur PCB, Anda dapat memesannya dari JLCPCB

. Anda dapat melihat desain Easy EDA melalui link ini :https://easyeda.com/ManojBR/harws1-1

Langkah 4:Kode dan Pustaka

Program ini adalah bagian terpenting dari proyek ini dan terima kasih banyak untuk sfrwmaker menulis programnya. Program ini menggunakan algoritma PID untuk mengontrol daya untuk mempertahankan suhu yang disetel. Ia bekerja dengan mengontrol jumlah siklus gelombang yang dikirimkan ke pegangan per detik.

Saat pengontrol dihidupkan, tongkat akan dalam keadaan OFF. Dengan memutar pembuat enkode suhu dan kecepatan kipas dapat disesuaikan. Tekan sebentar encoder akan beralih antara kecepatan Kipas dan Menyetel penyesuaian suhu.

Pistol udara panas mulai memanas segera setelah diangkat dari dudukannya dan menunjukkan Siap dan mengeluarkan bunyi bip pendek saat mencapai suhu yang disetel. Ini akan mematikan pemanas segera setelah dimasukkan kembali ke dudukannya. Tapi, kipas akan terus bertiup hingga mencapai suhu aman. Setelah suhu turun di bawah 50 C, akan berbunyi bip singkat dan menampilkan COLD.

Saat pistol udara panas dimatikan, pengontrol akan masuk ke mode Pengaturan jika pembuat enkode ditekan lama .

Mode penyiapan memiliki opsi Kalibrasi, Setel, Simpan, dan Batal, serta Atur Ulang Konfigurasi.

Catatan: Jika Anda menggunakan PCB dari easyEDA maka Anda harus mengubah nomor pin dari reed switch ke pin no. 8 dan Pin buzzer ke pin no.6

Anda harus menginstal perpustakaan Commoncontrols-master dan perpustakaan time-master agar kode berfungsi dengan baik.

Perhatian: Jangan sambungkan pengontrol ke stopkontak saat mem-flash firmware. Catu daya kipas yang tidak terisolasi dapat merusak laptop Anda.

unduh kode sumber sketsa dari halaman proyek.

Langkah 5:Siapkan

Pembacaan suhu harus dikalibrasi dengan nilai asli untuk mendapatkan pembacaan yang wajar. Jadi, untuk melakukannya, Anda harus mengikuti langkah-langkah berikut.

Pertama, masuk ke mode setup dan pilih opsi Tune. Dalam mode tune suhu internal (0-1023) ditampilkan di layar. Putar encoder untuk secara manual memilih daya yang diterapkan ke hot air gun. Panaskan pistol hingga 400 derajat. Saat suhu dan dispersi menjadi rendah, pengontrol berbunyi bip. Kemudian setel trim-pot untuk mengatur suhu internal sekitar 900 (dalam unit internal). Tekan lama untuk encoder kembali ke menu

Kemudian, masuk ke mode setup pilih opsi Calibrate. Pilih titik kalibrasi:200, 300 atau 400 derajat, tekan encoder. Pistol panas akan mencapai suhu yang diinginkan dan berbunyi bip. Dengan memutar encoder, masukkan suhu sebenarnya. Kemudian pilih titik referensi lain dan ulangi proses ini untuk semua titik kalibrasi.

Setelah ini tekan lama dan datang ke layar utama dan sekali lagi masuk ke mode Setup dan pilih simpan.

Dan sekarang stasiun pengerjaan ulang Hot air telah selesai.

Langkah 6:Video!

Lihat cara kerja pengontrol di video.

Terima kasih sfrwmaker telah menulis kodenya.

Terima kasih kepada LCSC atas dukungannya. LCSC Electronics adalah salah satu pemasok komponen elektronik dengan pertumbuhan tercepat di Cina. LCSC telah berkomitmen untuk menawarkan barang-barang beraneka ragam, asli dan dalam stok, sejak didirikan pada tahun 2011. Bertujuan untuk menyediakan seluruh dunia dengan suku cadang yang lebih unggul dari Asia. Detail lebih lanjut silakan kunjungi:https://lcsc.com/

Jika Anda harus membuat PCB sendiri di rumah, lihat tutorial ini:https://www.instructables.com/id/PCB-Making-1/

Terima kasih.

Kode

  • Firmware 1.4
Firmware 1.4C/C++
Dukungan buzzer aktif/pasif. Tolong ubah parameter BUZZER_ACTIVE
Tidak ada lagi peningkatan rotary encoder. Nilai berubah sebesar 1.
/* * Kontroler senapan angin panas berdasarkan IC atmega328 * Versi 1.4 * Dirilis 05 Desember 2020 */#include #include #include  #include #include #include #include const uint16_t temp_minC =100; // Suhu minimum yang dapat diperiksa pengontrol secara akuratconst uint16_t temp_maxC =500; // Batas suhu maksimum yang mungkin uint16_t temp_ambC =25; // Suhu lingkungan rata-rataconst uint16_t temp_tip[3] ={200, 300, 400}; // Titik referensi suhu untuk kalibrasiconst uint16_t min_working_fan =100; // Minimal mungkin kecepatan kipasconst uint8_t AC_SYNC_PIN =2; // Outlet 220 v pin sinkronisasi. Jangan diubah! const uint8_t HOT_GUN_PIN =7; // manajemen pemanas pistol panas pinconst uint8_t FAN_GUN_PIN =9; // Pin manajemen kipas pistol panas. Jangan berubah! const uint8_t TEMP_GUN_PIN =A0; // Pengecekan suhu hot gun pinconst uint8_t R_MAIN_PIN =3; // Pin utama encoder putar. Jangan ubah!const uint8_t R_SECD_PIN =4; // Rotary encoder pinconst uint8_t R_BUTN_PIN =5; // Tombol putar encoder pinconst uint8_t REED_SW_PIN =8; // Reed switch pinconst uint8_t BUZZER_PIN =6; // Buzzer pinconst bool BUZZER_ACTIVE =true; // Buzzer aktif berbunyi bip ketika +5v dipasok ke sana//-------------------------------------- ----- Data konfigurasi -------------------------------------------- -----/* Catatan konfigurasi di EEPROM memiliki format berikut:* uint32_t ID setiap kali bertambah 1 * data konfigurasi struct cfg, 8 byte * byte CRC checksum*/struct cfg { kalibrasi uint32_t; // Data kalibrasi dikemas dengan tiga titik suhu uint16_t temp; // Suhu prasetel IRON di unit internal kipas uint8_t; // Kecepatan kipas preset 0 - 255 uint8_t off_timeout; // Batas waktu mati otomatis};class CONFIG { public:CONFIG() { can_write =false; buffRecords =0; rAddr =wAddr =0; ePanjang =0; nextRecID =0; uint8_t rs =sizeof(struct cfg) + 5; // Total ukuran record konfigurasi // Pilih ukuran record yang sesuai; Ukuran record harus pangkat 2, yaitu 8, 16, 32, 64, ... byte untuk (record_size =8; record_size  recID) { minRecID =recID; minRecAddr =tambahan; } 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); kembali simpan(); // Simpan data baru ke dalam 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 jumlah =0; for (uint8_t i =0; i <4; ++i) { EEPROM.write(startWrite++, nxt &0xff); jumlah <<=2; jumlah +=nxt; nxt>>=8; } uint8_t* p =(byte *)&Config; for (uint8_t i =0; i  EEPROM.length()) wAddr =0; nextRecID++; // Bersiaplah untuk menulis record berikutnya return true;}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 |=Penggemar[byte(i)]; } resi =ts; memcpy(&Config, &Buff[4], sizeof(struct cfg)); kembali benar; } return false;}//------------------------------------------- class HOT GUN CONFIG ---------------------------------------------- kelas HOTGUN_CFG :public CONFIG { publik:HOTGUN_CFG() { } void init(void); uint16_t tempPreset(void); // Suhu preset dalam unit internal uint8_t fanPreset(void); // Kecepatan kipas preset 0 - 255 uint16_t tempInternal(uint16_t temp); // Terjemahkan suhu yang dapat dibaca manusia ke dalam nilai internal uint16_t tempHuman(uint16_t temp); // Terjemahkan suhu dari unit internal ke Celcius void save (suhu uint16_t, kecepatan kipas uint8_t); // Simpan suhu prasetel di unit internal dan kecepatan kipas batal applyCalibrationData(uint16_t tip[3]); void getCalibrationData(uint16_t tip[3]); void saveCalibrationData(tip uint16_t[3]); void setDefaults (bool Tulis); // Tetapkan nilai parameter default jika gagal memuat data dari EEPROM private:uint16_t t_tip[3]; const uint16_t def_tip[3] ={587, 751, 850}; // Nilai default pembacaan sensor internal pada suhu referensi const uint16_t min_temp =50; const uint16_t max_temp =900; const uint16_t def_temp =600; // Suhu preset default const uint8_t def_fan =64; // Kecepatan kipas preset default 0 - 255 const uint16_t ambient_temp =0; const uint16_t ambient_tempC=25;};void HOTGUN_CFG::init(void) { CONFIG::init(); if (!CONFIG::load()) setDefaults(false); // Jika gagal memuat data dari EEPROM, inisialisasi data konfigurasi dengan nilai default uint32_t cd =Config.calibration; t_tip[0] =cd &0x3FF; cd>>=10; // 10 bit per parameter kalibrasi, karena pembacaan ADC adalah 10 bit t_tip[1] =cd &0x3FF; cd>>=10; t_tip[2] =cd &0x3FF; // Periksa kalibrasi tip sudah benar 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]; } kembali;} kalibrasi uint32_t; // Data kalibrasi dikemas dengan tiga titik suhu uint16_t temp; // Suhu prasetel IRON di unit internal kipas uint8_t; // Kecepatan kipas preset 0 - 255 uint8_t off_timeout; // Batas waktu mati otomatis 16_t HOTGUN_CFG::tempPreset(void) { return Config.temp;}uint8_t HOTGUN_CFG::fanPreset(void) { return Config.fan;}uint16_t HOTGUN_CFG::tempInternal(uint16_t t) { // Terjemahkan suhu yang dapat dibaca manusia menjadi nilai internal t =constrain(t, temp_minC, temp_maxC); uint16_t kiri =0; uint16_t kanan =1023; // Nilai suhu maksimum dalam satuan internal uint16_t temp =map(t, temp_tip[0], temp_tip[2], t_tip[0], t_tip[2]); if (temp>
 (kiri+kanan)/ 2) { temp -=(kanan-kiri) / 4; } else { suhu +=(kanan-kiri) / 4; } for (uint8_t i =0; i <20; ++i) { uint16_t tempH =tempHuman(temp); if (tempH ==t) { kembalikan suhu; } uint16_t new_temp; if (suhu > 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];}tidak berlaku 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; // Kemas data kalibrasi tip dalam satu kata 32-bit:10-bit per nilai 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 (Tulis) { CONFIG::save(); }}//------------------------------------------- kelas BUZZER -- -------------------------------------------------- --class BUZZER { publik:BUZZER(byte buzzerP, bool active =true) { buzzer_pin =buzzerP; ini->aktif =aktif; } batal init(batal); void pendekBeep(void); batalkan bunyi bip rendah(batal); void doubleBeep(kosong); void gagalBeep(void); pribadi:byte buzzer_pin; bool aktif;};void BUZZER::init(void) { pinMode(buzzer_pin, OUTPUT); if (aktif) { digitalWrite(buzzer_pin, RENDAH); } else { noTone(buzzer_pin); }}void BUZZER::shortBeep(void) { if (aktif) { digitalWrite(buzzer_pin, HIGH); penundaan (80); digitalWrite(buzzer_pin, RENDAH); } else { nada(pin_buzzer, 3520, 160); }}void BUZZER::lowBeep(void) { if (aktif) { digitalWrite(buzzer_pin, HIGH); penundaan(160); digitalWrite(buzzer_pin, RENDAH); } else { nada(pin_buzzer, 880, 160); }}void BUZZER::doubleBeep(void) { if (aktif) { digitalWrite(buzzer_pin, HIGH); penundaan(160); digitalWrite(buzzer_pin, RENDAH); penundaan(150); digitalWrite(buzzer_pin, TINGGI); penundaan(160); digitalWrite(buzzer_pin, RENDAH); } else { nada(pin_buzzer, 3520, 160); penundaan (300); nada(pin_buzzer, 3520, 160); }}void BUZZER::failedBeep(void) { if (aktif) { digitalWrite(buzzer_pin, HIGH); penundaan (170); digitalWrite(buzzer_pin, RENDAH); penundaan (10); digitalWrite(buzzer_pin, TINGGI); penundaan (80); digitalWrite(buzzer_pin, RENDAH); penundaan(100); digitalWrite(buzzer_pin, TINGGI); penundaan (80); digitalWrite(buzzer_pin, RENDAH); } else { nada(pin_buzzer, 3520, 160); penundaan (170); nada(pin_buzzer, 880, 250); penundaan (260); nada(pin_buzzer, 3520, 160); }}//------------------------------------------- kelas lcd DSPLay untuk solder BESI ----------------------------- kelas DSPL :protected LiquidCrystal_I2C { publik:DSPL(void) :LiquidCrystal_I2C (0x27, 16, 2) { } batal init(batal); void clear(void) { LiquidCrystal_I2C::clear(); } void tSet(uint16_t t, bool Celsius =true); // Tampilkan suhu preset void tCurr(uint16_t t); // Tampilkan suhu saat ini batal tInternal(uint16_t t); // Tampilkan suhu saat ini dalam unit internal void tReal(uint16_t t); // Tampilkan suhu sebenarnya dalam Celcius dalam mode kalibrasi void fanSpeed(uint8_t s); // Tampilkan kecepatan kipas void applyPower(uint8_t p, bool show_zero =true); // Tampilkan daya yang diterapkan (%) void setupMode(mode uint8_t); batal msgON(batal); // Tampilkan pesan:"ON" void msgOFF(void); void msgReady(batal); void msgCold(batal); void msgFail(batal); // Tampilkan pesan 'Gagal' void msgTune(void); // Tampilkan pesan 'Tune' pribadi:bool full_second_line; // Apakah baris kedua penuh dengan pesan char temp_units; const uint8_t custom_symbols[3][8] ={ { 0b00110, // Derajat 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000 }, { 0b00100, // Tanda kipas 0b01100, 0b01100, 0b00110, 0b01011, 0b100000, 0b10000 , 0b000000 }, { 0b00011, // Tanda daya 0b00110, 0b01100, 0b11111, 0b00110, 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 =salah; temp_units ='C';}void DSPL::tSet(uint16_t t, bool Celsius) { char buff[10]; if (Celcius) { 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")); kembali; } LiquidCrystal_I2C::print(buff); if (baris_detik_penuh) { LiquidCrystal_I2C::print(F(" ")); full_second_line =salah; }}void DSPL::tInternal(uint16_t t) { char buff[6]; LiquidCrystal_I2C::setCursor(0, 1); if (t <1023) { sprintf(penggemar, "%4d ", t); } else { LiquidCrystal_I2C::print(F("xxxx")); kembali; } LiquidCrystal_I2C::print(buff); if (baris_detik_penuh) { LiquidCrystal_I2C::print(F(" ")); full_second_line =salah; }}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")); kembali; } LiquidCrystal_I2C::print(buff);}void DSPL::fanSpeed(uint8_t s) { char buff[6]; s =peta(s, 0, 255, 0, 99); sprintf(buff, " %c%2d%c", (char)2, s, '%'); LiquidCrystal_I2C::setCursor(11, 1); LiquidCrystal_I2C::print(buff);}void DSPL::appliedPower(uint8_t p, bool show_zero) { char buff[6]; jika (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:// tip kalibrasi LiquidCrystal_I2C::print(F("calibrate")); merusak; case 1:// tune LiquidCrystal_I2C::print(F("tune")); merusak; kasus 2:// simpan LiquidCrystal_I2C::print(F("simpan")); merusak; kasus 3:// batalkan LiquidCrystal_I2C::print(F("batal")); merusak; kasus 4:// setel default LiquidCrystal_I2C::print(F("reset config")); merusak; default:istirahat; }}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(" -==Gagal ==- "));}void DSPL::msgTune(void) { LiquidCrystal_I2C::setCursor(0, 0); LiquidCrystal_I2C::print(F("Tune"));}//---------------------------------- -------- SEJARAH kelas ---------------------------------------- ------------#define H_LENGTH 16class HISTORY { publik:HISTORY(void) { len =0; } void init(void) { len =0; } uint16_t terakhir(batal); uint16_t top(void) { kembali antrian[0]; } void put(item uint16_t); // Masukkan entri baru ke histori uint16_t average(void); // menghitung nilai rata-rata dispersi float(void); // menghitung dispersi matematika private:volatile uint16_t queue[H_LENGTH]; byte len yang mudah menguap; // Jumlah elemen dalam antrian volatile byte index; // Posisi elemen saat ini, gunakan ring buffer};void HISTORY::put(uint16_t item) { if (len =H_LENGTH) indeks =0; // Gunakan ring buffer }}uint16_t HISTORY::last(void) { if (len ==0) return 0; uint8_t i =len - 1; if (indeks) i =indeks - 1; kembali antrian[i];}uint16_t HISTORY::average(void) { uint32_t sum =0; jika (len ==0) kembali 0; if (len ==1) mengembalikan antrian[0]; for (uint8_t i =0; i > 1; // membulatkan jumlah rata-rata /=len; return uint16_t(sum);}float HISTORY::dispersion(void) { if (len <3) return 1000; uint32_t jumlah =0; uint32_t rata-rata =rata-rata(); for (uint8_t i =0; i > 1; pembaruan(nilai); return (emp_data + round_v) / emp_k;}void EMP_AVERAGE::update(int32_t value) { uint8_t round_v =emp_k>> 1; emp_data +=nilai - (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;}//-------------------------------------- ---- algoritma PID class untuk menjaga suhu -----------------------/* Algoritma PID * Un =Kp*(Xs - Xn) + Ki*jumlah{j=0; j<=n}(Xs - Xj) + Kd(Xn - Xn-1), * Dimana Xs - adalah suhu setup, Xn - suhu pada langkah iterasi n * Dalam program ini digunakan rumus interaktif:* Un =Un-1 + Kp*(Xn-1 - Xn) + Ki*(Xs - Xn) + Kd*(Xn-2 + Xn - 2*Xn-1) * Dengan langkah pertama:* U0 =Kp*( Xs - X0) + Ki*(Xs - X0); Xn-1 =Xn; * * Riwayat koefisien PID:* 14/10/2017 [768, 32, 328] * 27/11/2019 [ 2009, 1600, 20] * 27/04/2020 [ 50, 16, 50] */kelas PID { publik:PID(void) { Kp =50; Ki =16; Kd =50; } batal resetPID(int temp =-1); // reset parameter riwayat algoritma PID // Hitung daya yang akan diterapkan long reqPower(int temp_set, int temp_curr); int ubahPID(uint8_t p, int k); // set atau dapatkan (jika parameter <0) parameter PID private:void debugPID(int t_set, int t_curr, long kp, long ki, long kd, long delta_p); int temp_h0, temp_h1; // suhu yang diukur sebelumnya bool pid_iterate; // Apakah proses iteratif digunakan long i_summ; // Ringkasan ki dikalikan dengan penyebut daya panjang; // Perulangan pangkat dikalikan dengan penyebut long Kp, Ki, Kd; // Koefisien algoritma PID dikalikan dengan denominator const byte denominator_p =11; // The common coefficient denominator power of 2 (11 means divide by 2048)};void PID::resetPID(int temp) { temp_h0 =0; power =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) { case 1:if (k>=0) Kp =k; return Kp; case 2:if (k>=0) Ki =k; return Ki; case 3:if (k>=0) Kd =k; return Kd; default:break; } return 0;}long PID::reqPower(int temp_set, int temp_curr) { if (temp_h0 ==0) { // When the temperature is near the preset one, reset the PID and prepare iterative formula if ((temp_set - temp_curr) <30) { if (!pid_iterate) { pid_iterate =true; power =0; i_summ =0; } } i_summ +=temp_set - temp_curr; // first, use the direct formula, not the iterate process power =Kp*(temp_set - temp_curr) + Ki*i_summ; // If the temperature is near, prepare the PID iteration process } 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; power +=delta_p; // power kept multiplied by denominator! } if (pid_iterate) temp_h0 =temp_h1; temp_h1 =temp_curr; long pwr =power + (1 <<(denominator_p-1)); // prepare the power to delete by denominator, round the result pwr>>=denominator_p; // delete by the denominator return pwr;}//--------------------- High frequency PWM signal calss on D9 pin ------------------------- ---------------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, RENDAH); noInterrupts(); TCNT1 =0; TCCR1B =_BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer TCCR1A =0; ICR1 =256; TCCR1B =_BV(WGM13) | _BV(CS10); // Top value =ICR1, prescale =1 TCCR1A |=_BV(COM1A1); // XOR D9 on OCR1A, detached from D10 OCR1A =0; // Switch-off the signal on pin 9; interrupts();}//--------------------- Hot air gun manager using total sine shape to power on the hardware ---------------class 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 =constrain(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 appliedPower(void) { return actual_power; } void setFanSpeed(uint8_t f) { fan_speed =constrain(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(); // Save the current time to check the external interrupts if (!active &&(actual_power> 0)) { digitalWrite(gun_pin, HIGH); active =true; } } else if (cnt>=actual_power) { if (active) { digitalWrite(gun_pin, LOW); active =false; } } if (!active) { e_sensor.update(analogRead(sen_pin)); } return (cnt ==0); // End of the Power period (period AC voltage shapes)}void HOTGUN::switchPower(bool On) { switch (mode) { case POWER_OFF:if (hg_fan.fanSpeed() ==0) { // Not power supplied to the Fan 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; } } } } break; case POWER_ON:if (!On) { mode =POWER_COOLING; } merusak; case POWER_FIXED:if (hg_fan.fanSpeed()) { if (On) { // FAN &&On mode =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(); } } merusak; case POWER_COOLING:if (hg_fan.fanSpeed()) { if (On) { // FAN &&On if (isGunConnected()) { // FAN &&On &&connected mode =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 &&On mode =POWER_ON; } } } h_power.init();}// This routine is used to keep the hot air gun temperature near required valuevoid HOTGUN::keepTemp(void) { //uint16_t temp =analogRead(sen_pin); // Check the hot air gun temperature //uint16_t temp =emulateTemp(); uint16_t temp =e_sensor.read(); // Average value of the hot air gun temperature h_temp.put(temp); ...This file has been truncated, please download it to see its full contents.
Github
https://github.com/ManojBR105/ARDUINO-SMD-REWORK-STATIONhttps://github.com/ManojBR105/ARDUINO-SMD-REWORK-STATION

Skema

This is the power supply circuit to provide necessary voltage for the controller. hot_air_gunsch_l627KvauMg.sch

Proses manufaktur

  1. Liquid Crystal Display (LCD)
  2. Membuat Termocam DIY
  3. Stasiun Cuaca Raspberry Pi 2
  4. Stasiun Cuaca Raspberry Pi
  5. Possessed Portrait – Diperbarui
  6. Stasiun Cuaca V 2.0
  7. UVC Box Sterilizer UV DIY
  8. DIY Sederhana 20 kHz Arduino Oscilloscope pada LCD Nokia 5110
  9. Animasi dan Permainan LCD
  10. Osiloskop DIY 10Hz-50kHz pada Layar LCD 128x64