Jump to content
43oh

MSP430 meets LaCrosse Temperature/Humidity sensor TX3TH


Recommended Posts

Hi,

 

Excuses for the long post !!

 

After I found out that I could detect signals in the 433Mhz band using an AIR Boosterpack (See viewtopic.php?f=9&t=2944 AIR Boosterpack RF spectrum display) I wanted to display the data I was receiving on the 433 Mhz band.

Ive got a Lacrosse temperature/humidity logger WS8610 that can read up to 3 external sensors and log the data. These sensors broadcast their data every minute or so.

 

Since I have a logger and I have a display you might ask why do you want to read the data ? My motivation for this is simple, the datalogger can only capture data for about 1.5 weeks and then the oldest readings are overwritten and I need to connect the datalogger to an old PC (that still has a USB-DB9 connector) to be able to store the data. If I can read the data directly from the sensors I can hook them up in a system I allready have running with several other sensors (gas, electricityusage, inside temperature) and store the data on the internet. For those that are interested I am using Thingspeak to store my data.

 

So last week I started to look at a way to decode the signals I saw coming in using my spectrum display. Luckily other people had allready done a lot of work on the protocol used by the sensors. The sensordata is send using On/Off keying (OOK).

See http://ftp.f6fbb.org/domo/sensors/tx_signals.php and http:/ftp.f6fbb.org/domo/sensors/tx3_th.php

 

After a few days of trial-and-error approach (thanks go to larsie for the feedback and ideas !) I actually was getting signals that could be the sensordata. To cut a long story short, using asynchronous CarrierSense detection on the AIR BOOSTERPACK and timing the length of the pulse coming in I can read the incoming data from several sensors. The software is definitely in its alpha stages. I can read one sensor properly but reading multiple sensors does give problems, if I set the RF registers to read the nearby sensor (3-4 meters away) the far away sensor (>10m) doesnt get picked up. When I set to register to read the far away, the nearby gets picked up but the data isnt as it should be anymore.

 

Here's an image to show that I get results that are the same as my LaCrosse display shows (from left to right : MSP430 sandwich, Lacrosse display and a not active TX3TX sensor).

 

post-10448-135135559802_thumb.jpg

 

The code below is based on the same GLCD and TI libraries as I used for my spectrum display project.

 

regards

CorB

 

 


/*
* This file is licensed under BSD. The simplicity code is originally copyright Texas Instruments,
* but has been adapted by Lars Kristian Roland/Cor Berrevoets
* the glcd code is by Lars Kristian Roland/Cor Berrevoets
* the tx3th sensor information can be found at http://ftp.f6fbb.org/domo/sensors/tx3_th.php
* the sensor first sends temperature information consisting of 11 blocks of 4 bits repeated once
* the sensor secondly sends humidity information consisting of 11 blocks of 4 bits repeated once
* block 0 is 0000
* block 1 is 1010 (preamble)
* block 2 is sensortype 0=temperature E=humidity
* block 3 is 4 bits sensorID
* block 4 is 3 bits sensorID and another bit (unknown purpose)
* block 5/6/7 is temperature in tenths degrees BCD +50 degrees
* block 5/6/7 is humidity in tenths percent BCD (always ending at 0)
* block 8 = block 6
* block9 = block 7
* block10 = CRC
* */

//*******************************************************************
//

//                  G2553
//
//             -----------------
//            |                 |
//            |VCC          GND |
//   S1/GDO2  |P1.0         P2.6|-RF-GDO0
//       S2   |P1.1         P2.7|-RF-CS
//       SW1  |P1.2             |
//       LED  |P1.3             |
//  glcd-cs   |P1.4         P1.7|<-------| glcd/RF-MISO
//glcd/RF-CLK |P1.5         P1.6|------->| glcd/RF-SOMI
//       S3   |P2.0         P2.5|
//       S4   |P2.1         P2.4|
//            |P2.2         P2.3|
//            |                 |
//             -----------------


//*******************************************************************

#include "ti/include.h"
#include "../library/glcd_charset.c"
#include "../library/glcd.c"

unsigned long clockcnt=0,lastclock=0;
unsigned long lastpulsecnt, pulsecnt=0,faultcount=0, pulselength=0;

unsigned char bit; // bitcounter 0..3
unsigned char bitdata[4]={8,4,2,1};  // to create a nibble readout with MSB first coming in
char pulseindx; // nibblecounter
unsigned char pulsetrain[50],oldpulse[50]; // datapackage storage

unsigned char line=4; // display of temperature datapackage
int rssi;

#define signal BIT2


void setup433MhzOOKreader()
{
     TI_CC_SPIStrobe(TI_CCxxx0_SIDLE);			// set IDLE

  TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2,    0x10); // Freq control word, high byte
  TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1,    0x00); //Freq control word, mid byte.
     TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0,    0x00); //Freq control word, low byte.

  TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4,  0x06); // RX bandwidth and datarate MSB
	  TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3,  0x37); // datarate LSB
  TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2,  0x00); // no preamble/sync
  TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1,  0x00); // CHANNEL SPACING and channelspacing MSB
  TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0,  0xe5); // x2E5=200Khz x1E5=100Khz x0E5=50Khz x000=25Khz, CHANNEL SPACING LSB

  TI_CC_SPIWriteReg(TI_CCxxx0_FOCCFG, 0x00); // no IF compensation for OOK

  TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2,0xc3); // receiver gain 0xAB    A                             B

  TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x32); //asynchronous mode
 	  TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x0E); //GDO0Output Pin Configuration asynchronous output

 	  TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, 48); // change radio to channel 48 in 432Mhz band (50khz spacing)
 	  TI_CC_SPIStrobe(TI_CCxxx0_SRX);           // goto receivermode

}


void main (void)
{

  WDTCTL = WDT_MDLY_0_064;                     // WDT ~0.064ms interval timer
  IE1 |= WDTIE;                             // Enable WDT interrupt

  P1DIR |=signal;

  TI_CC_GDO0_PxIES &= ~TI_CC_GDO0_PIN;       // Int on falling edge (end of pkt)
  TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN;      // Clear flag for GDO0
  TI_CC_GDO0_PxIE |= TI_CC_GDO0_PIN;        // Enable interrupt on end of packet

  RF_init(); // SETUP ANAREN AIR RF
  __delay_cycles(50000);
  SPISetup();                         // Initialize SPI Display
  __delay_cycles(100000);
  clear();
  __delay_cycles(100000);

  //reset the pulsetrain indices and storage arrays
  	  for (pulseindx=0; pulseindx<49; pulseindx++)
  	  {
  		  pulsetrain[pulseindx]=0; oldpulse[pulseindx]=0;
  	  }
  	  pulsecnt=0; pulseindx=0;  bit=0; lastpulsecnt=0;

 	 writeInt(0,2,faultcount,3); // display faults
 	 writeInt(48,2,pulsecnt,3); // display how many packages have been read



     setup433MhzOOKreader();

     __enable_interrupt(); // enable all interrupts

  while (1) // do for ever
  {
    if (pulsecnt>lastpulsecnt) // display data only of we have received a package
    {       setcharmode(1);  // switch to large characters
			if ((oldpulse[1]==0x0a) && (oldpulse[12]==0x0a))
			{

				unsigned int temperature;
				unsigned int humidity;
				temperature=(oldpulse[5]-5)*100+oldpulse[6]*10+oldpulse[7];
				writeInt(0,0,temperature,3);

				humidity=oldpulse[27]*10+oldpulse[28];
				writeInt(48,0,humidity,3);
				lastpulsecnt=pulsecnt;

			}

			writeInt(0,2,faultcount,3); // display faults
			writeInt(48,2,pulsecnt,3); // display how many packages have been read

			setcharmode(0); // switch to small characters
			unsigned char temp;
			char i,x;
			x=0;
			// show the 11 nibbles of the temperature part of the package
			for (i=0; i<11; i++)
			{
				temp = oldpulse[i];
				temp += (temp > 9) ? 'A' - 10 : '0';
				writeChar(x,line,temp);
				x=x+6;
			}
			writeInt(x+6,line,rssi,4);



    }




   }

}


#pragma vector = WDT_VECTOR                             // - Watchdog timer interrupt vector
__interrupt void wdt_isr(void)                          // This interrupt will occur once per second
{                                                       //
   clockcnt++;

 }





#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
  // REALLY cheap debounce.  
  // We can get away with this because we're edge triggering but reading the level.

  if(TI_CC_GDO0_PxIFG & TI_CC_GDO0_PIN)
      {

  		pulselength=clockcnt-lastclock;

  		lastclock=clockcnt;

 		if (pulselength<30)
  			 {pulsetrain[pulseindx]|=bitdata[bit];}

  		bit++;
  		if (bit==4)
  		   {bit=0;
  		    pulseindx++;}

  		if (pulseindx>43) // we got all 44 bits in
  		   		        {

  			            rssi=TI_CC_SPIReadStatus(TI_CCxxx0_RSSI);
  					    __delay_cycles(100);

  					    if(rssi < 128) // convert RSSI readout to dB
  				           { rssi = -((rssi/2) - 74);
  				             }
  				           else{ rssi = -(((rssi - 256)/2) - 74);
  				             }



  			              char j;
  		   		          for (j=0; j<45; j++)
  		   		                {oldpulse[j]=pulsetrain[j];
  			                      pulsetrain[j]=0;
  		   		             	 }
  		   		          //reset indices
  			              pulseindx=0;
  		   		          bit=0;

  		   		          //increment the line to display the datapackage
  		   		          line++;
  		   		          if (line>7) {line=4;}

  		   		          if (oldpulse[1]==0x0a)
  		   		          {pulsecnt++;}
  		   		          else
  		   		          {faultcount++;
  		   		           pulsecnt++;}

  		   		    // add a long delay after reading the 44th nibble, corrects possible mistakes also
  		   		    		                   __delay_cycles(10000000);

  		   		        }

	    TI_CC_GDO0_PxIFG &= ~TI_CC_GDO0_PIN;      // After pkt RX, this flag is set.
       }

}

Link to post
Share on other sites

Thanks for sharing!

 

I have some Oregon Scientific weather sensors that also use 433Mhz and OOK. I am planning on using your setup to monitor the sensors. One thing that will help me is that someone has put together a complete protocol document on all the Oregon Scientific sensors. There may be some protocol similarities with your Lacrosse sensors. The same project also has Arduino code for decoding the protocol.

 

What kind of range are you seeing with your sensors?

Link to post
Share on other sites
Thanks for sharing!

 

I have some Oregon Scientific weather sensors that also use 433Mhz and OOK. I am planning on using your setup to monitor the sensors. One thing that will help me is that someone has put together a complete protocol document on all the Oregon Scientific sensors. There may be some protocol similarities with your Lacrosse sensors. The same project also has Arduino code for decoding the protocol.

 

What kind of range are you seeing with your sensors?

 

Hi,

 

Nice to hear that you are going to try to add these sensors.

I am currently tweaking several register settings (mainly channel, agcctrl2) to get the best range out of my sensors. I can easily read a sensor that sits 8 meters away with signals up to 60db still. However when the signal is that strong decoding definitely goes wrong so I am using less receiver gain (programmed using ACGCTRL2) to get a clean signal of 90dB or so. Choosing the right frequency is also important. In the code I posted this morning I was using channel 48 (base frequency 432Mhz and 50khz channelwidth) but Ive been testing more channels and now have moved to channel 45. Your sensors might need a different frequency for the best operation. Ive checked the protocol document you shared and you should be able to decode using the current setup. Ive used a WDT 64us timer as a simple way to measure pulsetime.

 

Im am Interested to hear about your progress.

 

regards

Cor

Link to post
Share on other sites
Whoa.. that's good work. I also learnt about ThingSpeak today.

 

Hi Bluehash,

 

Combine thingspeak with another free service called Pushingbox and you have a system that allows you to send you mail notifications if any of your sensor-values passes a threshold.

 

CorB

Link to post
Share on other sites

Is there a reason for choosing the Lacrosse sensor? Or was it just something you had on hand already? It looks pretty good but I can't find that model online.

 

I assume the advantage of using a commercial product over building something on your own is that it is already in a case and is waterproof...

Link to post
Share on other sites
Is there a reason for choosing the Lacrosse sensor? Or was it just something you had on hand already? It looks pretty good but I can't find that model online.

 

I assume the advantage of using a commercial product over building something on your own is that it is already in a case and is waterproof...

 

Hi,

 

As shown in my image I do indeed have these sensors and a display from LaCrosse. The sensors can be found in many weather stores. The reason is indeed that they are waterproof and run on a set of rechargable AAAs for several months. I am not yet at the stage where I can design my own weathersensor (temperature/humidity) in a waterproofbox under 20 Euro's.

 

regards

Cor

Link to post
Share on other sites

Hi,

 

Update on the code I use.

 

After a lot of experimentation (testing many different settings at different locations in the house) I now am using the settings as shown below in the code to receive the OOK signals. Especially the setting of AGCCTRL2 seems to be crucial. I initially tried to set AGCCTRL2 to get signals as strong as possible (using higher gains) but this gave problems. When I started to reduce the gain the signals became weaker but the signal quality was higher (I now receive signals at -105 dB). Additionally I have made the Bandwidth (MDMCFG4) smaller than I had it originally and that also helped signal quality. Reducing the bandwith further does still improve signal quality but the TX3TH sensors seem to be less stable in terms of the broadcast frequency and with a smaller bandwith you can more often loose the signal. The current setup allows me to read an outside mounted TX3TH from Lacrosse at 15meters or so (when I am inside the house behind a concrete wall) and 2 inside sensors at about 5 meters (havent tried to move them further away).

 

regards

Cor

 

void setup433MhzOOKreader()
{
     TI_CC_SPIStrobe(TI_CCxxx0_SIDLE);			// set IDLE
     // SET 432Mhz as base frequency
     TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2,    0x10); // Freq control word, high byte
     TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1,    0x00); //Freq control word, mid byte.
     TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0,    0x00); //Freq control word, low byte.

     TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4,  0x30); // RX bandwidth and datarate MSB
     TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG3,  0x37); // datarate LSB
     TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG2,  0x00); // no preamble/sync

     //Channel spacing is 25Khz
     TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG1,  0x00); // CHANNEL SPACING and channelspacing MSB
     TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG0,  0x00); // CHANNEL SPACING LSB

     //Receiver gain uses low gain   
     TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2,0x40); // receiver gain
     // channel position (multiply with channel spacing to obtain frequency)
     TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, 81);

    TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x32); //asynchronous mode
     TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x0E); //GDO0Output Pin Configuration asynchronous output

   TI_CC_SPIStrobe(TI_CCxxx0_SRX);           // goto receivermode
}

Link to post
Share on other sites

Were you able to get the boosterpack to connect with SmartRF Studio? I wondered how to do that/if it were possible. I know about the offline mode (it doesn't have to be connected to generate the configuration code).

 

I am just wondering if you were using SmartRF or figuring it out on your own.

Link to post
Share on other sites
Were you able to get the boosterpack to connect with SmartRF Studio? I wondered how to do that/if it were possible. I know about the offline mode (it doesn't have to be connected to generate the configuration code).

 

I am just wondering if you were using SmartRF or figuring it out on your own.

 

Hi,

 

Not thats not possible, so all the experimentation was done using trial-and-error approaches setting one variable at a time. For finding the best channel to receive the OOK data I used the buttons on the LCD boosterpack I am using.

 

It should BTW be technically possible to create an application alike smartRF that controls the AIR boosterpack using UART commands or so send via a PC.

 

Cor

Link to post
Share on other sites

Hi,

 

After another week of further experimentation I finally got the system running the way I want it. Its a bit of a multi-device design but it works fine.

 

Current setup:

- 3 TX3TH sensors (1 outside 2 inside) that transmit their data every minute at 433.92Mhz in On/Off Keying (OOK).

- 1 AIR Boosterpack programmed as a relay to collect OOK data at 433 Mhz and transmit datapacks using SimpliciTI at 868 Mhz

- 1 AIR Boosterpack programmed as 868Mhz SimpliciTI receiver connected via UART-serial to an Arduino

- 1 Arduino with ethernetboard connected to THINGSPEAK and PUSHINGBOX, data is pushed out every minute

 

Here's a plot of the temperature (left) and humidity(right) data I gathered the last 24hrs or so. My Lacrosse mainstation now has become more or less redundant and the tedious job of weekly downloading data from the mainstation via RS232 is also over.

 

post-10448-135135561727_thumb.jpg

 

 

regards

Cor

Link to post
Share on other sites
  • 4 weeks later...

Since my last mail I have updated the code, the code below is more sensitivy and also stable in receiving the OOK signals. Next to this I also have developed a more general OOK-sniffer that can display incoming OOK signals at 434 MHZ (or another frequecny) by reporting the signal ON/OFF times in microseconds. If anybody is interested I will publish that code.

 

void SetupOOKreader()

{

TI_CC_SPIStrobe(TI_CCxxx0_SIDLE); // set IDLE

 

//set at 433,92 Mhz

TI_CC_SPIWriteReg(TI_CCxxx0_FREQ2, 0x10); // Freq control word, high byte

TI_CC_SPIWriteReg(TI_CCxxx0_FREQ1, 0x13); //Freq control word, mid byte.

TI_CC_SPIWriteReg(TI_CCxxx0_FREQ0, 0xE9); //Freq control word, low byte.

 

TI_CC_SPIWriteReg(TI_CCxxx0_MDMCFG4, 0x4D); // RX bandwidth and datarate MSB

 

TI_CC_SPIWriteReg(TI_CCxxx0_AGCCTRL2,0x80); // receiver gain

TI_CC_SPIWriteReg(TI_CCxxx0_CHANNR, 0x00); //use no channel

 

TI_CC_SPIWriteReg(TI_CCxxx0_PKTCTRL0, 0x32); //asynchronous mode

 

TI_CC_SPIWriteReg(TI_CCxxx0_IOCFG0, 0x0E); //GDO0Output Pin Configuration asynchronous output

__delay_cycles(100000);

 

TI_CC_SPIStrobe(TI_CCxxx0_SRX); // directly start the receivermode

 

}

Link to post
Share on other sites
  • 1 month later...

Hi,

 

If you read through the initial postings you will see that these sensors send OOK signals (ON/OFF). Once you know which frequency they are sending you only need to listen and record the time the signals go HI->LO etc. Some people have found out the decoder scheme (see earlier mails) and using that its really simple.

 

cheers

CorB

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...