CorB 64 Posted July 26, 2012 Share Posted July 26, 2012 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). 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. } } Automate, RobG, larsie and 4 others 7 Quote Link to post Share on other sites
Automate 69 Posted July 26, 2012 Share Posted July 26, 2012 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? Quote Link to post Share on other sites
CorB 64 Posted July 26, 2012 Author Share Posted July 26, 2012 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 Quote Link to post Share on other sites
bluehash 1,581 Posted July 26, 2012 Share Posted July 26, 2012 Whoa.. that's good work. I also learnt about ThingSpeak today. Quote Link to post Share on other sites
CorB 64 Posted July 26, 2012 Author Share Posted July 26, 2012 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 Quote Link to post Share on other sites
Nytblade 24 Posted July 27, 2012 Share Posted July 27, 2012 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... Quote Link to post Share on other sites
CorB 64 Posted July 27, 2012 Author Share Posted July 27, 2012 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 Quote Link to post Share on other sites
CorB 64 Posted August 1, 2012 Author Share Posted August 1, 2012 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 } Nytblade, Automate and bluehash 3 Quote Link to post Share on other sites
Nytblade 24 Posted August 1, 2012 Share Posted August 1, 2012 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. Quote Link to post Share on other sites
CorB 64 Posted August 1, 2012 Author Share Posted August 1, 2012 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 Nytblade and bluehash 2 Quote Link to post Share on other sites
CorB 64 Posted August 5, 2012 Author Share Posted August 5, 2012 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. regards Cor RobG, Automate, bluehash and 1 other 4 Quote Link to post Share on other sites
tingo 22 Posted August 7, 2012 Share Posted August 7, 2012 A nice project, you really have put some work into this. Well done! Quote Link to post Share on other sites
CorB 64 Posted August 30, 2012 Author Share Posted August 30, 2012 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 } Automate, Nytblade and larsie 3 Quote Link to post Share on other sites
displacedtexan 1 Posted October 19, 2012 Share Posted October 19, 2012 I am interested! How did you decode the sensor data? I spent the first few years of my undergrad years as an EE, but unfortunately was not able to finish so a bit of a newb with this stuff. Quote Link to post Share on other sites
CorB 64 Posted October 19, 2012 Author Share Posted October 19, 2012 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 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.