Lisp est également un langage idéal pour apprendre les concepts fondamentaux de la programmation. Il intègre la gestion des chaînes de caractères, le traitement des listes et la collecte des déchets, et constitue donc un excellent langage pour exprimer des idées complexes, comme apprendre à un robot à résoudre des labyrinthes ou trouver le chemin le plus court sur une carte. En plus de supporter un ensemble de fonctions Lisp de base, uLisp inclut des extensions Arduino, ce qui le rend idéal comme langage de contrôle pour l'Arduino.
La dernière version d'ARM uLisp, la version 3.6b, permet maintenant de sauvegarder une image de l’espace de travail Lisp complet sur la mémoire flash des cartes ATSAMD21 qui ne fournissent pas de puce DataFlash séparée. Ceci ajoute le support de la sauvegarde d'image aux cartes Adafruit Neo Trinkey, Adafruit Gemma M0, Adafruit Feather M0, Arduino Zero, Arduino MKRZero, et Seeedstudio Xiao M0.
Comme uLisp est un interpréteur, il est possible de taper des commandes et voir l'effet immédiatement, sans avoir à compiler et télécharger le programme. Cela en fait un environnement idéal pour apprendre à programmer, ou pour configurer des appareils électroniques simples. Voici, ci-dessous, quelques projets développés avec uLisp :
Lisp Badge
Il peut être utilisé pour exécuter des programmes qui s'interfacent avec des composants tels que des LED et des boutons-poussoirs via les broches E/S, lire les entrées analogiques et faire fonctionner des périphériques externes via les interfaces I2C et SPI. Il dispose d'un écran OLED en niveaux de gris qui offre 8 lignes de 42 caractères, et d'un clavier intégré de 45 touches optimisé pour Lisp.
Spécifications
- Processeur : ATmega1284P ;
- Vitesse d'horloge : 16 MHz ;
- Affichage : 42 caractères x 8 lignes ;
- Taille : 107mm x 61mm (4.2" x 2.4" ;
- Consommation de courant : environ 20 mA ;
- Mémoire disponible : 2816 cellules Lisp (11264 octets) ;
- EEPROM : 1024 cellules Lisp (4096 octets), permet de sauvegarder l'espace de travail Lisp à l'aide de save-image ;
- Clavier : clavier intégré à 45 touches fournissant des caractères majuscules et minuscules, des chiffres et les symboles requis par uLisp.
Application de cartographie GPS
Voici un exemple pour démontrer une application GPS simple écrite en uLisp. Il utilise un module GPS avec une interface I2C, ce qui permet de lire facilement les paramètres GPS sans avoir à se soucier de l'analyse des phrases NMEA. Il existe également une version PCB du module. Le projet affiche la position GPS sur un écran OLED monochrome 128 x 64, de sorte que lorsque l’utilisateur se promène promenez, il affiche une trace de votre itinéraire.
L'écran doit être un écran OLED monochrome 128 x 64 basé sur le pilote de la puce SH1106 par exemple, l'écran OLED I2C 1.3" de Geekcreit. Le pilote de la puce SH1106 prend en charge la lecture de la mémoire de l'écran, ce qui est essentiel pour tracer un seul point sans affecter les points voisins. L'ItsyBitsy M4 a besoin de deux pullups de 4,7kΩ vers VCC sur les signaux I2C SDA et SCL. La broche d'entrée/sortie 2 est utilisée pour détecter le signal INT du module GPS, qui passe au niveau bas lorsque de nouvelles données GPS sont prêtes à être lues.
Ce circuit présente les interconnexions
Conversion de la latitude et de la longitude en x et y
La partie principale du programme lit la latitude et la longitude à partir du module GPS I2C, les convertit en coordonnées x et y, et les trace sous forme de point sur l'écran.
Pour les petites distances, nous pouvons supposer que la surface de la Terre est plate et utiliser les formules suivantes :
x = R ⋅ λ ⋅ cos (φ
y = R ⋅ φ
φ est la latitude en radians,
λ est la longitude en radians,
R est le rayon moyen de la terre, 6371km
Voici la position de la routine qui lit les octets de latitude et de longitude du module GPS I2C, les convertit en coordonnées x et y, et les renvoie sous forme de liste :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | (defun position () (let (lat long) (with-i2c (str 58) (write-byte 4 str) (restart-i2c str 8) (setq lat (/ (read4 str) 6e5)) (setq long (/ (read4 str) 6e5))) (list (* *r* (radians long) (cos (radians lat))) (* *r* (radians lat))))) |
Elle utilise la routine suivante, radians, pour convertir les degrés en radians :
Code : | Sélectionner tout |
1 2 | (defun radians (deg) (* deg (/ (asin 1) 90))) |
La variable *r* est le rayon de la terre, en mètres :
Code : | Sélectionner tout |
(defvar *r* 6.371e6)
La routine read4 lit quatre octets du flux I2C et renvoie un entier de 32 bits :
Code : | Sélectionner tout |
1 2 3 | (defun read4 (str) (+ (read-byte str) (ash (read-byte str) 8) (ash (read-byte str) 16) (ash (read-byte str) 24))) |
Traçage du chemin
Le programme utilise également des versions modifiées de certaines des routines de traçage de l'interface d'affichage du projet Graphics en Lisp. Le programme principal nav commence par initialiser et effacer l'affichage, puis attend que le module GPS ait obtenu une position. Il trace ensuite des points relatifs à la position de départ, qui est centrée sur le centre de l'écran :
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 | (defun nav () (init-display) (clear) (loop (unless (digitalread 2) (return))) (cross) (let ((home (position))) (loop (let* ((here (position)) (dx (round (- (first here) (first home)) 10)) (dy (round (- (second here) (second home)) 10))) (point (+ dx 64) (+ dy 32))) (loop (unless (digitalread 2) (return)))))) |
Avec ces chiffres, chaque pixel représente 10m, donc l'écran entier représente une surface de 1280 x 640m. Pour que le programme s'exécute automatiquement, il faut d'abord compiler et charger uLisp avec le #define :
Code : | Sélectionner tout |
#define resetautorun
Ensuite, entrez dans le programme et sauvegardez-le comme une image avec la commande :
Code : | Sélectionner tout |
(save-image 'nav)
Lorsque vous réinitialisez l'ItsyBitsy M4, l'image Lisp sera chargée et la fonction (nav) sera exécutée automatiquement. Il est possible d'alimenter l'ensemble du projet à partir d'une batterie LiPo 3,7V connectée à BAT et G.
Présentation de l'assembleur AVR
La version AVR de uLisp permet de générer des fonctions en langage machine intégrées à Lisp et écrites en assembleur AVR. Elle est actuellement supportée par les cartes Curiosity Nano AVR128DA48 ou AVR128DB48, et par les cartes basées sur l'ATmega1284P.
L'assembleur AVR fonctionne différemment des assembleurs ARM et RISC-V fournis pour uLisp. Comme les processeurs AVR ne peuvent pas exécuter de programmes en RAM, l'assembleur AVR copie le code machine assemblé de la RAM vers la mémoire flash, afin qu'il puisse être exécuté en flash. Ceci tire avantage de deux utilitaires développés pour les processeurs AVR : l'extension Flash Writing de DxCore de Spence Konde pour les cartes AVR128DA48 et AVR128DB48, et l'extension Optiboot Flasher pour l'ATmega1284P.
Bien que l'écriture sur la mémoire flash provoque une usure de celle-ci, la fiche technique indique que l'endurance de l'octet est de 100 000 cycles d'effacement/écriture. La mémoire flash n'est effacée/réécrite que lorsqu'on évalue une forme de defcode. Un avantage supplémentaire d'activer l'écriture flash sur ces cartes est que la mémoire flash peut être utilisée pour sauvegarder l'espace de travail Lisp, en utilisant save-image. Sur les cartes AVR128DA48, AVR128DB48, et ATmega1284P cela permet de sauvegarder entièrement l'espace de travail.
Source : uLisp
Et vous ?
Avez-vous connaissance du langage Lisp ? Que pensez-vous de ce langage ?
Quel est votre avis sur uLisp ?
Quelle fonctionnalité vous intéresse le plus ?
Voir aussi :
Pourquoi la programmation fonctionnelle n'est-elle pas la norme de l'industrie du code ? L'auteur de « Elm in action » s'exprime, « c'est une question de temps avant que la POO soit détrônée »
Le langage fonctionnel et impératif Janet, qui reprend des fonctionnalités de Lua et Clojure, s'apparente à une version légère de Lisp implémentée en C
Emploi développeur 2019 : les langages les plus demandés et les mieux payés
Quelques points clés sur la programmation défensive, destinée à assurer la fonction continue d'un logiciel dans des circonstances imprévues