Skip to content

📝 Blog

M5Stack ❀

Quand j'achĂšte une nouvelle carte, c'est souvent sur une impulsion, en voyant un projet qui m'a plus ou en ayant une idĂ©e en tĂȘte.

Pour la M5Stack core, ce fut plus le fruit du hasard et le fait que K33g_org en ait acheté 2 d'un coup :)

Ce petit bloc est un ensemble trÚs bien pensé articulé autour d'un ESP32 à 240Mhz en dual core. C'est parfois limite trop toute cette puissance qui arrive dans les micro contrÎleurs :)
L'intégration est généreuse avec un écran de 2" (320x240), du wifi et du bluetooth BLE, lecteur de carte SD, un haut parleur, un connecteur grove/I2C et accÚs en broches Dupont à tout ce qu'offre l'ESP32.

La communauté autour des différents produits de la marque est plutÎt dynamique, il y a pas mal de modules maintenant.
Cette carte est un point d'entrée trÚs intéressant pour quinconque voudrait se lancer dans le monde de l'embarqué et de l'IoT.

J'ai commencĂ© par une, puis deux, puis... je n'arrĂȘte pas de faire des vidĂ©os avec.
Il faut dire qu'on peut la programmer visuellement, en micropython ou en arduino C. Si on ajoute sa capacité à se connecter en wifi et en bluetooth, le terrain de jeu est vaste.

Je vous liste ici les différentes vidéos que j'ai faites à ce jour, je ferai des articles de fond dans l'été si cela interesse certains d'entre vous.

Les premiers pas, découverte de la carte et de l'environnement M5Stack

Utilisation de l'accéléromÚtre

Un peu de micropython

Lecture et écriture de fichiers

Météo et Wifi

Rassemblement de mes vidéos

Au fil des années, j'ai accumulé pas mal de vidéos de tutoriels divers, de code, d'électronique...

Sur la suggestion d'un des enfants présents à un atelier Mixteen, j'avais séparé ces vidéos sur une chaßne YouTube dédiée. C'était une idée séduisante, rendre propre cette partie de mes activités bénévoles semblait la chose à faire.

Mais avec les années, c'est surtout la galÚre de la gestion multicomptes de Google qui l'emporte.
Je n'ai pas de besoins de marque ou d'entreprise, je ne fais pas ces vidéos dans un but lucratif.

J'ai donc décidé de tout rapatrier au sein de ma chaßne perso YouTube.

Le processus est quand mĂȘme assez long et douloureux, YouTube ne souhaitant visiblement pas qu'on fusionne ou au moins qu'on rassemble les vidĂ©os (le nombre de vues ou ce genre de statistiques ne me font pas courir)

Heureusement, j'ai conservé les vidéos que j'ai publié mais il a fallut toutes les republier une par une, en complétant les titre, description, tags ou playlists.

Vous retrouverez toutes mes anciennes vidéos et celle à venir sur la chaine Youtube http://www.youtube.com/c/ThierryChantier

J'espĂšre vous y retrouver rapidement, Ă  trĂšs bientĂŽt !

Impression 3D : le retour

J'avais un peu mis de cĂŽtĂ© tout ce qui touchait Ă  l'impression 3D, mais mĂȘme si je n'ai toujours pas Ă©normĂ©ment de temps, un petit besoin m'a fait relancer ma EmotionTech MicroDelta Rework.

En ces temps de télétravail systématique, j'ai attaqué le gigantesque chantier de rangement de tout mon espace télétravail/jeu/musique/maker (on ne rigole pas, merci).
Pour récupérer de la place, j'ai installé un support multi écrans Duronic DM35.

L'idée est de libérer l'espace pris par un écran sur mon plan de travail maker et d'alléger le cÎté télétravail.
C'est pas top en colonne, mais je pourrais plus tard le passer en mode cĂŽte Ă  cĂŽte.

C'est lĂ , en regardant ces 2 Ă©crans que je me suis dis qu'il pourrait ĂȘtre utile de replacer ma webcam entre les Ă©crans par exemple.
Ma Logitech C910 marche super bien, mais au fil des bricolages, le support d'origine était en piÚce.

C'était peu esthétique tout en étant fonctionnel :)
Mais lĂ , je souhaite repartir sur quelque chose de plus net.

Un peu dans le doute de l'état de fonctionnement, mais surtout de réglage, de ma MicroDelta, je commence par un cube de 20mm.

Franchement, propre, mesures trĂšs bonnes, je peux tenter d'imprimer une piĂšce utile.
Du coup, direction Thingiverse pour récupérer le modÚle fait par Benjamin : ça me permettra de fixer la C910 proprement sur un support compatible gopro qui offre un pas de vis d'appareil photo.

Et comme rĂȘvĂ©, une vis M4 et un Ă©crou plus tard

J'ai donc une imprimante parfaitement fonctionnelle malgré plus d'un an sans l'utiliser :)

Il me reste maintenant à voir si j'utilise un des accessoires photo que j'ai pour fixer la caméra ou si je cherche une fixation plus personnalisée avec le poteau du support d'écran.
J'en parlerai ici bien sûr !

Comme d'habitude pour toute question, pour toute remarque, pour toute critique, vous pouvez me joindre par email ou sur Twitter.

Vert.x et React : dev et prod

Aujourd’hui, on va faire trĂšs bref, le confinement gĂ©nĂšre son lot de soucis.

Dans le précédent épisode, nous avions mis en place une application web avec un frontend React et un backend Vert.x en Kotlin.

Pour développer, il suffit de lancer le backend qui est une application JVM, de lancer le frontend qui sera alors une application Node, et tout fonctionne.

Pour une version déployée, appelons ça pompeusement notre production, il serait bon de simplifier cela en pilotant tout depuis l'application tournant dans la JVM.

Pour se faire, il faut apporter 2 modifications.

La premiĂšre sera d'indiquer Ă  notre MainVerticle qu'il aura des ressources statiques Ă  servir.

router.get().handler(StaticHandler.create())

Par défaut, le code que vous voyez servira les ressources statiques trouvées dans le répertoire webroot.

Reste à construire le frontend et copier ses fichiers dans ce répertoire webroot.
Modifions notre fichier de build en ajoutant quelques lignes.

node {
  version = "10.16.0"
  npmVersion = "6.9.0"
  download = true
  nodeModulesDir = File("frontend")
}

val buildFrontend by tasks.creating(NpmTask::class) {
  setArgs(listOf("run", "build"))
  dependsOn("npmInstall")
}

val copyFrontendFiles by tasks.creating(Copy::class) {
  from("frontend/build")
  destinationDir = File("${buildDir}/classes/kotlin/main/webroot")
  dependsOn(buildFrontend)
}

val processResources by tasks.getting(ProcessResources::class) {
  dependsOn(copyFrontendFiles)
}

Dorénavant, lorsque vous lancerez votre commande gradle run , vous aurez accÚs à l'application par http://localhost:8888/

La différence étant bien entendu qu'en phase de développement, le serveur node, qui répond dans notre cas sur le port 3000, vous permettra de travailler sans relancer toute la build à chaque modification.

VoilĂ , c'est court aujourd'hui.
Vous trouverez comme d'habitude le code dans le repository, dans la branche vertx3.

Je tenais à remercier au passage Thomas Segismont qui est l'auteur de l'un des articles que j'ai lu dans mon parcours de débutant.

Comme d'habitude pour toute question, pour toute remarque, pour toute critique, vous pouvez me joindre par email ou sur Twitter.

Vert.x : des routes et des apis

Dans le précédent article, nous avons vu comment avoir une base d'application déjà capable de servir une page de base.

Il va maintenant falloir enrichir tout ça, et je sais par avance que j'ai 2 tùches devant moi :

  1. servir un véritable frontend, de préférence une SPA avec React
  2. fournir les API pour interagir avec les données que je ne manquerai pas de manipuler

Pour faire les choses bien, commençons par le second point :)

Ajout d'une API

Ajouter une API, ça veut d'abord dire que notre serveur devra réagir différemment s'il doit servir le frontend ou s'il doit répondre à une API.

Vert.x dispose d'un systĂšme de routing pour choisir ce qui sera executĂ© en fonction de l’adresse qui lui est demandĂ©e.

override fun start(startPromise: Promise<Void>) {
    val router: Router = Router.router(vertx)

    // Handle <server>/api/ping
    router.get("/api/ping").handler { rc: RoutingContext ->
      rc.response().end("Pong!")
    }

    // Handle <server>/api/greetings
    router.get("/api/greetings").handler { rc: RoutingContext ->
      rc.response().end("Hello from vert.x backend api!")
    }

    vertx
      .createHttpServer()
      .requestHandler (router)
      .listen(8888) { http ->
        if (http.succeeded()) {
          startPromise.complete()
          println("HTTP server started on port 8888")
        } else {
          startPromise.fail(http.cause());
        }
      }
  }

On crée donc un Router qui sera en charge de cette gestion des routes.
On indique quelles routes sont gérées et on associe un handler.
Enfin, on crée le serveur http en lui indiquant d'utiliser le router.

Vous pouvez lancer l'application et tester les accĂšs Ă  ces api.
Personnellement, j'utilise la commande http du package httpie sur mon Ubuntu pour ce genre de test rapide.
Pour ĂȘtre prĂ©cis, cela donne :

❯ http :8888/api/ping
HTTP/1.1 200 OK
content-length: 5

Pong!

Le lecteur vigilant aura remarqué que je n'ai pas créé en soit une route pour le frontend. Nous verrons dans le chapitre suivant que pour le moment, l'environnement de développement fonctionnera avec le backend d'un cÎté et un frontend de l'autre, servi sur un autre port.
Un article ultérieur montrera comment gérer ce point en version production.

Servir le frontend

Nous allons maintenant définir un point de départ pour notre frontend.
Pour l'instant, je conserve le code du backend dans le répertoire src.

Nous allons créer le frontend dans un répertoire subtilement nommé frontend.
Je fais le choix d'utiliser React en codant avec le langage Typescript.
Oui, c'est comme ça, je fais comme je veux :)

Pour cela, je vais suivre les explications du site React.
A la racine du projet, je lance simplement la commande :

yarn create react-app frontend --template typescript

Pour faire simple à ce stade, j'édite directement le fichier frontend/src/app.tsx

import React, {useEffect, useState} from 'react';
import logo from './logo.svg';
import './App.css';

const App = () => {
  const [greetings, setGreetings] = useState<string>('Default before call API');
  useEffect(() => {
    console.log('Component mounted');
    fetch("/api/greetings")
      .then(res => res.text())
      .then(text => setGreetings(text))
    return () => {
      console.log('Component will be unmount');
    }
  });


  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo"/>
        <p>
          {greetings}
        </p>
      </header>
    </div>
  );
};

export default App;

J'ajoute une gestion d'un hook représentant le message de bienvenue, que l'on renseigne en appelant l'API /api/greetings définie dans notre backend.
Pour que l'ensemble fonctionne, pour le moment dans l'environnement de développement, je modifie le fichier frontend/package.json en lui ajoutant une rÚgle lui permettant d'interroger le backend.

...
},
  "proxy": "http://localhost:8888"
}

Vous pouvez alors lancer le frontend (en n'oubliant pas de relancer le backend si vous l'aviez stoppé) :

yarn start

Vous avez maintenant une application backend, servant votre API, ainsi qu'un frontend React capable de l'interroger, accessible sur http://localhost:3000/

il reste bien des choses à faire, mais vous pouvez déjà vérifier ce que je vous propose sur le repository avec la branche vertx2.

Pour toute question, pour toute remarque, pour toute critique, vous pouvez me joindre par email ou sur Twitter.