I'm back :-)

Mon dernier article remonte à février... D'ailleurs la réparation du Macbook de mon frère fonctionne toujours !

Entre temps, j'ai beaucoup été pris par le boulot, et par Atlantronic, mon équipe participant à la Coupe de France de robotique. Cette année, nous remettons le couvert pour une nouvelle participation, ma cinquième :-)

Sinon j'ai beaucoup de projets personnels plus ou moins avancés (dont mon horloge binaire à qui j'ai fait un beau boîtier), donc potentiellement plein d'articles à écrire. Encore une fois, il faut que je trouve le temps de faire tout ça, mais je ne désespère pas !

Démarrer un Macbook Unibody sans clavier

Récemment mon frère a renversé du Coca sur son Macbook Unibody, ce qui est peu recommandé. Le problème est que son clavier fonctionnait toujours, mais par intermittence, et parfois même des touches se "tapaient" toutes seules. Il existe deux solutions pour résoudre le problème :

  • Celle du riche fainéant : faire remplacer le clavier par Apple (200€)
  • Celle du pauvre, pardon de l'étudiant curieux : acheter un clavier externe (20 €) et déconnecter l'interne.

Le problème de la seconde solution, c'est que ça ne résout pas le problème des frappes intempestives sur clavier interne. Une solution facile est de déconnecter physiquement le clavier de la carte mère, et pour cela j'ai fait confiance un très célèbre site iFixit, spécialiste des réparations de produits Apple. La manipulation est décrite dans l'étape 15 de l'article de ce lien.

Le gros soucis, c'est que le bouton de mise en marche est justement relié par ce connecteur ! Qu'à cela ne tienne, j'ai donc cherché des les recoins d'internet et je suis tombé sur ce forum ou quelqu'un décrit quels sont les pins à relier ensemble pour simuler un appui sur le bouton.

Pour pouvoir allumer le Macbook sans le clavier, il suffit dont de faire contact entre les pins 5 et 29 du connecteur du clavier. Pour éviter d'avoir à ouvrir le portable pour chaque mise en route, j'ai donc soudé deux petits câbles, maintenus par un bon coup de pisto-colle, que j'ai fait sortir par la grille de ventilation arrière, et le tour est joué !

{filename}../images/macbook_inside.jpg

Et démarrer son Macbook à la MacGyver, ça n'a pas de prix !

{filename}../images/macbook_outside.jpg

(J'ai pensé à protéger un peu les contacts pour ne pas que la machine ne démarre ou s'arrête toute seule...)

Capteur de température DS1631 et Arduino

Le DS1631 est un capteur de température, et est disponible en sample sur le site de Maxim, le fabriquant. Ce capteur s'interface facilement avec l'Arduino avec une liaison I2C. Il retourne une température avec une précision réglable allant jusqu'au 1/16ème de degré.

{filename}../images/DS1631.png

Diagramme du DS1631

Ci-dessous un exemple de cablage avec l'Arduino, sachant qu'on peut choisir une partie de l'adresse I2C avec les pins A0, A1, A2 ce qui peut s'avérer pratique pour gérer plusieurs capteurs en même temps.

{filename}../images/DS1631_Arduino.png

Branchement du DS1631 avec l'Arduino

Et voici le code permettant de lire puis d'afficher la température sur à l'aide d'une liaison série sur mon Minitel.

/*
 * DS1631 Temperature sensor
 * www.peyregne.info
*/

#include

// Adress pins of the DS1631 device
// 0 if pin connected to GND, 1 to VDD

#define DS1631_A0 0
#define DS1631_A1 0
#define DS1631_A2 0

#define DS1631_CFG_R1     1  // resolution 9 to 12 bits
#define DS1631_CFG_R0     1  // set to 12 bits (750ms conversion time)
#define DS1631_CFG_POL    0  // T_OUT polarity (1=active high, 0=active low)
#define DS1631_CFG_1SHOT  1  // Conversion mode (1=one shot mode, 0=continuous mode)

// Do not change the following definitions

#define DS1631_ADDR (0x48 | DS1631_A2<<2 | DS1631_A1<<1 | DS1631_A0)

#define DS1631_CFG (DS1631_CFG_R1 << 3 \
                    | DS1631_CFG_R0 << 2 \
                    | DS1631_CFG_POL << 1 \
                    | DS1631_CFG_1SHOT)

#define DS1631_DONE_MASK 0x80;

void setup()
{
  // Opening I2C interface as Master
  Wire.begin();

  // First, stop the conversion (if configured in continuous
  // conversion mode) to access the configuration register.
  Wire.beginTransmission(DS1631_ADDR);
  Wire.send(0x22); // Stop conversion
  Wire.endTransmission();

  // Configuration of DS1631 (see Datasheet)
  Wire.beginTransmission(DS1631_ADDR);
  Wire.send(0xAC); // Access Configuration
  Wire.send(DS1631_CFG);
  Wire.endTransmission();

#if DS1631_CFG_1SHOT == 0
  // If continuous mode is set, start continuous conversion
  Wire.beginTransmission(DS1631_ADDR);
  Wire.send(0x51);
  Wire.endTransmission();
  delay(750); // delay to be sure that the first value is correct
#endif

  UCSR0C = B00100100; // passage en mode 7bits + bit de parité
  Serial.begin(1200);
  Serial.print(12,BYTE);
}


void loop()
{
  float t = 0.0;
  t = readTempOne(DS1631_CFG_1SHOT);
  Serial.print(12,BYTE);
  Serial.print(10,BYTE);
  Serial.print(13,BYTE);
  Serial.print("Temperature : ");
  Serial.print(t,4);
  Serial.print(" degres");

  delay(10000); // wait 10 seconds
}

float readTempOne(boolean oneShotMode)
{
  float temp = 0.0;

  if (oneShotMode)
  {
    // Temperature conversion request
    Wire.beginTransmission(DS1631_ADDR);
    Wire.send(0x51);
    Wire.endTransmission();

    delay(750); // delay for 12 bits precision

    // Now we wait the end of the conversion
    boolean tempAvailable = false;
    while (!tempAvailable)
    {
      // See if the conversion is finished
      // in the configuration byte
      Wire.beginTransmission(DS1631_ADDR);
      Wire.send(0xAC);
      Wire.endTransmission();
      Wire.requestFrom(DS1631_ADDR,1);
      Wire.available();
      tempAvailable = Wire.receive() & DS1631_DONE_MASK;
      delay(10);
    }
  }

  // read result
  Wire.beginTransmission(DS1631_ADDR);
  Wire.send(0xAA); // read last conversion
  Wire.endTransmission();
  Wire.requestFrom(DS1631_ADDR,2);
  Wire.available();
  int tempMS = (int) Wire.receive();
  Wire.available();
  int tempLS = (int) Wire.receive();

  tempLS >>= 4; // last 4 bits are always 0

  if (tempMS & 0x80) // if the signed bit = 1
    tempMS -= 256;

  // Float conversion
  temp = (float) (tempMS + tempLS*0.0625);

  return temp;
}
{filename}../images/photo_ds1631.jpg

Le programme en action

Chargement du .bashrc avec MacOS

Voici une petite astuce qui pourrait aider des personnes sur MacOS. En effet je lis souvent sur les forums que le .bashrc n'est pas pris en compte en lançant Terminal par exemple.

En fait, quand on lance un terminal, on accède au shell d'accès, qui n'est pas personnalisé. Pour faire simple, le .bashrc, .profile, etc. ne sont pas chargés. On va alors forcer le chargement de ces fichiers à l'ouverture d'un terminal.

Au lancement d'un shell, le fichier .bash_profile qui est situé à la racine du dossier personnel est lu (s'il existe). Il suffit donc dans ce fichier de dire qu'on souhaite charger le .bashrc avec la commande source (ou ".").

Voici à quoi doit ressemble le .bash_profile pour résoudre la problème (créer le fichier à la racine de votre répertoire personnel si ce n'est déjà fait) :

#!/bin/bash
clear
source ~/.profile
source ~/.bashrc

Maintenant, à chaque lancement du terminal, votre .bahrc et autres fichiers seront correctement pris en compte.

Diff via SSH avec vimdiff

J'ai souvent besoin de comparer des fichiers similaires situés sur des machines différentes. Plutôt que de copier les fichiers en local puis de faire un traditionnel diff (ou vimdiff pour les durs), j'utilise vimdiff qui permet d'ouvrir directement des fichiers via SSH avec le protocole SCP, de les modifier et de les sauver sur la cible :

$ vimdiff scp://user1@host1//chemin/fichier scp://user2@host2//chemin/fichier

Voici les commandes les plus utiles :

  • do pour obtenir la version de l'autre fichier de la

    modification courante,

  • dp pour propager la version à l'autre fichier,

  • ]c pour aller à la différence suivante,

  • [c pour aller à la différence précédente,

  • ctrl + w deux fois pour changer de fichier.

Pour finir, j'ai mappé les commandes ]c et [c qui sont très peu ergonomiques, en rajoutant ces lignes dans mon .vimrc :

nmap  ]c
nmap  [c
{filename}../images/vimdiff.png

Sources : Wiki vim, aide vimdiff