Hacer un probador de células solares con Mecrisp-Stellaris Forth

En los dos últimos artículos sobre Forth, hablé de lo hermoso que es, pero extraño, y luego instaló un sistema básico y parpadeó algunos LED. Y aunque le indiqué la multitarea, todavía no la usamos mucho. Iniciar un sistema Forth de este tipo es aproximadamente la mitad de la batalla. Trabajando internamente el microcontrolador difiere de la compilación para el microcontrolador, y averiguar el flujo de trabajo, cómo acceder a los problemas y dónde están los recursos útiles, no es necesariamente obvio. Además, hay algunas características sorprendentes de Mecrisp-Stellaris Forth que es posible que no note hasta que piratee el sistema por un tiempo.

Idealmente, mirarías por encima del hombro de alguien que hace lo suyo y verías cómo funcionan. Ese es el propósito de esta pieza. Si ya ha flasheado nuestra versión de Mecrisp-Stellaris-plus-Embello, está listo para seguir adelante. Si no es así, regrese y haga su tarea muy rápidamente. Todavía estaremos aquí cuando hayas terminado. Gran parte de este artículo será muy específico sobre el sabor Mecrisp-Stellaris de Forth, pero como funciona con toneladas de chips ARM, este no es un mal lugar.

Aclimatarse

Lo primero a lo que tendrás que acostumbrarte en Forth es la pila. ¿Conoces esa vieja tontería sobre el hecho de que las personas solo pueden tener cinco (¿siete?) Cosas en su mente a la vez. Forth intenta eso.

La última vez, mencioné brevemente el .s (“Pila de impresión”) comando. En La-Tecnologia Edition, redefiní el estándar Mecrisp .s ser un poco menos hablador y, a mis ojos, más legible. Si te encuentras golpeando .s mucho, y lo harás, también escribí una función que (temporalmente) reemplaza al “ocho”. Anímelo agregando una impresora de pila cada vez que presione adentro. Escribe print.stack y presione de nuevo para ver cómo funciona. Pulsando el botón de reinicio o escribiendo reset borrará todo lo que haya en la RAM, y eso incluye el mensaje de impresión de grapas, por lo que volverá a la pizarra limpia.

Probablemente sea un buen momento para jugar con los operadores de pila. ¿Leíste el vocabulario de Mecrisp? Eche un vistazo a la lista de operaciones de malabarismo de pila allí. Encender print.stack y jugar hasta que todos tengan sentido.

Corriste words ¿todavía? Escupe una lista enlazada de cada una palabra que Forth conoce, junto con las ubicaciones de memoria donde viven, y algunos detalles adicionales, demasiados detalles a menos que depure el sistema. Es una palabra extra, anormal, en Mecrisp, que solo imprime las funciones: list. Pruébalo ahora. Si aún no ha definido algunas palabras, hágalo.

: hw ." hello, world!" cr ;

es bueno tenerlo a mano.

Capas en la memoria

La memoria Mecrisp-Stellaris se divide en dos ubicaciones viles: RAM y flash. Todas las palabras enumeradas antes de la marca “- Mecrisp-Stellaris Core -” están en la RAM y se perderán al reiniciar o apagar. Las nuevas funciones de RAM se agregarán a la parte superior de la lista.

Después de que la marca “- Mecrisp-Stellaris Core -” comience a funcionar. En las primeras partes de flash, antes “- Flash Dictionary -” es el núcleo estándar de Mecrisp Forth. De ahí a “” son palabras tomadas de la distribución Mecrisp que son generalmente útiles, incluidas algunas funciones de depuración y multitarea. Antes de “” están las contribuciones de las bibliotecas de Embello, incluidas muchas definiciones GPIO, y las anteriores a “” se agregaron solo para esta serie de artículos.

Lo que no es obvio es que todos estos marcadores con corchetes los rodean cornerstones. Estos le permiten borrar un flash hasta esa ubicación de memoria. Entonces, si agregó algunas funciones adicionales a flash y desea borrar el estado predeterminado de La-Tecnologia Edition, puede escribir <<La-Tecnologia-extras>>. Se eliminarán las funciones adicionales y se restaurará el chip. (¡Tenga en cuenta que esto pierde todo lo que estaba en la RAM!) El comando eraseflash volverá al marcador “- Diccionario Flash -“.

Historial de sobrescritura

Si define una palabra dos veces con el mismo nombre, tendrá dos versiones de la palabra en el diccionario. Cuando se llama o se compila una palabra, el intérprete busca en la memoria, desde la parte superior de la RAM hacia abajo, y luego desde el final de un flash hasta el principio. Las palabras con el mismo nombre en RAM se denominan así antes que las de relámpago. Lo que puede ser particularmente extraño acerca de Forth es que, debido a que se compila en tiempo real, la palabra que se menciona en cualquier palabra de llamada es la que estaba arriba en ese momento se definió la palabra que llama. Hacer historias enredadas es una forma segura de volverse loco.

: foo ." foo!" ;
: bar foo ."  bar!" ;
bar foo! bar! ok.
: foo ." bizzle!" ; Redefine foo.  ok.
foo bizzle! ok.
bar foo! bar! ok.

Por otro lado, esta es una buena forma de trabajar que aprovecha estas diversas funciones de memoria. La RAM se borra en cada reinicio, lo que le da una pizarra limpia, pero usando conceptos básicos, un flash tampoco es inmutable. Por supuesto, cuanto más tenga que eliminar, más palabras tendrá que redefinir más adelante, asumiendo que algunas de ellas fueron útiles. Esto sugiere un enfoque en capas para el desarrollo, con la mayoría de las palabras “centrales” a la velocidad del rayo. Esto también es natural, porque uno tiene que definir palabras para nombrarlas, por lo que definir las bases primero tiene sentido de todos modos.

Puede compilar una nueva palabra en RAM (la predeterminada) llamando compiletoram o destellar invocando compiletoflash. Prototipo de sus palabras en RAM. Reemplácelas tantas veces como desee, pero recuerde que debe redefinir las palabras dependientes después de cambiar algo en sentido ascendente para mantener intacto el historial de llamadas. Después de terminar un poco de desarrollo, escriba reset y borre la RAM. Ahora redefine estas palabras en un instante. Si desarrolla su programa de abajo hacia arriba, encontrará que todo esto encaja. Cuando descubre un error en algo que ya está escrito para flash, el cornerstones viene a la salvación.

Finalmente, esta naturaleza estratificada de las definiciones de Forth puede ser muy útil. Por ejemplo, una función init el definido en flash funciona en cada reinicio. Incluye cosas como configurar la velocidad del procesador y el sistema con el que probablemente no quiera meterse. Porque puedes reemplazar init, y cualquier compilación utiliza las palabras disponibles durante la compilación, simplemente puede poner su función en init: : init init ." howdy!" cr ;. El primer “init” es el nombre de la nueva palabra y el segundo es el nombre de la palabra preexistente. inity hacer todos los arreglos. El resto de la definición te pertenece. Después de reiniciar, todo se ejecutará en el orden en que se definió.

Comodidades para niños

Escribo la mayoría de los códigos en un editor (Vim) y luego los envío al chip para jugar. Muy específicamente, escribí un guión llamado forth_upload.sh contiene lo siguiente:

[[ $1 ]] && TERM=$1 || TERM=/dev/ttyUSB0
DELAY=0.2
while read -r f; do echo "$f" ; echo "$f" > $TERM ; sleep ${DELAY}s ; done

Envíe un archivo al puerto serie y luego a Forth, forth_upload.sh < myfunctions.fs trabajará. Atraviesa cada línea del archivo, lo que permite un retraso de 0,2 segundos para que el sistema compile cualquier cosa. Este retraso es demasiado largo, en mi experiencia, pero los errores son breves. Folie toma el camino para buscar lo “bueno”. Fomenta acelerar las cosas, pero esto tiene sus propias cosas. Si usa Vim, puede enviar palabras sueltas o un archivo completo con lo siguiente:

nnoremap <Leader>u vip:<Home>silent <End>w !forth_upload.sh<cr>
inoremap <Leader>u <Esc>:silent .w !forth_upload.sh<Cr>
nnoremap <Leader>U :silent w !forth_upload.sh<Cr>

Esta configuración me permite desarrollar y escribir funciones en un editor favorito y luego enviarlas casi de inmediato al sistema Forth para probarlas. Mantengo una ventana abierta, que siempre está registrada en el sistema Forth, para poder ver las nuevas palabras definidas y luego comenzar a jugar con ellas de forma interactiva. Es bastante dulce.

El probador de células solares

Ahora veamos un ejemplo real rápido que usará todo lo anterior. Simplemente decidí presentar un conjunto de pequeños paneles solares que tenía en mi contenedor. Esto significa ajustar la carga en el panel y observar el voltaje generado por el panel y la corriente a través de la carga. Conecté dos multímetros y anoté algunos números, pero obviamente esa es una tarea para un microcontrolador.

Como muestra claramente la imagen, se trata de un azote rápido. La pieza más grande de revestimiento de cobre tiene una resistencia de medición de corriente y un par de resistencias configuradas como un divisor de voltaje para reducir el voltaje del panel a algo que el ADC de 3.3 V pueda manejar.

Colgando de esto está el circuito de carga variable (plateado), que es completamente inoportuno: un MOSFET disipa el calor al ser medio encendido por un voltaje de PWM filtrado por ese capacitor de 100 uF. La batería de 9 V y el optoaislador estaban conectados a tierra para garantizar un voltaje lo suficientemente alto como para abrir completamente el MOSFET, que quería más de 3.3 V.Este circuito de carga impresionante, pero funcional, fue una adición posterior: la primera versión solo tenía un potenciómetro aquí, hasta que fue fumado por demasiada corriente a través de él.

Los botones se utilizan para iniciar y detener las grabaciones del dispositivo en el balcón sin tener que volver corriendo. El procedimiento consistía en recortar un cocodrilo en un nuevo panel y mantener presionado el botón blanco mientras realizaba las grabaciones. El pequeño botón negro se presiona una vez para limitar los datos de una nueva celda. Los datos vuelven a mi computadora portátil a través de una serie UART a través de ESP8266 ejecutando un enlace esp como un puente WiFi transparente, que se ve en la parte superior izquierda, junto a las baterías recicladas de la computadora portátil. El pegamento termofusible y el cartón completan el edificio de alta tecnología.

¡A la hoja de datos!

Este tipo de construcción de herramientas rápida y práctica brilla en Forth. Las bibliotecas de Jeelabs Forth ya tienen algunas características que simplifican la configuración de ADC, pero en realidad no me funcionaron, así que busqué la hoja de datos. El único mínimo que se necesita para operar el ADC es encender los relojes laterales del ADC, habilitar la unidad ADC y luego seleccionar el tiempo de muestreo del ADC. También es posible que deseemos iniciar el procedimiento de calibración ADC para asegurarnos de que nuestras lecturas sean correctas. Este es todo el detalle de bajo nivel que debe hacer con cualquier microcontrolador, o apoyarse en una biblioteca que lo haga por usted.

Leyendo la hoja de datos, para encender el reloj del sistema ADC, necesitamos configurar el ADC1EN un poco en el RCC-APB2ENR registro de memoria. Lo que. Mecrisp-Stellaris tiene algún código de soporte que lee estos valores de archivos proporcionados por el fabricante. Los puse en el core/registers/ directorio. El archivo de mapa de memoria tenía buenos mnemónicos para todos los registros, pero no me encanta la forma en que se manejan los nombres de bits individuales. Aquí hay algo para afeitarme otro día, estoy tratando de lograr cosas.

Aquí está el conjunto de palabras ADC de nivel de bits que se me ocurrieron:

 Hookup
 PB0 - AIN8 is connected to panel voltage
 PB1 - AIN9 is connected to current sense resistor

: adc.rcc-enable  9 bit RCC-APB2ENR bis! ;  set ADC1EN
: adc.set-adon    0 bit ADC1-CR2    bis! ;  set ADON to enable ADC
: adc.set-cal-bit 2 bit ADC1-CR2    bis! ;

: adc.cal-done?    2 bit ADC1-CR2    bit@ 0= ;
: adc.isdone?      1 bit ADC1-SR     bit@ ;

9 bit crea un número con el noveno bit establecido y todos los demás cero, y RCC-APB2ENR bis! establece el bit deseado en el registro de control ADC relevante. En general, bastante opaco, pero también uno a uno con las instrucciones de la hoja de datos. Un buen nombre de estas palabras de subcapa mejora las cosas en una capa. Por ejemplo, la palabra responsable de iniciar una calibración (establecer un bit, esperar hasta que otro sea claro) es relativamente legible: : adc.cal adc.set-cal-bit begin adc.cal-done? until ;.

Y aquí vemos nuestro primer control de flujo, el begin...until construir. El orden es extraño, ¿no? Begin inicia el ciclo, la función de prueba adc-cal-done? realiza, dejando un valor verdadero o falso en la pila, y luego until lee este valor y vuelve a begin hasta que el valor sea verdadero. Esto es lo mismo que C while (!adc-cal-done()){;} bucle de espera ocupada. Y es una introducción a otro modismo de Forth: use ? para cualquier cosa que devuelva booleano.

Probar, reparar y volver a intentar

Así que probemos estas palabras. Iniciar el ADC y leerlo es fácil: ahora comencemos y asegurémonos de que los valores son los que esperamos. Azotar a un probador rápido en Forth es uno de sus principales puntos fuertes. : test-adc begin adc@ . cr 10 ms key? until ; define una palabra que lee el ADC, imprime el valor y se repite cada diez milisegundos hasta que presiona adentro. Si haces esto con un panel solar bajo luz fluorescente, por ejemplo, captarás las ondas de frecuencia de la red cuando golpeen tu panel, lo cual es posible que no hayas pensado. La capacidad de jugar con sus nuevas palabras tan pronto como los define, hace que dicha codificación de investigación fluya naturalmente.

Tiempo real de cuentos. Cuando escribí este código, definí un tiempo de muestra demasiado corto en las entradas de ADC. Esto hace que el valor de una lectura afecte a la siguiente, ya que el condensador interno del ADC no tiene tiempo para cargarse o descargarse por completo. Obtuve valores demasiado altos para la corriente cuando el voltaje era alto y valores demasiado bajos para la corriente cuando el voltaje era bajo. Lo depuré bastante rápido, escribiendo una rutina que leía cada canal varias veces seguidas e imprimía los valores, y dejé esas palabras para la posteridad.

( Take 8 samples of each, for debugging )
: read-both 8 0 do read-V . loop 8 0 do read-I . loop ;
: readloop begin read-both cr 100 ms key? until ;

Las observaciones de este ejercicio de prueba me llevaron a cambiar los tiempos de muestra en el ADC a su valor máximo, ya que aquí nada era crítico para el tiempo y utilicé una fuente de impedancia bastante alta. (El valor predeterminado es intentar lo más rápido posible). Después de ese cambio, lo intenté de nuevo y todo estaba visible. Este tipo de correcciones y pruebas rápidas interactivas son bastante comunes al depurar hardware nuevo, y Forth facilita la tarea de ir y venir para solucionarlos.

Envuélvelo

Después de usar el sistema varias veces fuera de mi escritorio, se hizo evidente que necesitaba agregar esos dos botones para habilitar la operación remota. También se agregaron algunas rutinas de parpadeo adicionales. Aunque estos fueron pensamientos tardíos, fue bastante fácil envolverlos en tareas y dejarlos trabajar todos a la vez.

Una tarea busca el botón de adquisición de datos, mientras que otra busca el botón “siguiente muestra” y tarda lo suficiente como para que no lo active dos veces por accidente. Me gustó mucho la forma en que funcionaba el tiempo de espera del botón con la multitarea habilitada ms orden. Puedes ver todo esto en el proyecto GitHub.

En cuanto a la computadora, debido a que todos los datos se ingresan a través de un puerto serie alojado en WiFi, ncat se usó para volcarlos en un archivo, donde se separaron en partes según los separadores, se convirtieron en una base de datos CSV válida y se trazaron. . Estos son todos de una sola línea, básicamente, pero también los arrojé al repositorio.

No soy un gurú de Forth, he estado usando Mecrisp en microcontroladores durante solo un año, así que estaré feliz de hacer una crítica constructiva del código. Este fue un truco rápido, pero hizo exactamente lo que necesitaba y fue un placer programarlo (además de depurar la configuración de ADC). Un paquete de diez de estas placas BRAK baratas con una configuración decente de Forth en llamas sería una gran cosa para cualquier proyecto de piratería. ¡Háganos saber si hace lo mismo!

  • Jonmayo dice:

    Es muy fácil encontrarse sin una fuente cuando realiza un flujo de trabajo típico de FORTH. Pero eso no es tan importante, porque la descomposición de FORTH a menudo está incorporada y es muy fácil.

    • Elliot Williams dice:

      … con la excepción de Mecrisp-Stellaris, desafortunadamente, que intercambia una compilación altamente optimizada y la correspondiente velocidad dramática para la visibilidad del código. Mattias llevó a cabo un comando “ver” en los libros de Mecrisp, pero muestra el código ensamblador / máquina en lugar del Forth.

      Dicho esto, el código resultante funciona tan rápido como C compilado, así que no me quejo. Sin embargo, editar en Forth, incluso uno con pantallas, etc., es un poco incómodo en comparación con un editor real.

  • notarealemail dice:

    Si alguien tiene una pregunta con en él, aquí hay una gran herramienta para convertirlo.
    http://accessify.com/tools-and-wizards/developer-tools/quick-escape/

    Un artículo genial, en mi cabeza. Marcado como favorito para cuando aprendo algunas habilidades reales de codificación.

  • TheRegnirps. dice:

    Elliott bastante serio. Pediste consejo 🙂 En una buena fortografía, defines nuevas palabras para que sea legible y versátil. Incluso si son triviales. En tu ejemplo final

    (Tome 8 muestras cada una para purificar)
    : read-both 8 0 do read-V. bucle 8 0 y legu-I. lazo;
    : readloop comienza a leer – ambos kr clave de 100 ms? hasta;

    Considere hacerlo con un número arbitrario de lecturas.

    : read-both dup 0 do read-V. loop 0 y legu-I. lazo;

    Utilizándolo “8 read-both”, copio la parte superior de la pila para que pueda ser utilizado por ambos bucles.

    Porque hay un dúplex que no define nada de eso.

    : multiplicado por dup;
    : leer-ambos 0 hacen leer-V. loop 0 y legu-I. loop cr;

    Entonces usa,

    8 veces leído – ambos

    El número de lecturas puede estar más allá.

    10 veces readloop

    • Elliot Williams dice:

      Tute. ¡Pero! 🙂

      Prueba un código. Solo tiendo a escribirlo y no pensar en ello. Se eligió el 8 para que fuera lo suficientemente grande como para permitir que el ADC resolviera si ese era el problema que terminaba. Y finalmente se instaló en dos o tres ejemplares.

      Esas palabras existieron durante unos 30 minutos, hasta que pude verificar que el ADC se estaba reproduciendo correctamente, y luego nunca se volvió a usar.

      Pero tu ejemplo es mucho más dulce. Las palabras de tipo “tiempos” donde la función de la palabra está completamente separada de la denominación, pero se elige para que coincida sintácticamente con una oración, todavía me da los ajustes en Forth. Estoy muy acostumbrado al paradigma de C de nombrar funciones por lo que hacen, en lugar de nombrarlas para que den como resultado el código resultante correctamente.

      Los ejemplos más extremos son palabras definidas para no hacer nada porque hacen que el código se lea como un idioma, o delimiten regiones, o lo que sea. Forth es extraño.

      • Ostraco dice:

        El cuarto es el idioma del pueblo.

        • TheRegnirps. dice:

          Po tong hua.

  • ruedas dice:

    La empresa para la que trabajo solía vender una fila de SBC con Forth en ellos. Comenzando en la década de 1980 con fig-Forth en procesadores 8088, más tarde Forth-83 en 8088, 80196 y 68000. Nuestra placa final con Forth proporcionó Forth compatible con ANSI en el 68332. Cada compilación se realizó en la mem. SBC.

    Nuestro flujo de trabajo utilizó el programa final de Windows 3.1, que tenía la característica interesante de que podía configurarlo para esperar a que se repitiera cada carácter o esperar a que se devolviera un carácter específico después de cada línea. Lo configuramos para esperar un retorno de carro y agregamos un par de entradas de diccionario llamadas DESCARGA y DESCARGA FINAL para deshabilitar y volver a habilitar el carácter eo en la entrada para una mejor velocidad, ya que nuestros puertos seriales se establecieron en 9600 baudios. En 1984, eso fue bastante rápido (la primera placa de la compañía habló a 4800 baudios), y luego mantuvimos esa velocidad por compatibilidad. No conseguir que cada personaje tuviera prisa se movió significativamente.

    Para acelerar la transferencia de archivos grandes (después de que nos alejamos de las pantallas), escribimos un preprocesador que hizo que un archivo incluyera y comentara / línea vacía.

    Guardé una copia de Windows 3.1 Terminal hasta que la perdí (junto con algunos otros archivos de una cosecha similar) el año pasado. Debería tener más copias de seguridad, supongo.

    @TheRegnirps –

    Desglosaría las cosas de manera diferente, probablemente más así:

    : veces (n – n 0) 0;
    : read-both (last + 1 first -) 2dup do read-V. bucle read-I. lazo;

    Mismo efecto, pero tiene más sentido para mí.

    • TheRegnirps. dice:

      Soy alérgico a poner un 2 delante de una palabra que no es matemática. 🙂 Viejos hábitos de FIG (Ragsdale 6502) y Forth79 donde DDUP hace lo mismo. O me haría cargo. Pero es más puro tener todos los argumentos en bucle juntos en un solo lugar.

      ¿Que compañia? National hizo un módulo híbrido con el nativo Forth en los años 80.

      • ruedas dice:

        Tengo un problema similar con DDUP, porque para mí la “D” principal significa “doble”, y aquí estamos tratando con dos números, no dos. ¿No es divertida la semántica?

        Ah, la implementación de 6502 FIG. Recuerdo que lo usé en un sistema Rockwell 65 en Life Imaging a principios de la década de 1980 y escribí las listas de mi Apple II en casa. No recuerdo el nombre del sistema Forth que compré para Apple antes de eso, pero lo reemplacé por FIG porque no era una implementación adecuada. Entre otras deficiencias, * / se definió como una multiplicación seguida de una separación, pero sin mantener una precisión adicional.

        Trabajo para Vesta Technology. La empresa fue fundada en Denver en 1984. Actualmente estamos en Golden. Seguimos fabricando SBC, pero ya nada con Forth. Triste historia: a finales de la década de 1990, una junta se enteró de que estábamos perdiendo ventas solo debido a una oferta de Forth como una opción para las personas que no querían usar C o BASIC (porque “Forth es para aficionados, por lo que sus juntas debe ser solo para uso aficionado. “), así que Forth dejó. Demasiado; Me pareció un entorno muy productivo.

  • Matthias Koch dice:

    Kara Elliot,

    gracias por los bonitos articulos!

    Matías

    Por cierto: Jean-Claude escribió un controlador de terminal USB para STM32F103, manejando apropiadamente el apretón de manos y permitiéndole simplemente “capturar” sus fuentes en Forth.

  • Mike Booth dice:

    Gracias por tus artículos Elliot, ¡y también a Matthias y JCW por todo el trabajo realizado! Quizás Forth reciba un nuevo aliento de vida entre los hackers de una nueva generación.
    Conocí a Forth a principios de los 80 por un genio del programa que cofundó el grupo Pentyre. Hicimos mucho trabajo integrado con los tableros Forth de Triangle Digital Systems y más tarde incluso diseñamos nuestro propio tablero de tarjetas Forth europeo integrado, el IDS2500. Este cachorro continuó siendo un controlador de medios central para el metro de Londres y también fue autorizado a un equipo de ingeniería de National Grid.
    Después de eso, una serie de plataformas de prueba de fábrica para Lucas Industries, incluida la plataforma de prueba final para el sistema de control de automóviles de Ford “mundial”.
    La belleza de Forth desde una perspectiva de ingeniería es la capacidad de interactuar pruebas a un nivel bajo durante el desarrollo; no hay abstracción como en C, etc. Este es el lenguaje para la programación de hot metal.
    Además, como nota histórica, hubo un chip dedicado en los años 80: el Rockwell 65F12, junto con un par de procesadores personalizados de dos pilas diseñados para implementar palabras Forth nativas de gama baja en silicio. ¡Animales veloces!
    FWIW, se puede considerar que una cuarta palabra funciona como una función C: toma los parámetros de llamada de la pila y da resultados en la pila.

Óscar Soto
Óscar Soto

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *