Things used in this project

Hardware components:
Hexiwear docking bd
NXP Hexiwear
Hexiwear Unit and Docking Station
×1
MikroElektronika RF Meter Click MIKROE-2034
1 MHz-8 GHz RF Power Meter, using Analog Devices AD8318
×3
Coax Cable
Any coax to connect the RF splitters. The two paths on each splitter should have a 3 inch difference in length between them in order to estimate frequency
×2
Antenna, Rubber duck style, or a wire
Any antenna to pick up signals
×1
Audio Indicator
Optional Beeper instead of using Hexiwear Vibro
×1
RF Splitter
Any wideband RF splitter, including TV splitters can be substituted, Like Walmart Monoprice 110013
×3
Software apps and online services:
ARM mbed.org Online Compiler
Putty
For serial com monitor
Hexi Blinky Example
Hexi OLED Text Example
Hexi Vibro Example
Hand tools and fabrication machines:
RF Signal Generator
Optional, to calibrate frequency and power
09507 01
Soldering iron (generic)
Optional, to solder in beeper instead of using Hexiwear Vibro motor
Oscilloscope
For troubleshooting & verification

Custom parts and enclosures

HexiWear RF Scanner
Draft of RF Scanner Enclosure
RFScanner v0.f3d

Schematics

Schematic Diagram
Hook Up Diagram for HexiWear, RF Clicks, RF Splitters, Coax, and Antenna
Blockdiagram

Code

mainC/C++
Main Program, Reads two RF Clicks and shows power and frequency on display along with alarm status based on thresholds of RF energy levels
#include "mbed.h"
#include "Hexi_OLED_SSD1351.h"
#include "Hexi_KW40Z.h"
#include "string.h"
#include "math.h"

 DigitalOut cs1(PTC4); // Dock 1
 DigitalOut greenLed(LED2,1); // To indicate some signals present
 DigitalOut redLed(LED1,1);  // To indicate siganls above alarm threshold
 DigitalOut spi_clk(PTC5);  // CLK Coms to RF Click
 DigitalIn spi_dat(PTC7);   // DATA Coms to RF Click
 DigitalOut vibro(PTB9);    // TO indicate signals above alarm threshold
 DigitalIn up_btn(PTA12,PullDown);
 DigitalIn down_btn(PTA13,PullDown);
 DigitalOut cs2(PTC3); // Dock 2

Serial pc(USBTX,USBRX);
 /* Instantiate the Hexi KW40Z Driver (UART TX, UART RX) */ 
KW40Z kw40z_device(PTE24, PTE25);

/* Instantiate the SSD1351 OLED Driver */ 
SSD1351 oled(PTB22,PTB21,PTC13,PTB20,PTE6, PTD15); /* (MOSI,SCLK,POWER,CS,RST,DC) */

int main() {
    unsigned int i;
    unsigned int mydata1,mydata2;
    unsigned int max1,max2;
    unsigned int min1,min2;
    unsigned int mysum1,mysum2;
    unsigned int ave1,ave2;
    unsigned int lut[]={0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 1024, 2048};
    unsigned int ave_samples1[10];
    unsigned int ave_samples2[10];
    unsigned int icount;
    unsigned int j;
    unsigned int num_ave;
    unsigned char trigger_vibro;
    unsigned int vibro_count;
    unsigned int loop_count;
    float pwr1;
    float frq;
    int delta;
    unsigned int longterm_ave;
    unsigned long longterm_sum;
    int threshold;
    float threshold_dbm;
    
     char text[20];  /* Text Buffer */ 
     vibro=0;
     greenLed=0;
     wait(0.25);
     greenLed=1;
     wait(0.25);
     greenLed=0;
     wait(0.25);
     greenLed=1;
   
   
     
 printf("\n\r--------------------\n\rProgram Started!\n\r---------------------------\n\r");    
    /* Get OLED Class Default Text Properties */
    oled_text_properties_t textProperties = {0};
    oled.GetTextProperties(&textProperties);    

    /* Turn on the backlight of the OLED Display */
    oled.DimScreenON();
    
    /* Fills the screen with solid black */         
    oled.FillScreen(COLOR_BLACK);

    /* Display Text at (x=7,y=0) */
    strcpy((char *) text,"Radio Energy");
    oled.Label((uint8_t *)text,7,0);
        
    /* Change font color to blue */ 
    textProperties.fontColor   = COLOR_BLUE;
    oled.SetTextProperties(&textProperties);

    /* Set text properties to white and right aligned for the dynamic text */
    textProperties.fontColor = COLOR_WHITE;
    textProperties.alignParam = OLED_TEXT_ALIGN_RIGHT;
    oled.SetTextProperties(&textProperties);    

    num_ave=10;
    min1=9999;
    min2=9999;
    max1=0;
    max2=0;
    icount=0;
    trigger_vibro=0;
    loop_count=0;
    threshold=3000;  // Default Red LED threshold
    
    while (true) {
       loop_count++;
       // Process Statistics
       min1=9999;
       min2=9999;
       max1=0;
       max2=0;
       mysum1=0;
       mysum2=0;
       for(j=0;j<num_ave;j++)
       {
         mysum1=mysum1+ave_samples1[j];
         mysum2=mysum2+ave_samples2[j];
         if(ave_samples1[j]<min1)min1=ave_samples1[j];
         if(ave_samples2[j]<min2)min2=ave_samples2[j];
         if(ave_samples1[j]>max1)max1=ave_samples1[j];
         if(ave_samples2[j]>max2)max2=ave_samples2[j];
        }         
        ave1=mysum1/num_ave;
        ave2=mysum2/num_ave;
        if(icount>=num_ave) icount=0;
         
         if (min1<2400)// Hard coded threshold for green LED
         {
             greenLed=0;
         }else
         {
             greenLed=1;
         }

        if (min1<threshold)
        {
            redLed=0;
            greenLed=1;
            trigger_vibro=1;
        }else
        {
            trigger_vibro=0;
        }

    if(trigger_vibro)
    {
        vibro_count=1;
        redLed=0;
        vibro=1;
    }
    else
    {
        vibro_count++;
        if(vibro_count>200)
        {
            vibro=0;
            redLed=1;
        }
    }
        


// We are doing a Bit Bang SPIbecause mbed.org spi.frequency(F) runs clock at >15 MHz, regardless of F
// RF Click can not sampel at that speed
// Clock 2 ycls, then clock 12 to read 12 bits of data out
    // Chips must be deselected
    cs1 = 1;
    cs2 = 1;
    
 // Read Dock 1
    cs1 = 0;
    mydata1=0;
    for (i=0;i<14;i++)  
    {
        spi_clk=0;
        spi_clk=1;
        if(i>2)
        {
            if(spi_dat.read())
            {      
            mydata1=mydata1+lut[13-i+1];
            }
        }
    }
    spi_clk=0;
   
// Read Dock 2   
    cs1=1;
    cs2=0;
    mydata2=0;
    for(i=0;i<14;i++)
    {
        spi_clk=0;
        spi_clk=1;
   
        if(i>2)
        {
            if(spi_dat.read())
            {
                    mydata2=mydata2+lut[13-i+1];
            }
        }
    }  
    spi_clk=0;
   cs2=1;

// Fill a running buffer   
ave_samples1[icount]=mydata1;
ave_samples2[icount]=mydata2;
icount++;
 longterm_sum=longterm_sum+ave1;
 if(loop_count>20000)  // Only update tghe display ocassionally, as sampling ADC more important to catch RF energy in pulses
 {
    // Update red LED threshold if user uis pressing buttons to change
    if(up_btn.read())threshold=threshold+100;
    if(down_btn.read())threshold=threshold-100;
    if(threshold>3300) threshold=3300;  //No signal ADC values
    if(threshold<100) threshold=100;
    
    threshold_dbm=(-0.020*threshold)+23;  // Calculate threshold in dBm from counts
    longterm_ave=longterm_sum/(loop_count-1);
    longterm_sum=0;
    loop_count=0;   
    pwr1=(-0.020*mydata1)+23.0;  // this converts counts to dBm (RF power referenced in dB to 1 mW)
    delta=mydata2-mydata1;   // Calculate difference between main channel and other channel
    frq=0.436+.0015*delta-5.886e-7*delta*delta;  // This calculates approximate frequency
    sprintf(text,"Set:%.1fdBm", threshold_dbm);
    /* Display time reading in 35px by 15px textbox at(x=2, y=40) */
    oled.TextBox((uint8_t *)text,2,25,80,15); //Increase textbox for more digits
    sprintf(text,"Now:%.1fdBm",pwr1);
    oled.TextBox((uint8_t *)text,2,45,80,25);
  
    if(frq<0.7)  // Its flat below 700 MHz, cant really declare a frequency
    {
       sprintf(text,"F=    <0.7 GHz");
    }
    else
    {
       sprintf(text,"F=    %.1f",frq);
    }
    oled.TextBox((uint8_t *)text,2,65,80,25);
   // Print some debug info to serial port
   printf("flr: %i frq:%.2f Min: %i\tNow: %.1f\tAve: %i\tMax: %i\t\tMin: %i\tNow: %i\tAve: %i\tMax: %i\t\n\r",longterm_ave,frq,min1,pwr1,ave1,max1,min2,mydata2,ave2,max2);
   }
 }
 
    printf("\n\r ---- Program Complete ----- \n\r");
}

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login