Microblog : A very long article Wikipedia article on the orientation of toilet paper [7 jun à 22:52] [R]

Lundi, 10 décembre 2012

Ugly Ruby

Traduction: [ Google | Babelfish ]

Catégories : [ Informatique ]

A few months ago, I started to use ruby for work. Twice I burnt my fingers on the following behaviour in Ruby:

def foo
  "bar"
end
 
puts "foo = #{foo.inspect}"
 
if foo.nil?
  foo = "quux"
  puts "Not coming here"
end
 
puts "foo = #{foo.inspect}"
The method foo returns the string "bar", which is therefore not nil. The result any sane coder expects would be
foo = "bar"
foo = "bar"
What actually comes out when you run this snippet is
foo = "bar"
foo = nil

I remember reading that in order to decide whether foo is a call to the foo method or the use of the local variable foo, Ruby checks the code before for any assignment to foo. As it happens, the local variable foo gets assigned inside the if clause, but the statement is never executed. My guess is that Ruby then decides that the local variable foo is put to use after the if clause, but is never actually assigned to, and therefore its value is nil. As it happens, the foo method still exists and returns "bar", as expected, when called as foo().

[ Posté le 10 décembre 2012 à 22:30 | pas de commentaire | ]

Samedi, 16 juin 2012

Faut-il courir sous la pluie ?

Catégories : [ Science ]

diagramme_pluie

Est-on moins mouillé si on court sous la pluie au lieu de marcher ? En modélisant un piéton comme un parallélépipède rectangle de hauteur h et d'épaisseur l, et en notant vm la vitesse du piéton et vp la vitesse de chute de la pluie, on obtient une vitesse v de la pluie relativement au piéton. Le vecteur vitesse fait un angle a avec la verticale. On peut alors calculer que la projection de la surface frontale du piéton dans la direction de ce vecteur est Sh, et la projection correspondant à la surface supérieur est Sl. Le produit de ces surfaces avec la vitesse de la pluie donne le débit d'eau, et si on multiple par le temps mis pour parcourir un trajet d'une longueur donnée d sous la pluie, on obtient le volume d'eau qui s'est déversé sur le piéton. Le détails des calculs est laissé en exercice au lecteur, mais le résultat est V = d(h + l vp / vm).

En conséquence, pour minimiser le volume d'eau V, il faut maximiser que vm / vp >> l / h. Si on considère un piéton de 1,80 m de hauteur et 0,3 m d'épaisseur, il faut que la vitesse du piéton soit plus grande que 1/6 vp. Diverses sources sur le Web ont indiqué que la vitesse de la pluie en arrivant près du sol est d'environ 9 m/s, il faut donc que le piéton se déplace à plus de 1,5 m/s, soit 5,4 km/h.

[ Posté le 16 juin 2012 à 18:35 | pas de commentaire | ]

Mardi, 15 mai 2012

E-mail Git Patches

Traduction: [ Google | Babelfish ]

Catégories : [ Informatique/Git ]

This is, in a nutshell, how to send commits to the (single) maintainer of a project by e-mail.

Add the maintainer's e-mail address to the repository's config:
git config --set sendemail.to "John Smith <john.smith@example.com>"
Make a set of patches from the commits e.g.,
git format-patch HEADˆ
or
git format-patch origin/master..master

Send the patches by e-mail:

git send-email *.patch
(this sends one e-mail per patch).

On the receiving side, the maintainer can then feed the content of each e-mail into git am to apply the patches and record new commits.

The git send-email command is packaged separately in Debian, the package git-email needs to be installed.

This post is based on this page from the Chromium project.

[ Posté le 15 mai 2012 à 19:47 | pas de commentaire | ]

Lundi, 14 mai 2012

More Git Recipes

Traduction: [ Google | Babelfish ]

Catégories : [ Informatique/Git ]

Resolve a binary file conflict with Git

Found on lostechies.com

In case of conflict with a binary file during a merge, you have two choices for resolving it:

  • Use your own version:
    git add thefile
  • Use the other version:
    git checkout --theirs -- thefile; git add thefile

Then commit the changes.

Show the content of a deleted file

Found on stackoverflow.com

git show commitid:path/to/file

The trick here is that one must use the full path to the file (relatively to the repository's root)

Restore a deleted file in a Git repo

Found on stackoverflow.com

Find the last commit where the file was deleted:
git rev-list -n 1 HEAD -- thefile
Then checkout the file from the commit before that:
git checkout commitid -- thefile

[ Posté le 14 mai 2012 à 13:39 | pas de commentaire | ]

Mercredi, 9 mai 2012

Super Mario Dice

Catégories : [ Jeux ]

super_mario_dice-all

Je me suis récemment intéressé aux jeux de dés, et j'ai découvert Zombie Dice. Le principe est très simple, le jeu est rapide, mais le thème ne me plaisait pas. Alors j'ai décidé de changer le thème en Super Mario. J'avais d'abord songé au Super Mario Bros. original tournant sur NES, mais je trouvais les graphismes de la réédition pour SNES (Super Mario All Stars) nettement plus beaux, et donc j'ai repris les graphiques de cette version là.

super_mario_dice-dice

Les dés viennent de blankdice.co.uk, chez qui j'ai déjà acheté un certain nombre de dés. Les faces ont un léger creux, qui permettent de coller un autocollant carré de 14,5 mm de coté. J'ai imprimé sur un autocollant au format A4 et découpé les carrés avec un cutter rotatif sans trop appuyer, ce qui permet de couper l'autocollant sans couper le papier-support et donc de décoller les petits autocollants bien plus facilement.

super_mario_dice-track

Zombie Dice est vendu sous blister et ne comprend qu'un gros gobelet et 13 dés. Il nécessite quelque chose pour marquer le score (papier/crayon, jetons…) J'ai donc fabriqué une piste pliante de 13 cases plus une case départ, encore une fois en imprimant sur un autocollant A4. À la place du gobelet, je vais fabriquer un sac en tissu, assez grand pour contenir tous les composants (il reste à trouver le tissu).

Une amie m'a proposé de fabriquer des pions en forme de personnages de Super Mario en échange de quoi je lui fabrique quelques copies du jeu. On verra ce que ça donne.

[ Posté le 9 mai 2012 à 18:28 | 2 commentaires | ]

Samedi, 24 mars 2012

Task-Based JeeNode Communication

Traduction: [ Google | Babelfish ]

Catégories : [ Bricolage/Arduino | Informatique ]

For my car heater controller I decided to use Alan Burlison's scheduler. I like it, because it leaves the main program file reasonnably short and allows to separate the code into multiple objects. I don't know if it makes the software more or less easy to write/maintain, but I find it fun to do it this way, and that's all that counts.

To implement 2-way communication between the JeeLink (master) and the JeeNode (slave) using Jean-Claude Wippler's RF12 library, I created a Listener object and a Speaker object that deal with receiving data and sending data respectively, while the Protocol object implements the higher-level protocol.

Here' how the slave's .pde file looks like. Notice how it contains only definitions and a bit of initialization, but no big mess of code?

#define NB_ELEMENTS(a) sizeof(a) / sizeof(a[0])
 
Speaker speaker;
Protocol protocol(&speaker);
Listener listener(&protocol);
 
Task * tasks[] = { &listener, &speaker };
TaskScheduler scheduler(tasks, NB_ELEMENTS(tasks));
 
void setup() {
  rf12_initialize(SLAVE_ID, RF12_868MHZ, HEATER_GROUP);
}
 
void loop() {
  scheduler.run(); // infinite loop
}
Here's a sample of the slave's Listener.
class Listener: public Task { // Task from Alan Burlison's scheduler
    public:
    Listener(Protocol * protocol):
      protocol(protocol)
      {};
 
    bool canRun(uint32_t now); // Taks's interface
    void run(uint32_t now);    // Task's interface
 
  private:
    Protocol * protocol;    // higher-level protocol handler
    uint8_t recv_buffer[BUFFER_LEN];
    uint8_t recv_buffer_len;
};
 
bool Listener::canRun(uint32_t now) {
  if (rf12_recvDone())
    return (rf12_crc == 0 &&  rf12_len <= BUFFER_LEN);
  return false;
}
 
void Listener::run(uint32_t now) {
  recv_buffer_len = rf12_len;
  memcpy((void *)recv_buffer, (void *)rf12_data, recv_buffer_len);
  if (rf12_hdr == (RF12_HDR_CTL | (MASTER_ID & RF12_HDR_MASK)))
    protocol->got_ack();
  else {
    if (RF12_WANTS_ACK) {
      rf12_sendStart(RF12_ACK_REPLY, 0, 0);
      rf12_sendWait(0);
    }
    protocol->handle(recv_buffer, recv_buffer_len);
  }
}

And there's the slave's Speaker. Note that the Spaker tries to send data only if its buffer_len is greater than zero. This prevents calling rf12_canSend() when it's not necessary (according to the RF12 driver, you must not call rf12_canSend() only if you intend to send data immediately after calling it). When the Protocol wants to send something, it needs to get the Speaker's buffer with get_buffer(), fill the buffer with data, and then call send(). Also, I implemented a retry mechanism in case no ACK has been received from the master.

class Speaker: public Task { // Task from Alan Burlison's scheduler
  public:
    Speaker();
    uint8_t* get_buffer();
    void send(uint8_t len, bool ack);
    void got_ack(); // called by the Protocol when it gets an ACK
    bool canRun(uint32_t now);  // Task interface
    void run(uint32_t now);     // Task interface
 
  private:
    uint8_t buffer[BUFFER_LEN];
    uint8_t buffer_len;
    bool with_ack;
    uint8_t retry_count;
    unsigned long next_retry_millis;
};
 
bool Speaker::canRun(uint32_t now) {
  if (buffer_len > 0 && retry_count > 0
                     && millis() > next_retry_millis)
    return rf12_canSend();
  return false;
}
 
void Speaker::run(uint32_t now) {
  if (with_ack && retry_count == 1) {
    buffer_len = 0;
  }
  uint8_t header = (with_ack ? RF12_HDR_ACK : 0)
                  | RF12_HDR_DST | MASTER_ID;
  rf12_sendStart(header, buffer, buffer_len);
  rf12_sendWait(0);
  if (with_ack) {
    retry_count  – ;
    next_retry_millis = millis() + SEND_RETRY_TIMEOUT;
  }
  else
    buffer_len = 0;
}
 
void Speaker::send(uint8_t len, bool ack) {
  with_ack = ack;
  buffer_len = len;
  retry_count = SEND_RETRY_COUNT + 1;
  next_retry_millis = millis();
}
 
void Speaker::got_ack() {
  buffer_len = 0;
}

The master's code is very similar, you can check it there.

[ Posté le 24 mars 2012 à 16:17 | pas de commentaire | ]

Jeudi, 22 mars 2012

Car Heater Controller

Traduction: [ Google | Babelfish ]

Catégories : [ Bricolage/Arduino ]

heater_controller_2

Finnish winters are cold, and petrol engines don't like starting when it's very cold. That's why cars are often equipped with an electric heater that preheat's the cooling liquid for some time before starting the engine. The duration of this pre-heating depends on the temperature (in French). Moreover, since I don't leave home every morning at the same time, I don't want to start heating the car at the same time every day, even if the outside temperature doesn't change much from day to day. Hence this project of a remote-controlled switch for the car heater.

The system is composed of two Arduino-compatible parts: one master, connected to the home computer (always on), and one slave, in the garage. The master is a JeeLink and the slave is based on a JeeNode. Master and slave communicate with each other with a radio (868 MHz, a free Low-power_communication_device band in Europe).

The master

Not much to say about the master, the hardware is a standard JeeLink, which for the purpose of this project is really only a radio transceiver on a Serial-over-USB interface.

The slave

heater_controller_1

The electronic is very simple, and only a few components are needed. I paid special attention to selecting components that are specified to work from -40 °C (although I have no idea how well the device works at that temperature).

The slave is organised around a JeeNode (vertical, in the right-hand corner of the picture), and has the following three features.

It controls a relay (the black box above the orange PCB on the picture), which can be open or closed.

It measures the outside temperature with a DS18S20 sensor.

It measures the current flowing out of the relay using a current transformer (the black ring aroung the brown wire on the left side of the picture).

Moreover, it has a power supply (the black box on the lower left corner of the picture).

You can also notice that the mains cable (a 5 m, outdoors prolongation cord) has an earth wire that has not been severed. The live (brown) and neutral (blue) wires have been cut and connected to the relay. Power for the power supply is taken from the plug-side of the cable, before the relay (so it's always connected to the mains).

Power supply

The power comes from a compact switching power supply that converts 230 V AC into 12 V DC (maximum output power: 4 W). In case the power supply fails, the 1 A fuse (in the holder on the big red wire on the lower-left corner of the picture) should blow before the whole thing catches on fire. Also, although the power supply is designed to be placed on a PCB, I decided not to have any 230 VAC on the PCB, so I soldered the wires straight to its input pins, and isolated them with heat-shrink tube and added epoxy for strenght (the pins are not so strong, I don't want to break them once they are connected to the thick and not-so-flexible wires).

The relay requires 12 V, hence the output value for the power supply. The JeeNode requires a 3.3 V supply, and the onboard voltage regulator could take the 12 V, but would ouput only a low current (less than 100 mA). By adding a 5 V regulator (7805) to supply the JeeNode, the latter can get more current from its on-board regulator.

Relay

The relay (specified to switch up to 400 VAC and 30 A) requires 160 mA to be activated. It is therefore controlled via a BC337 transistor, which is strong enough to withstand the current. The base of the transistor is connected to one digital pin of the JeeNode via a 2 kΩ resistor, which allows to open or close the relay by applying a High or Low signal to that pin.

Temperature sensor
heater_controller_temperature_sensor

The DS18S20 transmits the temperture information digitally over a 1-Wire bus, and therefore requires really nothing more than a 4.7 kΩ pull-up resistor. It works quite happily with 3.3 V at the end of a 15 m cable (an old phone extension cord). Note that since I have three wires in the cable, I didn't even try to power the sensor with parasitic power (anyway, I read somewhere that it doesn't work well at 3.3 V). The Arduino OneWire library does all the work for you, all you need is to connect the data pin of the sensor to one digital input of the JeeNode.

Current sensor

Finally, the current transformer is placed around the live wire coming out of the relay. The design is based on a page at OpenEnergyMonitor that does not appear to exist anymore, but this one should give a good start.

Basically, the current transformer produces a current (not a voltage) that is proportional (depending on the number of turns, my transformer has 1012 turns) to the current flowing through the mains wire that goes through the transformer. A burden resistor (68 Ω in my case) across the two wires produces an AC voltage that is proportional to this current and varies between -1.65 and +1.65 V (corresponding to mains current between -23 and +23 A peak-to-peak). Then one wire of the transformer is connected to a voltage divider made of two 20 kΩ resistors (with a filtering 47 μF capacitor) and the other wire goes to one of the analog inputs of the JeeNode. This way, the analog input sees a voltage that varies between 0 and 3.3 V, which is within the tolerance of the device.

After that, the software samples the analog value 3000 times, applies a high-pass filter to remove the DC offset, and simple math computes the RMS current. After a bit of calibration (using a 60 W lamp, and 500 W halogen lamp, a 1400 W flat iron and a 2300 W electric kettle, and comparing my measurments against those of a wattmeter), I noticed that the reported current is quite accurate (to about 0.01 A, which is more than enough for my purposes).

Box
heater_controller_in_box

The PCB and the relay a screwed on a piece of plexiglas, and the whole device is placed in a project box to protect it from dust. Zip ties around the cables near the holes prevent the cables from being accidentally pulled out of the box.

Schematics
heater_controller

The schematics are available as a PNG picture, and in Eagle format. Note that since I used strip board to assemble the circuit, I haven't paid attention to choosing the right component packages, nor the right type of component. The Eagle schematics is therefore provided for information purposes only, generating a board from it is not going to produce correct results.

The Software

It's all available there. You can obtain it with git using the command
git clone http://weber.fi.eu.org/software/arduino/heater_controller/.git/

[ Posté le 22 mars 2012 à 23:23 | 1 commentaire | ]

Jeudi, 15 mars 2012

Very big, very small

Traduction: [ Google | Babelfish ]

Catégories : [ Science ]

Scaling the solar system down to human sizes leads to more interesting comparisons. Let's assume the Earth is the size of a pin head (2 mm in diameter). We then have the following results:

  • A human being living on the surface of the pinhead would be 0.30 nm (the size of two dihydrogen molecules)
  • Mount Everest would be 1.4 μm tall (1/5 of the thickness of a strand of spider's web silk)
  • Geostationary satellites would orbit the pin head at 5 mm from its surface but the International Space Station would be at only 60 μm from the surface (the thickness of a hair)
  • A lightyear would be 1500 km long (the distance between Copenhagen, Denmark and Rome, Italy), so the closest star (Proxima Centauri) would be 6600 km away (distance between Paris, France and New Dehli, India, or between New York, USA and Berlin, Germany)
  • The Oort cloud would be 3000 km in diameter (the distance between Madrid, Spain and Helsinki, Finland, with the volley ball representing the Sun located somewhere near Cologne, Germany)
  • The diameter of the Milky Way (our galaxy) would be equivalent to the distance between the Sun and Earth
  • The whole universe would be 20·1012 km in diameter, that is 2 lightyears (diameter of the Oort cloud, or half the distance to Proxima Centauri)

[ Posté le 15 mars 2012 à 10:06 | pas de commentaire | ]

Mercredi, 14 mars 2012

The Solar system is big!

Traduction: [ Google | Babelfish ]

Catégories : [ Science ]

http://www.aerospaceweb.org/question/astronomy/q0247.shtml

Aerospaceweb.org

The solar system is big, that's well known. But how big, exactly?

Let's assume the Sun is the size of a volleyball (about 21 cm in diameter). We would then have the following relative planet sizes and distances to the ball:

  • Mercury: 1 mm diameter (a small pin head), 9 m from the ball (a bus)
  • Venus: 2 mm diameter (a pin head), 16 m from the ball (a semi-trailer truck)
  • Earth: 2 mm diameter (a pin head), 23 m from the ball
  • Mars: 1 mm diameter (a small pin head), 35 m from the ball (a blue whale)
  • Jupiter: 22 mm diameter (a walnut), 120 m from the ball (maximum length of a football/soccer field)
  • Saturn: 19 mm diameter (a smaller walnut), 220 m from the ball (one TGV train)
  • Uranus: 8 mm diameter (a cherry's kernel), 460 m from the ball (a double TGV train)
  • Neptune: 8 mm diameter (a cherry's kernel), 700 m from the ball (length of the Avenue de l'opéra, Paris, France)

By comparison, the Moon would be 0.5 mm in diameter (a grain of sand) and 6 cm from the pin head (the length of the little finger).

[ Posté le 14 mars 2012 à 23:20 | pas de commentaire | ]

Vendredi, 9 mars 2012

Large Numbers

Traduction: [ Google | Babelfish ]

Catégories : [ Science ]

Googolplex

My daughter asked me yesterday what is the largest number I know. The answer was “a Googolplex”, which is 10googol with googol = 10100.

While you can write a googol on a sheet of paper (it's a one followed by 100 zeros), you cannot write a googolplex on paper. Or can you? how much paper do you need for that?

Let's assume you can write 10 000 digits on one sheet of A4 paper. You therefore need 1096 sheets of paper. One tree can produce 10 000 sheets of paper, and there are about 1012 trees on Earth. You'd need 1080 Earths to provide all the paper. Not going to work.

Now let's see if there's even enough matter in the universe to make all this paper: assuming that all the matter in the universe can be converted to paper, is there enough of it? Paper is made of cellulose, chains of D-glucose, the latter weighing 128 g/mol. So a 5 g sheet of A4 paper contains about 2.5·1022 molecules of linked D-glucose, each of which is made of 128 hadrons (protons and neutrons). A sheet of paper is therefore made of 3·1024 hadrons, which is almos the same thing as an atom of hydrogen. The universe contains roughly 1080 atoms, which translate roughly as 1056 sheets of paper. We'd need 1040 universes to make all the needed paper. Not going to work either.

That was a very big number.

[ Posté le 9 mars 2012 à 11:44 | 1 commentaire | ]

Lundi, 13 février 2012

Git Status in Shell Prompt

Traduction: [ Google | Babelfish ]

Catégories : [ Informatique/Git ]

I thought it would be very convenient to see from the shell's prompt what branch I am currently working on. Of course, someone had got that idea well before me, and I found this implementation and this variant (the second adds space between the name of the branch and the symbols indicating the state of the branch relative to the remote branch it is tracking).

[ Posté le 13 février 2012 à 15:30 | pas de commentaire | ]

Jeudi, 9 février 2012

Stripboard Sketch Paper

Traduction: [ Google | Babelfish ]

Catégories : [ Bricolage ]

proto_board_sketch

I don't like to start soldering on a stripboard without having sketched the positions of the different components beforehand on a paper. While this is easily done on the back of an envelope, having 1:1 scale sketchpaper would be handy. So I made such a printable sketchpaper.

[ Posté le 9 février 2012 à 08:55 | pas de commentaire | ]

Mardi, 31 janvier 2012

Temperature Histogram

Traduction: [ Google | Babelfish ]

Catégories : [ Science ]

temperature_jkl_10_years_frequency

I have collected slightly over 10 years worth of hourly tempertature readings in Jyväskylä. The sources of temperature over the years have been the University of Jyväskylä's weather station, the METAR data for Jyväskylä's airport and the Finnish meteorological service which is currently being used; these services together were on average available 98.7% of the time.

The other day I wondered what a histogram of those values would look like, and here it is. The numbers have been rounded to the their closest integer values, and range from -35 °C to +34 °C. One disproportionately large peak large can be observed at 0 °C, probably due to melting ice/freezing water remaing in the sensor's surface and keeping it at exactly that temperature while the air around it would be slightly different (if you have a better explanation, don't hesitate to leave a comment!). Surprisingly, there is a second peak at 13 °C (explanations are welcome too!).

Finally, the average temperature is 4.0 °C, which is consistent wit the average minima (-1.4 °C) and maxima (7 °C) values given on Wikipedia's article about Jyväskylä.

[ Posté le 31 janvier 2012 à 22:54 | pas de commentaire | ]

Jeudi, 5 janvier 2012

Circuit auto Noël 2011

Catégories : [ Jeux ]

circuit_auto_noel_2011

Pas de circuit auto l'été passé, mais j'en ai monté un pendant ces vacances. Composé essentiellement de virages, j'ai réussi à en faire le tour en (un peu) moins de 4 secondes.

[ Posté le 5 janvier 2012 à 19:46 | pas de commentaire | ]