Applications utiles et gratuites : gestion de fichiers

Explorer++ : explorateur de fichiers

https://explorerplusplus.com
Système : Windows
Langue : Multi (dont Français)

Remplace avantagement l'explorateur de fichiers de Windows avec multi-tab, favoris et personnalisations.


Free OTFE : disque chiffré

https://sourceforge.net/projects/freeotfe.mirror
Système : Windows
Langue : Multi (dont Français)

Monte et démonte des volumes pouvant être un fichier ou une partition. Supporte SHA-512, RIPEMD-320, Tiger et les algorithmes AES, Twofish et plus.


Nexus Font : gestion de polices

http://www.xiles.net
Système : Windows
Langue : Multi (dont Français)

Pour (dés)installer sans les déplacer, visualiser, renommer, ranger et gérer vos polices de caractère favorites.


Tera Copy : copie de fichiers

http://www.codesector.com/teracopy
Système : Windows
Langue : Multi (dont Français)

Peut remplacer le gestionnaire de copie de Windows. File d'attente, pause, information supplémentaires, mémoire tampon, logs... D'autres options dans sa version Pro uniquement, mais largement suffisant dans sa version gratuite.


AntRenamer : renommer des fichiers

https://antp.be/software/renamer/download/fr
Système : Windows
Langue : Multi (dont Français)

Permet de renommer des fichiers par lots avec des règles, expressions, énumérations, données EXIF, IDv3...


Yoyo Cut : découpe/recompose les fichiers

http://siteayoyo.free.fr/YoyoCut
Système : Windows, Linux
Langue : Multi (dont Français)

Permet de découper n'importe quel fichier pour le scinder en plusieurs autres fichiers plus léger. Ils peuvent être auto-recomposables ou recomposés avec Yoyo Cut. Compatible avec l'essentiel des formats : XtremSplit, CutKiller, HJSplit...


Cathy : indexer les fichiers

http://rva.mtg.sk
Système : Windows
Langue : Multi (dont Français)

Permet d'indexer tous les supports comme les CD/DVD, disques durs, clés et disques réseau pour permettre de retrouver un fichier sans avoir à le(s) réinsérer/connecter.

Montage imprimante 3D Tronxy XY-100

Réception d'une petite imprimante 3D en kit... déballage et assemblage :

imprimante3d-xy100-1

imprimante3d-xy100-2

imprimante3d-xy100-3

imprimante3d-xy100-4

imprimante3d-xy100-5

Les outils sont fournis (tournevis cruciforme et plat, trois clés allen et autres).
Une vidéo assiste au montage, mais ne suffit pas à elle seule ; il faut compléter avec la notice PDF.
J'ai passé plus de temps à décoller la protection recto/verso des éléments plastiques qu'à l'assembler.
la position en X, due aux 2 tiges est délicate : le réglage est fin mais difficile.
Les trous des glissières du plateau semblent avoir un mauvais alignement ce qui accentue le frottement en Y.
la plupart des cables sont trop longs, ou c'est moi... aussi, il me reste une trentaine de vis et boulons.

imprimante3d-xy100-6

imprimante3d-xy100-7

imprimante3d-xy100-8

Accéder au flux et vidéos des caméras ipc365 ShowMo, Fredi...

Télécharger et installer CMS (mirroir)


les caméras sont prêtes et connectées à l'ordinateur, et CMS est lancé


A droite, aller sur System puis Device Manager
Cliquer sur ADD AREA et valider


Cliquer sur Add Device, puis IP search pour obtenir la liste des caméras


Doule-cliquer sur une, personnaliser le nom et préciser le mot de passe : 123456 puis valider


Connection Test permet de vérifier l'état des caméras configurées


A gauche, double-cliquer sur une caméra pour accéder au flux direct


Accéder aux vidéos enregistrées

A droite, cliquer sur PlayBack
Choisir le flux concerné et cliquer sur Search


Cocher les vidéos souhaitées (ici il n'y en a qu'une)
Cliquer sur Download pour extraire la vidéo


On peut aussi configurer la caméra. Après, à vous de creuser.
Pour quitter CMS, laisser le champ mot de passe vide.

"Cube" 3D 3x3x7 à LED sur Arduino - partie 3 : Le code

Comme prévu, voici la troisième et dernière partie, le code Arduino de la guirlande 3D. A noter qu'il est possible de télécharger l'intégralité du code en fin d'article, avec d'avantage de commentaires pour une meilleure compréhension.

Donc, pour démarrer, la déclaration des constantes et variables :

// CONSTANTES
const int fps = 20;
const int milli_fps = 1000 / fps; // durée d'une frame en milliseconde
const int etages = 7;
const int colonnes = 9;
const int cote = sqrt(colonnes);
const int persiste = 2; //  délai d'affichage en millisecondes
const int delai_defaut = 1; // calcul la frame de l'animation toutes les x frames (à toutes les frames par défaut)
const char colonne[] = {5, 6, 10, 4, 8, 7, 9, 2, 3}; // défini les 9 PINS colonnes (+)
const char etage[] = {A1, A2, A3, A5, A4, 0, 1}; // défini les 7 PINS étages (-)
const int serpent_tour[8] = {0,1,2,5,8,7,6,3};
// VARIABLES
unsigned long last_millis = millis(); // sert à définir à quelle frame nous sommes
unsigned long programme_millis = millis(); // gère le temps pour permettre de changer d'animation
int programme_count = 0; // numéro en cours du programme
int programme_delai = 10; // durée en seconde d'une animation
int frame = 0;
int niveau = 0;
int led = 0;
bool grille[etages][colonnes] = { {0,0,0, 0,0,0, 0,0,0} };
// VARIABLES EFFETS (correspond au variables pouvant être utilisées par les différentes fonctions)
int var_init = 0; // initialisation de l'effet
int var_tmp = 0;
int var_rnd = 0;
int var_etage = 0;
int var_1 = 0;
int var_2 = 0;
int var_3 = 0;
int var_y1 = 0;
int var_y2 = 0;
int var_y3 = 0;
int var_colonne = 0;
int var_frame = 0;
int var_delai = 1;
int var_delai_count = 0;
int var_array[5];
int var_array8[8];
int var_array9[9];
int var_colonnes[cote];
int var_etages[cote];
int var_direction;


Les 3 fonctions principales qui seront utilisées pour modifier l'état des LED :

// ------------------------------------- etage (traite l'état des étages)
void etage_maj (int num = -1, bool etat = 0) { // étage à dés/activer (defaut rien), etat (defaut désactive)
    if (num > -1) // s'il y a un étage à activer
        digitalWrite(etage[num], etat == 1 ? LOW : HIGH); // dés/active l'étage
    else { // sinon
        for (int e = 0; e < etages; e++) { // désactive tous les étages
            digitalWrite(etage[e], HIGH);
            }
        }
    };
// ------------------------------------- de même pour les colonne
void colonne_maj (int num = -1, bool etat = 0) {
    if (num > -1)
            digitalWrite(colonne[num], etat == 1 ? HIGH : LOW); // inverse
    else {
        for (int c = 0; c < colonnes; c++) {
            digitalWrite(colonne[c], LOW);
            }
        }
    };
// ------------------------------------- active les leds pour afficher la frame, traitement par ETAGE
void affiche_frame () {
for (int e = 0; e < etages; e++) { // sur 7 étages (0-6)
    etage_maj(e, 1); // allumer l'étage e
    for (int c = 0; c < colonnes; c++) { // pour les 9 colonnes
        if (grille[e][c] == 1) { // si l'une est à activer
            colonne_maj(c, 1); // allume la colonne c
            }
        }
        delay(persiste); // pause persistance rétinienne
        etage_maj(e); // eteindre l'étage e
        for (int c = 0; c < colonnes; c++) { // désactive toutes les colonnes
                colonne_maj(c);
            }
        }
    };


Le Setup qui se contente d'initialiser et désactiver l'état de toutes les LED :

void setup () {
    for (int e = 0; e < etages; e++) {
        pinMode(etage[e], OUTPUT); // initialise chaque étage (-) 0 à 6
        etage_maj(e); // désactive
        }
    for (int c = 0; c < colonnes; c++) {
        pinMode(colonne[c], INPUT); // initialise chaque colonne (+) 0 à 8
        colonne_maj(c); // désactive
        }
    }


La boucle qui va activer telle ou telle fonction. Il s'agit en gros de la programmation des différentes animations :

void loop () {
    if (millis() - last_millis >= milli_fps) {
        if (millis() - programme_millis >= programme_delai * 1000) {
            programme_millis = millis();
            programme_count++;
            var_init = 0; // réinitialise la variable pour indiquer à la fonction si une nouvelle fonction commence ou si une fonction continue d'être traitée
            }
        switch(programme_count) { // programmation à moduler en fonction des envies
            case 0:
                programme_count = 7;
            break;
            case 7:
                programme_delai = 5; // change la durée d'affichage de l'animation en fonction de cette dernière. Peut être fixe ou aléatoire
                anim_etage(1, 1); // inverse
            break;
            case 8:
                programme_delai = 15;
                anim_sin(3);
            break;
            case 9:
                programme_delai = 5;
                anim_etage(2);
            break;
            case 10:                
                programme_delai = 10;
                anim_point_aleatoire(3, 2); // nombre de point alétoires
            break;
            case 11:
                programme_delai = 5;
                anim_point_aleatoire(1, 5);    
            break;
            case 12:
                programme_delai = 10;
                anim_point_aleatoire(10, 18);    
            break;
            case 13:
                programme_delai = 7;
                anim_empli_rand(1, 0);
            break;
            case 14:
                programme_delai = 2;
                anim_vide_rand(1);
            break;
            case 15:
                anim_empli_rand(1, 0); // 0 = ne vide pas le contenu au départ
            break;
            case 16:
                anim_vide_rand(1);
            break;
            case 17:
                anim_empli_rand(1, 0);
            break;
            case 18:
                programme_delai = 7;
                anim_vide_rand(1);
            break;
            case 19:
                programme_count++;
            break;
            case 20:
                programme_delai = 10;
                anim_rand_haut_bas(3);
            break;
            case 21:
                anim_point_aleatoire(1, 5);    
            break;
            case 22:
                programme_delai = 5;
                anim_tourne(3, 3); //    3 colonnes
            break;
            case 23:
                programme_count++;
            break;
            case 24:
                programme_delai = 10;
                anim_pluie(2); // de bas en haut                
            break;
            case 25:
                programme_delai = 15;
                anim_points_haut_bas(1);
            break;
            case 26:
                programme_delai = 5;
                anim_clignote_plein_vide(10);
            break;
            default:
                programme_delai = 10;
                programme_count = 0;
            }
        var_frame++; // frame suivante
        if (var_frame >= fps) // dernière frame
            var_frame = 0; // revient à la première
        last_millis = millis(); // raffraichit time pour la prochaine frame
        }
    affiche_frame(); // à toutes les boucles, active, désactive sans cesse les leds de la frame (array grille)
    }


Enfin, les différentes fonctions d'animations avec une petite description pour chacune. La variable delai indique le temps d'affichage d'une frame de l'animation en fonction des frames à afficher par seconde (par défaut à 2, soit 5 par seconde)


Fait clignoter l'ensemble des LED, jour, nuit, jour, nuit... :

void anim_clignote_plein_vide (int delai = delai_defaut) {
    
    if (var_init == 0) {
        var_init = 1;
        var_delai = delai;
        var_delai_count = 0;
        var_1 = 0;
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = {0};
                }
            }
        }
        
    if (var_delai_count >= var_delai) {
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = var_1 == 1 ? 1 : 0; // active ou desactive
                }
            }
        var_1 = var_1 == 1 ? 0 : 1; // change var plein -> vide, vide -> plein pour next
        var_delai_count = 0; // remet à zéro, fin du code joué toutes les x frames
        }
    
    var_delai_count++;
    };


Eclaire une étage à la fois de haut en bas, ou inversement :

void anim_etage (int delai = delai_defaut, bool inverse = 0) {
    
    if (var_init == 0) {
        var_init = 1;
        var_etage = 0;
        if (inverse == 1)
            var_etage = colonnes-1;
        var_delai = delai;
        var_delai_count = 0;
        }
        
    if (var_delai_count >= var_delai) {
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = 0; // désactive
                }
            }
        for (int c = 0; c < colonnes; c++) {
            grille[var_etage][c] = 1; // active toutes
            }
        if (inverse == 1)
            var_etage--;
        else
            var_etage++; // étage suivant (vers le bas)
        
        if (inverse == 0 && var_etage >= etages) {
            var_etage = 0; // boucle l'animation
            }
        else if (inverse == 1 && var_etage < 0) {
            var_etage = colonnes-1;
            }
        var_delai_count = 0;
        }
    var_delai_count++;

    };


Neuf points se déplacent aléatoirement et tour à tour de haut en bas :

void anim_points_haut_bas (int delai = delai_defaut) {

    if (var_init == 0) {
        var_init = 1;
        var_etage = var_colonne = var_direction = 0;
        var_delai = delai;
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = 0;
                }
            }
        for (int c = 0; c < colonnes; c++) {
            var_1 = random(0, 2);
            var_1 = var_1 == 1 ? etages-1 : 0; // si 1, etage max
            var_array9[c] = var_1; // renseigne l'étage de la colonne 0 (haut) ou 6 (bas)
            grille[var_1][c] = 1; // met à jour la grille
            }
        }
        
    if (var_delai_count >= var_delai) {
        if (var_direction == 0) { // 0 = pas de déplacement de point en cours
            var_colonne = random(0, colonnes); // choisi une des 9 colonnes
            var_etage = var_array9[var_colonne]; // récupère son étage
            var_direction = var_etage == 0 ? 1 : -1; // 1 descend, -1 monte en conséquence
            }
        else { // sinon, déplace -1 bas ou +1 haut
            grille[var_etage][var_colonne] = 0; // eteint la précédente
            if (var_etage+var_direction >= 0 && var_etage+var_direction <= etages-1) { // s'il peut encore se déplacer
                var_etage += var_direction; // passe à 'étage suivant
                var_array9[var_colonne] = var_etage; // change l'étage du point fini d'etre déplacé 0 haut ou 6 bas
                }
            else // sinon, arrivé tout en bas/haut
                var_direction = 0; // remet à zéro pour passer à un autre point
            grille[var_etage][var_colonne] = 1; // allume la suivante (ou rallume la derniere si au bout)
            }
        var_delai_count = 0;
        }
    
    var_delai_count++;
    };


Trois points se suivent et se déplacent alétoirement le long des colonnes extérieures à la manière du fameux jeu Nokia Snake :

void anim_serpent (int delai = delai_defaut) {

    if (var_init == 0) {
        var_init = 1;
        var_delai = delai;
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = 0;
                }
            }
        var_tmp = random(0, colonnes); // un point au hasard
        var_3 = var_2 = var_1 = var_tmp;
        var_y3 = var_y2 = var_y1 = random(0, etages);        
        var_direction = random(1, 5);
        }

    if (var_delai_count >= var_delai) {
        var_rnd = random(0, 4); // 1 fois sur 4
        if (var_rnd == 0) {
            var_tmp = random(1, 5); // direction random
            if ((var_tmp - 2 != var_direction) || (var_tmp + 2 != var_direction)) { // vérifie qu'il ne s'agit pas d'un demi-tour
                var_direction = var_tmp;
                }
            }
        grille[var_y3][serpent_tour[var_3]] = grille[var_y2][serpent_tour[var_2]] = grille[var_y1][serpent_tour[var_1]] = 0;
        var_3 = var_2;
        var_2 = var_1;
        var_y3 = var_y2;
        var_y2 = var_y1;
        if (var_direction == 1) {
            var_tmp--;
            if (var_tmp < 0)
                var_tmp = 7;
            var_1 = var_tmp;
            }
        else if (var_direction == 3) {
            var_tmp++;
            if (var_tmp > 7)
                var_tmp = 0;
            var_1 = var_tmp;
            }
        else if (var_direction == 2) { // étage haut
            var_y1--;
            if (var_y1 < 0)
                var_y1 = etages - 1;
            }
        else if (var_direction == 4) { // étage bas
            var_y1++;
            if (var_y1 >= etages)
                var_y1 = 0;
            }
        grille[var_y3][serpent_tour[var_3]] = grille[var_y2][serpent_tour[var_2]] = grille[var_y1][serpent_tour[var_1]] = 1;
        var_delai_count = 0;
        }
    
    var_delai_count++;
    };


Des points apparaissent alétoirement et tombent tour à tour comme une pluie :

void anim_pluie (int delai = delai_defaut, bool inverse = 0) {
    
    if (var_init == 0) {
        var_init = 1;
        var_etage = var_colonne = var_direction = 0;
        var_delai = delai;
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = 0;
                var_array9[c] = 0;
                if (inverse == 1)
                    var_array9[c] = etages-1;
                }
            }
        }
        
    if (var_delai_count >= var_delai) {
        if (var_direction == 0) {
            var_colonne = random(0, colonnes);
            var_etage = var_array9[var_colonne];
            var_direction = 1;
            if (inverse == 1)
                var_direction = -1;    
            grille[var_etage][var_colonne] = 1;
            }
        else {
                grille[var_etage][var_colonne] = 0;    
            if (var_etage+var_direction >= 0 && var_etage+var_direction <= etages-1) {
                var_etage += var_direction;
                grille[var_etage][var_colonne] = 1;    
                }
            else
                var_direction = 0;
            }
        var_delai_count = 0;
        }
    
    var_delai_count++;
    };


Une à plusieurs colonnes extérieurs s'allument en tournant :

void anim_tourne (int delai = delai_defaut, int longueur = 1) {
    
    if (var_init == 0) {
        var_init = 1;
        var_delai = delai;
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = 0;
                }
            }
        var_1 = 0; // premiere sequence relative à serpent_tour
        var_2 = 1;
        var_3 = 2;
        }
    
    if (var_delai_count >= var_delai) {
        for (int e = 0; e < etages; e++) {
            grille[e][serpent_tour[var_1]] = 0;
            if (longueur > 1)
                grille[e][serpent_tour[var_2]] = 0;
            else if (longueur > 2)
                grille[e][serpent_tour[var_3]] = 0;
            }
        var_1++;
        if (var_1 > 7) // si dépasse array8
            var_1 = 0;
        var_2++;
        if (var_2 > 7)
            var_2 = 0;
        var_3++;
        if (var_3 > 7)
            var_3 = 0;
        for (int e = 0; e < etages; e++) {
            grille[e][serpent_tour[var_1]] = 1;
            if (longueur > 1)
                grille[e][serpent_tour[var_2]] = 1;
            else if (longueur > 2)
                grille[e][serpent_tour[var_3]] = 1;
            }        
        var_delai_count = 0;
        }
    
    var_delai_count++;
    };


Allume des LED aléatoirement :

void anim_empli_rand (int delai = delai_defaut, bool vide = 1) {
    
    if (var_init == 0) {
        var_init = 1;
        var_delai = delai;
        if (vide == 1) {
            for (int e = 0; e < etages; e++) {
                for (int c = 0; c < colonnes; c++) {
                    grille[e][c] = 0;
                    }
                }
            }
        }
    
    if (var_delai_count >= var_delai) {
        grille[random(0, etages)][random(0, colonnes)] = 1;
        var_delai_count = 0;
        }
    
    var_delai_count++;
    };


Eteint des LED aléatoirement :

void anim_vide_rand (int delai = delai_defaut) {
    
    if (var_delai_count >= var_delai) {
        grille[random(0, etages)][random(0, colonnes)] = var_delai_count = 0;
        }
        
    var_delai_count++;
    };


Effet de pluie :

void anim_rand_haut_bas (int delai = delai_defaut) {
    
    if (var_init == 0) {
        var_init = 1;
        var_etage = var_colonne = var_direction = 0;
        var_delai = delai;
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = var_array9[c] = 0;
                }
            }
        }

    if (var_delai_count >= var_delai) {
        for (int e = etages-1; e >= 0; e--) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = e == 0 ? 0 : grille[e-1][c]; // déplace vers le bas
                }
            }
        grille[0][random(0, colonnes)] = 1;
        var_delai_count = 0;
        }
    var_delai_count++;
    
    };


Effet de vague diagonale défilante :

void anim_sin (int delai = delai_defaut) {
    
    if (var_init == 0) {
        var_init = 1;
        var_etage = var_colonne = var_direction = 0;
        var_delai = delai;
        
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = var_array9[c] = 0;
                }
            }
        var_1 = 0; // etapes
        }
    
    if (var_delai_count >= var_delai) {
        for (int e = etages-1; e >= 0; e--) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = e == 0 ? 0 : grille[e-1][c];
                }
            }
        for (int c = 0; c < colonnes; c++) {
                grille[0][c] = 0;
                }
        switch(var_1) {
            case 0: case 8:
                grille[0][0] = 1;
            break;
            case 1: case 7:
                grille[0][1] = grille[0][3] = 1;
            break;
            case 2: case 6:
                grille[0][2] = grille[0][4] = grille[0][6] = 1;
            break;
            case 3: case 5:
                grille[0][5] = grille[0][7] = 1;
            break;
            case 4:
                grille[0][8] = 1;
            break;
            default:
                var_1 = 0;
            }
        var_1++;
        if (var_1 >= 8)
            var_1 = 0;
            
        var_delai_count = 0;
        }
    var_delai_count++;
    };


Allume et éteint une ou plusieurs LED aléatoirement :

void anim_point_aleatoire (int delai = delai_defaut, int nombre = 1) {
    
    if (var_init == 0) {
        var_init = 1;
        var_delai = delai;
        }
    
    if (var_delai_count >= var_delai) {
        for (int e = 0; e < etages; e++) {
            for (int c = 0; c < colonnes; c++) {
                grille[e][c] = 0;
                }
            }
        for (int e = 0; e < nombre; e++) {
            grille[random(0, etages)][random(0, colonnes)] = 1;
            }
        var_delai_count = 0;
        }
    
    var_delai_count++;
    }


Beaucoup d'autres animations sont possibles (tetris, lettrage, effets de scintillement en jouant sur la durée d'affichage etc), mais c'est déjà une base suffisante pour commencer à égayer vos apéros !

Télécharger le code commenté


Et pour conclure, une vidéo en situation réelle avec la programmation en Loop, qui permet de visualiser le comportement des différentes fonctions :

Voila pour ce premier projet qui a été mené à terme et sans trop d'accroc.

Pour le prochain, je souhaite m'attaquer à un coin pusher, dit pousse-pièce ou cascade ou plus vulgairement : une machine à sous de forain, mais de comptoir et toujours original.
Projet qui fera certainement l'objet de plusieurs articles s'il se concrétise... à suivre !

 

Partie 1 : Le prototype
Partie 2 : Le premier modèle
Partie 3 : Le code (vous êtes ici)