Translate

Friday, August 14, 2015

Cooling the server area

Problem, cool down the server area.

The server is placed under a stair and the server area is insulated.
The area is in contact with the garage and the laundry room. The garage of course is not an insulated area, but the laundry it is.
Thus the idea : drill a hole in the stairs and connect a fan to aspire the fresh air from the laundry room.

So I did drill a 2 inches hole in the stairs, covered with a 2 inch air vent.
Initially I just attached a PC fan to the hole, from inside the server area, with the idea to aspire the air.
It did work but not much. I needed a more powerful fan.

But powerful fan are also bigger, no space to attach a bigger fan.
Thus the idea to build a box, connect a 3 inches flexible pipe (the one used for the dryer) to the hole in the stairs and place the fan on the box.
I had around some foam insulated box and voila' :)

An economic cooling box for the server area.

The cooling box. Just cut a hole for the fan


The pipe coming out from the box

The hole in the stairs ...

... with the cover

The box installed.I changed the fan with a blower, the fan was not powerful enough to suck enough fresh air from the small hole.

The final installation
It works !
Here some graphs:





The fan is controlled by an X10 appliance module, controlled by the server itself.
There are also some temperature sensors, one of them inside the server area. A script  on the server checks the temperature of the server area and the CPU every 5 minutes.
It uses Digitemp to read the sensors and Sensors to read the CPU temperature.
If the temperature goes above a threshold, the server activate the blower and fresh air enter in the server area.

Tuesday, August 11, 2015

MSP430 - Energia and Grove

I do have few Arduino around.
Like many people I bought some of them because ... well, I don't know, I guess at the time it was the news, to see what it is.
And I didn't like it much.

Or better, I like something, but not the underlined assumption that you can actually "learn" something. I'm always skeptical about claims of "easy learning".

It could be a good platform for fast prototyping but if you want to write some libraries to support some components or if you need a reliable system, is not an easy environment and it takes actually more time than writing some code from scratch.
Also for speed, power consumption and memory usage, the Arduino platform is not exactly the best.
Too "under the hood" things unknown, unless you are willing to spend a lot of time checking the source code of every library you are using, losing exactly the main reason to use such platform.
Never the less, it is a popular platform and the offer of libraries and 'shields' is impressive.

Ok, why I entitled this post related to the MSP430 if I'm talking about Arduino ?

Recently a friend of mine introduced me to Energia, the equivalent of Arduino for the MSP430.
The same concept, the same language, the same offer of libraries but for the MSP430 LaunchPad  instead the Arduino family based on the AVR microcontrollers.
Actually is possible to run many Arduino sketches "as is" on Energia and viceversa.

The reasons why I don't like Arduino can be applied to Energia, however for some irrational reasons I'm quite attracted to Energia, especially when I discovered the Grove system.
The Grove System is a set of "sensors/actuators" that can be easily connected to a  Grove platform, available for Arduino, Raspberry Pi and .. MSP430 LaunchPad.
For fast prototyping should be quite useful, the offers of modules is impressive and thus it can become very interesting at a price that is still affordable somehow.
Energia has many libraries capable to handle the Grove system sensors/actuators, but I'm still looking out to write the code from scratch.
Simply put, the Grove system should simplify the building of a prototype with a kind of "standardization" connections.
Energia can maybe used in the  "Proof of Concept" or to test some ideas, writing simple, non critical "sketch" to handle the hardware built.

So, I decided to spend some money and time in this platform, Energia plus MSP430 Grove system, starting with a basic entry kit and a MSP430f5529 LaunchPad.


Will see in the near future if is something I'll like or not :)
I'll post future experiments and considerations over this platform.

Saturday, August 8, 2015

MSP430 - I2C library

There are many different library out there to handle I2C with the MSP430.
Some of the libraries are also "official", from TI.

I found a nice and simple C library to handle the I2C with USI is on github and apparently is easy to deploy and use.
This article contains some notes about how to deploy and use the library, closing some missing practical information.

Let's start with ... the hardware.

Hardware


The library was originally developed and tested on an MSP430g2452.
It surely can work on any MSP430 family member that has a USI, that's was anyway my initial intent.
I tried to use an MSP430f2013 but in the end I opted to buy some MSP430g2452 because the 2013 doesn't have enough memory (only 2K ROM) to handle protocol and the rest of the code needed for a project.
The MSP430g2452 has 8K ROM.

After choosing the microcontroller, the attention was concentrated on the I/O pin to use.
Note ! Initially I'm experiment using a Launchpad.
The library expects to use the USI pins, i.e. the P1.6 for the SCL and the P1.7 for the SDA.
Apparently there is NO need to bother with the I/O ports to inform the MSP430 that the 2 pins are dedicated to the USI in I2C mode.
Is enough to program the USI control register to do that, and that is taken care in the i2c_init function provided by the library.

Important !!! The P1.6 on the Launchpad is connected to the green LED !
Remove the jumper on that LED in order to have something working !

Software

Compile it


The library presumably is written for IAR or other commercial system.
In order to compile it with Mspgcc few modifications are necessary.


  1. Remove the specific include of the msp430g2452 header from usi_i2c.c
  2. Add the generic include of msp430 in the usi_i2c.h
  3. Remove the include of the stdint.h header from usi_i2c.c and move in the usi_i2c.h
  4. Change the interrupt declaration, from:
    #pragma vector = USI_VECTOR
    __interrupt void USI_TXRX(void)
    {
      switch(__even_in_range(i2c_state,12))

    to

    __attribute__((__interrupt__(USI_VECTOR)))
    void Usi_txrx (void){  switch(__even_in_range(i2c_state,12))
  5. Move the inline function i2c_done() from the header file (usi_i2c.h) into the module (usi_i2c.c) and leave a function prototype for that function in the usi_i2c.h header file
With these modifications I was able to compile the library using mspgcc.

I also fixed a bug that was preventing the library to read more than 8 bit at a time.
In the usi_i2c.c file, in the interrupt function Usi_txrx change the highlighted line :

..................................................................
..................................................................
case I2C_RECEIVED_DATA:       // received data, send ACK/NACK
    *i2c_receive_buffer = USISRL;
    i2c_receive_buffer++;
    USICTL0 |= USIOE;           // SDA = output
    if(i2c_sequence_length > 1) {    
      // If this is not the last byte
      USISRL = 0x00;                // ACK 
..................................................................
..................................................................

with

..................................................................
..................................................................
case I2C_RECEIVED_DATA:       // received data, send ACK/NACK
    *i2c_receive_buffer = USISRL;
    i2c_receive_buffer++;
    USICTL0 |= USIOE;           // SDA = output
    if(i2c_sequence_length > 0) {   // TheFwGuy MOD !!!    
      // If this is not the last byte
      USISRL = 0x00;                // ACK 
..................................................................
..................................................................


Use it


The library has only three "public" functions and act as Master.
Let see how to use it.

i2c_init


The first public function is called i2c_init and like the name imply, is used to initialize the USI and set up the MSP430 to use it.
It must be called once, preferably after other basic I/O initializations happens.
After that, the "system" should be able to send out I2C messages.

Example:

        i2c_init(USIDIV_5, USISSEL_2);

The first parameter determine the division applied to the input clock.
USIDEV_0 divide by 1, USIDEV_1 divide by 2, USIDEV_2 divide by 4 and so on (see MSP430 Family user guide - USICKCTL register).
The second parameter determine the source of the clock (see MSP430 Family user guide - USICKCTL register).
In the example above the source for the clock is the SMCLK divided by 32.

i2c_done


This function returns TRUE (1) or FALSE (0) to indicate if a transaction is running.
The I2C messages are sent via interrupt so it is possible that the main program is ready to send another sequence when the system is still handling the previous sequence.
So before to perform any request, better to see if the system is ready to accept it.
Example:

      if(i2c_done())
         i2c_send_sequence((uint16_t *)seq1, 2, (uint8_t *)recseq, 0);

or
      while(!i2c_done());

Strongly suggested to use it to prevent to start a sequence when another one is still running.

i2c_send_sequence

This is the main function and the most complex to handle.
Simply put, this function can send and receive information via I2C using a "sequence".
The sequence  is a series of word and commands.
i2c_usi.h  defines two commands :
  • I2C_RESTART
  • I2C_READ
The function has these inputs:

  • sequence
    sequence is a pointer to an array containing the I2C operation sequence that should be performed.
    It can include any number of writes, restarts and reads.
    The sequence is composed of uint16_t, not uint8_t elements.
    This is because the need  to support out-of-band signalling of I2C_RESTART and I2C_READ operations, while still passing through 8-bit data.
    The sequence uses the Bus Pirate I2C convention.
    The address must be prepared manually, adding the R/W bit.
    The address is prepared shifting the 7-bit I2C address to the left and add the R/W bit (0 to write, 1 to read).
    The examples above communicate with a device whose I2C address is 0x1c, which shifted left gives 0x38.
    For reads we use 0x39, which is (0x1c<<1)|1.

    So for example, to write at the address 0x39, the sequence would be:

    • 0x39 << 1 = 0x72
    And to read from the address 0x39:
    • (0x39 << 1) | 1 = 0x73
  • sequence length
    sequence_length is the number of sequence elements (not bytes).
    Sequences of arbitrary (well, 32-bit) length are supported.
  • received data
    received_data should point to a buffer that can hold as many bytes as there are I2C_READ operations in the sequence.
    If there are no reads, 0 can be passed, as this parameter will not be used.
  • wake up sr bits
    Used if you want to use the MSP430 in low power mode.

Building sequences


The sequences to send depends strictly to a specific component so there is no a generic suggestion if not to carefully read the datasheet of the component.