Wednesday, May 15, 2013

Trasee noi în gis.modulo.ro

Odată cu actualizarea din 15 Mai 2013 în site-ul nostru de trasee montane au apărut:

Wednesday, May 01, 2013

Battery powered thermometer based on MSP430

Three or four months ago I started experimenting with a MSP430 launchpad; at the time I used it as an ADC device for a Raspberry Pi, having it sample data and send it back to the RPi via i2c.

Some time later I decided I want to build a battery powered thermometer. It took me about three months of spare time to build a thermometer that should run for more than two months on a pair of AA batteries.

I found writing code for the MSP430 an interesting experience as it reminded me of writing Z80 code where you use interrupts heavily, have a hard time debugging, use all kinds of tricks to make up for slow floating point arithmetic and use very little memory. At least you don't have to write assembly - the MSP430 can be programmed in C.

Soldering and component placement on the other hand proved to be a constant exercise in frustration; its requirement for careful planning is not a good match to my getting things done quickly approach so I found myself repeatedly looking for an undo button after two or three wires were soldered in the wrong place.

In my attempts to handle planning I tried to use PCB design software such as Fritzing or Eagle but I couldn't use either to find a layout solution on a single side 10cmx5cm board - they were unable of doing autorouting so I abandoned plans of building a PCB. In the end, I laid oud a pinout table and a hand drawn diagram based on a stripboard image printed using Fritzing.

MSP430 thermometer prototype

This is the latest version of the thermometer prototype running on its own stripboard:
It's using:
  • 1 MSP430 (I'm using a 2452)
  • 4 CD4543 ICs (3 for digits, 1 for special symbols - decimal point, minus sign, low battery sign)
  • A 7 segment 3 1/2 digits raw LCD
  • 1 DS18B20 digital thermometer sensor

The system is powered by 2 AA batteries and draws 100-150 microAmps per second; every 10th second it reads data from the temperature sensor drawing 1-2 milliAmps for 1/10th of a second or so.

The measurements are guesstimates at this point as I can't use a multi-meter to properly compute them -> I'm looking into building a current measuring system based on the MSP430, a shunt resistor and a operational amplifier.

Notes on displays

The most challenging part of the thermometer project has been identifying a display that can run 24/7 with minimum current.

Displays I've tried:

DisplayConsumptionNotes
7 segment LED30 milliAmps32 mA to display "22.5" (2 mA per segment, 2 mA for the decimal point)
Photo © Peter Halasz
HD44780 character LCD2-3 milliAmps16x2 characters (with backlight 100mA)
Nokia 5510 display3 milliAmpswithout backlight


How 10 milliAmps per second kills your battery in 1 day

2 milliAmps might not sound like a lot but a cheap 9V battery has about 400mAh capacity - that means you'll run a 2 milliAmps display for less than 8 days on a fresh battery.

My first thermometer prototype (using a HD44780 display) consumed in the order of 10 mAmps (2-3 mAmps the display, 4-5 mAmps for 2 voltage regulators and 2 mAmps for the MSP430 running in active mode) - it ran for 16 hours on a fresh 9 V battery:



Low power display (DE 113-RS-20)

After experimenting with the displays described above I've settled to using a "raw" 7 segment LCD such as the DE 113-RS-20.

The display's datasheet states 1 microAmp per centimeter (larger displays take more current) and I've measured a MSP430 displaying two digits on a DE 113-RS-20 LCD using 2 CD4543BE binary to 7 digit decoders at 30-35 microAmps.





The only notable thing about using the CD4543BE with the raw LCD is you have to feed a square wave (30-100Hz, typically 32 Hz) into the PHASE pin of the IC and the BP pins of the display. Just toggle one of the MSP's pins between 0 and 1 (logical 1, i.e. Vcc) every 15 milliseconds.

If you have't used raw LCD panels you might want to read this well written application note from Purdy Electronics: Field Effect (FE) LCD Panels.

Interesting info I picked up during my research

  1. Normal voltage regulators have relatively large quiescent currents

    My original thermometer design was based on a HD44780 display using two voltage regulators (a 5V and a 3V3).

    The 5V and the 3V3 voltage regulators each took 2-3 milliAmps without anything else connected in the circuit.

    This version ran for less 1 day on a fresh 9V battery.

  2. It's more efficient to run a MSP 430 using a (properly chosen) voltage regulator than running it directly off batteries

    There are some voltage regulators - such as those from the TPS780 series that take 500 nanoAmps quiescent current.

    Using this type of voltage regulator makes sense because the MSP430 takes more current when running off higher voltage.

    This is described in detail in Texas Instruments' Using power solutions to extend battery life in MSP430 applications, including a very cool trick using voltage regulators that can be instructed (via a input pin) that the MSP430 has been put in low power mode and hence requires lower voltage (they call this dynamic voltage scaling).

  3. Never leave an IC's input floating

    Although you might get away with this on the breadboard (for reasons I've been explained but fail to understand) leaving a floating input is asking for trouble.

    This is what killed thermometer version 2: I left a floating input and diagnosed it after tearing the stripboard apart.

  4. It's relatively easy to re-program the MSP430 off the launchpad

    One of the biggest hurdles I've faced when dealing with the MSP430 was taking it off the prototype board and onto the launchpad for software changes (I've broken one of 2452's pins in the process)

    The MSP430 can be programmed directly on the prototype board via Spy-By-Wire as described in Kerry D. Wong's Using MSP430 LaunchPad As Programmer.


Wednesday, April 10, 2013

Prognoze meteo de la wunderground.org

Am introdus un nou tab în site-ul nostru de trasee montane, care conține prognoza pe 3 zile pe baza datelor de la wunderground.com.

Prognoza este actualizată zilnic, deocamdată în engleză pentru că varianta în română pe care o oferă serviciul de la wunderground.com are câteva probleme.


Friday, January 11, 2013

Raspberry PI - MSP 430 - LCD

I finally managed to have the Raspberry PI talk to MSP430 over a SPI serial line and to have the MSP430 print whatever is received to the HD44780 LCD - my notes below.

DEM16101 LCD unusable

No matter how hard I tried, I couldn't figure out how to use it.

I think I managed to talk to the KS066 controller correctly (I reliably reset the controller using the initialization sequence) but I could not figure out the voltage required to power the LCD.

It looks like the LCD might require negative voltage (it's the only way I managed to have the LCD show some character blocks) but I did not find working setting.

In the end I replaced it with a HD44780 LCD and things went fairly smoothly.

MSP430 __delay_cycles

As part of trying to figure out why I could not initialize the DEM16101 I timed, using a scope, delays produced using __delay_cycles vs delays produced by using a timer interrupt.


ClockMethodTime (expected)Time (measured)
1 MHz__delay_cycles(1)1 us2.2 us
8 MHz__delay_cycles(8)1 us1.1 us
1 MHzTimer_A interrupt1 us1.1 us


Since the LCD controller is not that sensitive to the delay's length (it requires minimum values) in the end i used __delay_cycles and did not bother with timer interrupts.

MSP430 to LCD HD44780

I've used the code here to get started: Interface MSP430 Launchpad with LCD Module (LCM) in 4 bit mode. However, since I had 3 P1 pins busy for the SPI serial connection, I had to use a different pinout.

Although P2.0 was free, the voltage it yields when set to high is only 2.2-2.3V (the rest of the ports yield around 3V when high) so I switched to P1.7 for the register select RS pin. This makes the MSP code messier as two ports are in use - both P1 and P2.

I had to change the initialization a bit and add the 8 bit initialization before the 4 bit part, i.e. my working init routine is:

#define     LCM_DIR               P2DIR
#define     LCM_OUT               P2OUT

#define     LCM_PIN_RS            BIT7          // P1.7 -> on P1!
#define     LCM_PIN_EN            BIT1          // P2.1
#define     LCM_PIN_D7            BIT5          // P2.5
#define     LCM_PIN_D6            BIT4          // P2.4
#define     LCM_PIN_D5            BIT3          // P2.3
#define     LCM_PIN_D4            BIT2          // P2.2

void InitializeLcm(void)
{
        // P1 bit 7 is used for RS
        P1DIR |= BIT7;

        //
        // set the MSP pin configurations
        // and bring them to low
        //
        LCM_DIR |= LCM_PIN_MASK;
        LCM_OUT &= ~(LCM_PIN_MASK);


        // wait for the LCM to warm up and reach
        // active regions. Remember MSPs can power
        // up much faster than the LCM.
        //
        __delay_cycles(80000);
        P1OUT |= (LED_0 + LED_1); // turn LEDs on
        //
        // initialize the LCM module
        //
        P1OUT &= ~BIT7;
        LCM_OUT &= ~LCM_PIN_EN;


        // init (part of 8 bit mode)
        LCM_OUT = LCM_PIN_D4 | LCM_PIN_D5;
        PulseLcm();
        __delay_cycles(40000); // at least 4.1 ms
        LCM_OUT = LCM_PIN_D4 | LCM_PIN_D5;
        PulseLcm();
        __delay_cycles(200);
        LCM_OUT = LCM_PIN_D4 | LCM_PIN_D5;
        PulseLcm();

        // 4 bit mode
        // function set
        LCM_OUT = LCM_PIN_D5;
        PulseLcm();
        SendByte(0x28, FALSE);
        __delay_cycles(40000); //to check in datasheet

        // clear display
        SendByte(0x1, FALSE);
        __delay_cycles(40000); //to check in datasheet

        // entry mode set
        SendByte(0x6, FALSE);
        __delay_cycles(40000); //to check in datasheet

        SendByte(0xC, FALSE);
        __delay_cycles(40000); //to check in datasheet

        P1OUT &= ~(LED_0 + LED_1); // init complete, turn LEDs off
}

Rasperry PI to MSP430 via SPI

References:

My code is an awful hack using code from both references.

If you use the MSP430 board with the jumpers in their default position the maximum speed you can us is 9600. So you need to set the speed on the Raspberry Pi at 9600 and use the "-H" option (clock phase).

MSP430 hardware UART

To use the MSP430's hardware UART you need to rotate the TX and RX jumpers 90 degrees:

When using the hardware UART you can use higher speeds (50000 baud works). You still have to use the "-H" (clock phase) option on the Raspberry side


Circuit (drawn using fritzing.org)

Parts:

  • Raspberry PI
  • MSP 430 (powered from the PI via USB)
  • LCD HD44780
  • 5KΩ pot (LCD contrast)
  • 40Ω resistor (to LCD LED +)

Note: the pot for the LCD contrast is usually listed at 10KΩ. I didn't have one so I replaced it with a 5K.

and a photo of the physical setup (a bit different from the diagram depicted in the circuit (there's a pot used to drive an ADC input and the 5K pot used for LCD contrast is replaced by two fixed resistors):

Monday, October 29, 2012

Seagate Momentus XT 750 Gb drive probably incompatible with MacBook Pro Mid 2009

To whom it may concern:

It looks like Seagate Momentus XT is incompatible with some MacBook Pro models (Mid 2009, model identifier MacBookPro5,4, Serial-ATA NVidia MCP79).

The incompatibility manifests itself by the system being hung in I/O - in Activity Monitor both Reads in/sec and Writes in/sec will stay at zero for tens of seconds and eventually the hang will become permanent requiring reboot.

Another possible related symptom is smartctl (part of smartmontools) showing non-zero "UDMA_CRC_ERROR_COUNT", e.g. for a brand new drive:

199 UDMA_CRC_Error_Count    0x003e   200   196   000    Old_age   Always       -       32529

I've tried shorting two jumper pins as described in the Momentus XT manual to tell the drive to avoid negotiating at 3Gb and force 1.5 Gb instead to no avail - with the jumper in place System Report still showed a "Negotiated Link Speed" of 3Gb.

Most likely related: Ugh, SSDs in the MacBook Pro


Tuesday, September 18, 2012

Actualizări în harta OpenStreetMap

În ultima vreme am folosit destul de des hărțile T.C.R. (Hărțile turistice ale T.C.R. - Avântul turismului montan în România ) pentru completarea informațiilor din zonele montane ale harții OpenStreetMap.

Deși vechi (anii 1930), hărțile constituie o sursă importantă de toponime și sunt admirabil de corecte având în vedere tehnologia epocii. Totuși există locuri în care harta nu pare sa corespundă cu profilele de altitudine (spre exemplu în zona Clăilor din Jepii Mici) deci vectorizarea direct de pe hărțile T.C.R.-ului nu este o soluție.

Metodologia preferată de adăugare de date în harta OSM, prin colectare de track-uri cu dispozitiv GPS nu se potrivește marcării vârfurilor mici. Vârfurile mici nu sunt marcate în teren în niciun fel, iar detecția pe baza altitudinii indicate de GPS nu este fezabilă din cauza erorilor mari ale dispozitivelor GPS la detecția altitudinii.

În astfel de cazuri plasarea vârfurilor am facut-o combinând datele din hărțile T.C.R. geo-referențiate cu măsurătorile de altitudine de la Aster GDEM (Global Digitial Elevation Map).

Procesul este ilustrat mai jos:

  • In QGIS, se încarcă harta geo-referențiată, peste care se adaugă pentru referință conținutul planet_osm_line (way-urile din OSM, în poză cu albastru):
  • Cu GDAL se generează curbe de nivel pentru fișa corespunzătoare Aster GDEM (în exemplul nostru 45 latitudine Nord, 25 longitudine Est)
  • gdal_contour -i 20 -snodata 32767 -a height ~/Downloads/ASTGTM2_N45E025/ASTGTM2_N45E025_dem.tif curbe_nivel.shp
  • Raster-ul Aster GDEM se suprapune cu simbolizare care să facă ușor de observat diferența dintre cote. Celula izolată cu altitudine 1754 metri corespunde vârfului din teren (în măsura preciziei Aster GDEM-ului, de 1 arc-secundă)
  • În final, se poate observa diferența relativ mică (aproximativ 50 metri) între plasamentul vârfului pe harta T.C.R. si poziția corespunzătoare conform profilului de altitudine Aster GDEM
  • Odată localizată celula raster-ului cu altitudinea cea mai ridicată din proximitatea vârfului, se citesc coordonatele WGS84 și se folosesc la adăugarea vârfului în harta OSM.

    Rezultatul in zona Baiului: openstreetmap.org Baiului

    Diferențe față de hărțile moderne:

    • Zamora (modern) / Zamura (T.C.R.)
    • Pe harta OSM am lăsat Zamora, toponimul nou este deja prezent în Bușteni în foarte multe locuri (Strada Zamora, Valea Zamora, etc).

    • Dutca (modern, hartă Munții Baiului Mihai Ielenicz, 1984) / Duțca (T.C.R.)
    • Pe harta OSM am preluat Duțca. Motivul este ca pârâul din zonă (tributar al Văii Fetei) a rămas cu denumirea Duțca (vezi Wikipedia).

    • Valea Ceaușoaiei (modern) / Valea Ceușoaiei (T.C.R.)
    • Am considerat greșeala in harta T.C.R., pe aceeași hartă vârful e numit "Vârful Ceaușoaiei", parte din "Muntele Ceaușoaiei".

    În sfârșit, acolo diferențele erau ne-semnificative (Mierlele/Mierle, Răzoarele/Răzoare), am mers pe varianta din harta T.C.R.

    Friday, September 14, 2012

    Poiana Țapului - Cascada Urlătoarea

    Am simbolizat un nou traseu în harta OSM, între Poiana Țapului si Cascada Urlătoarea (harta zonei).

    Din păcate zona este foarte umblată și ca atare destul de murdară - mult mai frumos este traseul către Cascada Spumoasă (nemarcat dar ușor de găsit și parcurs):
    Pe vreme bună, merită și o vizita la Castelul Cantacuzino în Zamora - se văd grozav Jepii Mici, Caraiman și Coștila:
    Caraiman și Coștila. Sunt curios dacă o lunetă zdravănă ar apropiat suficient cât să se vadă cei ce urcă in peretele Văii Albe:
    Din Zamora Jepii Mici - de la stânga la dreapta Claia Mare, Valea Seacă dintre Clăi, Claia Mică, Creasta cu Zâmbri, Valea Jepilor: