El problema
"Entre toda la basura productiva que tengo está un switch 3300 mx cuyos coolers hacían un terrible ruido. Luego compré unos nuevos pero seguían siendo muy ruidosos. Así que modifiqué un poco las conexiones internas y los pasé de 12v a 5v.
Pero aún así, sigue siendo muy molesto para mis delicados oidos.
¿Qué pasa si los apago completamente? Es lo que se llama "enfriamiento pasivo". El switch está diseñado para trabajar con hasta 24 bocas activas a full y un matrix connector. En casa con suerte hay cuatro bocas en uso a la vez, quizás de conjunto no se caliente mucho, pero algún chip en particular sí y eso lo rompa, no puedo prescindir de la ventilación.
Es un excelente candidato para un arduino o similar con un sensor de temperatura y mediante PWM regular la velocidad de los coolers."
Hasta acá había llegado hace meses sino años, lo había guardado en un cajón y reemplazado por un hub muy bonito, pero de 10, lo cual me ofende y no me facilita los backups por red pero bueno, es lo que hay.
Ahora con #quedateencasa, la red hogareña se vé más exigida y me molesta tanta cosa en el backlog y me aburro asi que lo retomo, pero escribo desde el futuro, lo termino casi cuatro meses despues debido a lo infernalmente complicado que me ha resultado.
Resumen
Es un texto largo, pero puse bastantes dibujitos:
- Elección de microcontrolador según sus recursos, me quedé con un ATMega328p, por fallas en la ArduinoIDE respecto a 1-wire en ATtiny85.
- Elección de la comunicación al exterior buscando no romper el switch, un módulo RS-232.
- Mi falta de conocimiento de electrónica analógica básica me frenó bastante e incluyó la destrucción de dos transistores y dos ATtiny85 pero aún no logré determinar el porqué, sí la destrucción de un ATMega328 por colocarlo desplazado un pin en el protoboard.
- Desarrollo de un programa con parametría en EEPROM para no tener que estar abriendo y cerrando el gabinete, probablemente lo único con algún mérito.
- Primer contacto con ATtiny85, EEPROM, SoftUART, PWM amplificado, sensor interno de temperatura.
Temperatura
Para ir familiarizándome con el problema, lo medí de varias maneras con un termómetro IR (UNI-T UT306A) y con uno de contacto (UNI-T UT202) que en realidad debe ser un poco mayor, pues como estoy apretando el sensor con el dedo contra el chip, hago de disipador.
Abierto, cerrado, sólo prendido, con gente mirando streaming, va de 50 a 60 grados en el chip que está más caliente.
Disipación
Considerá que yo no sé nada de este tema, usaré mi sentido común.
Como
disipador probé un perfíl L de aluminio que tiene poca superficie de
intercambio, pero es lo que tengo. La pregunta es, si los chips están
diseñados para trabajar sin disipador, el agregarle un disipador que no
lo es tanto, ¿mejorará o empeorará la situación? ¿Serán refrigerantes o
abrigantes?
Estos disipadores sacan el
calor de los chips y lo pondrán en el aire dentro del switch, en
términos "totales" no hace diferencia. Lo que mejora es que los chips
estarán menos calientes entonces podré tolerar temperaturas mayores en
ese espacio, que es dónde mido.
Esto me obliga a medir nuevamente, lamentablemente las herramientas que
tengo no sirven así que no tiene mucho sentido que transcriba los
valores. Sí puedo afirmar que midiendo un chip sin disipador me da una
temperatura, le pongo el perfil un rato y se lo saco y me una inferior,
asi que parece funcionar.
Si pongo uno de los termómetros adherido al perfil, quizás tenga un mejor apreciación de lo que ocurre ahí dentro.
Finalmente he decidido no poner disipadores por que me resulta muy difícil mantenerlos en posición a menos que use la cinta bifaz ridículamente cara.
Ventilación
Hasta donde yo sé, la velocidad de motores como los coolers se pueden regular de dos maneras, con el voltaje o con PWM. Lo primero es con un DAC, Digital to Analog Converter, que por lo general va afuera del microcontrolador. Mejor PWM, que es darle pulsos todo o nada.
- Tengo que medir la corriente que circula en los coolers para ver que transistor usar. (listo, 300 mA)
Voltaje y consumo de un cooler |
En la foto podemos ver un cooler conectado con un transistor y su consumo.
- Durante un tiempo debe ser externo por si falla no me rompa nada (ok, lo haré)
- Tengo que ver la frecuencia del PWM por si genera ruido (faltan semanas de pruebas).
Tendría que arrancar al máximo por que tiene onda, como los server raqueables que arrancan a full y despues bajan. Pero tras romper algunos transistores mejor que arranque a la mitad y luego suban y vuelvan a bajar, mantiene la onda y los transistores.
Microcontrolador
Tengo varias opciones, poner un ATMega328p, un ATtiny85 o un ATtiny85 Digispark.
Lo bueno del ATtiny85 Digispark es que tiene un conector USB 1.1 Tipo A macho que en realidad es sólo serial no USB arbitrario como lo que tiene un Teensy. Lo malo es que provee alimentación y el microcontrolador ya va a recibir alimentación desde la fuente del switch y tengo entendido que no es buena idea conectar alimentaciones distintas así no más. Como carezco de los conocimientos, me tengo que quedar con comunicación serial, ya sea el ATMega328p o un ATtiny85 pelado.
Grilla elección microcontrolador
Aspecto | ATMega328p | ATtiny85 |
Comunicación serial | Hardware | Software |
Memoria RAM | 2KB | 512B |
Memoria EPROM | 1024B | 512B |
Memoria FLASH | 32KB | 8KB |
PWM | Si | Si |
Sensor temperatura | Interno | Interno |
GPIO libres para sensores | montones | 2 |
Interesante | No | Si |
Lo bueno de haber confeccionado esta tabla es que me enteré que ambos chips contienen un sensor interno de temperatura.
Voy a intentar usar el ATtiny85 por los siguientes motivos:
- Nunca lo usé antes
- Tener recursos más restringidos es un buen desafío
Comunicación
De un modo u otro, tengo que hacer la adaptación a la PC, puede ser un adaptador a RS-232 (el que maneja voltajes 12 y -12) o estaría re lindo ponerle un db9 y utilizar los transceptores no utilizados del max241c que tiene el switch, pues tiene un puerto serial y ese chip tiene cuatro, tendría que determininar si alguno no está en uso, desoldar las patitas, conectarlas al microcontrolador, poner el conector en el chasis. Tambien podría meterme en el medio si tuviera dos seriales en el microcontrolador e interceptar el diálogo de la terminal serial. Aunque muy interesante, hacker e instructivo, es más tiempo, así que voy por el algo más sencillo primero y además no corro el peligro de romper el chip y quedarme sin poder administrar al switch.
El chip serial candidato |
Dado que está en un switch, podría usar ethernet, no? no:
- Si no recuerdo que IP fija tiene o no coincide con la red actual...
- Si levanta IP por DHCP tengo que buscarla...
- Tengo que meter mucho más hardware y software...
Grilla de elección de comunicaciones
Aprovechar Max241c | Interceptar Max241c | Serial RS232 | Serial Pelado | USB | Infrarrojo RF Bluetooth | |
Interesante | Lo máximo | Lo máximo | Más o menos | Para nada | Para nada | Bastante |
Riesgoso | Completo | Completo | Para nada | Bajo pero podría conectar invertido | Para nada | Para nada |
Hardware | Sólo conector db9 que ya tengo | Nada | Usaría un módulo que ya tengo | Para nada | Usaría un módulo que ya tengo | El que corresponda |
Costo Software | Ínfimo | SoftUart | Ínfimo | Ínfimo | Ínfimo | Complicado |
Adaptador PC | Quizás | No | Quizás | Si | No | Tengo que hacerlo |
Integración Hardware | Perfecta | Perfecta | Perfecta | Horrible | Medio rara | Depende, infrarrojo muy complicado, RF y BT supongo que antena afuera |
Dificultad | Difícil | Difícil | Fácil | Fácil | Fácil | No tan fácil |
Puntos | 13 | 14 | 16 | 12 | 15 | 8 |
Los puntos son 3, 2, 1 y 0. Perdón que la grilla salga medio rota, esto no es muy WYSIWYG y no ando con energías de hacerla bien en otro lado y pegar la imagen.
Tuve que agregar Dificultad pues me quedaban empatados los dos primeros pero a la vez no me cerraba.
Memoria EEPROM
Un detalle importante de este proyecto es que
estoy usando el switch mientras lo diseño. No puedo estar abriéndolo y
cerrándolo en cualquier momento. Entonces la calibración es un problema,
no puedo ponerla en el programa pues puede cambiar ni ponerla en RAM
por que de reiniciarse la pierdo. Tambien tendré que lidiar con el
próximo verano. Salvando las distancias, es un escenario como el de las sondas interplanetarias, donde se manda el hardware con un mínimo software y durante el tiempo de viaje se desarrolla el software que se va a utilizar en el destino de la misión.
Planificación
Tareas de armado
- Colocar conector serial.
- Colocar termómetros.
- Colocar microcontrolador.
Tareas de hardware
- Conectar microcontrolador a 5v de la fuente del switch.
- Conectar microcontrolador a termómetro.
- Conectar adaptador de potencia de los coolers a 12v.
- Conectar adaptador serial.
Tareas de software
- Programar blinky para ATtiny85 y transferirlo.
- Implementar comunicación serial.
- Leer sensor de temperatura incorporado y mostrar por serial.
- Leer sensor de temperatura vía 1-wire.
- Implementar PWM
- Cambiar configuración del PWM según parametría en EEPROM.
- Diseñar función velocidad.
- Atender al REPL vía serial.
- Mostrar temperatura.
- Mostrar velocidad y PWM.
- Cambiar velocidad y PWM.
- Mostrar parametría en EEPROM.
- Modificar parametría en EEPROM.
De todo esto, tengo experiencia en todo salvo el acceso a EEPROM y la función de parametrización que no deja de ser un algoritmo más, así que digamos que si.
Manos a la obra
Como lo más difícil es la función de velocidad, por esta comenzaré.
Función de velocidad, Brain para los amigos
Necesito una velocidad que sea resultado de la temperatura actual de los sensores y la variación que hayan tenido.
O sea si la temperatura actual es normal pero antes era alta, debo mantener la velocidad actual. Cuando vuelva a calcular la actuar será normal y la anterior normal, puedo bajar un poquito y así.
Se me ocurren dos funciones:
Velocidad = v( Tr0, Tr1, Tr2, Ts0, Ts1, Ts2, Tendencia)
Donde:
Tr0 | Temperatura referencia para el sensor interno |
Tr1 | Temperatura referencia para el sensor externo 1 |
Tr2 | Temperatura referencia para el sensor externo 2 |
Tr0 | Temperatura sensor interno |
Ts1 | Temperatura sensor externo 1 |
Ts2 | Temperatura sensor externo 2 |
La variación de velocidad está dada por la siguiente tablita para cada tipo sensor interno/externo:
Ts < Tr | Ts == Tr | Ts > Tr | |
(+2) Subió mucho | + | ++ | +++ |
(+1) Subió | = | + | ++ |
(0) Igual | - | = | + |
(-1) Bajó | -- | - | = |
Para facilitarme la vida, entre paréntesis está el valor que es multiplicado por TA, Amplificador de Tendencia.
Y esta es la Tendencia:
Tendencia = t (TA, Promedio)
y este el Promedio:
Promedio = (W0,W1,W2,Ts0,Ts1,Ts2,Ts0-1,Ts1-1,Ts2-1,TsX-n,Ts2-n,..)
que debe tener en cuenta el peso de los sensores, W0 a W2 y el Promedio
Los variables que tengo para almacenar en la EEPROM son:
Nombre | Descripción | Nombre variable |
Tr0 | Temperatura referencia sensor interno 0 | param_temp_ref_0 |
Tr1 | Temperatura referencia sensor externo 1 | param_temp_ref_1 |
Tr2 | Temperatura referencia sensor externo 2 | param_temp_ref_2 |
W0 | Peso sensor interno 0 | param_weight_0 |
W1 | Peso sensor externo 1 | param_weight_1 |
W2 | Peso sensor externo 2 | param_weight_2 |
-- | Cuánto decrementar mucho | param_dec_1 |
- | Cuánto decrementar | param_dec_2 |
+ | Cuánto incrementar | param_inc_1 |
++ | Cuánto incrementar mucho | param_inc_2 |
+++ | Cuánto incrementar muchísimo | param_inc_3 |
TA | Amplificador de tendencia | param_ta |
== | Margen de igualdad | param_delta_eq |
ST | Tiempo de sampleo | param_sample_interval |
Son todos valores enteros para facilitarme la carga con el REPL.
Si en algún momento la velocidad fuera cero y la temperatura subiera, habría que arrancar con la velocidad inicial y luego ir a la mínima.
Más adelante puedo reemplazar por AI, me han dicho en un webinar que hay algo llamado PID que podría andar en microcontroladores de 8 bits y hay algo para arduino, pero eso será en otra ocasión.
Aca ya vemos que la fórmula de la tendencia va a tener que ser tambien parametrizable si quiero seguir en el modo "sonda espacial". Luego volveré sobre la implementación, ahora, que funcione en modo prototipo.
Programación del microcontrolador
Ya tengo un circuito armado para ATMega328p, pero no para ATtiny85, aparte cuento como me las arreglé.
SoftUART
Cuando me disponía a hacer el blinky para ver que pueda programarlo, me dí cuenta que ATtiny85 no cuenta con puerto serial, eso lo resolví usando una clase de Arduino llamada SerialSoftware acá.
PWM
Piece of Cake, al programa previo le agregué:
const byte pwm = 4;
char pwmSpeed = 128;
y algunos
analogWrite(pwm, pwmSpeed);
Sensor interno de temperatura
En las páginas 123 y 253 de la datasheet explica como usarlo:
"writing the MUX3...0 bits in ADMUX register to "1000"
enablesthe temperature sensor"
Luego hay que convertir el voltaje leido según esta tabla:
Temperature | -40°C | +25°C | +85°C |
ADC | 230 LSB | 300 LSB | 370LSB |
Luego hay que ajustarse a la variación del proceso según esta fórmula:
T = k * [(ADCH << 8) | ADCL] + Tos
Donde Tos hay que guardarlo en EEPROM o en mi caso como tengo un solo ejemplar lo podría hardcodear, k es un coeficiente que no dice de donde sale y el resto no lo entiendo, lo que si entiendo es que
"the accuracy of the temperature measurement is +/- 10°C"
así que no me voy a molestar mucho con esto, o quizás si, en otro lado dice que se puede llegar a +/- 2°C.
Para inicializar:
ADMUX = B10001111;
ADCSRA = (1<<ADPS2) | (1<<ADPS1) | (1<<ADEN);
// Perform Dummy Conversion to complete ADC init
ADCSRA |= (1<<ADSC);
while ((ADCSRA & (1<<ADSC)) != 0);
y luego en cada lectura:
ADCSRA |= (1<<ADSC);
while ((ADCSRA & (1<<ADSC)) != 0)
Ctemp = (ADC - 247)/1.22;
swSerial.println(Ctemp);
Luego veré si lo calibro bien, todavía no sé si me va a alcanzar la memoria.
EEPROM
#include <EEPROM.h>
y usar:
char tmp;
swSerial.print("stored pwn speed is: ");
EEPROM.get(0,tmp);
swSerial.println(int(tmp));
swSerial.print("stored: ");
EEPROM.put(0, pwmSpeed);
swSerial.println(int(pwmSpeed));
DHT11
Para estos sensores me quedan dos pines
No me salió a la primera, el dht adafruit tenía unas dependencias que no me gustaron, dht algo le falló al intentar instalar las librerías y me quedé con dhtnew que copié en lib y debo haber sacado de...
Otra vez, muy sencillo:
#include <dhtnew.h>
#define DHTPIN1 2
#define DHTPIN2 3
DHTNEW dht1(DHTPIN1);
DHTNEW dht2(DHTPIN2);
float humidity1;
float temperature1;
humidity1 = dht1.getHumidity();
temperature1 = dht1.getTemperature();
swSerial.print("Temperature 1: ");
swSerial.println(temperature1);
...en teoría. Creéme, no funciona, hay algo mal con delayMicrosecond(), cuando me haga un rato lo diagnosticaré, ahora no aguanto más el ruido del switch.
Conexiones finales que no fueron
Así hubiese quedado:
+---------------+
5v -> RESET Vcc - 5v
1-wire 2 <-> PB3 PB2 <-> 1-wire 1
PWM <- PB4 PB1 -> TX
GND - GND PB0 <- RX
+---------------+
Fall back and regroup
No estoy sobrellevando bien los fracasos desde lo de sacar el firmware del router al que le cayó el rayo y lo del 8051, voy a tener que descartar ATtiny85 y pasarme a ATMega328p.
Como ahora tengo una cantidad infernal de pines de sobra podría regular la velocidad de cada cooler independientemente pero no descarto volver a usar un ATtiny85 y para ello debería hacer un circuito que sea pin compatible entre ambos chips, algo en el estilo de lo que hice para el programador, pero me supera y así no voy a terminar nunca. Olvidemos el ATtiny85.
Además no quiero llenar todo de cables.
Puedo (debo) prescindir de la soft UART.
Recalculando...
Grilla de elección de comunicaciones revisada
Como me gustó la tabla, la voy a rehacer para divertirme, me gusta hacer tablas:
Aprovechar Max241c | Interceptar Max241c | Serial RS232 | |
Interesante | Lo máximo | Lo máximo | Más o menos |
Riesgoso | Completo | Completo | Para nada |
Hardware | Sólo conector db9 que ya tengo | Nada | Usaría un módulo que ya tengo |
Costo Software ATtiny85 | SoftUart | Imposible | SoftUart |
Costo Software ATMega328p | Ínfimo | SoftUart | Ínfimo |
Adaptador PC | Quizás | No | Quizás |
Integración Hardware | Perfecta | Perfecta | Perfecta |
Dificultad | Difícil | Difícil | Fácil |
Puntos ATMega328/ATtiny85 | 13/12 | 14/12 | 16/15 |
Si mirás el código, para ATtiny85 he ido probando cada funcionalidad por separado y luego juntado. Con ATMega328p tomé una camino más audaz, voy agregando funcionalidad en cada paso, apostando a que no hay interferencias.
PWM
Me quise saltar el paso del Serial pero el configurar ArduinoIDe para ATMega328p pelado era una deuda que tuve que pagar:
File -> Preferences -> Settings -> Additional Boards Manager URLs:
https://www.leonardomiliani.com/repository/package_leonardomiliani.com_index.json
La URL la saqué de:
Luego:
Tools -> Board -> Boards Manager -> "atmega328p" ofrece boards de Leonardo Miliani
Y por último elegí "Arduino ATMega328p @8Mhz with Arduino as ISP".
Habiendo recuperado el Serial, al PWM sólo hubo que pescarlo, pues no sé cual es el mapeo. Lo que sí sé es que los pines de PWM son problablemente 11, 12, 15, 16, 17 y accidentalmente al primer intento con 11 en PB3 tengo PWM.
Sensor interno de temperatura
En las páginas 252 y 253 de la datasheet explica como usarlo:
"Selecting the ADC8 channel by writing the MUX3...0 bits in
ADMUX register to "1000" enables the temperature sensor"
Luego hay que convertir el voltaje leido según esta tabla:
Temperature | -40°C | +25°C | +85°C |
Voltage/mV | 242mV | 314mV | 380mV |
Luego hay que ajustarse a la variación del proceso según esta fórmula:
T = { [(ADCH << 8) | ADCL] - T OS } / k
EEPROM
Sin problemas, así que aproveché para averiguar por qué cada vez que grabo el programa, la EEPROM me queda borrada. El motivo es el bit EESAVE de HFUSE:
Ahora que entiendo lo que pasa, la verdad es que no me molesta, cambiaré los fuses cuando lo necesite.
DHT11
El primer problema es mapear los pines igual que con PWM, pero ya amerita intentar hallar las definiciones, tras un poco de escarbar, en
$BASEPATH/arduino-1.8.10/hardware/arduino/avr/variants/standard/pins_arduino.h
hay un mapeo que aunque no dice explícitamente ATMega328p parece corresponder:
// ATMEL ATMEGA8 & 168 / ARDUINO
//
// +-\/-+
// PC6 1| |28 PC5 (AI 5)
// (D 0) PD0 2| |27 PC4 (AI 4)
// (D 1) PD1 3| |26 PC3 (AI 3)
// (D 2) PD2 4| |25 PC2 (AI 2)
// PWM+ (D 3) PD3 5| |24 PC1 (AI 1)
// (D 4) PD4 6| |23 PC0 (AI 0)
// VCC 7| |22 GND
// GND 8| |21 AREF
// PB6 9| |20 AVCC
// PB7 10| |19 PB5 (D 13)
// PWM+ (D 5) PD5 11| |18 PB4 (D 12)
// PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
// (D 7) PD7 13| |16 PB2 (D 10) PWM
// (D 8) PB0 14| |15 PB1 (D 9) PWM
// +----+
//
// (PWM+ indicates the additional PWM pins on the ATmega168.)
Me iba a quedar con:
+------------------+
RESET -> PC6 -
RX -> PD0 A -
TX <- PD1 T -
- PD2 m -
- PD3 e -
- PD4 g -
5v - Vcc a GND - GND
GND - GND 3 -
- PB6 2 -
- PB7 8 -
- PD5 p -
- PD6 PB3 -> PWM
DHT2 - PD7 -
DHT1 - PB0 -
+------------------+
Pero luego cuando armé la placa puse los sensores junto a los pines de power para poder usar un conector sacado de un mother o placa de sonido.
+------------------+
RESET -> PC6 -
RX -> PD0 A -
TX <- PD1 T -
- PD2 m -
DHT2 - PD3 e -
DHT1 - PD4 g -
5v - Vcc a GND - GND
GND - GND 3 -
- PB6 2 -
- PB7 8 -
- PD5 p -
- PD6 PB3 -> PWM
- PD7 -
- PB0 -
+------------------+
Anda todo ok, salvo el termómetro interno.
Regulando velocidad del cooler
Llegó la hora de tocar el mundo real, puse un transistor a la salida PWM según lo planeado, quemé dos, no quiero entrar en detalles pues no sé de electrónica digital, sería irresponsable de mi parte, pero si te sirve te cuento que no les daba la potencia, por eso es que arranco a media velocidad y uso tres transistores. Luego tuve que poner un par de capacitores por que se reseteaba el chip, no pongo detalles por que no puedo justificarlos con mi conocimiento.
Implementación de las funciones
Para facilitarme la vida he decidido ignorar al sensor interno.
Hasta ahora, todo el código ha sido DLP (Debug Later Programming) en lugar de TDD (Test Driven Programming) y tiene que ver con que lo que he hecho es bastante sencillo. Pero las funciones de cálculo de velocidad, teniendo en cuenta un historial de longitud variable en tiempo de ejecución se me complica, así que a rescatar Test Driven Development for Embedded C (Pragmatic Programmers) 1st Edition de James W. Grenning y aplicarlo.
La tentación de los que venimos de TDD en software "puro" es
- hacer un test
- que falle
- hacerlo pasar
- refactorizar.
En este libro hay algo extra extremadamente importante debido a la dualidad de targets, el código que estoy haciendo no necesariamente va a correr donde lo estoy testeando, quizás ni use el mismo compilador y entorno.
En TDD "normal", uno mockea lo que no tiene bajo control, o sea la DB, la API a la que va a consultar, el otro componente. En el caso de embebidos, suele ser el hardware mismo, lo que nos conduce a mockear el objeto mismo bajo test hasta tener todos o la mayoría de los tests antes de implementar ningún código. No estoy completamente seguro y no tengo ganas de volver a leer el libro, pero como que hay dos rondas:
- tests puros
- hacer un test sobre un mock
- que falle
- hacerlo pasar
- implementación completando tests faltantes
- reemplazar mock por código real
- hacerlo pasar
- refactorización
Esto es conceptual, no hace falta usar un mock, se puede usar el CUT (Code Under Test) mismo.
La integración de cpputest con ArduinoIDE es muy simple, armás la clase que querés testear en su ubicación, le agregás unos
#ifdef UNIT_TEST
para incluir lo que no necesitás desde ArduinoIDE y desde el proyecto hacés unos links simbólicos a la clase, pero con nombres .ino en lugar de .cpp así ArduinoIDE hace su magia.
Luego te dás cuena que parte de la magia de ArduinoIDE es que en lugar de abrir los archivos los vuelve a crear y te los reemplaza por lo que salve, así que tenés que invertir el sentido del link:
/src/atmega328p/05_prototype/
Brain.hpp
Brain.ino
Brain.ino
/src/brain/
Brain.hpp -> ../atmega328p/07_alpha/Brain.hpp
Brain.cpp -> ../atmega328p/07_alpha/Brain.ino
La función respeta esta forma:
velocidad actual | ||||
0 | <=min | > min | ||
delta | -20 | 0 | min (-> powerOff) | actual -20 |
-10 | 0 | min (-> powerOff) | actual -10 | |
cero | 0 | min (-> powerOff) | actual - cero | |
+ * | arrancar | min + * | actual + * (max 255) |
cero es 0 o un número negativo bajo
Este tipo de funciones seguro tienen un nombre y se estudian quizás en alguna materia de secundaria y sin duda universidad, son las funciones que hacen que por ejemplo un autito siga una linea blanca en el piso. Pude haber buscado en internet, no digo en stackoverflow sino en foros especializados y libros pero la verdad es que he preferido sufrirlo para que el día que investigue lo existente estar en mejores condiciones de comprenderlo.
Hardware
Esto es lo que quería:
Modelo 3D kicad |
En mi imaginación, arriba a la izquierda va un conector de floppy y en el centro el conector está en la otra cara.
Esta es mi triste realidad, soy incapaz de hacer algo tan prolijo, gracias que con el tutorial de kicad y mi experiencia previa del curso CAPSE que en la primera cohorte se llamó Paquete tecnológico del proyecto CIAA, pero ahora parece haberse movido a otra materia, decía, pude hacer un bonito modelo pero no pude hacer el transfer con un papel viejo que tenía y no ando con ganas de $404 de envío por un sobre de $200. Entonces lo hice a mano y es como una herida en mi autoestima que me avergüenza mostrar:
Herida en la autoestima |
Ni lo pasé por el ácido pues algunos agujeros me salieron tan desalineados que la verdad es que no entiendo por qué me molesté en dibujar el circuito.
Todo este manoséo me retrasó tres fines de semana más.
Ni a mi me gusta, pero no dejo de sentir un ínfimo orgullo:
La fijación
Entonces,
pensé en los descartados disipadores, si hiciera una pieza que los
sujete y a la vez sostuviera los cables y sensores, tendría bastante
sentido y este es el momento en que muero por tener una impresora 3D.
Tambien me pregunto por qué tiré toda la basura que tiré, ahí tenía
superficies plásticas para rescatar.
- No puedo usar madera por el riesgo de combustión. Lo mismo podría decir del plástico pues no sé como diferenciar un plástico apto de uno que no, pero de plástico será.
- No debe interrumpir el flujo del aire.
- No puedo usar mucho metal por que no sé como interacturá en términos electromagnéticos.
Algunos percances
Cuando ya estaba todo aparentemente funcionano, ocurrieron varios inconvenientes juntos:
Por conectar RS-232 prendido, aparentemente rompí el chip del ponncho educativo y quizás el adaptador USB-RS-232. Terminé usando aglo como esto:
Adaptadores varios |
Aparentemente rompi otro ATMega328p en la misma operación.
No sé si me sobró un tornillo, pues había uno en la misma cajita donde venía juntando, la verdad es que no lo recuerdo.
Resumen, conclusiones y aprendizajes
- He instalado un microcontolador con algunos sensores de temperatura para regular la velocidad de los coolers según la temperatura interior del switch.
- Decidí usar las soluciones menos riesgosas en términos de intervención del switch, lo cual es muy frustante, si encuentro otro switch, meteré las manos.
- No agregué disipadores por la dificultad de mantenerlos en posición.
- Hay que tener más chips cuando estás haciendo tantas pruebas.
- Si me restrinjo al aspecto económico, por las horas que invertí me hubiera costado menos comprar un switch que no hiciera ruido.
Como a la vez estaba en el trabajo a full con javascript, e ocurrió un error muy lindo, escribí esto, a ver si te das cuenta del error
Serial.println("EEPROM valid");
Serial.print("Stored speed: " + pwmSpeed);
La salida fue:
speed formula <REMOVE>
Debí haber escrito:
Serial.println("EEPROM valid");
Serial.print("Stored speed: ");
Serial.println(pwmSpeed);
Próximos pasos...
...que quizás nunca haga:
- Investigar si la frecuencias de PWM hace diferencia en el ruido.
- Esto implica medir la velocidad de giro mientras aplico distintos voltajes y distintos duty-cycles de PWM midiendo el sonido.
- Reportar como me fué con la parametrización de Brain
- Tengo que esperar al verano pues no tengo estufa en el cuarto donde está el switch.
- Tengo que medir la temperatura exterior
- Tomar registro de ambas mediciones
- Excelentes candidatos para integrar a mi TP de CEIoT
- Reemplazar la implementación actual de Brain por algo más inteligente:
- Fuzzy Logic?
- AI?
- Reemplazar por otro mejor pensado que me permita reprogramarlo sin abrir el switch
Ejemplo de ejecución
En estos 12 minutos acelerados a 5x (2:30) vemos el inicio y las mediciones periódicas junto a los ajustes:
T1 y T2 son las temperaturas, CS la velocidad, siendo 127 el 50% y 255 el 100%.
# T1:29.70, H1:38.00, T2:30.00, H2:39.00, CS:127
Tras un ratito los coolers se apagan, muy pronto vuelven a prenderse, entonces le cambio la marca de temperatura y así...
El código en github
No hay comentarios:
Publicar un comentario