Découpage laser de l’asclépiade

J’ai fait des tests en soumettant la fibre d’asclépiade à différentes puissances de mon laser. Ce que je me suis rendu compte, c’est qu’il ne se passe rien en-dessous de 70mW. À cette valeur, lorsqu’un bout de fibre simple est exactement au focus, il commence à brûler. Lorsque la fibre d’asclépiade brûle, elle agit en quelque sorte comme de l’encens à très haute vitesse, prenant environ 1 seconde pour que le tison la parcourt au complet.

La fibre est tellement lisse qu’elle réfléchit la lumière du laser comme un miroir cylindrique avec très peu de distorsion, c’est fascinant et ça provoque divers effets de lumière et d’optique vraiment intéressants. Il faudrait penser si on pourrait l’intégrer dans de l’optique, comme un diffuseur ayant de bonnes propriétés thermiques et acoustiques, je ne sais pas.

Lorsque le laser commence à interagir avec la fibre, on entend un petit bourdonnement, celui de la fréquence du PWM. Je restais à des fréquences aux alentours de 60Hz. Peut-être que je pourrais expérimenter avec d’autres valeurs, pour voir, mais je ne pense pas que cela soit vraiment différent.

En conclusion, le laser est approprié pour faire de la découpe de la fibre, avec les bons paramètres, c’est possible d’éviter de la faire prendre en feu et de produire une coupure nette et propre au travers de toutes les fibres en même temps. Autrement dit, une fois qu’un tissu d’asclépiade sera conçu, on pourra en faire la découpe facilement avec un faisceau laser. Par contre, pour modifier les propriétés de la fibre et ainsi pouvoir la filer, le laser n’a vraiment pas l’air d’être le bon outil. Soit il passe complètement au travers, soit il la laisse intacte. Il faut continuer à chercher d’autres alternatives!

Automatisation complète de mon extracteur de commentaires YouTube

Je me suis rendu compte, à force de laisser rouler mon extracteur de commentaires pendant plusieurs heures, voire plusieurs jours, qu’il finit toujours par y avoir une erreur qui le fait crasher, malgré tous les niveaux de robustesse que j’ai tenté de lui inculquer. Je pense que c’est dû en partie à la mémoire vive qui a besoin d’un petit sommeil de quelques instants, le temps de repartir à zéro. En tout cas, je me suis dit qu’un reboot de temps en temps ne doit pas faire de mal à ce pauvre ordi qui subit tous mes scripts plus ou moins legit.

Afin de me débarrasser de la nécessité de brancher un écran pour que firefox fonctionne, j’ai commencé par installer un serveur VNC, en suivant les instructions suivantes. C’est un guide très complet, qui explique également comment faire pour que le serveur VNC se mette en marche tout seul au démarrage. Il est fait pour debian, mais j’ai pu l’adapter sans problème pour Fedora.

Par la suite, j’ai essayé de démarrer mon programme classique d’extracteur de commentaires depuis le bureau virtuel sur lequel je me suis connecté. Ça n’a pas marché, je me suis rendu compte qu’il y avait encore un problème de PATH avec mon geckodriver (je l’avais placé dans ~/bin), il ne le trouvait pas puisque j’étais à l’intérieur du bureau virtuel, pour une raison ou une autre. J’ai donc placé le geckodriver dans /usr/bin, et ça a réglé le problème.

Par la suite, j’ai modifié mon programme pour qu’il se connecte d’abord sur une immense playlist de vidéos YouTube, qu’il enregistre où il est rendu dedans et qu’il commence avec la première vidéo qu’il n’a pas déjà en mémoire, c’est comme un immense générateur de « seed » pour mon crawlbot, ça lui fait des milliers de points de départ différents, tous rassemblés sur une seule page web.

Une fois tout cela testé, j’ai voulu le rendre automatique au démarrage, lorsque l’ordi boote, qu’il lance le crawler une fois que le serveur VNC est parti. C’est là que les problèmes ont commencé. J’ai essayé toutes sortes d’approches, comme d’inclure un appel à mon script python à même le service du VNC… sans grand succès. Ce qui a fini par fonctionner, toutefois, c’est de créer une crontab utilisateur avec ceci à l’intérieur :

@reboot python /home/fred/Documents/python/youtube_com_autoextract.py >> /home/fred/Documents/python/out.log 2>&1

Puisque le serveur VNC se logue directement à l’utilisateur fred de manière automatique, sans qu’il n’y ait besoin d’entrer le mot de passe associé, cela fonctionne, mon script python est lancé. Toutefois, j’obtenais toujours l’erreur récurrente de Selenium qui dit grosso modo que firefox n’a pas d’interface graphique. Je me suis buté à cette erreur un bon bout de temps, puisque lorsque je lançais moi-même exactement le même script depuis le bureau virtuel, tout fonctionnait bien. À force de me promener sur internet, j’ai fini par trouver la réponse ici : il faut spécifier dans le script python quel display on utilise, sinon ça doit sûrement être la valeur par défaut qui embarque, qui est sans doute nulle lorsque le script est lancé automatiquement depuis le crontab. J’ai donc simplement rajouté la ligne :

os.environ[‘DISPLAY’] = ‘:1’

après avoir mis un import os.

Cela fonctionne, puisque mon serveur VNC crée le display virtuel 1, donc la sortie de mon programme python, le browser firefox automatisé, est redirigé sur ce display.

Dernière chose mais non la moindre, je voulais également que mon programme envoie une commande de reboot lorsqu’il crashe. J’ai essayé le os.system(‘sudo shutdown -r now’), tel que trouvé ici, sans succès, l’erreur dit qu’il n’y a ni console ni mot de passe de fourni par l’utilisateur, ce qui est assez vrai.

En fouillant un peu, j’ai trouvé qu’il était possible de désactiver la demande de mot de passe pour n’importe quelle commande avec visudo (j’ai trouvé l’information ici). J’ai essayé avec %user ALL=(ALL) NOPASSWD:/usr/bin/shutdown, ça n’a pas marché. Finalement, je me suis rendu compte que c’était mieux d’utiliser systemd avec la commande systemctl pour lancer la procédure de reboot. J’ai trouvé l’information ici :

user hostname =NOPASSWD: /usr/bin/systemctl reboot

En remplaçant user et hostname par mes valeurs, dans le visudo. En mettant simplement la ligne

os.system(‘sudo systemctl reboot’)

dans un except qui ramasse toutes les erreurs non identifiées de mon script en python, le redémarrage se fait automatiquement lui aussi, sans crasher à cause d’une demande de mot de passe. Tout fonctionne? Je viens de le partir, pour l’infini ou presque on l’espère, ça reste à voir! Mais cette fois-ci, c’est une araignée aux pattes d’acier, je vois mal ce qui va pouvoir la tuer, mis à part une panne de courant.

Vidéo sur mon télescope à réalité augmentée

J’ai réalisé une vidéo sur mon projet de télescope à réalité augmentée. Je l’ai présenté en long et en large dans les articles précédents. L’ajout dont je n’ai pas parlé est l’arduino et le BMP085 (un capteur de température et de pression), permettant d’afficher sur l’écran LCD les données de température et d’altitude en temps réel. L’arduino envoie une commande par un port série à la carte Nextion, qui actualise les données affichées à l’écran. Le code arduino, basé sur les exemples de Nextion (je n’arrive plus à retrouver le lien) est le suivant :

#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP085.h>

SoftwareSerial mySerial(10, 11); /*Even though you can use the hardware serial port in this case I think it is better to
leave the hardware serial open for debugging purposes*/

Adafruit_BMP085 bmp = Adafruit_BMP085(10085);

float temperature;

void setup() {

Serial.begin(57600); //open the hardware serial port
while (!Serial) { // wait for serial port to connect. Needed for native USB port only
;
}
/* Initialise the sensor */
if(!bmp.begin())
{
/* There was a problem detecting the BMP085 … check your connections */
Serial.print(« Ooops, no BMP085 detected … Check your wiring or I2C ADDR! »);
while(1);
}

Serial.println(« Serial On »); //Print this messages when the serial port is connected
mySerial.begin(9600); // set the data rate for the SoftwareSerial port
}

void loop() {
/* Get a new sensor event */
sensors_event_t event;
bmp.getEvent(&event);

/* Display the results (barometric pressure is measure in hPa) */
if (event.pressure)
{
/* Display atmospheric pressue in hPa */
Serial.print(« Pressure: « );
Serial.print(event.pressure);
Serial.println( » hPa »);

/* Calculating altitude with reasonable accuracy requires pressure *
* sea level pressure for your position at the moment the data is *
* converted, as well as the ambient temperature in degress *
* celcius. If you don’t have these values, a ‘generic’ value of *
* 1013.25 hPa can be used (defined as SENSORS_PRESSURE_SEALEVELHPA *
* in sensors.h), but this isn’t ideal and will give variable *
* results from one day to the next. *
* *
* You can usually find the current SLP value by looking at weather *
* websites or from environmental information centers near any major *
* airport. *
* *
* For example, for Paris, France you can check the current mean *
* pressure and sea level at: http://bit.ly/16Au8ol */

/* First we get the current temperature from the BMP085 */
float temperature;
bmp.getTemperature(&temperature);
Serial.print(« Temperature: « );
Serial.print(temperature);
Serial.println( » C »);

/* Then convert the atmospheric pressure, SLP and temp to altitude */
/* Update this next line with the current SLP for better results */
float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
Serial.print(« Altitude: « );
float alt = bmp.pressureToAltitude(seaLevelPressure,
event.pressure,
temperature);
Serial.print(alt);
Serial.println( » m »);
Serial.println(«  »);
String sendThis = «  »; //Declare and initialise the string we will send

delay(300); //Probably unneccessary, but I give the screen some time to respond
sendThis = « n0.val= »; //Build the part of the string that we know
sendThis.concat(int(temperature)); //Add the variable we want to send
writeString(sendThis); /*Use a function to write the message character by character to the Nextion because
mySerial.write(sendThis) gives you an error due to a datatype mismatch*/
delay(300); //Probably unneccessary, but I give the screen some time to respond
sendThis = « n1.val= »; //Build the part of the string that we know
sendThis.concat(int(alt)); //Add the variable we want to send
writeString(sendThis); /*Use a function to write the message character by character to the Nextion because
mySerial.write(sendThis) gives you an error due to a datatype mismatch*/
}
else
{
Serial.println(« Sensor error »);
}

}

//NOTE: A great big thanks to: RamjetX for writing this function. You can find his/her post here: http://forum.arduino.cc/index.php?topic=89143.0. Please go give him/her some Karma!
void writeString(String stringData) { // Used to serially push out a String with Serial.write()

for (int i = 0; i < stringData.length(); i++)
{
mySerial.write(stringData[i]); // Push each char 1 by 1 on each loop pass
}

mySerial.write(0xff); //We need to write the 3 ending bits to the Nextion as well
mySerial.write(0xff); //it will tell the Nextion that this is the end of what we want to send.
mySerial.write(0xff);

}// end writeString function

Test du laser sur l’asclépiade

J’ai fait plusieurs tests avec le laser et la bouteille qui essaie de faire une extrusion continue de la fibre d’asclépiade. C’est vraiment un échec. Premièrement, la fibre reste toute coincée avant d’entrer dans la buse, je ne comprends pas comment répéter les résultats que j’obtenais précédemment. Peut-être que l’asclépiade que j’avais utilisé alors avait des fibres plus courtes, je ne sais pas.

Toute la fibre qui arrive à sortir est simplement brûlée par le laser. Il faudrait trouver une façon de pouvoir contrôler la vitesse de sortie, pour que chaque bout soit exposé au laser de manière contrôlée. Bien sûr, je suis capable d’ajuster la puissance du laser avec un PWM pour obtenir n’importe quelle valeur entre 0 et 3W.

Je vais abandonner l’idée de l’alignement par air comprimé, les résultats ne sont pas concluants. Il va falloir trouver une autre méthode plus fiable et plus reproductible.

Sinon, j’ai fait des tests avec un motton d’asclépiade placé dans le faisceau laser. La fibre étant très petite, elle est aussitôt transformée en fumée. Des bouts brûlés se situent en périphérie du trajet du faisceau. Je les ai regardés au microscope, on peut les voir sur les images ci-dessous. Cela semble donner toutes sortes de formes tordues aux fibres, ce qui est bon signe. Il faudrait voir si elles sont tout aussi isolantes. De plus, je ne sais pas à quel point cela les brise, possiblement qu’elles deviennent encore plus fragiles qu’elles ne le sont déjà, se transformant en poussière encore plus facilement.

En conclusion pour cette petite séance de laboratoire, il faut repenser complètement la méthode d’alignement et expérimenter avec différentes puissances de faisceau, de manière reproductible. L’ajout d’une seconde fibre ou d’un liant quelconque est à investiguer.

Ajout d’une carte fona 3G à mon raspberry pi

J’avais déjà acheté une carte fona 3G l’été passé, j’ai eu bien du plaisir à la faire fonctionner avec un arduino et le code d’exemple fourni par Adafruit. À présent, j’aimerais rendre le tout plus portatif, et la manière la plus simple de le faire est de rajouter la carte à ma station raspberry pi portative. Cela me donnera donc en résultat un « téléphone intelligent » pas mal badass : raspberry pi 3, écran 7 pouces et assez de batterie pour durer 10h.

J’ai connecté l’entrée du 5V de la carte au 5V du raspberry pi, le VIO à 3.3V, le RX de la carte dans le TX du raspberry et vice-versa, et le RTS dans le ground puisque j’ai configuré le fona pour avoir le serial à 7 lignes afin d’avoir une sortie dans la pin de RING.

Après avoir activé l’interface série dans la configuration du raspberry pi (cela ajoute essentiellement la ligne enable_uart=1 à la fin du fichier /boot/config.txt) et avoir redémarré, j’ai ouvert le port série avec

sudo screen /dev/serial0 4800

dans un terminal. Cela marchait à moitié, voire pas du tout. Par exemple, j’écrivais AT et la carte me répondait une seule fois avant de figer. J’ai essayé à peu près tous les baudrate, sans plus de résultat. Après avoir tout essayé, j’ai trouvé comment régler le problème.

Il se trouve que le kernel du raspberry pi utilise lui aussi le port série par défaut comme console pour faire du déboguage, il envoie donc des données à la carte, qui ne sait évidemment pas comment les gérer, ce qui fait tout bugger lorsque l’on essaie d’y accéder avec screen. Pour désactiver cette fonction, il faut aller dans :

/boot/cmdline.txt

et supprimer la partie de la ligne qui dit console=serial0,115200 en gardant le reste de la ligne et en faisant bien attention de ne pas laisser un retour à la ligne dans ce fichier. Cela fait en sorte que le kernel ne se sert plus de cet interface comme console. Une fois le raspberry pi redémarré, tout fonctionne à merveille!

La suite du projet va être de créer une sonnette pour le cellulaire, ensuite de faire un petit boitier pour bien fixer le tout à ma station portative, et éventuellement, de créer ou d’utiliser un petit programme d’interface utilisateur pour commander la carte fona sans passer par les commandes AT qui peuvent vite devenir épuisantes à utiliser.

Conception du détecteur de l’imagerie oxymétrique

Pour pouvoir mesurer le signal dans chaque fibre, je devais trouver un moyen de les imager avec ma caméra à haute sensibilité. J’ai tout d’abord réussi à trouver une lentille en ménisque convergent qui a une distance focale de 35 mm, en la collant directement sur l’objectif de la caméra, cela permet de rapprocher l’objet de la distance hyperfocale (approx 30 cm je crois) jusqu’à 35 mm, en diminuant le champ de vue par la même occasion.

J’ai donc imprimé deux pièces s’emboîtant en une boite en prisme cubique. La première est une plaque comportant 49 trous afin de faire passer toutes les fibres et de les aligner sur un même plan. La deuxième a un trou au centre pour y insérer la caméra ainsi qu’un petit remontant cylindrique afin d’y fixer la lentille. Le tout permet de bien maintenir toute l’optique solidement en position et dans l’obscurité, autant les fibres que la lentille et la caméra.

Une fois la boîte refermée, cela donne le détecteur assemblé visible sur les deux photos ci-dessus. D’un côté, il y a la caméra, bien insérée et collée, et de l’autre, le paquet de 49 fibres formant l’image. On peut voir le résultat capté par la caméra ci-dessous. L’espacement entre les fibres est tel qu’il permet à chacune d’être bien résolue et échantillonnée sur un bon nombre de pixels, même lorsque l’intensité lumineuse dans la fibre optique est très élevée. Dans le cas présent, j’avais pointé quelques fibres directement sur une ampoule incandescente. Bien évidemment, comme je n’utilise pas de lentille de champ à la sortie des fibres, celles sur le bord de l’image vont avoir une intensité captée par la caméra beaucoup plus faible que celles au centre, il va donc falloir faire une calibration pour appliquer la correction sur le signal mesuré.

 

Test du LCD sur le télescope LCD

J’ai testé l’écran LCD de mon télescope LCD hier. Après moult essais, je ne suis pas parvenu à afficher quoi que ce soit dessus. Tout semblait pourtant fonctionner, je n’avais pas de message d’erreur dans le logiciel. Je me suis rendu compte en fait que je l’avais brisé en l’insérant dans ma monture, comme en témoigne la photo ci-dessous.

C’est bien plus fragile que je le pensais en fait, les bords supportent peu les stress mécaniques.

Je me suis donc rabattu sur mon autre écran LCD modifié, celui qui est branché sur une carte Nextion que j’avais utilisé comme preuve de concept au tout début du projet. Sa conception mécanique est un peu différente, ce qui fait que j’avais gardé la monture métallique qui fait la bordure du verre, lui donnant tout de même une bonne résistance au stress mécanique lors de l’insertion dans ma monture. En fait, je pense que c’est le poids du raspberry pi qui a joué, fissurant le verre et les connecteurs internes.

Cela donne donc les résultats suivants, ce qui est très satisfaisant, et ça l’est encore plus lorsque l’on place un oeil face à l’oculaire au lieu de l’objectif d’une caméra.

Les lentilles de champ permettent d’avoir une bonne luminosité de l’image malgré l’atténuation du LCD lorsque l’oeil est bien aligné avec l’optique. Le vignettage que l’on peut observer sur les images est dû à l’aperture stop de la caméra, pour l’oeil, on voit surtout des aberrations sur les bords de l’image.

Mais tout fonctionne bien, les images réelles et virtuelles se combinent à merveille dans mon système, et tout est à l’endroit!

Assemblage mécanique pour le traitement laser de l’asclépiade

J’ai terminé l’assemblage mécanique de mon laser 3W. L’objectif était de le monter à la verticale, de manière à ce que le faisceau pointe vers le sol, puis de l’aligner sur la sortie de ma buse par laquelle sort la fibre. Pour cela, j’utilise principalement des extrusions d’aluminium. Il y avait plusieurs trous filetés dans le boîtier du laser, dont le diamètre était parfait pour y visser mes vis de 2mm. J’ai donc simplement imprimé en 3D une plaque avec des trous aux bons endroits (3e photo). Un arduino connecté sur l’entrée TTL de la carte de contrôle du laser permet de sélectionner la puissance de sortie du laser. Pour faire l’alignement, j’utilise la puissance la plus basse possible, en deçà du 1mW (non mesuré pour de vrai). Je porte tout de même des lunettes classées OD5 à 450nm en tout temps, les lunettes fournies avec le laser lors de l’achat sont une vraie blague, mais vraiment pas drôle en fait, puisqu’elles ne bloquent (à peu près) rien, elles sont très probablement fausses, mais bon, au prix que m’a coûté le laser, c’est normal. On peut voir sur la 4e photo le faisceau vu par la caméra à cette puissance. Le focus se fait en tournant la petite lentille à la sortie du laser. Sur la 5e photo, c’est le laser lorsqu’il est à pleine puissance (supposément 3W, non mesuré). On peut voir que c’est amplement suffisant pour passer au travers d’une feuille de papier en une fraction de seconde (dernière image). Le tout sera utilisé dans une boîte fermée, pour limiter les risques laser au maximum.

Défrichage de fibre optique pour l’imagerie oxymétrique

Parce que oui, c’est possible de faire autre chose que des sapins de Noël avec de la fibre en PMMA à 10¢ le mètre. Je me suis lancé sérieusement, dans les derniers jours, dans mon projet d’imagerie oxymétrique. Pour commencer, j’ai découpé 147 bouts de 30 centimètres afin d’avoir une image composée d’un carré de 7×7 (ou toute autre forme comprenant 49 bouts de fibre sur l’image de la caméra).

Sources lumineuses

En utilisant deux sources de longueur d’onde différente, l’une dans le rouge, l’autre dans l’infrarouge, il est possible de déterminer le taux d’hémoglobine oxygénée par rapport à l’hémoglobine désoxygénée, en se basant sur les courbes d’absorption particulières. Ce principe est largement utilisé dans les sphygmo-oxymètres optiques, mesurant la concentration d’oxygène en un point (normalement un doigt) et supposant qu’elle est homogène dans le reste du corps. Or, la consommation d’oxygène par les organes varie selon l’effort énergétique qu’ils doivent fournir. En ayant une méthode qui permet de mesurer les variations d’oxygénation dans un volume donné, on ouvre la porte à toutes sortes d’applications intéressantes, comme l’imagerie spectroscopique proche infrarouge fonctionnelle (functional near-infrared imaging, fNIR, en anglais), ce qui est très excitant puisqu’elle permet de visualiser les processus mentaux en temps réel avec, ce que je souhaite vérifier, du matériel très peu coûteux et facile à trouver.

 (source : http://www.oximetry.org/pulseox/principles.htm)

Atténuation de la fibre

Résultats de recherche d'images pour « attenuation pmma fiber »

L’atténuation dans le proche-infrarouge pour le PMMA grimpe rapidement, comme on peut le voir sur le graphique. À 850nm, on a environ 5dB/m d’atténuation. Il faut donc garder les bouts de fibre très courts. Avec 30 centimètres, les pertes sont de 1,5dB (~71% du signal est transmis), ce qui fait mal, mais pas trop, espérons-le.

Matériel

Pour mes sources lumineuses, j’utilise deux DEL à très haute puissance optique (2,6W) afin d’être certain d’avoir suffisamment de signal. J’aurais pu utiliser des lasers, mais mon objectif était d’injecter simultanément toutes les fibres, le plus simplement possible. De plus, les DEL sont moins coûteuses et moins dangereuses (quoique à cette puissance, même si ce n’est pas un faisceau cohérent, j’ai tendance à être prudent quand même).

Je les avais déjà préalablement soudées l’année passée, lorsque j’avais commencé ce projet. Je leur ai rajouté un petit cylindre imprimé en 3D, qui se met directement autour du petit bulbe-lentille de la DEL et qui est suffisamment large pour y faire tenir les 49 fibres.

J’utilise pour les alimenter un power supply d’ordi, qui me donne 15V et 5A, le tout régulé à 700mA par diode par des régulateurs spécialisés pour cette application.

J’ai remarqué qu’allumées à pleine puissance, elles deviennent très chaudes très rapidement, ce qui va être à tenir en compte dans la suite du projet. Il va falloir soit les utiliser périodiquement avec un rapport cyclique faible, soit rajouter un système de refroidissement adéquat, ou bien y aller avec une combinaison de ces deux approches.

À 850nm, l’oeil perçoit un rouge très faible, sûrement la limite inférieure du spectre de la diode, qui est en fait bien plus lumineuse, tel qu’on peut l’observer avec la caméra qui lui donne une couleur mauve.

  

La DEL à 660nm est extrêmement brillante, puisque la quasi-totalité de son spectre est dans le visible. On peut voir que les fibres contiennent bien le faisceau.

Pour la caméra, j’utilise une caméra de drone de marque RunCam qui a une sensibilité absolument phénoménale pour son prix abordable : jusqu’à 0,0001 Lux (elle m’avait coûté 50$US si je me souviens bien). Je lui ai imprimé en 3D un petit adaptateur qui rassemble toutes les fibres et y fait tenir la caméra. Toutefois, comme on peut le voir sur la dernière image, ce sera à refaire puisque le focus de la caméra est à l’infini, ce qui mélange toutes les fibres en un gros blob de lumière. Il va donc falloir rajouter de l’optique pour imager correctement les fibres et arriver à les distinguer individuellement afin de pouvoir traiter le signal. C’est le pari à relever en ce moment dans ce projet.