Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Estación de retrabajo SMD DIY

Componentes y suministros

SparkFun Arduino Pro Mini 328 - 5V / 16MHz
× 1
LCD estándar Adafruit - 16x2 blanco sobre azul
× 1
módulo lcd i2c
× 1
Codificador rotatorio con pulsador
× 1
Mango de pistola de aire caliente
× 1
Soporte para pistola de aire caliente + boquilla
× 1
BTA12-600B
× 1
IRFZ44
× 1
MCP602
× 1
MOC3052
× 1
4N25
× 1
Puente rectificador
× 1
Buzzer
× 1
Diodo rectificador rápido FR107
× 1
condensador de 0,01 uF, 400 V
× 1
Condensador 100 nF
× 6
Resistencia de orificio pasante, 39 ohmios
× 1
Resistencia de orificio pasante, 33 kohm
× 2
Resistencia de 330 ohmios
× 1
Resistencia 220 ohmios
× 1
Resistencia 1k ohm
× 3
Resistencia de orificio pasante, 470 ohmios
× 1
potenciómetro multivuelta de 500k
× 1
Resistencia de 10k ohmios
× 3

Herramientas y máquinas necesarias

Soldador (genérico)

Aplicaciones y servicios en línea

Arduino IDE
Autodesk Eagle

Acerca de este proyecto

Introducción:Estación de retrabajo SMD de bricolaje

En este tutorial, puede aprender cómo hacer un controlador de pistola de aire caliente usando Arduino y otros componentes comunes. En este proyecto, el algoritmo PID se utiliza para calcular la potencia requerida y está controlado por un controlador Triac aislado.

Este proyecto utiliza un mango compatible con 858D. Tiene un termopar tipo K, calentador de 700 vatios 230 VCA y ventilador de 24 VCC.

Este controlador es eficiente y confiable en comparación con el comercial y es fácil de construir.

Paso 1:cableado

El esquema completo se muestra en la siguiente imagen.


Cableado para el módulo LCD I2C:

Módulo I2C <--------------> Arduino Pro Mini

TIERRA <-----------------------> TIERRA <---------> TIERRA

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

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

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

Cableado para módulo codificador rotatorio:

Codificador <----------------------> Arduino

TIERRA <---------------------------> TIERRA

+ <--------------------------------> NC (No conectado, el código utiliza pull-up de entrada incorporado de arduino)

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

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

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

Cableado de la manija: (7 hilos)

Conector de 3 pines - (verde, negro, rojo)

Cable rojo <-----------------------> Termopar +

Cable verde <--------------------> Interruptor de lengüeta

Cable negro <---------------------> Tierra común.

Conector de 2 pines - (azul, amarillo)

Cable azul <--------------------------> Ventilador +0

Cable amarillo <------------------------> Ventilador - (o GND)

2 Conector de clavija grande - (blanco, marrón)

Cable blanco <-----------------------> Calentador

Cable marrón <----------------------> Calentador (sin polaridad)

NOTA:

El cableado del mango de la pistola de aire caliente puede ser diferente para diferentes tipos de varillas. Por lo tanto, consulte el diagrama de cableado en la foto y siga la ruta del cable para encontrar los pines respectivos.

Paso 2:diagrama de circuito

El circuito consta principalmente de 3 partes.

La parte de la interfaz:

Consiste en una pantalla LCD 1602 con módulo I2C y un codificador rotatorio con pulsador. La pantalla muestra la temperatura establecida, la temperatura actual, la velocidad del ventilador y la potencia aplicada y el estado actual del mango. El codificador se usa para varias entradas y para navegar a través de las opciones y controles.

La parte del sensor:

Consiste en un termopar tipo K para la detección de temperatura y un interruptor de lengüeta para determinar la posición del mango. El voltaje del termopar es amplificado por el amplificador operacional a un nivel de voltaje medible por el arduino. La ganancia del amplificador operacional se controla mediante un potenciómetro de ajuste de 200 K.

La parte del controlador:

Hay principalmente 2 controladores en este circuito. El primero es un controlador de velocidad de ventilador PWM simple con un MOSFET. El otro es un controlador aislado para calentador. Consiste en un TRIAC impulsado por un DIAC optoacoplado y se realiza controlando el número de ciclos de onda que se entrega al calentador. El optoacoplador 4N25 ayuda a mantener la sincronización con la forma de onda de CA.

Paso 3:PCB

El circuito de este proyecto es un poco complicado, así que te recomiendo que uses una placa impresa que una PCB de puntos. Si quieres hacer tu propia PCB, adjunto los archivos eagle al final del proyecto. Pero, si desea que los haga una empresa de fabricación de PCB, puede solicitarlos a JLCPCB

. Puede ver el diseño Easy EDA a través de este enlace:https://easyeda.com/ManojBR/harws1-1

Paso 4:el código y las bibliotecas

El programa es la parte más crucial del proyecto y muchas gracias por sfrwmaker escribiendo el programa. El programa utiliza algoritmo PID para controlar la potencia para mantener la temperatura establecida. Funciona controlando la cantidad de ciclos de onda entregados al mango por segundo.

Cuando se enciende el controlador, la varilla estará en estado APAGADO. girando el codificador la temperatura y la velocidad del ventilador se pueden ajustar. Pulsación corta del codificador cambiará entre la velocidad del ventilador y el ajuste de temperatura establecida.

La pistola de aire caliente comienza a calentar tan pronto como se levanta del soporte y muestra Listo y emite un pitido corto cuando alcanza la temperatura establecida. Apagará la calefacción tan pronto como se vuelva a colocar en el soporte. Pero el ventilador seguirá funcionando hasta que alcance la temperatura segura. Después de que la temperatura descienda por debajo de 50 C, emitirá un pitido corto y mostrará FRÍO.

Cuando la pistola de aire caliente está apagada, el controlador entrará en el modo de configuración si el codificador está presionado durante mucho tiempo .

El modo de configuración tiene las opciones Calibrar, Ajustar, Guardar y Cancelar y Restablecer configuración.

Nota: Si está utilizando PCB de easyEDA entonces debería cambiar el número de pin del interruptor de lengüeta al pin no. 8 y Pin del zumbador en el pin n. ° 6

debe instalar la biblioteca Commoncontrols-master y la biblioteca time-master para que el código funcione correctamente.

Precaución: No conecte el controlador a la toma de corriente cuando actualice el firmware. La fuente de alimentación no aislada del ventilador podría dañar su computadora portátil.

descargue el código fuente del boceto desde la página del proyecto.

Paso 5:configuración

Las lecturas de temperatura deben calibrarse con el valor original para obtener lecturas razonables. Entonces, para hacerlo, debe seguir los siguientes pasos.

Primero, vaya al modo de configuración y seleccione la opción Tune. En el modo Tune, la temperatura interna (0-1023) se muestra en la pantalla. Gire el codificador para seleccionar manualmente la potencia aplicada a la pistola de aire caliente. Caliente la pistola a 400 grados. Cuando la temperatura y la dispersión bajen, el controlador emite un pitido. Luego, sintonice el potenciómetro para ajustar la temperatura interna a unos 900ºC (en las unidades internas). Mantenga presionado el codificador para regresar al menú

Luego, vaya al modo de configuración y seleccione la opción Calibrar. Elija el punto de calibración:200, 300 o 400 grados, presione el codificador. La pistola caliente alcanzará la temperatura deseada y emitirá un pitido. Girando el codificador, ingrese la temperatura real. Luego seleccione otro punto de referencia y repita este proceso para todos los puntos de calibración.

Después de esta pulsación larga, vaya a la pantalla principal y luego vuelva al modo Configuración y seleccione guardar.

Y ahora la estación de reparación de aire caliente está lista.

Paso 6:¡Video!

Eche un vistazo al funcionamiento del controlador en el video.

Gracias sfrwmaker por escribir el código.

Gracias a LCSC por su apoyo. LCSC Electronics es uno de los proveedores de componentes electrónicos de más rápido crecimiento en China. LCSC se ha comprometido a ofrecer artículos multitudinarios, genuinos y en stock, desde su fundación en 2011. Con el objetivo de proporcionar al mundo entero piezas más superiores de Asia. Más detalles, visite:https://lcsc.com/

Si tiene que hacer su propia PCB en casa, consulte este tutorial:https://www.instructables.com/id/PCB-Making-1/

Gracias.

Código

  • Firmware 1.4
Firmware 1.4 C / C ++
Soporte de zumbador activo / pasivo. Por favor cambie el parámetro BUZZER_ACTIVE
No más codificador rotatorio aumentado. El valor cambia en 1.
 / * * Controlador de pistola de aire caliente basado en atmega328 IC * Versión 1.4 * Lanzado el 05 de diciembre de 2020 * / # include  #include  #include  #include  #include  #include  #include  const uint16_t temp_minC =100; // Temperatura mínima que el controlador puede verificar con precisiónconst uint16_t temp_maxC =500; // Temperatura máxima posible constante uint16_t temp_ambC =25; // Temperatura ambiente promedioconst uint16_t temp_tip [3] ={200, 300, 400}; // Puntos de referencia de temperatura para la calibraciónconst uint16_t min_working_fan =100; // Velocidad mínima posible del ventiladorconst uint8_t AC_SYNC_PIN =2; // Pin de sincronización de salida 220 v. ¡No lo cambie! Const uint8_t HOT_GUN_PIN =7; // Gestión del calentador de pistola caliente pinconst uint8_t FAN_GUN_PIN =9; // Pin de gestión del ventilador de la pistola caliente. ¡No cambies! const uint8_t TEMP_GUN_PIN =A0; // Comprobación de la temperatura de la pistola caliente pinconst uint8_t R_MAIN_PIN =3; // Pin principal del codificador rotatorio. ¡No lo cambie! Const uint8_t R_SECD_PIN =4; // Codificador rotatorio secundario pinconst uint8_t R_BUTN_PIN =5; // Botón codificador rotatorio pinconst uint8_t REED_SW_PIN =8; // Interruptor de lengüeta pinconst uint8_t BUZZER_PIN =6; // Zumbador pinconst bool BUZZER_ACTIVE =true; // El zumbador activo emite un pitido cuando se le suministran + 5v // ------------------------------------- ----- Datos de configuración ------------------------------------------- ----- / * El registro de configuración en la EEPROM tiene el siguiente formato:* uint32_t ID cada vez que se incrementa en 1 * estructura de datos de configuración cfg, 8 bytes * byte CRC la suma de comprobación * / struct cfg {uint32_t calibración; // Datos de calibración empaquetados por tres puntos de temperatura uint16_t temp; // La temperatura preestablecida del HIERRO en las unidades internas uint8_t fan; // La velocidad del ventilador preestablecida 0 - 255 uint8_t off_timeout; // Tiempo de espera de apagado automático}; class CONFIG {public:CONFIG () {can_write =false; buffRecords =0; rAddr =wAddr =0; eLength =0; nextRecID =0; uint8_t rs =tamaño de (struct cfg) + 5; // El tamaño total del registro de configuración // Seleccione el tamaño de registro apropiado; El tamaño del registro debe ser una potencia de 2, es decir, 8, 16, 32, 64, ... bytes para (tamaño_registro =8; tamaño_registro  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); return save (); // Guardar nuevos datos en la 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; para (uint8_t i =0; i <4; ++ i) {EEPROM.write (startWrite ++, nxt &0xff); suma <<=2; suma + =nxt; nxt>> =8; } uint8_t * p =(byte *) &Config; para (uint8_t i =0; i  EEPROM.length ()) wAddr =0; nextRecID ++; // Prepárese para escribir el siguiente registro 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 | =Buff [byte (i)]; } recID =ts; memcpy (&Config, &Buff [4], sizeof (struct cfg)); devuelve verdadero; } return false;} // ------------------------------------------ clase CONFIGURACIÓN DE PISTOLA CALIENTE ---------------------------------------------- clase HOTGUN_CFG:public CONFIG {public:HOTGUN_CFG () {} void init (void); uint16_t tempPreset (vacío); // La temperatura preestablecida en unidades internas uint8_t fanPreset (void); // La velocidad preestablecida del ventilador 0-255 uint16_t tempInternal (uint16_t temp); // Traducir la temperatura legible por humanos en valor interno uint16_t tempHuman (uint16_t temp); // Traducir la temperatura de las unidades internas a Celsius void save (uint16_t temp, uint8_t fanSpeed); // Guardar la temperatura preestablecida en las unidades internas y la velocidad del ventilador void applyCalibrationData (uint16_t tip [3]); void getCalibrationData (uint16_t tip [3]); void saveCalibrationData (uint16_t tip [3]); void setDefaults (bool Write); // Establecer valores de parámetros predeterminados si no se pudieron cargar datos de EEPROM privado:uint16_t t_tip [3]; const uint16_t def_tip [3] ={587, 751, 850}; // Valores predeterminados de las lecturas del sensor interno a temperaturas de referencia const uint16_t min_temp =50; const uint16_t max_temp =900; const uint16_t def_temp =600; // Temperatura preestablecida por defecto const uint8_t def_fan =64; // Velocidad predeterminada del ventilador predeterminada 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 (falso); // Si no pudo cargar los datos de EEPROM, inicialice los datos de configuración con los valores predeterminados uint32_t cd =Config.calibration; t_tip [0] =cd &0x3FF; cd>> =10; // 10 bits por parámetro de calibración, porque las lecturas de ADC son 10 bits t_tip [1] =cd &0x3FF; cd>> =10; t_tip [2] =cd &0x3FF; // Compruebe que la calibración de la punta sea correcta if ((t_tip [0]> =t_tip [1]) || (t_tip [1]> =t_tip [2])) {setDefaults (false); para (uint8_t i =0; i <3; ++ i) t_tip [i] =def_tip [i]; } retorno;} uint32_t calibración; // Datos de calibración empaquetados por tres puntos de temperatura uint16_t temp; // La temperatura preestablecida del HIERRO en las unidades internas uint8_t fan; // La velocidad del ventilador preestablecida 0 - 255 uint8_t off_timeout; // Tiempo de espera de apagado automáticouint16_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) {// Traducir el temperatura legible por humanos en valor interno t =restricción (t, temp_minC, temp_maxC); uint16_t izquierda =0; uint16_t derecha =1023; // Valor máximo de temperatura en unidades internas uint16_t temp =map (t, temp_tip [0], temp_tip [2], t_tip [0], t_tip [2]); if (temp>
 (izquierda + derecha) / 2) {temp - =(derecha-izquierda) / 4; } else {temp + =(derecha-izquierda) / 4; } para (uint8_t i =0; i <20; ++ i) {uint16_t tempH =tempHuman (temp); if (tempH ==t) {temp de retorno; } uint16_t new_temp; si (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]; sugerencia [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; // Empaquete los datos de calibración de la punta en una palabra de 32 bits:10 bits por valor cd | =tip [1] &0x3FF; cd <<=10; cd | =punta [0]; Config.calibration =cd; t_tip [0] =propina [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 (Escribir) {CONFIG ::save (); }} // ------------------------------------------ clase BUZZER - -------------------------------------------------- --clase BUZZER {público:BUZZER (byte buzzerP, bool active =true) {buzzer_pin =buzzerP; esto-> activo =activo; } void init (void); void shortBeep (vacío); void lowBeep (vacío); void doubleBeep (vacío); void failedBeep (void); privado:byte buzzer_pin; bool active;}; void BUZZER ::init (void) {pinMode (buzzer_pin, OUTPUT); if (activo) {digitalWrite (buzzer_pin, LOW); } else {noTone (buzzer_pin); }} void BUZZER ::shortBeep (void) {if (activo) {digitalWrite (buzzer_pin, HIGH); retraso (80); digitalWrite (buzzer_pin, BAJO); } else {tono (buzzer_pin, 3520, 160); }} void BUZZER ::lowBeep (void) {if (activo) {digitalWrite (buzzer_pin, HIGH); retraso (160); digitalWrite (buzzer_pin, BAJO); } else {tono (buzzer_pin, 880, 160); }} void BUZZER ::doubleBeep (void) {if (activo) {digitalWrite (buzzer_pin, HIGH); retraso (160); digitalWrite (buzzer_pin, BAJO); retraso (150); digitalWrite (buzzer_pin, ALTO); retraso (160); digitalWrite (buzzer_pin, BAJO); } else {tono (buzzer_pin, 3520, 160); retraso (300); tono (buzzer_pin, 3520, 160); }} void BUZZER ::failBeep (void) {if (activo) {digitalWrite (buzzer_pin, HIGH); retraso (170); digitalWrite (buzzer_pin, BAJO); retraso (10); digitalWrite (buzzer_pin, ALTO); retraso (80); digitalWrite (buzzer_pin, BAJO); retraso (100); digitalWrite (buzzer_pin, ALTO); retraso (80); digitalWrite (buzzer_pin, BAJO); } else {tono (buzzer_pin, 3520, 160); retraso (170); tono (buzzer_pin, 880, 250); retraso (260); tono (buzzer_pin, 3520, 160); }} // ------------------------------------------ clase lcd DSPLay para HIERRO de soldadura ----------------------------- clase DSPL:LiquidCrystal_I2C protegido {público:DSPL (void):LiquidCrystal_I2C (0x27, 16, 2) {} void init (void); vacío claro (vacío) {LiquidCrystal_I2C ::clear (); } void tSet (uint16_t t, bool Celsius =verdadero); // Muestra la temperatura preestablecida void tCurr (uint16_t t); // Muestra la temperatura actual void tInternal (uint16_t t); // Muestra la temperatura actual en unidades internas void tReal (uint16_t t); // Muestra la temperatura real en grados Celsius en modo calibrar void fanSpeed ​​(uint8_t s); // Muestra la velocidad del ventilador void applicationPower (uint8_t p, bool show_zero =true); // Muestra la potencia aplicada (%) void setupMode (modo uint8_t); void msgON (vacío); // Mostrar mensaje:"ON" void msgOFF (void); void msgReady (vacío); void msgCold (vacío); void msgFail (vacío); // Muestra el mensaje 'Fallo' void msgTune (void); // Mostrar el mensaje 'Tune' private:bool full_second_line; // Si la segunda línea está llena con el mensaje char temp_units; const uint8_t custom_symbols [3] [8] ={{0b00110, // Grado 0b01001, 0b01001, 0b00110, 0b00000, 0b00000, 0b00000, 0b00000}, {0b00100, // Signo de ventilador 0b01100, 0b01100, 0b00110, 0b1100000, , 0b00000}, {0b00011, // Signo de encendido 0b00110, 0b01100, 0b11111, 0b00110, 0b01100, 0b01000, 0b10000}};}; void DSPL ::init (void) {LiquidCrystal_I2C ::begin (); LiquidCrystal_I2C ::clear (); para (uint8_t i =0; i <3; ++ i) LiquidCrystal_I2C ::createChar (i + 1, (uint8_t *) custom_symbols [i]); full_second_line =falso; temp_units ='C';} void DSPL ::tSet (uint16_t t, bool Celsius) {char buff [10]; if (Celsius) {temp_units ='C'; } más {temp_units ='F'; } LiquidCrystal_I2C ::setCursor (0, 0); sprintf (buff, "Conjunto:% 3d% c% c", t, (char) 1, unidades_temp); 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")); regreso; } LiquidCrystal_I2C ::print (buff); if (línea_segunda_completa) {LiquidCrystal_I2C ::print (F ("")); full_second_line =falso; }} 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")); regreso; } LiquidCrystal_I2C ::print (buff); if (línea_segunda_completa) {LiquidCrystal_I2C ::print (F ("")); full_second_line =falso; }} 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")); regreso; } LiquidCrystal_I2C ::print (buff);} void DSPL ::fanSpeed ​​(uint8_t s) {char buff [6]; s =mapa (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]; si (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 (mejora); }} anular DSPL ::setupMode (modo byte) {LiquidCrystal_I2C ::clear (); LiquidCrystal_I2C ::print (F ("configuración")); LiquidCrystal_I2C ::setCursor (1,1); cambiar (modo) {caso 0:// punta calibrar LiquidCrystal_I2C ::print (F ("calibrar")); descanso; caso 1:// sintonizar LiquidCrystal_I2C ::print (F ("sintonizar")); descanso; caso 2:// guardar LiquidCrystal_I2C ::print (F ("guardar")); descanso; caso 3:// cancelar LiquidCrystal_I2C ::print (F ("cancelar")); descanso; caso 4:// establecer valores predeterminados LiquidCrystal_I2C ::print (F ("restablecer config")); descanso; predeterminado:descanso; }} void DSPL ::msgON (void) {LiquidCrystal_I2C ::setCursor (10, 0); LiquidCrystal_I2C ::print (F ("ENCENDIDO"));} void DSPL ::msgOFF (void) {LiquidCrystal_I2C ::setCursor (10, 0); LiquidCrystal_I2C ::print (F ("APAGADO"));} void DSPL ::msgReady (void) {LiquidCrystal_I2C ::setCursor (10, 0); LiquidCrystal_I2C ::print (F ("Listo"));} void DSPL ::msgCold (void) {LiquidCrystal_I2C ::setCursor (10, 0); LiquidCrystal_I2C ::print (F ("Frío"));} void DSPL ::msgFail (void) {LiquidCrystal_I2C ::setCursor (0, 1); LiquidCrystal_I2C ::print (F ("- ==Falló ==-"));} void DSPL ::msgTune (void) {LiquidCrystal_I2C ::setCursor (0, 0); LiquidCrystal_I2C ::print (F ("Sintonizar"));} // ---------------------------------- -------- clase HISTORIA ---------------------------------------- ------------ # define H_LENGTH 16class HISTORY {public:HISTORY (void) {len =0; } void init (void) {len =0; } uint16_t último (vacío); uint16_t top (void) {cola de retorno [0]; } void put (elemento uint16_t); // Coloca una nueva entrada en el historial uint16_t average (void); // calcula el valor medio de la dispersión flotante (void); // calcula la dispersión matemática private:volatile uint16_t queue [H_LENGTH]; len de bytes volátiles; // El número de elementos en el índice de bytes volátiles de la cola; // La posición actual del elemento, usa el búfer de anillo}; void HISTORY ::put (uint16_t item) {if (len  =H_LENGTH) índice =0; // Usa el búfer de anillo}} uint16_t HISTORY ::last (void) {if (len ==0) return 0; uint8_t i =len - 1; si (índice) i =índice - 1; cola de retorno [i];} uint16_t HISTORIA ::promedio (vacío) {uint32_t suma =0; if (len ==0) return 0; if (len ==1) return cola [0]; para (uint8_t i =0; i > 1; // redondear la suma media / =len; return uint16_t (suma);} float HISTORIA ::dispersión (void) {if (len <3) return 1000; uint32_t suma =0; uint32_t avg =promedio (); para (uint8_t i =0; i > 1; actualizar (valor); return (emp_data + round_v) / emp_k;} void EMP_AVERAGE ::update (int32_t value) {uint8_t round_v =emp_k>> 1; emp_data + =valor - (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;} // -------------------------------------- ---- clase algoritmo PID para mantener la temperatura ----------------------- / * El algoritmo PID * Un =Kp * (Xs - Xn) + Ki * suma {j =0; j <=n} (Xs - Xj) + Kd (Xn - Xn-1), * Donde Xs - es la temperatura de configuración, Xn - la temperatura en el paso de n iteraciones * En este programa se usa la fórmula interactiva:* Un =Un-1 + Kp * (Xn-1 - Xn) + Ki * (Xs - Xn) + Kd * (Xn-2 + Xn - 2 * Xn-1) * Con el primer paso:* U0 =Kp * ( Xs - X0) + Ki * (Xs - X0); Xn-1 =Xn; * * Historial de coeficientes PID:* 14/10/2017 [768, 32, 328] * 27/11/2019 [2009, 1600, 20] * 27/04/2020 [50, 16, 50] * / clase PID { público:PID (vacío) {Kp =50; Ki =16; Kd =50; } void resetPID (int temp =-1); // reset PID algorithm history parameters // Calculate the power to be applied long reqPower(int temp_set, int temp_curr); int changePID(uint8_t p, int k); // set or get (if parameter <0) PID parameter private:void debugPID(int t_set, int t_curr, long kp, long ki, long kd, long delta_p); int temp_h0, temp_h1; // previously measured temperature bool pid_iterate; // Whether the iterative process is used long i_summ; // Ki summary multiplied by denominator long power; // The power iterative multiplied by denominator long Kp, Ki, Kd; // The PID algorithm coefficients multiplied by 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, BAJO); 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; } break; 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(); } } break; 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

Esquemas

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

Proceso de manufactura

  1. Pantalla de cristal líquido (LCD)
  2. Cree una Thermocam de bricolaje
  3. Estación meteorológica Raspberry Pi 2
  4. Estación meteorológica Raspberry Pi
  5. Retrato poseído - Actualizado
  6. Weather Station V 2.0
  7. Caja UVC un esterilizador UV DIY
  8. DIY Osciloscopio Arduino simple de 20 kHz en Nokia 5110 LCD
  9. Animación LCD y juegos
  10. Osciloscopio DIY de 10Hz-50kHz en pantalla LCD de 128x64
  11. Estación meteorológica local