{"id":28588475,"url":"https://github.com/kr4fty/reballingmachine","last_synced_at":"2025-06-11T07:11:09.362Z","repository":{"id":289670238,"uuid":"972023752","full_name":"kr4fty/ReballingMachine","owner":"kr4fty","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-24T12:56:37.000Z","size":327,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-24T13:31:00.648Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kr4fty.png","metadata":{"files":{"readme":"README.txt","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-24T12:22:52.000Z","updated_at":"2025-04-24T12:56:40.000Z","dependencies_parsed_at":"2025-04-24T13:41:13.806Z","dependency_job_id":null,"html_url":"https://github.com/kr4fty/ReballingMachine","commit_stats":null,"previous_names":["kr4fty/reballingmachine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kr4fty%2FReballingMachine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kr4fty%2FReballingMachine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kr4fty%2FReballingMachine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kr4fty%2FReballingMachine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kr4fty","download_url":"https://codeload.github.com/kr4fty/ReballingMachine/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kr4fty%2FReballingMachine/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259219729,"owners_count":22823579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-11T07:11:08.105Z","updated_at":"2025-06-11T07:11:09.349Z","avatar_url":"https://github.com/kr4fty.png","language":"C","readme":"Librería max6675.h\n==================\nSe utiliza un fork de la librería de Adafruit, porque esta ultima NO utiliza \nSPI por hardware. En su lugar se utiliza la siguiente:\n    https://github.com/banoz/MAX6675-library\n\n    PINOUT\n    ------\n    SO:  MISO\n    CS:  chip Select\n    SCK: Entrada reloj\n    VCC: 3.3V or 5V\n    GND: GND\n\nLibrería Adafruit_ST7735.h\n==========================\nSe utiliza la librería de Adafruit\n    https://github.com/adafruit/Adafruit-ST7735-Library\n\n    PINOUT\n    ------\n    VLED:   Soporte LED UTFT\n    SCL:    Entrada de reloj serie\n    SDA/SDI:Entrada de datos serie\n    DC:     Selección de datos / comandos\n    RST:    Restablecer nivel bajo activo\n    CS:     Selección de chip, nivel bajo activo\n    GND:    Tierra\n    VDD33:  Pin de fuente de alimentación 3.3V\n\nLibreria PID_v1.h\n=================\nLibrería PID\n    https://github.com/br3ttb/Arduino-PID-Library\n\nLibrería AiEsp32RotaryEncoder.h\n===============================\nLibrería para el control de un encoder y un botón\n    https://github.com/kr4fty/ai-rotary-encoder\n\nLibrería ElegantOTA.h\n=====================\nLibrería para la actualizacion del firmware utlizando OTA\n    https://github.com/ayushsharma82/ElegantOTA\n\nLibrería ArduinoOTA.h (UTILIZADO)\n=====================\nLibreria para controlar las actualizaciones por medio de OTA\n    https://github.com/arduino/arduinoOTA\n\n/******************************************************************************\n                               Corriente Alterna\n******************************************************************************/\n\nPara controlar la potencia de los calentadores conectados a la linea eléctrica\ndomiciliaria, 220Vca, se utilizara un triac, el cual me permitirá controlar el\nangulo de fase y de esta forma manejar la potencia que le llega a los calenta-\ndores.\nEl triac se activa con un pequeño pulso en el pata Gate (G) del triac, el cual\npermanecerá activo hasta que el ciclo de la señal eléctrica se haga cero, con\nuna duración del pulso es de unos 10uSeg. Se debe enviar en cada cruce por cero \npara activarlo. Caso contrario solo permanecerá activo en el semiciclo\nEl angulo de fase lo controlaremos sabiendo cuando exactamente la señal pasa por\ncero, enviando a partir de ese momento y a la fase deseada, el pulso de control\n\nControl utilizado:\n    https://github.com/pmarchini/Esp32Dimmer\n\nControl de Cruce por Cero\n=========================\nhttps://www.reddit.com/r/AskElectronics/comments/vgd0lq/zerocrossing_detector_circuit_with_esp32/\n\n    Problemas:\n        * Lecturas/Interrupciones falsas por interferencia\n            º Solución 1, usando un Smith Triger (use un 74LS244/14, con muy \n              buenos resultados. La contra es que se usa otro IC dedicado\n            º Solución 2, usando filtro entes del puente (hubo pequeña mejora)\n            º Solución 3, una vez recibido un pulso de interrupción, se ignora \n              en una pequeña ventana de tiempo las interrupciones y asi evitar\n              falsos positivos. Buenos resultados\n        * Utilizando millis y micros no se puede controlar correctamente el\n          pulso para activar el TRIAC, debido a que posiblemente no llegamos\n          con el tiempo a activarlo el pulso\n            º Se utilizo interrupciones de dos timers, uno para la subida del\n              pulso y el segundo para la bajada\n\nControl de Fase\n===============\n    Problemas:\n        * Al ver mediante el osciloscopio los pulsos enviados en cada cruce\n          por cero, se ve que el ancho de dicho pulso es proporcional a el\n          valor del capacitor de filtrado que esta antes del puente de diodos.\n          Con un capacitor de 100nF me da un ancho aproximado de 1200 uSeg.\n          Por lo que a el momento 0 desde donde comienza cada ciclo, esta en \n          aproximadamente 600 desde el momento en que se recibe la interrupción\n\n        * Al trabajar con UNA salida pseudo-PWM utilizamos dos timers para\n          controlar el pulso de activación del Triac.\n          Ahora si quisiera trabajar con dos salidas al mismo, pseudo-PWM,\n          con este método seria imposible, ya que al enviar un pequeño pulso\n          los timers cuentan hasta:\n\n              Timer 1: timerTicks \u003c---------- Pulso de subida\n              Timer 2: timerTicks + G_PULSE_WIDTH \u003c-----Pulso de bajada\n          \n          El tema es como implementar los dos pulsos simultáneos, que lógica\n          usar si se quiere implementar por medio de los dos timers, por que\n          se solaparían\n\n          Solución:\n            Se utiliza un solo Timer. Este oscila a una frecuencia de 1.8MHz y\n            se configura a timerAlarm() para que produzca un interrupción en \n            unos TIMER_INTERVAL cuentas. Este valor de TIMER_INTERVAL es fijo\n            por lo que me dara los 10 mili segundos divididos en 180, de los\n            grados. Luego dentro de cada interrupción voy sumando un contador y\n            verificando en cada momento si una de las salidas coincide con la\n            cuenta de este contador para poner en estado alto la salida.\n            Luego para bajar, como TIMER_INTERVAL es de aprox. 55.55 uSeg, en\n            la siguiente interrupción se pone en bajo el pin de salida,\n            logrando de esta manera que se envie un pulso por la salida\n            seleccionada al angulo de disparo requerido.\n            Lo bueno de esta solicion es que puedo enviar en simultaneo, mismo\n            y único Timer, varios pulsos hacia el Triac.\n            Como contra se puede decir que consume mas recursos del MCU ya que\n            el timer entrara a la ISR muchísima mas veces ya que el timer se\n            desborda cada TIMER_INTERVAL, y esto es continuamente. Por este \n            motivo dicha ISR deberá esta MUY BIEN OPTIMIZADA\n\n\nCalentadores\n============\n    * Calentador Inferior\n          Se utiliza uno de 1300W, obtenido de una Air Fryer eléctrica\n          39 Ohms, 14cm de diámetro aproximado\n\n    * Calentador Superior\n          Se utiliza un calentador de 1800W de una Pava eléctrica\n          27 Ohms, 8cm de diámetro aproximado\n\nTIMER y PWM:\n============\n    Problema:\n        Se había implementado mediante el Timer1 y Timer2 una reimplementación\n        de un PWM, pero adaptado para nuestro uso. Su función era la siguiente:\n          Espero por la llega de un cruce por cero y de acuerdo con el dutty\n          seleccionado, envió un pulso (HIGH), esto medido con el timer1. Luego\n          al activarse el timer2 bajo el pin a LOW.\n          En resumen: al momento de la llegada del cruce por cero, se espera un\n          tiempo, duty, y se envía un pulso, de 15uS, para activar el TRIAC.\n        Esto se había implementado con la API v2 del Timer, pero ahora se\n        actualizo a la v3. Se re acomodo de acuerdo a los cambios de la nueva v3\n        pero aun no se probo en placa.\n\nPERFILES DE TEMPERATURA\n=======================\n    Se Intentara leer archivos de configuración, por ejemplo en formato JSON,\n    que contenga el perfil a utilizar. De este modo se buscara tener varios de\n    estos perfiles para ser seleccionados en el momento de arranque.\n    \n    Ejemplo de archivos:\n     https://github.com/dukeduck1984/uReflowOven-Esp32-Micropython/tree/master/MAIN/profiles\n    \n    Solución implementada:\n        Por ahora se guardan Perfiles en my_profiles.h y se cargan desde ahi\n\n    \n\n///////////////////////////////////////////////////////////////////////////////\nHACER\n=====\n    * Utilizar interrupciones del Timer para recrear el pulso G hacia el Pin\n      de activación del TRIAC\n      \n        Solución 1: Se utiliza DigitalWrite, ya que esta muy bien implementada\n                    y es muy rápida. Nada que ver con la implementación hecha\n                    para los ATMEGA328 (Arduino UNO).\n        Solución 2: Se implemento interrupciones de los timers con resultados\n                    positivos. Lo único es que el ancho del pulso generado no\n                    tiene un ancho fijo. Aparentemente por ruido????\n\n    * Calculo de superficie del semiciclo en función del angulo de disparo\n      Al no ser una curva escalón la superficie/potencia entregada no va a ser\n      lineal a medida que nos movemos a través del semiciclo con el pulso en G.\n      Por tal, me imagino que tendré que hacer una variable vector con valores\n      de los ángulos de fase y sus equivalentes en potencia\n\n      Otra solución seria trabajar con medio semiciclo por vez, de 0 a 90º y de\n      90º a 180º\n\n      Solución:\n                Se obtuvo la ecuación real de la superficie correspondiente al\n                valor seteado del dutty. Para que quede lineal desde 0 a 180º.\n                \n                = acos(1-encoderCounter/90.0)*(180.0/M_PI)\n    \n    * Implementar una función genérica que se encargue de actualizar los datos\n      a mostrar en el LCD. \n      Este debería ocupar menos tiempo que imprimir nuevos datos a medida que\n      se van actualizando\n\n      Solución:\n                Implementado\n    \n    * Reordenar y dividir el código en diferentes archivos/headers, para lograr\n      mas legibilidad\n\n      Solución:\n                Implementado\n    \n    * Utilizar Librería Pthreads para hacer un control en paralelo de la\n      temperatura de los calentadores\n    \n    * Tratar de utilizar PWM en modo 2 (asi se llama en STM32, cuando el pulso)\n      recién pasa a nivel alto, cuando se desborda el contador. A la inversa \n      que el PWM tradicional. AVERIGUAR ESTO!!!\n\n///////////////////////////////////////////////////////////////////////////////","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkr4fty%2Freballingmachine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkr4fty%2Freballingmachine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkr4fty%2Freballingmachine/lists"}