2020/10/30

Algunas mediciones del regulador de velocidad de ventilación del switch

Estas son las mediciones sobre el comportamiento del regulador de ventilación que he incorporado a un switch.

Saga completa

Para comenzar, lo dejé prendido varios días y seguí a ojo el comportamiento apagándolo de noche, luego prendido permanente y finalmente le pasé las conexiones que tenía en el hub.

Mientras, hice adaptaciones al Display Serial para fundamentalmente incorporar la medición de temperatura ambiental y poder realizar las mediciones finales.

 

Ruido

 

2AM, todo cerrado, con un programa medidor en el celular, es lo que hay...

Puse al máximo y lo dejé bajar:

 



Con paciencia tomé nota de los valores en la siguiente tabla:


+-----+------+
| 245 | 71.6 |
+-----+------+
| 234 | 71.0 |
+-----+------+
| 224 | 70.4 |
+-----+------+
| 214 | 70.0 |
+-----+------+
| 204 | 69.7 |
+-----+------+
| 194 | 69.3 |
+-----+------+
| 184 | 68.8 |
+-----+------+
| 174 | 67.8 |
+-----+------+
| 164 | 68.1 |
+-----+------+
| 154 | 67.3 |
+-----+------+
| 144 | 67.8 |
+-----+------+
| 134 | 68.2 |
+-----+------+
| 124 | 67.9 |
+-----+------+
| 114 | 66.0 |
+-----+------+
| 104 | 63.3 |
+-----+------+
|  94 | 63.8 |
+-----+------+
|  84 | 63.0 |
+-----+------+
|   0 | 44.0 |
+-----+------+

 

Subjetivamente no hay dudas de que va bajando el ruido con la velocidad, pero si mirás la tabla hay inconsistencias. Puede ser por la falta de coordinación mía, puede ser que esté muy cerca el celular de la fuente de ruido, se puede estar colando ruido del exterior al que no estoy prestando atención, puede haber algún componente del ruido muy agudo para mí pero que esté siendo medido.


Vibración

 

Entiendo que el ruido debe tener al menos tres componentes:

La hélice contra el aire. Esto depende sin duda de la velocidad y la calidad, la última fuera de mi control.

He leido por ahí una mala elección de frecuencia del PWM podría generar más ruido, algún día lo investigaré. De todos modos la librería de arduino no ofrece cambiarla, no sé por que perverso motivo.

La vibración, resultado de la calidad. Intuyo que distintas velocidades deben producir distintas vibraciones, no necesariamente relacionadas, deben haber algunas velocidades óptimas, para eso hay que ser ingeniero y saber física.

El programa medidor del celular o el sensor mismo no es lo suficientemente sensible, pero mis manos dicen que vibra y bastante, sin números.


 

Temperatura y velocidad en el tiempo

 

Para esto he usado una EDU-CIAA-NXP que recibe los mensajes y le agrega la temperatura exterior y la configuracion, según detallo en https://seguridad-agile.blogspot.com/2020/10/adaptador-usb-rs-232-con-display-usando.html y https://seguridad-agile.blogspot.com/2020/10/modificaciones-al-display-serial.html


Pensé en usar cacti, pues hace dos trabajos, Javier A. lo usaba, pero cuando ví que además de aprender a usarlo y configurarlo había que instalar un mysql, miré fijo y noté que decía "The Complete RRDTool-based Graphing Solution" me pareció mejor ir directo a rrdtool.

Esa noche no podía dormir, así que me machaqué el cerebro contra el teclado y pasé de no entender absolutamente nada a estar en condiciones de darte un introducción muy sencilla, espero que sea correcta, es como un hello world.

 

Instalación


sudo apt install rddtool

 

Configuración


La idea es que rddtool guarda los mensajes en su propia base, que es un buffer circular y pretende que le des datos con regularidad en el tiempo.


  rrdtool create "$DB" --step 60s \
  DS:temp1:GAUGE:120:0:60 \
  DS:temp2:GAUGE:120:0:60 \
  DS:temp3:GAUGE:120:0:60 \
  DS:speed:GAUGE:120:0:255 \
  DS:ref:GAUGE:120:0:60 \
  RRA:LAST:0.5:1:864000


El step es la expectativa de llegada en el tiempo de los mensajes. Cada DS debe ser un DataSet, ponele, tiene un nombre, un tipo, para este caso DERIVE o GAUGE.

Luego heartbeat, tiempo para meter un UNKNOWN. Luego valor mínimo y máximo. Ojo con esos dos valores, si te equivocás, no ves nada pues le pone UNKNOWN.

Luego viene el RRA, que descripción del comportamiento con respecto a como almacenar los valores, por ejemplo LAST es el valor tal como viene pero podrían guardarse el promedio de los últimos N valores recibidos, como para eliminar ruido.

El resto no lo he explorado aún. Entiendo que se pueden poner varios RRA.

 

Insertar


Luego le vas dando mensajes.

Los lees de algún modo y los insertás así, las variables se llaman igual que los DS por disciplina, no hace falta que coincidan, son variables de bash:

rrdtool update "$DB" "N:$temp1:$temp2:$temp3:$speed:$ref"

 

Graficando


y periódicamente podés graficar la información que ya tengas, encontré un RRDTool Wizard muy bonito, ojo que no le pone bien el nombre de la rrd.

  rrdtool graph 'graph.png' \
  --width '800' \
  --height '300' \
  --start end-1h \
  'DEF:t1=temp.rrd:temp1:LAST' \
  'DEF:t2=temp.rrd:temp2:LAST' \
  'DEF:t3=temp.rrd:temp3:LAST' \
  'DEF:sp=temp.rrd:speed:LAST' \
  'DEF:ref=temp.rrd:ref:LAST' \
  'LINE3:ref#FF0000' \
  'LINE2:t2#00f7ff' \
  'LINE2:t3#00FF00' \
  'LINE3:sp#FF00FF' \
  'LINE2:t1#0000FF'


El orden de los LINEx importa pues va pisando.


Graficando temperaturas
Graficando temperaturas

Verde es temperatura ambiente

Rojo temperatura límite

Magenta es la velocidad del cooler

Azul y cyan las temperaturas internas


El programa completo de update


stty -F "$DEV" ispeed "$BAUDRATE" ospeed "$BAUDRATE" \
      cread icanon time 10
exec 99<>$DEV
while true;  do
 read MSG <&99
 #echo $MSG
 MSG=$( echo $MSG | tr "{:,}\"" "     " )
 read _label_cs speed \
      _label_t1 temp1 \
      _label_h1  _h1 \
      _label_t2 temp2 \
      _label_h2 _h2 \
      _label_t3 temp3 \
      _label_h3 _h3 \
      _label_r1 ref \
      _tail  < <(echo $MSG)
 #echo "t1: $temp1 t2: $temp2 t3: $temp3 speed: $speed ref: $ref"
 rrdtool update "$DB" "N:$temp1:$temp2:$temp3:$speed:$ref"
done


Te recuerdo que mis mensajes son así:


{ "CS" : "0", "T1" : "40.10", "H1" : "13.00", "T2" : "40.50", "H2" : "13.00", "T3" : "20.70", "H3" : "51.00", "R1" : "48", "R2" : "48", "R3" : "0", "W1" : "5", "W2" : "5", "W3" : "0", "D2" : "20", "D1" : "10", "D0" : "0", "I1" : "10", "I2" : "20", "I3" : "50", "MS" : "84", "SC" : "1", "DE" : "2", "SI" : "15000"}

y tr "{:,}\"" "     " los convierten en 


CS     0    T1     42.70    H1     14.00    T2     47.90    H2     17.00    T3     23.00    H3     48.00    R1     48    R2     48    R3     0    W1     5    W2     5    W3     0    D2     20    D1     10    D0     0    I1     10    I2     20    I3     50    MS     84    SC     1    DE     2    SI     15000


y el read ... < <(echo $MSG) toma las variables.

 

MQTT


Tambien hice un scriptcito para que mande los mensajes con MQTT

BAUDRATE="19200"
DEV="/dev/ttyUSB2"
TOPIC="/switch/data"
BROKER_IP="127.0.0.1"
BROKER_IP="192.168.1.134"

stty -F "$DEV" ispeed "$BAUDRATE" ospeed "$BAUDRATE" cread icanon time 10
exec 99<>$DEV
while true;  do
  read MSG <&99
  echo "$MSG";
  mosquitto_pub -m "$MSG" -t "$TOPIC" -h "$BROKER_IP"
done

Todo el código en https://github.com/cpantel/CoolerControl




2020/10/15

Modificaciones al display serial

Había hecho un display serial  para poder ver las temperaturas y la velocidad del controlador de ventilación de un switch y cuando me preparé para comenzar a registrar los valores para estudiarlos y poder parametrizar correctamente al algoritmo me encontré con algunos problemas.

Saga completa

 

 

Hardware


El primero, tal como había contado, había sido perder el max232n del poncho educativo debido a falta de pericia. Me pasé entonces al poncho PLC pero no me sirve pues me complica agregar el sensor de temperatura ambiental que necesito como referencia.


Volví al poncho educativo y le saqué el chip, suponiendo que no había roto todo el chip si no la mitad, pero no resultó. Si supiera un poco más o tuviera más dedicación podría haber medido como corresponde, pero fuí directo a "recablear" para usar la mitad supuestamente sana, no funcionó, mala suerte, algún día conseguiré el repuesto, le conecté al poncho educativo el adaptador.


Edu-ciaa-nxp en todo su esplendor
Edu-ciaa-nxp en todo su esplendor

 

En el display las dos temperaturas internas y la externa en la primera linea, en la segunda las temperaturas de referencia y la velocidad, tapada, dice 0. Y luego un "#" que alterna con "@" como heartbeat.


A la izquierda el sensor externo, atras el switch.



La fuente...

 
...calienta más que el resto, cambié uno de los sensores de lugar, lamentablemente no tomé nota de cuál, luego usaré el "peso" para darle mayor o menor participación en las decisiones.



Temperatura ambiental


El display serial tenía que mostrar en la pantallita los valores y dejar pasar los mensajes ida y vuelta y ahora se le agrega incorporar su propia medición. Esto lo resolví agregando un sensor de temperatura a la EDU-CIAA-NXP y actualizando el mensaje JSON recibido desde el controlador.

 

 

La información y el formato de los mensajes


Aquí cometí varios errores. Para comenzar debí haber generado JSON, pues tiene una fácil lectura para el humano y es inmediatamente integrable a cualquier aplicación, más que espero que el 99.99% de los mensajes sean leidos por un proceso, no por humanos.

Otro, siguiendo en la linea de centrada en el usuario, no estoy publicando en cada mensaje la parametría y tengo que pedirla explícitamente. Esto me complica asociar los valores medidos con esta parametría.

En términos de ancho de banda, más que tengo un solo sensor y es por UART que es como una red interna, no me hace diferencia. Esto no significa que de cada mensaje almacene todos los datos, pero esa decisión la hago al momento de almacenar, no de emitir.

Dado que no quiero estar abriendo y cerrando el switch para reprogramar, debo ingeniármelas con lo que hay adentro. Recordemos: hice un sistema parametrizable justamente para evitar reprogramar, hasta que haya una nueva versión, debo lidiar externamente con todo.

Una posibilidad es sumarle la tarea al display serial: como ya tiene que tomar el mensaje que viene y agregarle su propia medición, puede tambien cuando ve pasar la parametría tanto al comienzo como ante cualquier cambio, tomar nota y agregarla.

Tambien puede hacer la conversión a JSON.

La otra es del lado de la compu, que tiene la ventaja de ser mucho más fácil... recalculando... cuál es la gracia de hacerlo fácil...?

Listo, va todo a la edu-ciaa y luego que la app decida qué y cómo almacenar.


+----------+             +--------+
| sensores |             | sensor |
+-----+----+             +---+----+
      |                      |
+-----v--+              +----v-----+          +-----+
|        |  medición +  |          | +        |     |
| Switch |  parametría  | edu-ciaa | medición | app |
|        +-------------->          +---------->     |
+--------+              +----+-----+          +-----+
                             |
                         +---v-----+
                         | display |
                         +---------+

 

Lo que había implementado es una FSM que va buscando los mensajes de reporte y al hallarlos extrae la información y la va pasando caracter a caracter al display.

Voy a tener que cambiar de enfoque, leer por lineas. El problema es que se me bloquea en la lectura, debe ser por ello que la sAPI no lo implementa.

Una manera de lidiar con esto sería pasar a FreeRTOS, una experiencia interesante pero quiero hacerlo así.

Lo que hice finalmente es una sencilla FSM que busca '{'. Si no la encuentra imprime en USB. Si la encuentra, comienza a copiar en un buffer hasta que encuentra '}'.


En ese momento, corre este lindo:


sscanf(buffer,"{ \"T1\" : \"%f\", \"H1\" : \"%f\", \"T2\" : \"%f\", \"H2\" : \"%f\", \"CS\" : \"%d\", \"R1\" : \"%d\", \"R2\" : \"%d\", \"W1\" : \"%d\", \"W2\" : \"%d\", \"D2\" : \"%d\", \"D1\" : \"%d\", \"D0\" : \"%d\", \"I1\" : \"%d\", \"I2\" : \"%d\", \"I3\" : \"%d\", \"MS\" : \"%d\", \"SC\" : \"%d\", \"DE\" : \"%d\", \"SI\" : \"%d\"}", &t1, &h1, &t2, &h2, &cs, &temp_ref_1, &temp_ref_2, &weight_1, &weight_2, &decrement_2, &decrement_1, &decrement_0, &increment_1, &increment_2, &increment_3, &min_speed, &scale, &delta_eq, &sample_interval);

 

lee la temperatura ambiental:

 
float tmp_t3;
float tmp_h3;
if( dht11Read(&tmp_h3, &tmp_t3) ) {
   t3 = tmp_t3;
   h3 = tmp_h3;
} else {
   t3 = -1;
   h3 = -1;
}

 

y luego imprime en USB:


sprintf(buffer,"{ \"CS\" : \"%d\", \"T1\" : \"%.2f\", \"H1\" : \"%.2f\", \"T2\" : \"%.2f\", \"H2\" : \"%.2f\", \"T3\" : \"%.2f\", \"H3\" : \"%.2f\", \"R1\" : \"%d\", \"R2\" : \"%d\", \"R3\" : \"%d\", \"W1\" : \"%d\", \"W2\" : \"%d\", \"W3\" : \"%d\", \"D2\" : \"%d\", \"D1\" : \"%d\", \"D0\" : \"%d\", \"I1\" : \"%d\", \"I2\" : \"%d\", \"I3\" : \"%d\", \"MS\" : \"%d\", \"SC\" : \"%d\", \"DE\" : \"%d\", \"SI\" : \"%d\"}", cs, t1, h1, t2, h2, t3, h3, temp_ref_1, temp_ref_2, temp_ref_3, weight_1, weight_2,weight_3, decrement_2, decrement_1, decrement_0, increment_1, increment_2, increment_3, min_speed, scale, delta_eq, sample_interval);

uartWriteString( UART_USB, buffer);

 

 y display:

 

sprintf(lcdOut0, "%.1f %.1f %.1f\0", t1,t2,t3);
sprintf(lcdOut1, "%d   %d   %d   %c\0",  temp_ref_1, temp_ref_2, cs);
lcdClearAndHome();
lcdSendStringRaw(lcdOut0);
lcdGoToXY( 0, 1 );
lcdSendStringRaw(lcdOut1);

 

El código actual esta en github: controlador y display



Salida JSON
Salida JSON












 

 




2020/10/07

Adaptador USB RS-232 con display usando EDU-CIAA-NXP con un poncho

Cuando hice el regulador de velocidad de los coolers de mi ruidoso switch, elegí usar RS-232 para la comunicación una vez instalado en módulo en el switch y usé un adaptador USB-UART tambien llamado USB-TTL mientras desarrollaba.



sin rs232

En la fotico podemos ver de izquiera a derecha el cable USB proveniente de la computadora, el adaptador USB-UART y a la derecha medio escondido el controlador de velocidad de los coolers.


+---------+   +-----------+   +----------+
| compu | | +-------+ | | +------+ |
| | | | UART ---------- UART | |
| | | +---|---+ | | +------+ |
| +-----+ | | +---|---+ | | |
| | USB --------- USB | | | control |
| +-----+ | | +-------+ | | cooler |
+---------+ +-----------+ +----------+

Por decisiones tomadas y justificadas en el otro proyecto, al conectar el adaptador RS-232 al módulo de control, ese cosito con el conector DB9 que apareció a la izquierda del controlador de velocidades, necesito un adaptador RS-232 - USB, que no tengo.


con rs232


+---------+   +-----------+        +----------+  +----------+
| compu | | +-------+ | | +------+ | | control |
| | | | RS-232 ------------ RS-232| | | cooler |
| | | +---|---+ | | +---|--+ | | |
| +-----+ | | +---|---+ | | +---|--+ | | +------+ |
| | USB --------- USB | | | | UART -------- UART | |
| +-----+ | | +-------+ | | +------+ | | +------+ |
+---------+ +-----------+ +----------+ +----------+


Mientras lo consigo, puedo usar una EDU-CIAA-NXP con el poncho educativo de UNSJ que tiene RS-232 y aprovechar que tiene un display para mostrar la información de temperatura, humedad y PWM aplicado a los coolers que envía el controlador de velocidades con el siguiente formato:

# T1:18.10, H1:60.00, T2:18.90, H2:60.00, CS:84

T1: temperatura sensor 1
H1: humedad sensor 1
T2: temperatura sensor 2
H2: humedad sensor 2
CS: duty cycle del PWM, cuanto mayor, mayor la velocidad de los coolers.


Use sAPI del firmware_v3 en el tag r1.2.0 pues en r1.3.0 algo falla:

git clone https://github.com/ciaa/firmware_v3.git
git checkout r1.2.0

creé una carpeta "projects"en la cual hice un symlink a mi proyecto:

cd firmware_v3
mkdir projects
cd projects

ln -s ../../../cpantel/SerialDisplayAdapter
cd ..

luego en program.mk

PROGRAM_PATH = projects/SerialDisplayAdapter


Canibalicé un poquito de dos proyectos, este y este y le sumé una FSM:

 estado actual  
 data[0] acción
 pasa a estado
 seek     '#' lcdClearAndHome(); seekT1
 seekT1 ':'  readT1
 readT1     ',' lcdSendStringRaw(space); seekH1
 readT1 *
 lcdSendStringRaw(data); 
 seekH1 ':'  readH1
 readH1 ',' lcdGoToXY( 0, 1 ); seekT2
 readH1 * lcdSendStringRaw(data); 
 seekT2 ':'  readT2
 readT2 ',' lcdSendStringRaw(space); seekH2
 readT2 * lcdSendStringRaw(data); 
 seekH2 ':'  readH2
 readH2 ',' lcdSendStringRaw(space); seekCS
 readH2 * lcdSendStringRaw(data); 
 seekCS ':'  readCS
 readCS eol  seek
 readCS * lcdSendStringRaw(data); 


Lo que hace es descartar todo caracter hasta hallar '#' como identificador de linea de datos, es que yo puedo estar operando y no hay necesidad de que aparezca nada en el display, sólo debo tener cuidado de no ingreser ningún '#' por que si no se me va a trabar la FSM, mmmh, le pongo que si encuentra un '#' y no está en estado SEEK que se resetee a SEEK y listo, dame dos minutos... listo.

Tuve la tentación de en lugar de usar switches e ifs anidados utilizar una estructura parametrizable, pero este proyecto es sólo un accesorio para otro más grande que ya quiero terminar y si me meto en tanto detalle no voy a terminar nunca.

Lamentablemente,  mientras hacía pruebas quemé el max232n del poncho educativo y ahora estoy usando el poncho PLC con un adaptador TTL-RS-232

 
 

Mostrando los mensajes del switch
Mostrando los mensajes del switch


Abajo a la izquierda el adaptador, en el display las temperaturas, humedades y velocidad del cooler.
 

Lecturas por serial
Lecturas por serial




El código en https://github.com/cpantel/SerialDisplayAdapter, pronto progresará cuando le agregue un termómetro y registre la información para ajustar los parámetros.


2020/10/06

Prototipo de un regulador de ventilación de un switch

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 comenzar, no sé cuál es la temperatura aceptable, el manual dice la temperatura de trabajo "exterior", no la que puede haber ahí dentro, dice ser 50 grados centígrados. Tampoco dice hasta que temperatura pueden llegar los chips, a ver la referencia, si, lo más parecido que encontré dice 70, así que procuraré mantener la temperatura dentro del switch por debajo de 60, 65, grados, veremos. La realidad es que este equipo estuvo mucho tiempo en un cuartito cerrado sin aire acondicionado con todas las bocas conectadas y los coolers trabados y sigue vivo.


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
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
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
USBInfrarrojo
RF Bluetooth
InteresanteLo máximo
Lo máximoMás o menosPara nadaPara nadaBastante
RiesgosoCompletoCompletoPara nada
Bajo pero podría conectar invertidoPara nadaPara nada
HardwareSólo conector db9 que ya tengoNadaUsaría un módulo que ya tengo
Para nadaUsaría un módulo que ya tengo El que corresponda
Costo SoftwareÍnfimoSoftUartÍnfimoÍnfimoÍnfimoComplicado
Adaptador PCQuizásNoQuizásSiNoTengo que hacerlo
Integración HardwarePerfectaPerfectaPerfectaHorribleMedio rara
Depende, infrarrojo muy complicado, RF y BT supongo que antena afuera
DificultadDifícilDifícilFácilFácilFácilNo 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.


Venía ganando USB pese a que durante un momento había pensado que era con ATtiny85 Digispark lo que no es posible por la doble alimentación ya conversada y además me gustaría que tenga el conector Type-B.

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


De paso aprovecho para practicar parte de lo aprendido en la materia de gestión de proyectos del CEIoT. Podría hacer hacer un Gantt pero no lo voy a respetar.


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
 n Cantidad de historial de la tendencias
 param_history_length
 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 LSB300 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.

Y luego me basé en https://microchipdeveloper.com/8avr:avradc


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


Tomé los ejemplos de ArduinoIDE, otra vez muy fácil:


  #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
InteresanteLo máximo
Lo máximoMás o menos
RiesgosoCompletoCompletoPara nada
HardwareSólo conector db9 que ya tengoNadaUsaría un módulo que ya tengo
Costo Software ATtiny85
SoftUart
Imposible
SoftUart
Costo Software ATMega328p
ÍnfimoSoftUart Ínfimo
Adaptador PCQuizásNoQuizás
Integración HardwarePerfectaPerfectaPerfecta
DificultadDifícilDifícilFácil
Puntos ATMega328/ATtiny85
 13/12 14/12 16/15



Los puntos son 3, 2, 1 y 0. Sigue ganando usar el Serial, en particular con ATMega328p.

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 242mV314mV
 380mV

Luego hay que ajustarse a la variación del proceso según esta fórmula:

T = { [(ADCH << 8) | ADCL] - T OS } / k


que nuevamente ignoraré por ahora.

El valor que me da es entre 84 y 87 grados, luego veré por qué.


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:


Hfuses


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
/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
  + * arrancarmin + *
 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
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
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:



El circuito instalado
El circuito instalado





La fijación


Hasta este momento no había caido en cuenta que no he pensado nada, medio que me imaginé que los sensores estarían pegados a... no sé. El microcontrolador está ok, pues va agarrado al conector serial, pero los sensores y los cables flotan perdidos.

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.




Malla plástica soporta sensores
Malla plástica soporta sensores

 

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
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>

¿Nada? Es parte del mensaje del menú, ¿nada?

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