Ingeniería de regalos



Fuera de la ventana está lloviendo, diciembre está en el calendario. Se acerca el tiempo de las vacaciones y, por lo tanto, el tiempo de los regalos. El colega Pavel quiere una nueva computadora portátil para él y su novia Masha quiere una casa junto al mar. Y a pesar del salario digno de la profesión de tyzhprogrammer, no vivimos en un mundo de posibilidades infinitas, lo que significa que no puedo darle a estas personas exactamente lo que más quieren (aunque Pasha sea mi mejor Pavel, a quien Lo sé, pero Masha está bien).

Aquí es donde aparece el problema de los "regalos baratos". No funciona dar un regalo costoso a todos, pero no quiero dar otra caja de chocolates, una vela o una figurita indistinta. Por lo tanto, debe combinar los negocios con el placer: me gusta hacer las cosas con mis propias manos y el resultado es excelente como regalo. Esta es una historia sobre cómo una vez más fingí ser ingeniero y hice varios regalos a mano.

Una pequeña digresión del tema principal.


No puedo ir inmediatamente al tema principal, así que comenzaré desde lejos. Hace unos años, se lanzó el juego "The Witcher 3". Mi amigo me aconsejó que jugara, y en general realmente admiré el juego. Luego decidí qué hacer y le di algo temático relacionado con el juego ... No profundizaré en la descripción del juego (Google ayudará a todos) ni diré que no se me ocurrieron muchas cosas. para las palabras clave "The Witcher, Engineer, Gift".

El personaje principal del juego tiene un caballo llamado "Roach" (en ruso), el héroe de vez en cuando la conduce con la frase "Move, Roach". Decidí hacer un juguete mecánico sobre el tema de "remover cucarachas".

Naturalmente, el regalo fue concebido como algo completamente inútil, estúpido pero divertido, por lo que el plan fue el siguiente:

  1. Hay una caja que oculta el mecanismo en sí mismo.
  2. El mecanismo es un eje que gira y que mueve el caballo.
  3. La máxima "tenacidad" del movimiento del caballo es bienvenida. Inicialmente, incluso se pensaba que el caballo debería moverse como un pez, y no como un caballo (después de todo, cucaracha), pero el resultado fue "algo intermedio".
  4. Todo esto se hará con madera contrachapada, que de acuerdo con los dibujos se puede cortar con precisión a pedido con un láser.

La principal desventaja de la elección del material y el hecho de que el corte se realizará a pedido fue el hecho de que perdí la oportunidad de crear un prototipo, lo que significa que todos los problemas de las manos torcidas y el incumplimiento de la regla de "siete medidas" se hicieron sentir con bastante rapidez:



Aunque al final, el hecho de que muchos detalles del mecanismo de reacción debido a espacios demasiado grandes ayudaron a compensar el hecho de que conecté las partes y el eje de manera bastante torcida. Aquí, como dicen, "menos menos da más" y el mecanismo en su conjunto funcionó, como se pretendía:



Después de que solo hubo una pequeña pintura y el resultado fue una caja así:



Entonces alguien dirá que era necesario hacer que la caja fuera transparente para que fuera posible observar el trabajo del interior, pero de hecho al principio supuse que no podía ensamblar todo el mecanismo y la caja desde el interior de manera tan limpia y ordenada que no dolería. mira a través de las paredes transparentes de la caja. Por lo tanto, una caja opaca es una medida necesaria.

Solo queda empacarlo, atar un lazo en una caja y el regalo está listo:



Pero para no molestar al niño interior, que quería sentirse como un ingeniero en una situación en la que, de hecho, pegué un par de piezas de madera contrachapada, decidí hacer un "dibujo". Perdóname a todos aquellos que entienden algo en los dibujos técnicos, porque Entiendo que esto es más una parodia del dibujo que un dibujo real, pero como me pareció, agregó valor a un juguete simple:



Hoy yo ...


A veces el destino juega con nosotros y de alguna manera insinúa que algo debería suceder pronto. La historia de uno de mis dispositivos comienza exactamente igual. Pedí algunos pequeños dispositivos electrónicos por un valor de alrededor de $ 5, que, como de costumbre, pasaron un mes en la carretera, después de lo cual recibí un SMS que el paquete me estaba esperando en la oficina de correos local. La caja resultó ser mucho más grande de lo que esperaba e inmediatamente generó dudas sobre su contenido. Se confirmaron las dudas: en el interior, además de las pequeñas cosas que pedí, también había una pantalla de tinta electrónica de tres colores con una diagonal de 4,2 pulgadas. Me puse en contacto con el vendedor, él confirmó que había estropeado algo al empacar, pero dijo que puedo considerar esto como un regalo y usarlo como mejor me parezca.

Fate me insinuó que ha llegado el momento de comenzar un nuevo proyecto y este proyecto será algo con una pantalla de tinta electrónica. Después de familiarizarme brevemente con las especificaciones del dispositivo y conectar la pantalla al controlador, me aseguré de que la especificación no me mintiera sobre el tiempo de actualización. La pantalla se actualizó durante más de 10 segundos, parpadeando y tratando de causarme un ataque epiléptico:


(No tengo fotos anteriores de la conexión de la pantalla, así que aquí el dispositivo ya tiene un aspecto más significativo)

Quedó claro que necesita un dispositivo simple que no requiera animaciones complejas (y animaciones en general). Y luego me encontré con un calendario de humor:


El calendario del estado de ánimo es un conjunto de imágenes simples y firmas irónicas para ellos. Decidí que haría un calendario (que en realidad no es un calendario en absoluto) con el nombre "Hoy I" ... Será un dispositivo simple que cada día muestra alguna imagen que caracteriza el "estado mental" de hoy y una descripción del mismo. Además, el calendario también podría tener otras funciones, pero el calendario principal sería precisamente el "calendario", su propia imagen para cada día.

El módulo de papel electrónico permitía mostrar tres colores (negro, rojo y blanco), que deberían transmitirse al módulo, como dos imágenes: blanco y negro y rojo y blanco. De hecho, sería más correcto decir que la pantalla simplemente espera un mapa de bits monocromo, donde cada bit determina el color de un píxel (no estoy seguro de que este término sea aplicable al papel electrónico, pero espero que la idea sea clara). Se puede establecer un mapa de bits separado para el canal negro o rojo. Por lo tanto, hay un conjunto de bytes donde cada bit que se establece en 1 corresponderá a un píxel de color, y todos los bits que permanecen 0 serán píxeles blancos en la pantalla. La resolución de la pantalla es de 400 x 300 píxeles, es decir para una imagen en blanco y negro, se requerirán 15,000 bytes (8 píxeles están codificados en un byte). Para los tres colores, tomará 30,000 bytes, si no intenta empaquetar la imagen de manera más compacta. Desde el punto de vista de la implementación, los creadores de la pantalla podrían simplemente seleccionar dos bits por píxel y almacenar el estado real de las cosas (dónde es rojo, dónde es negro y dónde es blanco), pero esto requeriría los mismos 30,000 bytes, pero incluso para imágenes monocromas requeriría la transferencia de 30,000 bytes.

Como en cualquiera de mis otras "manualidades", comencé a inventarme tareas para que todo no se convirtiera en "enchufar el cableado y descargar la biblioteca". Incluso si tenemos en cuenta la capacidad de implementar algún tipo de algoritmo de compresión de imagen en el lado del controlador, quedó claro que sin un almacenamiento externo para archivos de imagen, el controlador estaría muy deprimido. Se decidió tomar una tarjeta SD y escribir un contenedor de código simple para trabajar con FAT32. Por supuesto, sería posible prescindir de un sistema de archivos y escribir datos en una tarjeta de memoria directamente, pero me pareció que era menos conveniente agregar nuevos archivos, y fue interesante para mí implementar las operaciones básicas para trabajar con FAT32 con mis propias manos.

Es importante aclarar que tengo la costumbre de escribir cosas yo mismo (no deberías decirme que hay un mar de bibliotecas, lo sé y con Google) cuando hago esas cosas, pero desde Antes de eso, no tuve el placer de trabajar con FAT32 en un nivel bajo, fue un proceso bastante entretenido.

No entraré en detalles sobre el trabajo con FAT32 y la tarjeta SD en su conjunto, como Internet está lleno de artículos sobre este tema (y no quiero convertir mi historia en un recuento de especificaciones), pero hablaré sobre algunas cosas que deben implementarse. Es necesario implementar no solo las funciones de lectura de un archivo y escritura en un archivo (decidí almacenar algunas configuraciones y estados en la misma tarjeta SD, y no en la EEPROM), sino también las funciones de búsqueda de un archivo en el sistema de archivos si necesita trabajar con de la forma habitual

Todos los datos en la tarjeta de memoria se dividen en grupos (la unidad direccionable principal en el sistema de archivos FAT32), y los grupos ya están divididos en sectores. Para leer el archivo "habr.txt" de la tarjeta SD en FAT32, necesita:

  1. Inicialice la tarjeta de memoria.
  2. Lea el sector en la dirección cero y verifique que el sistema de archivos FAT32 tenga un encabezado determinado (puede omitir este paso si creemos en la suerte).
  3. Lea el sector en la dirección cero y obtenga "Direccionamiento de bloque lógico" (LBA).
  4. Lea el sector en la dirección recibida (LBA) y obtenga los datos necesarios (qué clúster es la raíz: el directorio raíz, cuántos sectores hay en el clúster, etc.).
  5. Lea el grupo "Directorio raíz" (de hecho, la lectura se realiza por sectores, solo necesita leer tantos sectores como sectores hay en el grupo) por su número. Tiene su propia fórmula para convertir números de serie del clúster en direcciones físicas. La información del archivo se almacena aquí, por lo que leemos los datos en busca del archivo deseado. Hay un poco más sobre los nombres de archivo: el nombre puede ser corto o largo, dependiendo de esto, los datos se almacenan en un lugar (en la misma estructura) o en un registro adicional, que también debe leerse por separado. Cuando se encuentra un archivo con el nombre deseado, obtenemos el clúster en el que se encuentra su inicio (o tal vez el archivo completo si cabe en el tamaño del clúster), así como el tamaño del archivo. Si el archivo no se encuentra en este grupo, buscamos el siguiente grupo y repetimos el proceso de búsqueda de archivos.
  6. Lea el clúster en la dirección encontrada. Y continúe leyendo más los grupos y busque el siguiente grupo hasta que se hayan leído todos los datos.

Me parece que es más fácil decir el principio del sistema de archivos a aquellos que han implementado listas vinculadas al menos una vez, porque de hecho, el sistema de archivos FAT32 es un conjunto de bloques de datos y un tipo de tabla que dice dónde buscar el siguiente bloque de datos. Leer cualquier dato de FAT32 es un proceso en el que leemos los datos, buscamos la dirección del siguiente bloque, leemos los datos, buscamos la dirección del siguiente bloque, etc.

No implementé todos los escenarios posibles y simplifiqué algunas cosas:

  • Todos los archivos están en la raíz de la tarjeta de memoria y no se utiliza la exploración de directorios.
  • Todos los archivos tienen nombres cortos.
  • El controlador al inicio lee una lista de archivos y los almacena en la memoria para no buscar cada archivo nuevamente.
  • El número máximo de archivos está limitado por una constante (y de hecho dibujé solo un par de docenas de imágenes).

En resumen, todo lo anterior es una razón convincente para tomar una biblioteca preparada y no gastar mucho tiempo leyendo documentación, desarrollando y depurando. Me aconsejaría implementar tales cosas solo con fines educativos o "por diversión".

La pantalla también impuso algunas limitaciones, ya que cualquier imagen en ella se muestra de esta manera:

  1. Nos despertamos e inicializamos la pantalla (para extender su vida útil y ahorrar energía, la pantalla básicamente duerme).
  2. Exponemos el canal necesario (por ejemplo, negro).
  3. Reenviamos 15000 bytes de la imagen.
  4. Exponemos el canal necesario (por ejemplo, rojo).
  5. Reenviamos 15000 bytes de la imagen.
  6. Le decimos a la pantalla que extraiga datos del búfer.
  7. Esperamos hasta que la pantalla termine de dibujar.
  8. Le decimos a la pantalla que duerma.

Para las imágenes monocromas, puede omitir los pasos 4 y 5. Para una imagen de tres colores, el orden de transmisión de las imágenes en blanco y negro y rojo-blanco no es importante, porque el rojo siempre se pinta sobre negro, el negro solo sobre blanco y solo los píxeles permanecen en blanco, que son blanco y negro y blanco y rojo y blanco.

Para simplificar (para no aumentar el número total de archivos), decidí almacenar las imágenes en blanco y negro y rojo blanco como un solo archivo, donde la imagen en blanco y negro es seguida inmediatamente por rojo-blanco:



El resultado de comparar estas imágenes fue algo como esto (me parece que cada uno de nosotros al menos una vez en nuestra vida nos sentimos como un ciervo con cuernos, una pata):



De hecho, las dos imágenes fueron seguidas por otra imagen que contenía una descripción del estado (al hacer clic en el botón, puede obtener una descripción que coincida con la imagen que se muestra hoy).

Debido a la memoria limitada del controlador, los datos de la tarjeta de memoria nunca se leen por completo en la memoria del controlador. La imagen de la tarjeta de memoria se lee en fragmentos que están determinados por el tamaño del sector (por simplicidad, suponemos que este tamaño siempre es estático y no puede cambiar de una tarjeta a otra) y cae en el proceso de procesamiento de datos de la tarjeta. En mi implementación, la función de leer un archivo toma como entrada el número de clúster, el tamaño del archivo y la devolución de llamada para "extraer" para cada lectura de sector. Este enfoque nos permitió utilizar varias funciones diferentes de procesamiento de archivos para leer y mostrar la imagen en sí o su descripción.

Entonces, la siguiente lógica recayó en la función de devolución de llamada de leer imágenes de una tarjeta de memoria:

  1. Establezca el canal requerido (el canal se determina al azar) antes de enviar datos a la pantalla.
  2. Realice un seguimiento de los datos transmitidos para cambiar de canal cuando se complete el envío de datos para el canal anterior.
  3. Enviar datos recibidos de la tarjeta.
  4. Determine que se han transmitido los datos necesarios y que se puede ignorar el resto de los datos (imagen con descripción).

Fue complicado por el hecho de que decidí ingresar imágenes que contenían más datos de los que deberían mostrarse en la pantalla. Es decir hay una imagen, que es el fondo y siempre es estática y corresponde al tamaño de la pantalla, y hay una imagen mucho más grande de la que debe tomar un área aleatoria (el tamaño de la pantalla) y mostrarla.

Dicha imagen impuso requisitos adicionales en el controlador: era necesario calcular cuántos bytes de la línea actual de la pantalla se transfirieron, cuánto más se debía agregar en la siguiente llamada (si la línea caía en el borde del tamaño del sector) y cuántos se deberían omitir.

Visualmente, esta situación se puede mostrar así:



Hay un cierto búfer en el que hay una "ventana" del tamaño requerido (sección verde) y solo necesita leer los datos de esta ventana, leyendo los datos del búfer en fragmentos de N bytes. Sería posible visualizar un proceso de lectura como este:



En general, agregar la lógica de trabajar con la pantalla en una función que siempre recibe un búfer de 512 bytes y que debería determinar cuál de estos 512 bytes se necesita (si se necesita algo) resultó no ser una tarea tan fácil de resolver "En la frente". Más precisamente, la tarea no era tan complicada como no estándar en comparación con las soluciones cotidianas, por lo tanto, sorprendentemente, fue muy interesante resolverla. Para mí fue como una "tarea de olimpiada", donde era necesario calcular la cantidad de electricidad necesaria para contraer los músculos con el fin de transferir agua de un cubo a otro con dos cucharas (una cuchara en cada mano).

Para comprender mejor cuál es la dificultad aquí, agregaré otra animación aquí, solo "en términos de" el contenido del clúster, y no todo el archivo (toda la otra información debe almacenarse por separado):



Según lo planeado, el calendario debe mostrar una nueva imagen todos los días, es decir debe poder monitorear el tiempo (incluso cuando está apagado), lo que significa que también se necesita un módulo de reloj en tiempo real (RTC). Y a pesar de que mi controlador tiene un reloj de tiempo real incorporado, es casi imposible tomarle una batería, porque los contactos no están conectados a la placa. Decidí no violar las piernas del controlador en un intento de soldarlas y tomé el RTC chino externo. Se suponía que trabajar con RTC era completamente simple:

  • Cuando esté activado, obtenga el tiempo del RTC chino.
  • Establecer hora en RTC interno.
  • Use el RTC interno para contar el tiempo y olvídese de los chinos hasta el próximo cierre.

Pero aquí, todo resultó no ser tan simple, porque el RTC interno del controlador funciona con el tiempo en el formato habitual (marca de tiempo UNIX), y su amigo chino usa decimal codificado en binario (BCD). Antes de esto, no encontré este formato y me sorprendió mucho que incluso los módulos modernos para Arduino lo usen. La esencia del formato es bastante simple: hay un byte que, por ejemplo, almacena la cantidad de segundos. Los cuatro bits de orden superior almacenan decenas, y los cuatro bits de orden inferior almacenan unidades. Resulta que la representación hexadecimal de este byte contiene un tiempo legible: el byte 0x49 corresponde a un valor de 49 segundos (aunque en el sistema decimal, este byte corresponde a 72).

Según tengo entendido, sucedió tan históricamente que fue más fácil usar RTC directamente con codificadores de pantalla para crear un reloj, pero tuve que convertir BDC a la marca de tiempo UNIX con bolígrafos.

Además de la pantalla, el módulo de reloj en tiempo real, la tarjeta de memoria y el sistema de archivos, era necesario envolver todas estas glándulas en un estuche, que también tenía que fabricarse, es decir "Dibujar". Puedes leer con más detalle todo el dolor que encontré en mi última publicación, aquí todo era exactamente igual:


(No planifiqué la producción en masa, todos los detalles son el resultado de mediciones incorrectas o soluciones mal pensadas)

Como resultado, se dibujaron el caso y los detalles necesarios (no hay portada en la imagen):



Los botones se colocaron en una parte separada para facilitar el ensamblaje (parece que todavía aprendí algo desde el momento del último proyecto):



el ensamblaje (con la excepción de las cubiertas frontal y posterior) se ve así: la



pantalla está unida a la caja con bridas. Esto resultó ser un método mucho más conveniente que atornillarlo.

Bueno, un pequeño infierno para los perfeccionistas (una barba de cables y componentes):



el ensamblaje resultó ser un dispositivo para el que hice un pequeño libro: instrucciones:



la tapa posterior está atornillada, lo que le permite desmontar el dispositivo si se requiere violencia adicional en su interior:



Sí, ¡es más fácil comprar una casa junto al mar!


Y luego, alguien que haya leído hasta este punto dirá: “¡¿Y esta es una alternativa a los simples regalos ?! Sí, inmediatamente necesita invertir 100500 horas de su tiempo, ¡lo cual es mucho más caro que el dinero! No discutiré sobre este tema, solo diré que para mí este es un proceso meditativo y mato dos pájaros de un tiro; por un lado, hago cosas que básicamente nadie necesita (pocos me pagarían por desarrollar algo tal), pero que son interesantes para mí, y una persona recibe un objeto único como regalo, que, aunque no tiene una carga útil obvia, sonríe.

Sin embargo, para que no haya un regusto de las soluciones que requieren mucho tiempo, compartiré algunas historias más.

Ahora, en general, se ha puesto muy de moda imprimir cosas en una impresora 3D. Los dispositivos de impresión se han vuelto mucho más accesibles, y el software para crear modelos es lo suficientemente simple para que los niños lo entiendan.

Llorar por ayuda


En el trabajo, recibimos una broma sobre el hecho de que si necesitas ayuda, solo tienes que gritarle a la gaviota y alguien definitivamente te ayudará. En verdad, no sé con qué está relacionado o de dónde vino esta broma, pero en la correspondencia interna a menudo comenzaron a aparecer imágenes de gaviotas, insinuando que alguien necesita ayuda.

Sin embargo, la oficina de tipo abierto y la modestia interna de algunos colegas no les permitieron aprovechar al máximo la oportunidad de pedir ayuda de esta manera. Luego, un "hombre que no era ingeniero" decidió ir al rescate, tomando un "Módulo de reproductor de música MP3 para Arduino", un clon chino de Arduino Nano, algunos cables y un par de mp3 con la grabación de los sonidos de las gaviotas.

En general, debe tenerse en cuenta aquí que tengo la costumbre de pedir varios módulos con descuento, lo que, según me parece, algún día puede ser útil, o recibiré tales artículos electrónicos como un regalo de amigos / conocidos que no encontraron útiles estos artículos electrónicos. Por lo tanto, la palabra "tumbarse" no es accidental, sino que describe con mucha precisión el estado de las cosas.

Como soy una persona que está lejos del modelado 3D, simplemente tomé un modelo ya hecho de la cabeza de la gaviota e hice los cambios necesarios. A saber, de los cambios fue necesario:

  1. Separe el pico de la cabeza para imprimir el pico en un color diferente.
  2. Haga una "cavidad" en la que se encuentren todos los componentes electrónicos (altavoz, reproductor, arduino y cables).

El resultado es algo como esto (el pico se divide en dos partes para una mejor calidad de impresión):



no creo que tenga sentido hablar de código, porque Además de inicializar el reproductor, solo había un controlador de clic de botón y se reproducía una de las grabaciones de voz de la gaviota (en general: playSound (rand () & 3);).

Después de eso, simplemente deje la gaviota para imprimir y juntar todo. Como resultado, tenemos un "simulador de té" completo (el color de la gaviota está determinado por el plástico que estaba disponible), que se conecta al USB y cuando hace clic en el botón en la cabeza de la gaviota, reproduce el "pedido de ayuda":



¿Aún más fácil?


Un colega se quejó de que estaba constantemente distraída mientras escribía los exámenes. Encontramos en Internet un modelo 3D de gafas y hacemos pequeños cambios:



Como resultado, tenemos gafas - anteojeras. No estamos distraídos por nosotros mismos y los demás entienden que no debes distraerte:



¡Muy simple!


Entonces, para crear necesitas:

  1. La capacidad de encontrar o dibujar una muleta en el editor de vectores.
  2. La capacidad de dibujar 2 cilindros en el editor 3D, uno más que el otro en ~ 0.4 mm.
  3. La capacidad de hacer un simple trozo de papel: una etiqueta.
  4. Impresora 3D (servicio de impresión propio o personalizado).
  5. La impresora es ordinaria.

Y ahora, en orden ... Dibujamos una muleta:



dibujamos dos cilindros:



imprimimos las partes y la etiqueta y obtenemos un gran y sencillo regalo para "tyzhprogramistov":



¿Para qué fue todo esto?


"A veces el destino juega con nosotros y de alguna manera insinúa que algo debería suceder pronto". Varias veces en mi vida tuve ideas que quería realizar, pero esperé algo. No haría un "calendario" electrónico si una pantalla gratuita no viniera de China, lo que significa que ni siquiera trataría con FAT32, no aprendería sobre el formato BCD utilizado en RTC.

Quizás alguien lea esta historia (o al menos mire las fotos) y piense: "¡Maldición, si él pudiera hacerlo, entonces yo podría hacerlo aún mejor!" Y como resultado, alegrará a alguien cercano.

Fuera de la ventana está lloviendo, diciembre está en el calendario. Se acerca el tiempo de las vacaciones y, por lo tanto, el tiempo de los regalos. Haga y reciba regalos interesantes, no solo otra caja de bombones, una vela o una estatuilla.

Source: https://habr.com/ru/post/480792/


All Articles