Category Archives: Logbook

Audio synthesis and sharing the timers

We’re using the Mozzi sound synthesis library for Arduino to allow the robots to produce sound.  Our synthesis is implemented on the auxiliary circuit (environmental), which is also responsible for interfacing with all environmental sensors.  The main challenge with using Mozzi is that the library disables Arduino time functions millis(), micros(), delay(), and delayMicroseconds(), which we use often with various sensors.  Once Mozzi has been started, the library does not provide a method of stopping and regaining use of the timers.  Our solution is outlined below.

Mozzi modifies the following registers when starting up: TCCR0A, TCCR0B, OCR0A, TIMSK0, TCCR1A, TCCR1B, OCR1A, TIMSK1. Therefore, before starting Mozzi we backup the values of these registers:

byte _TCCR0A = TCCR0A;
byte _TCCR0B = TCCR0B;

etc… for the other registers.

When we want to stop Mozzi, we simply restore the backed up values:

TCCR0A = _TCCR0A;
TCCR0B = _TCCR0B;

etc… for the other registers.

These routines are wrapped in a custom audio library used for managing sound.

Orientation IR

Les bateaux sont équipés de récepteurs infrarouges afin de communiquer et de s’orienter entre eux. Le deuxième prototype est équipé de 6 récepteurs, pour une plus grande précision angulaire, comparativement à 4 pour la version précédente. En plus les entrés sur cette dernière version sont analogiques et non numériques, ce qui augmente la précision à +/-5 degrés.

Tous les entrés sont dirigés premièrement dans un inverseur pour être ensuite accumulé dans une porte logique OU à six entrés. Ensuite le signal est inversé une dernière fois avant la lecture. 

Eagle_IR_orientation

Schéma du système de communication et d’orientation infrarouge

Le filtre est constitué d’un amply op et d’un réseau RC pour être indépendamment filtré afin d’être lu par des convertisseurs analogues suivant chaque réception de paquet IR validé. Voici une visualisation des entrés analogiques.

MAX_IR_orientation

Exemple de patch MAX/MSP qui démontre l’amplitude des données infrarouges à l’entré des convertisseur.

Les émetteurs leds IR (QED234) se sont avérés très puissants, c’est a dire que les signaux étaient perçus par tout les capteurs  (TSOP39338) en même ce qui faussait l’orientation. Nous avons du abaisser la puissance de ceux-ci. Le circuit officiel sera donc doté de selecteur de puissance automatique pour ajuster les longueurs de transmission dépendemment de l’environnement des bateaux.

Magnetic interference between the motor and the compass

Compas_magnet

We ran into a major issue today with our HMC6352 compass which had worked fine up til now. The problem arises when we move the servo motor that makes the pump rotate. It changes the magnetic field (because of the coil in the motor that drives the pump) which results in the compass losing direction. If there is too much exposure, the compass is stuck into this bad state even when the motor is away, until it is recalibrated.

The HMC6352 datasheet gives some insight into that issue. There are three ways in which to reduce interferences. First there’s the calibration mode, which we were already using to adjust the compass. The problem with it is that is presupposes a stable magnetic field which isn’t our case because the pump moves along 180 degrees to navigate.

Second is what the datasheet refers to as the set/reset function. This one is a bit more obscure but basically I believe that over time, when in the presence of a magnetic field, the sensor accumulates static and needs to be “reset”. The way to call the reset function is not clear at all but by digging in the datasheet I found a mention on p. 8 about the “update bridge offsets” message which reads “Update Bridge Offsets (S/R Now)”, so I guess the message calls the reset function. I have tried it and didn’t notice any difference but I need to do more investigation.

Finally, on p. 13 there are informations about the amplifier filter which basically controls the sensitivity of the sensor. By adding a resistor between pins CA1 and CA2 you can reduce the gain and thus the sensitivity:

An optional gain reducing resistor (Rext) could also place across the feedback loop of the amplifier stages. With the amplifier set with the internal 1200 k-ohm feedback for ±750 milli-gauss maximum magnetic field flux density, a second 1200k-ohm external resistor would halve the gain and permit ±1.5 gauss capability if desired. Gain can be reduced for up to ±6 gauss capability for magnetometry-only applications or compassing with significant magnetic stray fields nearby.

We did a test with a 1200kΩ resistor but we didn’t notice a major difference. We yet have to try with a bigger resistor (the datasheet is not clear on the maximum resistor you can use but it suggests you can get up to a “±6 gauss capability” so by doing a simple calculation we esimate the maximum resistor to reach that gain to 8700kΩ).

Another idea we tried was to enclose the motor in a magnetic shield made of aluminium foil, but even with 1 inch of foil it’s still doing major interferences (although it’s a little bit better). We could try using a material with a higher electromagnetic permeability such as mu metal which is way more permeable than aluminium.

Some research on IR communication protocols

IR sender/receiver

I spent some time looking around for information on infrared communication protocols, especially in the context of multiple communicating nodes / robots.

e-Puck is an educational robot project developed at EPFL. The robots communicate between each other through IR in a very similar fashion to us. I’ve digged a bit into their code and they don’t seem to have a very elaborated communication protocol between their robots, appart from the format of the messages which use a CRC and a pre-defined packet size, which is similar to what we are doing. An interesting thing they do is that they use a queue to save their messages, which is something we should definitely do.

I found a great article on IR communication for swarm robotics. There are many things in that article and it’s definitely worth a read. One interesting thing is that they talk about using IR for detection of other robots, detection of obstacles (proximity) and communication. They suggest the following loop for the robots:

  1. Proximity detection
  2. Receive messages
  3. Send messages
  4. Decision making
  5. Behavioral commands

Finally I looked at the IrDA communication protocol. It’s definitely overkill for us but there are things we can use in terms of communication protocols. The IrDA protocol follows the following procedure (see fig. 10 on p. 8 for a summary of the procedure):

  1. Discovery: “The discovery procedure is used to determine the physical addresses of all devices that are within range.”
    1. “An initiator starts the discovery procedure by sending out an Exchange Station Information (XID) discovery frame. […] All devices within range will generate a random address and respond with an XID response frame.”
    2. “The Sniff-Open procedure allows a device to begin the discovery process while conserving power. A Sniffing device will periodically wake-up and check for any IR traffic. If any IR traffic is detected, the device will go back to sleep. If there currently no IR traffic detected, the device will send out an XID response frame to address 0xFFFFFFFF. The device will the wait for an XID command, an XID discovery frame or a Set Normal Response Mode (SNRM) frame, which begins normal connect procedures. If no frames are forthcoming, the device will go back to sleep and repeat the process later.”
  2. Connection: This is where the connection parameters are negotiated: baudrate, maximum turnaround time, data size, window size, etc. I don’t think we’re going to use that in our case because these parameters are known in advance. However the relationship between turnaround time, window size and transfer efficiency is useful (see p. 10).
  3. Information transfer: “Once connected, devices can either exchange data, reset or disconnect. Data can be sent using reliable, sequenced frames. Using the reliable (I) mode, data can span multiple frames with counters keeping track of the number of frames sent and the number of the next frame expected to be received. Data can also be sent using unreliable, expedited (U) service. In this case the data cannot span multiple frames.
    If both devices agree, the connection can be reset, which clears the frame counters and retry counters but keeps the connection open. A connection can also be disconnected by either device. The disconnection does not require approval from both devices.”

More examples (on IR sensing):

Programming multiple AVR/Arduino boards with XBee

Multi AVR programming using XBee

One of the major issues we have with the project is that we’re working with many robots (our goal is to make about 50 of them). Planning ahead, we thought it would be nice to be able to program them all at once to accelerate the development, especially towards the end of the project. We thus decided to experiment with multi-board wireless programming using XBees.

Step 1 : One-to-one wifi programming

There’s not much information on the web on how to program many AVR/Arduino using XBees but there is information on how to program one board. The first set of instructions we found are from LadyAda but we had better results with the instructions for the Arduino FIO.

The tutorial gives a detailed account of the different parameters that need to be set for the master (transmitter) and the slave (receiver). If you follow it step-by-step it should work fine. You can also check the extra tips they give if you run into trouble. We even tried with a very big program (50k!) and it works great.

The only thing we had trouble with is that the data transmission quality was bad and dropped quickly as we increased the distance between the XBees. This was likely caused by interferences with other wifi networks in the area. We solved this by changing to a different channel (the XBee CH parameter).

Step 2 : One-to-many wifi programming

In the Arduino FIO guide they mention: “Note: If you set the programmer’s destination address (DL) to FFFF, it will re-program all Fios in its PAN ID. To program one Fio at a time wirelessly while others are on, set the programmer’s DL to that Fio’s MY address.”

Basically, you have two choices: sequential or parallel programming. In the case of sequential programming, what you would do is more or less something like:

  1. Assign a unique MY address to each slave
  2. For each address do the following:
    1. Change the master’s DL to the slave’s address
    2. Upload the program

The advantage of this is that you get a chance to check that each board was programmed successfully before moving on. The disadvantage is that it takes as much time as there are boards: it just automates the switching from one board to the next for you.

(Notice that at this step we’re working with only two slaves.) We didn’t try that technique (yet). Instead we used the parallel programming trick. For this, you set the master/programmer’s DL address to FFFF. At first it didn’t work because all the slaves were sending data back to the master which seemed to overflood it. We tried to have only one slave return data back by setting it’s DL to the master’s MY address and by setting the other slave’s DL to an unexisting MY address, but this didn’t work well either.

We finally got it working by cutting the physical connection between the AVR first UART TX pin and the XBee’s TX. This worked great and seems stable, even for large programs and high baud rates (57600). We yet have to test it with more boards than two.

The files:

Simple XBee link quality test

Screenshot of the processing application for testing the XBee connection quality

Screenshot of the processing application for testing the XBee connection quality

We created a small Processing/Arduino program to check on the connection quality between two XBees (one linked to the computer and the other on an Arduino board). The Processing host just sends data packets (bytes) which are read and returned by the Arduino board. The host then compares the received packet to the one that was expected to establish the quality of the connection. It’s pretty simple but it works.

The files: