Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

DIY SMD Rework Station

Componenten en benodigdheden

SparkFun Arduino Pro Mini 328 - 5V/16MHz
× 1
Adafruit Standaard LCD - 16x2 Wit op Blauw
× 1
lcd i2c-module
× 1
Roterende encoder met drukknop
× 1
Handvat heteluchtpistool
× 1
Heteluchtpistoolhandvathouder + mondstuk
× 1
BTA12-600B
× 1
IRFZ44
× 1
MCP602
× 1
MOC3052
× 1
4N25
× 1
Bruggelijkrichter
× 1
Zoemer
× 1
FR107 snelle gelijkrichterdiode
× 1
0.01 uF condensator, 400V
× 1
Condensator 100 nF
× 6
Through Hole Resistor, 39 ohm
× 1
Through Hole Resistor, 33 kohm
× 2
Weerstand 330 ohm
× 1
Weerstand 220 ohm
× 1
Weerstand 1k ohm
× 3
Through Hole-weerstand, 470 ohm
× 1
500k multi-turn potentiometer
× 1
Weerstand 10k ohm
× 3

Benodigde gereedschappen en machines

Soldeerbout (algemeen)

Apps en online services

Arduino IDE
Autodesk Eagle

Over dit project

Intro:DIY SMD Rework Station

In deze tutorial leer je hoe je een heteluchtpistoolcontroller maakt met Arduino en andere veelvoorkomende componenten. In dit project wordt het PID-algoritme gebruikt om het benodigde vermogen te berekenen en wordt het bestuurd door een geïsoleerde Triac-driver.

Dit project maakt gebruik van een handgreep die compatibel is met 858D. Het heeft een K-type thermokoppel, 700 watt 230 VAC verwarming en een 24 VDC ventilator.

Deze controller is efficiënt en betrouwbaar in vergelijking met de commerciële en is eenvoudig te bouwen.

Stap 1:Bedrading

Het volledige schema is te zien op de onderstaande afbeelding.


Bedrading voor I2C LCD-module:

I2C-module<--------------> Arduino Pro Mini

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

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

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

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

Bedrading voor roterende encodermodule:

Encoder<---------------------->Arduino

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

+<-------------------------------->NC (Niet verbonden, code gebruikt ingebouwde invoer pull-up van Arduino)

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

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

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

Bedrading van handvat: (7-draads)

3-pins connector - (Groen, Zwart, Rood)

Rode draad<----------------------->Thermokoppel +

Groene draad<-------------------->Reed-schakelaar

Zwarte draad<--------------------->Gemeenschappelijke aarde.

2-pins connector - (Blauw, Geel)

Blauwe draad<--------------------------> Ventilator +0

Gele draad<------------------------>Fan - (of GND)

2 grote pin-connector - (wit, bruin)

Witte draad<-----------------------> Verwarming

Bruine draad<----------------------> Verwarming (geen polariteit)

OPMERKING:

De bedrading van de handgreep van het heteluchtpistool kan verschillen voor verschillende soorten staven. Raadpleeg dus het bedradingsschema op de foto en volg het pad van de draad om de respectievelijke pinnen te vinden.

Stap 2:Schakelschema

Het circuit bestaat voornamelijk uit 3 delen.

Het interfacegedeelte:

Het bestaat uit een 1602 LCD-display met I2C-module en een roterende encoder met drukknop. Het display toont de ingestelde temperatuur, de huidige temperatuur, de ventilatorsnelheid en het toegepaste vermogen en de huidige status van de handgreep. De encoder wordt gebruikt voor verschillende ingangen en om door de opties en bedieningselementen te navigeren.

Het sensorgedeelte:

Het bestaat uit een K-type thermokoppel voor temperatuurmeting en een reed-schakelaar voor het bepalen van de positie van de handgreep. De spanning van het thermokoppel wordt versterkt door de op-amp tot een spanningsniveau dat meetbaar is door de Arduino. De versterking van de op-amp wordt geregeld door een trimpot van 200K.

Het controllergedeelte:

Er zijn voornamelijk 2 controllers in dit circuit. De ene is een eenvoudige PWM-ventilatorsnelheidsregelaar met een MOSFET. De andere is een geïsoleerde controller voor verwarming. Het bestaat uit een TRIAC die wordt aangedreven door een opto-gekoppelde DIAC en wordt gedaan door het aantal golfcycli te regelen dat aan de verwarming wordt geleverd. De 4N25 optocoupler helpt om de synchronisatie met de AC-golfvorm te behouden.

Stap 3:PCB

Het circuit van dit project is een beetje ingewikkeld, dus ik raad je aan om een ​​printplaat te gebruiken dan een dot-PCB. Als je je eigen PCB wilt maken, heb ik de adelaarsbestanden aan het einde van het project bijgevoegd. Maar als u ze door een PCB-productiebedrijf wilt laten maken, kunt u dit bestellen bij JLCPCB

. U kunt het Easy EDA-ontwerp bekijken via deze link:https://easyeda.com/ManojBR/harws1-1

Stap 4:De code en bibliotheken

Het programma is het meest cruciale onderdeel van het project en heel erg bedankt voor sfrwmaker het schrijven van het programma. Het programma gebruikt PID-algoritme om het vermogen te regelen om de ingestelde temperatuur te behouden. Het werkt door het aantal golfcycli te regelen dat per seconde aan het handvat wordt geleverd.

Wanneer de controller is ingeschakeld, staat de staaf in de UIT-status. Door aan de encoder te draaien de temperatuur en ventilatorsnelheid kunnen worden aangepast. Korte druk van de encoder schakelt tussen de ventilatorsnelheid en de temperatuurinstelling.

Het Heteluchtpistool begint te verwarmen zodra het uit de houder wordt getild en toont Klaar en maakt een korte pieptoon wanneer het de ingestelde temperatuur bereikt. Hij schakelt de verwarming uit zodra hij weer in de houder wordt geplaatst. Maar de ventilator blijft blazen totdat hij de veilige temperatuur bereikt. Nadat de temperatuur onder de 50 C is gedaald, klinkt er een korte pieptoon en wordt KOUD weergegeven.

Wanneer het heteluchtpistool is uitgeschakeld, gaat de controller naar de Instelmodus als de encoder lang ingedrukt is .

De instellingsmodus heeft opties voor Kalibreren, Afstemmen, Opslaan en Annuleren en Configuratie opnieuw instellen.

Opmerking: Als u PCB van easyEDA gebruikt dan moet u het pinnummer van de reed-schakelaar wijzigen in pinnr. 8 en Zoemer pin naar pin nr.6

je moet de Commoncontrols-master-bibliotheek en de time-master-bibliotheek installeren om de code correct te laten werken.

Let op: Sluit de controller niet aan op het stopcontact tijdens het flashen van de firmware. Een niet-geïsoleerde voeding van de ventilator kan uw laptop beschadigen.

download de schetsbroncode van de projectpagina.

Stap 5:Instellen

De temperatuurmetingen moeten worden gekalibreerd met de oorspronkelijke waarde om redelijke metingen te krijgen. Om dat te doen moet u dus de volgende stappen volgen.

Ga eerst naar de setup-modus en selecteer de Tune-optie. In de tune-modus wordt de interne temperatuur (0-1023) weergegeven op het scherm. Draai aan de encoder om handmatig het toegepaste vermogen naar het heteluchtpistool te selecteren. Verwarm het pistool tot 400 graden. Wanneer de temperatuur en dispersie laag worden, piept de controller. Stem vervolgens de trim-pot af om de interne temperatuur in te stellen op ongeveer 900 (in de interne eenheden). Lang indrukken om de encoder terug te keren naar het menu

Ga vervolgens naar de instellingsmodus en selecteer de optie Kalibreren. Kies het kalibratiepunt:200, 300 of 400 graden, druk op de encoder. Het hete pistool zal de gewenste temperatuur bereiken en piept. Voer de werkelijke temperatuur in door aan de encoder te draaien. Selecteer vervolgens een ander referentiepunt en herhaal dit proces voor alle kalibratiepunten.

Druk daarna lang op en ga naar het hoofdscherm en ga dan opnieuw naar de Setup-modus en selecteer opslaan.

En nu is het herwerkstation voor hete lucht klaar.

Stap 6:Video!

Bekijk de werking van de controller in de video.

Bedankt sfrwmaker voor het schrijven van de code.

Met dank aan LCSC voor hun steun. LCSC Electronics is een van de snelst groeiende leveranciers van elektronische componenten in China. LCSC zet zich sinds de oprichting in 2011 in voor het aanbieden van een groot aantal, echte en op voorraad zijnde artikelen. Met als doel de hele wereld te voorzien van meer superieure onderdelen uit Azië. Ga voor meer informatie naar:https://lcsc.com/

Als je thuis je eigen PCB moet maken, bekijk dan deze tutorial:https://www.instructables.com/id/PCB-Making-1/

Dank je.

Code

  • Firmware 1.4
Firmware 1.4C/C++
Ondersteuning voor actieve/passieve zoemer. Wijzig alstublieft de BUZZER_ACTIVE parameter
Geen verhoogde roterende encoder meer. Waarde verandert met 1.
/* * Heteluchtpistoolcontroller gebaseerd op atmega328 IC * Versie 1.4 * Uitgegeven op 5 december 2020 */#include #include #include  #include #include #include #include const uint16_t temp_minC =100; // Minimumtemperatuur die de controller nauwkeurig kan controlerenconst uint16_t temp_maxC =500; // Maximaal mogelijke temperatuurconst uint16_t temp_ambC =25; // Gemiddelde omgevingstemperatuurconst uint16_t temp_tip[3] ={200, 300, 400}; // Temperatuurreferentiepunten voor kalibratieconst uint16_t min_working_fan =100; // Minimaal mogelijke ventilatorsnelheid uint8_t AC_SYNC_PIN =2; // Outlet 220 v synchronisatiepin. Niet veranderen!const uint8_t HOT_GUN_PIN =7; // Beheer pinconst van hete pistoolverwarming uint8_t FAN_GUN_PIN =9; // Beheerpin voor hete pistoolventilator. Verander niet! const uint8_t TEMP_GUN_PIN =A0; // Controle van de temperatuur van het hete pistool pinconst uint8_t R_MAIN_PIN =3; // Hoofdpen van roterende encoder. Niet wijzigen!const uint8_t R_SECD_PIN =4; // Rotary encoder secundaire pinconst uint8_t R_BUTN_PIN =5; // Draaiknop pinconst uint8_t REED_SW_PIN =8; // Reed-schakelaar pinconst uint8_t BUZZER_PIN =6; // Zoemer pinconst bool BUZZER_ACTIVE =true; // Actieve zoemer piept wanneer er +5v aan wordt geleverd//------------------------------------- ----- Configuratiegegevens ------------------------------------------- -----/* Config-record in de EEPROM heeft het volgende formaat:* uint32_t ID wordt telkens met 1 verhoogd * struct cfg config data, 8 bytes * byte CRC de checksum*/struct cfg { uint32_t Calibration; // Verpakte kalibratiegegevens door drie temperatuurpunten uint16_t temp; // De vooraf ingestelde temperatuur van de IRON in interne eenheden uint8_t fan; // De vooraf ingestelde ventilatorsnelheid 0 - 255 uint8_t off_timeout; // Time-out voor automatische uitschakeling};class CONFIG {public:CONFIG() {can_write =false; buffRecords =0; rAddr =wAddr =0; eLengte =0; volgendeRecID =0; uint8_t rs =sizeof(struct cfg) + 5; // De totale grootte van het configuratierecord // Selecteer de juiste recordgrootte; De recordgrootte moet een macht van 2 zijn, d.w.z. 8, 16, 32, 64, ... bytes voor (record_size =8; record_size  recID) { minRecID =recID; minRecAddr =adres; } 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); terug opslaan(); // Sla nieuwe gegevens op in de 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); som <<=2; som +=nxt; nxt>>=8; } uint8_t* p =(byte *)&Config; for (uint8_t i =0; i  EEPROM.length()) wAddr =0; volgendeRecID ++; // Maak je klaar om het volgende record als resultaat te schrijven;} bool CONFIG::load (void) { bool is_valid =readRecord (rAddr, nextRecID); volgendeRecID ++; 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 |=Verbetering [byte(i)]; } recID =ts; memcpy(&Config, &Buff[4], sizeof(struct cfg)); retourneer waar; } return false;}//------------------------------------------ klasse HOT GUN CONFIG ----------------------------------------------klasse HOTGUN_CFG:public CONFIG {public:HOTGUN_CFG() {} void init(void); uint16_t tempPreset(void); // De vooraf ingestelde temperatuur in interne eenheden uint8_t fanPreset(void); // De vooraf ingestelde ventilatorsnelheid 0 - 255 uint16_t tempInternal (uint16_t temp); // Vertaal de door mensen leesbare temperatuur naar interne waarde uint16_t tempHuman (uint16_t temp); // Vertaal de temperatuur van interne eenheden naar de Celsius void save (uint16_t temp, uint8_t fanSpeed); // Bewaar vooraf ingestelde temperatuur in de interne eenheden en ventilatorsnelheid void ApplyCalibrationData(uint16_t tip[3]); ongeldig getCalibrationData(uint16_t tip[3]); ongeldig saveCalibrationData (uint16_t tip [3]); void setDefaults (bool Schrijven); // Stel standaard parameterwaarden in als het niet lukt om gegevens van EEPROM privé te laden:uint16_t t_tip [3]; const uint16_t def_tip[3] ={587, 751, 850}; // Standaardwaarden van interne sensormetingen bij referentietemperaturen const uint16_t min_temp =50; const uint16_t max_temp =900; const uint16_t def_temp =600; // Standaard ingestelde temperatuur const uint8_t def_fan =64; // Standaard ingestelde ventilatorsnelheid 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); // Als de gegevens niet uit EEPROM kunnen worden geladen, initialiseert u de configuratiegegevens met de standaardwaarden uint32_t cd =Config.calibration; t_tip[0] =cd &0x3FF; cd>>=10; // 10 bits per kalibratieparameter, omdat de ADC-waarden 10 bits zijn t_tip[1] =cd &0x3FF; cd>>=10; t_tip[2] =cd &0x3FF; // Controleer of de tipkalibratie correct is als ((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 kalibratie; // Verpakte kalibratiegegevens door drie temperatuurpunten uint16_t temp; // De vooraf ingestelde temperatuur van de IRON in interne eenheden uint8_t fan; // De vooraf ingestelde ventilatorsnelheid 0 - 255 uint8_t off_timeout; // Automatische uitschakeling timeout16_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) { // Vertaal de door mensen leesbare temperatuur in interne waarde t =constrain (t, temp_minC, temp_maxC); uint16_t links =0; uint16_t rechts =1023; // Maximale temperatuurwaarde in binnenunits uint16_t temp =map(t, temp_tip[0], temp_tip[2], t_tip[0], t_tip[2]); if (temp>
 (links+rechts)/ 2) { temp -=(rechts-links)/4; } else { temp +=(rechts-links) / 4; } for (uint8_t i =0; i <20; ++i) { uint16_t tempH =tempHuman(temp); if (tempH ==t) { retourtemp; } uint16_t nieuwe_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; // Verpak tipkalibratiegegevens in één 32-bits woord:10-bits per waarde 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; Configuratie.kalibratie =c; Config.temp =def_temp; Config.fan =def_fan; if (Schrijf) { CONFIG::save(); }}//------------------------------------------ klasse ZOEMER -- -------------------------------------------------- --class BUZZER { public:BUZZER (byte buzzerP, bool active =true) { buzzer_pin =buzzerP; dit->actief =actief; } void init(void); ongeldig shortBeep (ongeldig); void lowBeep(void); void doubleBeep (ongeldig); void misluktBeep(void); privé:byte buzzer_pin; bool actief;};void BUZZER::init(void) { pinMode(buzzer_pin, OUTPUT); if (actief) {digitalWrite(buzzer_pin, LOW); } else { noTone(buzzer_pin); }}void BUZZER::shortBeep(void) { if (active) { digitalWrite(buzzer_pin, HIGH); vertraging (80); digitalWrite (buzzer_pin, LAAG); } else { tone(buzzer_pin, 3520, 160); }}void BUZZER::lowBeep(void) { if (active) { digitalWrite(buzzer_pin, HIGH); vertraging (160); digitalWrite (buzzer_pin, LAAG); } else { tone(buzzer_pin, 880, 160); }}void BUZZER::doubleBeep(void) { if (active) { digitalWrite(buzzer_pin, HIGH); vertraging (160); digitalWrite (buzzer_pin, LAAG); vertraging (150); digitalWrite (buzzer_pin, HOOG); vertraging (160); digitalWrite (buzzer_pin, LAAG); } else { tone(buzzer_pin, 3520, 160); vertraging (300); toon (buzzer_pin, 3520, 160); }}void BUZZER::failedBeep(void) { if (active) { digitalWrite(buzzer_pin, HIGH); vertraging (170); digitalWrite (buzzer_pin, LAAG); vertraging(10); digitalWrite (buzzer_pin, HOOG); vertraging (80); digitalWrite (buzzer_pin, LAAG); vertraging (100); digitalWrite (buzzer_pin, HOOG); vertraging (80); digitalWrite (buzzer_pin, LAAG); } else { tone(buzzer_pin, 3520, 160); vertraging (170); toon (buzzer_pin, 880, 250); vertraging (260); toon (buzzer_pin, 3520, 160); }}//------------------------------------------ klasse lcd DSPLay voor soldeerbout -----------------------------klasse DSPL:beschermd LiquidCrystal_I2C { openbaar:DSPL (void) :LiquidCrystal_I2C (0x27, 16, 2) {} void init(void); void clear(void) { LiquidCrystal_I2C::clear(); } void tSet(uint16_t t, bool Celsius =true); // Toon de vooraf ingestelde temperatuur ongeldig tCurr (uint16_t t); // Toon de huidige temperatuur ongeldig tInternal(uint16_t t); // Toon de huidige temperatuur in interne eenheden void tReal(uint16_t t); // Toon de echte temperatuur in Celsius in kalibreermodus void fanSpeed ​​(uint8_t s); // Toon de ventilatorsnelheid void toegepastPower (uint8_t p, bool show_zero =true); // Toon toegepast vermogen (%) void setupMode (uint8_t-modus); void msgON (ongeldig); // Toon bericht:"ON" void msgOFF (void); ongeldig msgReady (ongeldig); void msgCold (ongeldig); ongeldig msgFail (ongeldig); // Toon 'Fail' bericht void msgTune (void); // Toon 'Tune' bericht privé:bool full_second_line; // Of de tweede regel vol is met het bericht char temp_units; const uint8_t custom_symbols[3][8] ={ { 0b00110, // Graad 0b01001, 0b01001, 0b00110, 0b00000, 0b000000, 0b00000, 0b00000 }, { 0b00100, // Ventilatorteken 0b01100, 0b01100, 0b00110, 0b011110 0b , 0b0000 }, { 0b00011, // Power sign 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 =onwaar; temp_units ='C';}void DSPL::tSet(uint16_t t, bool Celsius) { char buff [10]; if (Celsius) { 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")); opbrengst; } LiquidCrystal_I2C::print(buff); if (full_second_line) { LiquidCrystal_I2C::print(F(" ")); full_second_line =onwaar; }}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")); opbrengst; } LiquidCrystal_I2C::print(buff); if (full_second_line) { LiquidCrystal_I2C::print(F(" ")); full_second_line =onwaar; }}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")); opbrengst; } LiquidCrystal_I2C::print(buff);}void DSPL::fanSpeed(uint8_t s) { char buff[6]; s =kaart(en, 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]; als (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-modus) { LiquidCrystal_I2C::clear(); LiquidCrystal_I2C::print(F("setup")); LiquidCrystal_I2C::setCursor(1,1); switch (mode) { case 0:// tip Calibrate LiquidCrystal_I2C::print(F("kalibreren")); pauze; geval 1:// tune LiquidCrystal_I2C::print(F("tune")); pauze; geval 2:// save LiquidCrystal_I2C::print(F("save")); pauze; geval 3:// annuleer LiquidCrystal_I2C::print(F("cancel")); pauze; geval 4:// stel de standaardwaarden in LiquidCrystal_I2C::print(F("reset config")); pauze; standaard:pauze; }}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(" -==Mislukt ==- "));}void DSPL::msgTune(void) { LiquidCrystal_I2C::setCursor(0, 0); LiquidCrystal_I2C::print(F("Tune"));}//---------------------------------- -------- klas GESCHIEDENIS ---------------------------------------- ------------#define H_LENGTH 16class HISTORY { public:HISTORY(void) { len =0; } void init (void) { len =0; } uint16_t last(void); uint16_t top(void) { return wachtrij [0]; } void put (uint16_t item); // Plaats een nieuw item in de geschiedenis uint16_t gemiddelde (void); // bereken de gemiddelde waarde float dispersion (void); // bereken de wiskundige spreiding privé:vluchtige uint16_t wachtrij [H_LENGTH]; vluchtige byte-lens; // Het aantal elementen in de wachtrij volatiele byte-index; // De huidige elementpositie, gebruik ringbuffer};void HISTORY::put(uint16_t item) { if (len =H_LENGTH) index =0; // Gebruik ringbuffer }}uint16_t HISTORY::last(void) { if (len ==0) return 0; uint8_t ik =len - 1; if (index) i =index - 1; retourwachtrij [i];}uint16_t GESCHIEDENIS::gemiddelde(void) { uint32_t sum =0; if (len ==0) retourneer 0; if (len ==1) retourwachtrij [0]; for (uint8_t i =0; i > 1; // rond de gemiddelde som af /=len; return uint16_t(sum);}float HISTORY::dispersion(void) { if (len <3) return 1000; uint32_t som =0; uint32_t avg =gemiddeld(); for (uint8_t i =0; i > 1; bijwerken (waarde); return (emp_data + round_v) / emp_k;}void EMP_AVERAGE::update(int32_t value) { uint8_t round_v =emp_k>> 1; emp_data +=waarde - (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;}//-------------------------------------- ---- klasse PID-algoritme om de temperatuur te behouden -----------------------/* Het PID-algoritme * Un =Kp*(Xs - Xn) + Ki*summ{j=0; j<=n}(Xs - Xj) + Kd(Xn - Xn-1), * Waar Xs - de insteltemperatuur is, Xn - de temperatuur bij n-iteratiestap * In dit programma wordt de interactieve formule gebruikt:* Un =Un-1 + Kp*(Xn-1 - Xn) + Ki*(Xs - Xn) + Kd*(Xn-2 + Xn - 2*Xn-1) * Met de eerste stap:* U0 =Kp*( Xs - X0) + Ki*(Xs - X0); Xn-1 =Xn; * * Geschiedenis PID-coëfficiënten:* 14-10-2017 [768, 32, 328] * 27-11-2019 [ 2009, 1600, 20] * 27-04-2020 [ 50, 16, 50] */klasse PID { publiek:PID(void) { Kp =50; Ki =16; Kd =50; } ongeldig resetPID (int temp =-1); // reset PID-algoritmegeschiedenisparameters // Bereken het toe te passen vermogen lange reqPower (int temp_set, int temp_curr); int changePID(uint8_t p, int k); // set of get (als parameter <0) PID-parameter privé:void debugPID (int t_set, int t_curr, lange kp, lange ki, lange kd, lange delta_p); int temp_h0, temp_h1; // eerder gemeten temperatuur bool pid_iterate; // Of het iteratieve proces lang wordt gebruikt i_summ; // Ki samenvatting vermenigvuldigd met noemer lange macht; // De iteratieve macht vermenigvuldigd met de noemer lange Kp, Ki, Kd; // De PID-algoritmecoëfficiënten vermenigvuldigd met de noemer 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, LAAG); 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; } pauze; 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(); } } pauze; 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

Schema's

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

Productieproces

  1. Liquid Crystal Display (LCD)
  2. Bouw een doe-het-zelf Thermocam
  3. Raspberry Pi 2 weerstation
  4. Raspberry Pi-weerstation
  5. Possessed Portrait – Updated
  6. Weerstation V 2.0
  7. UVC Box een doe-het-zelf UV-sterilisator
  8. DIY Eenvoudige 20 kHz Arduino-oscilloscoop op Nokia 5110 LCD
  9. LCD-animatie en gaming
  10. DIY 10Hz-50kHz Oscilloscoop op 128x64 LCD-scherm
  11. Lokaal weerstation