I have been stuggling with the signal strength for a while now. Here are the
two componets that I am currently using, both of them are modifications of
the components that Alec Woo had sent to me.
Let me know if this works for you.
Vlad.
[EMAIL PROTECTED] wrote:
> By the way, Samir is not the only one having this problem. I've been
> trying to do the same thing for some time now, and have not had any
> success. I've located the character in the packet which is supposed to
> represent signal strength, but it always reads 00. If you find an answer
> Samir, I would appriciate hearing about it.
>
> "Samir Goel" <[EMAIL PROTECTED]> (Mailed by:
> [EMAIL PROTECTED])
> 04/29/2001 07:25 PM AST
> Please respond to "Samir Goel" <[EMAIL PROTECTED]>
>
> To: <[EMAIL PROTECTED]>
> cc: <[EMAIL PROTECTED]>, <[EMAIL PROTECTED]>
> Subject: Re: [tinyos-users@mm] Extracting radio signal strength
>
> hello All,
> I was able to get the code to compile (a bug from my own doing). But
> when I tested it out, I didn't observe any changes in signal strength
> correlated with distance. I would really appreciate if someone can help me
> out or point me in the right direction.
>
> Regards,
>
> Samir Goel
> [EMAIL PROTECTED]
/* tab:4
*
*
* "Copyright (c) 2000 and The Regents of the University
* of California. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Authors: Jason Hill
*
*
*/
#include "tos.h"
//#define FULLPC_DEBUG 1
#include "PACKETOBJ_SIGNAL.h"
#define TOS_FRAME_TYPE PACKET_obj_frame
TOS_FRAME_BEGIN(PACKET_obj_frame) {
char state;
char count;
TOS_Msg buffer;
char* rec_ptr;
char* send_ptr;
//int strength;
int ss_sum;
int ss_cnt;
}
TOS_FRAME_END(PACKET_obj_frame);
char TOS_COMMAND(PACKET_TX_PACKET)(TOS_MsgPtr msg){
if(VAR(state) == 0){
VAR(send_ptr) = (char*)msg;
VAR(state) = 1;
VAR(count) = 1;
if(TOS_CALL_COMMAND(PACKET_SUB_TX_BYTES)(VAR(send_ptr)[0])){
return 1;
}else{
VAR(state) = 0;
VAR(count) = 0;
return 0;
}
}else{
return 0;
}
}
void TOS_COMMAND(PACKET_POWER)(char mode){
//do this later;
;
}
char TOS_COMMAND(PACKET_INIT)(){
TOS_CALL_COMMAND(PACKET_SUB_INIT)();
VAR(rec_ptr) = (char*)&VAR(buffer);
VAR(state) = 0;
#ifdef FULLPC
printf("Packet handler initialized.\n");
#endif
return 1;
}
char TOS_EVENT(PACKET_RX_BYTE_READY)(char data, char error, int strength){
#ifdef FULLPC_DEBUG
printf("PACKET: byte arrived: %x, STATE: %d, COUNT: %d\n", data, VAR(state),
VAR(count));
#endif
if(error){
VAR(state) = 0;
return 0;
}
if(VAR(state) == 0){
VAR(state) = 5;
VAR(count) = 1;
VAR(rec_ptr)[0] = data;
//VAR(strength) = strength;
VAR(ss_sum)=strength;
VAR(ss_cnt)=1;
}else if(VAR(state) == 5){
VAR(rec_ptr)[(int)VAR(count)] = data;
VAR(count)++;
if (strength != 0){
/*
VAR(strength) += strength;
VAR(strength) >>= 1;
*/
VAR(ss_sum)+=strength;
VAR(ss_cnt)++;
}
if(VAR(count) == sizeof(TOS_Msg) -
sizeof(((TOS_MsgPtr)(VAR(rec_ptr)))->strength)){
TOS_MsgPtr tmp;
printf("got packet\n");
VAR(state) = 0;
((TOS_MsgPtr)(VAR(rec_ptr)))->strength=(VAR(ss_sum)/VAR(ss_cnt));
//VAR(strength);
tmp = TOS_SIGNAL_EVENT(PACKET_RX_PACKET_DONE)((TOS_Msg*)VAR(rec_ptr));
if(tmp != 0) VAR(rec_ptr) = (char*)tmp;
return 0;
}
}
return 1;
}
char TOS_EVENT(PACKET_TX_BYTE_READY)(char success){
char i;
if(success == 0){
printf("TX_packet failed, TX_byte_failed");
TOS_SIGNAL_EVENT(PACKET_TX_PACKET_DONE)(0);
VAR(state) = 0;
VAR(count) = 0;
}
if(VAR(state) == 1){
if(VAR(count) < sizeof(TOS_Msg) - sizeof(
((TOS_MsgPtr)(VAR(rec_ptr)))->strength)){
#ifdef FULLPC_DEBUG
printf("PACKET: byte sent: %x, STATE: %d, COUNT: %d\n",
VAR(send_ptr)[(int)VAR(count)], VAR(state), VAR(count));
#endif
TOS_CALL_COMMAND(PACKET_SUB_TX_BYTES)(VAR(send_ptr)[(int)VAR(count)]);
VAR(count)++;
}else if(VAR(count) == sizeof(TOS_Msg) - sizeof(
((TOS_MsgPtr)(VAR(rec_ptr)))->strength)){
VAR(count)++;
return 0;
}else{
VAR(state) = 0;
VAR(count) = 0;
TOS_SIGNAL_EVENT(PACKET_TX_PACKET_DONE)((TOS_MsgPtr)VAR(send_ptr));
return 0;
}
}
return 1;
}
char TOS_EVENT(PACKET_BYTE_TX_DONE)(){
return 1;
}
/* tab:4
*
*
* "Copyright (c) 2000 and The Regents of the University
* of California. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Authors: Jason Hill
*
*
*/
#include "tos.h"
#include "SEC_DED_RADIO_BYTE_SIGNAL.h"
/* list of states:
*
* 0 -- wating in idle mode, searching for start symbol
* 1 -- starting a transmission, 0 bytes encoded.
* 2 -- 1 byte encoded
* 3 -- 1 byte encoded, 1 byte waiting to be encoded
* 4 -- 2 bytes encoded
* 5 -- start symbol received waiting for first bit
* 6 -- clocking in bits
*
* 10 -- waiting to listen for idle channel
*/
#define TOS_FRAME_TYPE bitread_frame
TOS_FRAME_BEGIN(radio_frame) {
char primary[3];
char secondary[3];
char state;
char count;
char last_bit;
char waiting;
int strength;
char s_count;
int led_state;
}
TOS_FRAME_END(radio_frame);
TOS_TASK(radio_encode_thread)
{
//encode byte and store it into buffer.
encodeData();
//if this is the start of a transmisison, encode the start symbol.
if(VAR(state) == 1){
//VAR(primary)[1] = 0x26; //start frame 0x00100110
//VAR(primary)[2] = 0xb5; //start frame 0x10110101
//VAR(primary)[0] = 0x1; //start frame 0x1
//VAR(primary)[1] = 0x35; //start frame 0x00110101
//VAR(primary)[2] = 0x15; //start frame 0xXXX10101
//VAR(count) = 3;
VAR(primary)[0] = 0x2; //start frame 0x10
VAR(primary)[1] = 0x6b; //start frame 0x01101011
VAR(primary)[2] = 0x05; //start frame 0xXXXX0101
VAR(count) = 4;
VAR(state) = 4;//there are now 2 bytes encoded.
}else{
VAR(state) = 4;//there are now 2 bytes encoded.
}
#ifdef FULLPC_DEBUG
printf("radio_encode_thread running: %x, %x\n", VAR(secondary[1]),
VAR(secondary[2]));
#endif
}
TOS_TASK(radio_decode_thread)
{
int strength;
#ifdef FULLPC_DEBUG
printf("radio_decode_thread running: %x, %x\n", VAR(secondary[1]),
VAR(secondary[2]));
#endif
//check the signal strength;
strength = VAR(strength) >> 2;
VAR(strength) = 0;
VAR(s_count) = 0;
printf("byte strength %x\n", strength);
//decode the byte that has been recieved.
if(!TOS_SIGNAL_EVENT(RADIO_BYTE_RX_BYTE_READY)(decodeData(), 0, strength)){
//if the event returns false, then stop receiving, go to search for the
//start symbol at the high sampling rate.
VAR(state) = 0;
TOS_CALL_COMMAND(RADIO_SUB_SET_BIT_RATE)(0);
}
}
char TOS_COMMAND(RADIO_BYTE_INIT)(){
VAR(state) = 0;
TOS_CALL_COMMAND(RADIO_SUB_INIT)();
// Added by BVL
TOS_CALL_COMMAND(SIGNAL_ADC_INIT)();
// -----
#ifdef FULLPC
printf("Radio Byte handler initialized.\n");
#endif
return 1;
}
char TOS_COMMAND(RADIO_BYTE_TX_BYTES)(char data){
#ifdef FULLPC_DEBUG
printf("TX_bytes: state=%x, data=%x\n", VAR(state), data);
#endif
if(VAR(state) == 0){
//if currently in idle mode, then switch over to transmit mode
//and set state to waiting to transmit first byte.
VAR(secondary[0]) = data;
VAR(state) = 10;
#ifdef FULLPC
VAR(waiting) = 9;
TOS_SIGNAL_EVENT(RADIO_BYTE_RX_BIT_EVENT)(0);
#endif
return 1;
}else if(VAR(state) == 2){
//if in the middle of a transmission and one byte is encoded
//go to the one byte encoded and one byte in the encode buffer.
VAR(state) = 3;
VAR(secondary[0]) = data;
//schedule the encode task.
TOS_POST_TASK(radio_encode_thread);
return 1;
}else if(VAR(state) == 4){
return 0;
}
return 0;
}
//mode 1 = active;
//mode 0 = sleep;
char TOS_COMMAND(RADIO_BYTE_PWR)(char mode){
if(mode == 0){
//if low power mode, tell lower components
VAR(state) = 0;
TOS_CALL_COMMAND(RADIO_SUB_PWR)(0);
}else{
//set the RMF component into "search for start symbol" mode.
TOS_CALL_COMMAND(RADIO_SUB_PWR)(1);
TOS_CALL_COMMAND(RADIO_SUB_RX_MODE)();
TOS_CALL_COMMAND(RADIO_SUB_SET_BIT_RATE)(0);
VAR(state) = 0;
VAR(count) = 0;
VAR(last_bit) = 0xff;
VAR(waiting) = 0;
}
return 1;
}
char TOS_EVENT(RADIO_BYTE_TX_BIT_EVENT)(){
#ifdef FULLPC_DEBUG
printf("radio tx bit event %d\n", VAR(primary)[2] & 0x1);
#endif
//if we're not it a transmit state, return false.
if(VAR(state) != 2 && VAR(state) != 3 && VAR(state) != 4) return 0;
//send the next bit that we have stored.
TOS_CALL_COMMAND(RADIO_SUB_TX_BIT)(VAR(primary)[2] & 0x01);
//right shift the buffer.
VAR(primary)[2] = VAR(primary)[2] >> 1;
//increment our bytes sent count.
VAR(count) ++;
if(VAR(count) == 8){
//once 8 have gone out, get ready to send out the nibble.
VAR(primary)[2] = VAR(primary)[1];
}else if(VAR(count) == 16){
VAR(primary)[2] = VAR(primary)[0];
}else if(VAR(count) == 18){
if(VAR(state) == 4){
//if another byte is ready, then shift the
//data over to first and second.
VAR(primary)[0] = VAR(secondary)[0];
VAR(primary)[1] = VAR(secondary)[1];
VAR(primary)[2] = VAR(secondary)[2];
VAR(count) = 0;
VAR(state) = 2;//now only one byte is bufferred.
TOS_SIGNAL_EVENT(RADIO_BYTE_TX_BYTE_READY)(1);//fire the byte transmitted
event.
}else{
//if there are no bytes bufferred, go back to idle.
VAR(state) = 0;
TOS_SIGNAL_EVENT(RADIO_BYTE_TX_BYTE_READY)(1);
TOS_SIGNAL_EVENT(RADIO_BYTE_TX_DONE)();
TOS_CALL_COMMAND(RADIO_SUB_RX_MODE)();
TOS_CALL_COMMAND(RADIO_SUB_SET_BIT_RATE)(0);
}
}
return 1;
}
char TOS_EVENT(RADIO_BYTE_RX_BIT_EVENT)(char data){
#ifdef FULLPC
//because the FULLPC version doesn't do 2x sampling, we fake it out with
//this.
VAR(last_bit) = data;
#ifdef FULLPC_DEBUG
printf("RX %d\n", data);
#endif
#endif
if(VAR(state) == 0){
//if we are in the idle state, the check if the bit read
//matches the last bit.
if(VAR(last_bit) != data){
VAR(last_bit) = data;
return 1;
}
//if so, set last bit to invalid,
VAR(last_bit) = 0xff;
//right shift previously read data.
VAR(primary)[2] >>= 1;
//mask out upper bit
VAR(primary)[2] &= 0x7f;
//if lowest bit of first is one, store it in second
if(VAR(primary)[1] & 0x1) VAR(primary)[2] = VAR(primary)[2] | 0x80;
//don't forget that the start symbol is only 9 bits long.
VAR(primary)[1] = data & 0x1;
#ifdef FULLPC_DEBUG
printf("checking for start symbol: %x, %x\n", VAR(primary)[1] & 0xff,
VAR(primary)[2] & 0xff);
#endif
//if you now have the start symbol, go to the waiting for first bit state.
if(VAR(primary)[1] == (char)0x1 && VAR(primary)[2] == (char)0x35){
VAR(state) = 5;
VAR(count) = 0;
//set bit rate so next sample falls in middle of next
//transmitted bit.
TOS_CALL_COMMAND(RADIO_SUB_SET_BIT_RATE)(1);
}
}else if(VAR(state) == 5){
//just read first bit.
//set bit rate to match TX rate.
TOS_CALL_COMMAND(RADIO_SUB_SET_BIT_RATE)(2);
VAR(state) = 6;
VAR(count) = 1;
//store it.
if(data){
VAR(primary)[1] = 0x80;
}else{
VAR(primary)[1] = 0;
}
}else if(VAR(state) == 6){
//clock in bit.
VAR(count)++;
VAR(primary)[1] >>= 1;
VAR(primary)[1] &= 0x7f;
if(data){
VAR(primary)[1] |= 0x80;
TOS_CALL_COMMAND(SIGNAL_ADC_GET_DATA)(0);
}
if(VAR(count) == 8){
VAR(secondary[2]) = VAR(primary[1]);
}else if(VAR(count) == 16){
VAR(count)++;
//sore the encoded data into a buffer.
VAR(secondary)[1] = VAR(primary)[1];
VAR(state) = 7;
//scheduled the decode task.
//TOS_POST_TASK(radio_decode_thread);
}
}else if(VAR(state) == 7){
VAR(secondary)[0] = data;
VAR(state) = 8;
}else if(VAR(state) == 8){
//throw away the higest bit.
VAR(state) = 5;
//scheduled the decode task.
TOS_POST_TASK(radio_decode_thread);
#ifdef FULLPC_DEBUG
printf("entire byte received: %x, %x\n", VAR(secondary)[1], VAR(secondary)[2]);
#endif
}else if(VAR(state) == 10){
//waiting for channle to be idle.
if(data){
//if we just read activity, then reset the waiting counter.
VAR(waiting) = 0;
}else{
VAR(waiting) ++;
//if we've not heard anything for 8 samples then...
if(VAR(waiting) > 8){
//go to the transmitting state.
VAR(state) = 1;
VAR(waiting) = 0;
//schedule task to start transfer, set TX_mode, and set bit rate
TOS_CALL_COMMAND(RADIO_SUB_TX_MODE)();
TOS_CALL_COMMAND(RADIO_SUB_SET_BIT_RATE)(2);
TOS_POST_TASK(radio_encode_thread);
}
}
}
return 1;
}
void encodeData(){
char ret_high = 0;
char ret_low = 0;
char ret_mid = 0;
char val = VAR(secondary[0]);
if((val & 0x1) != 0) {
ret_high ^=0;
ret_mid ^=0x0;
ret_low ^=0x77;
}
if((val & 0x2) != 0) {
ret_high ^=0;
ret_mid ^=0x1;
ret_low ^=0x34;
}
if((val & 0x4) != 0) {
ret_high ^=0;
ret_mid ^=0x2;
ret_low ^=0x32;
}
if((val & 0x8) != 0) {
ret_high ^=0;
ret_mid ^=0x8;
ret_low ^=0x31;
}
if((val & 0x10) != 0) {
ret_high ^=0;
ret_mid ^=0x10;
ret_low ^=0x26;
}
if((val & 0x20) != 0) {
ret_high ^=0;
ret_mid ^=0x60;
ret_low ^=0x25;
}
if((val & 0x40) != 0) {
ret_high ^=0;
ret_mid ^=0x80;
ret_low ^=0x13;
}
if((val & 0x80) != 0) {
ret_high ^=0x1;
ret_mid ^=0;
ret_low ^=0x7;
}
if((ret_low & 0xc) == 0) ret_low |= 0x8;
if((ret_low & 0x40) == 0 && (ret_mid & 0x1) == 0) ret_low |= 0x80;
if((ret_mid & 0xa) == 0) ret_mid |= 0x4;
if((ret_mid & 0x50) == 0) ret_mid |= 0x20;
if((ret_high & 0x1) == 0) ret_high |= 0x2;
VAR(secondary[0]) = ret_high;
VAR(secondary[1]) = ret_mid;
VAR(secondary[2]) = ret_low;
}
char decodeData(){
//strip the data
char ret_high = 0;
char ret_low = 0;
char val, val2, output;
ret_high = (char)((VAR(secondary)[0] << 4) & 0x10);
ret_high |= (char)((VAR(secondary)[1] >> 4) & 0xc);
ret_high |= (char)((VAR(secondary)[1] >> 3) & 0x3);
ret_low = (char)((VAR(secondary)[1] << 6) & 0xc0);
ret_low |= (char)((VAR(secondary)[2] >> 1) & 0x38);
ret_low |= (char)(VAR(secondary)[2] & 0x7);
//check the data
val = ret_low;
val2 = ret_high;
output = 0;
if((val & 0x1) != 0) output ^= 0x1;
if((val & 0x2) != 0) output ^= 0x2;
if((val & 0x4) != 0) output ^= 0x4;
if((val & 0x8) != 0) output ^= 0x8;
if((val & 0x10) != 0) output ^= 0x10;
if((val & 0x20) != 0) output ^= 0x1f;
if((val & 0x40) != 0) output ^= 0x1c;
if((val & 0x80) != 0) output ^= 0x1a;
if((val2 & 0x1) != 0) output ^= 0x19;
if((val2 & 0x2) != 0) output ^= 0x16;
if((val2 & 0x4) != 0) output ^= 0x15;
if((val2 & 0x8) != 0) output ^= 0xb;
if((val2 & 0x10) != 0) output ^= 0x7;
if(output == 0){}
else if(output == 0x1) { val ^= 0x1;}
else if(output == 0x2) { val ^= 0x2; }
else if(output == 0x4) { val ^= 0x4; }
else if(output == 0x8) { val ^= 0x8; }
else if(output == 0x10) { val ^= 0x10;}
else if(output == 0x1f) { val ^= 0x20;}
else if(output == 0x1c) { val ^= 0x40;}
else if(output == 0x1a) { val ^= 0x80;}
else if(output == 0x19) { val2 ^= 0x1; }
else if(output == 0x16) { val2 ^= 0x2; }
else if(output == 0x15) { val2 ^= 0x4; }
else if(output == 0xb) { val2 ^= 0x8; }
else if(output == 0x7) { val2 ^= 0x10;}
//pull off the data bits
output = (char)((val >> 5) & 0x7);
output |= ((char)val2 << 3) & 0xf8;
return output;
}
char TOS_EVENT(SIGNAL_DATA_READY)(int data){
if(VAR(s_count) < 4){
if(data == 0) data = 0x3ff;
VAR(strength) += data;
// BVL
// if(data > VAR(strength))
// VAR(strength)=data;
// ---
VAR(s_count) ++;
}
// XXX
//if (++VAR(led_state) % 2) CLR_GREEN_LED_PIN();
//else SET_GREEN_LED_PIN();
// XXX
return 1;
}