Proton BASIC Compiler - Simple EMI detector


  • PicŪ Basic


  • Simple EMI detector

    Here's a very simple, but remarkably effective, EMI (Electro Magnetic Interference) detector using a single microcontroller and 8 LEDs.

    The code is written for the Amicus18 board, which uses a PIC18F25K20 microcontroller operating at 64MHz, however, the code lends itself to, pretty much, any device.

    The interesting part of the code is not the detection itself, but the Map8 macro which can scale one unsigned integer value to another unsigned integer value. With simple changes to the variable types used, it is also able to scale other sized values. i.e. signed or unsigned 16-bit, 32-bit or floats.

    Code:
    '*************************************************************************************************************
    '* This source code is provided 'as is' and any express or implied warranties, including,                    *
    '* but not limited to, the implied warranties of merchantability and fitness for a particular                *
    '* purpose are disclaimed.                                                                                   *
    '*                                                                                                           *
    '* In no event shall the author, Crownhill or contributers be liable for any direct, indirect, incidental,   *
    '* special, exemplary, or consequential damages (including, but not limited to,  procurement of substitute   *
    '* goods or services; loss of use, data, or profits; or business interruption) however caused and on any     *
    '* theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise)   *
    '* arising in any way out of the use of this source code, even if advised of the possibility of such damage. *
    '*                                                                                                           *
    '* Any views and conclusions contained in the source code and any documentation are those of the author's    *
    '* and should not be interpreted as representing official policies,                                          *
    '* either expressed or implied, of Crownhill Associates Ltd.                                                 *
    '*************************************************************************************************************
    '
    ' EMI (Electro Magnetic Interference) detector
    ' 
    ' Connect 8 LEDs to PORTB
    ' Connect a short wire approx 10cm to PORTA.0 (AN0) to act as an antenna
    ' Connect a 10K potentiometer from VREF+ to Vdd/Vcc for sensitivity
    ' 
    ' The LEDs will progressively illuminate as more EMI is detected
    '
    ' Written by Les Johnson for the Proton BASIC compiler version 3.5.5.4
    '
    ' Circuit layout:
    '
    '            |        \   /
    '            |         \_/  Antenna (approx 10cm)     
    '            |          |                           _ _+3.3V
    '     PORTA.0|__________|                            |
    '            |                                      _|_
    '            |                                     |   |
    '       VREF+|____________________________________||   | 10K Pot
    '            |                                    ||   |Sensitivity
    '            |                                     |_ _|
    '            |                                       |
    '            |                                      _|_ GND
    '            |                                         
    '     PORTB.0|_________________________________________________________________________________
    '     PORTB.1|_______________________________________________________________________          |
    '     PORTB.2|_____________________________________________________________          |         |
    '     PORTB.3|___________________________________________________          |         |         |
    '     PORTB.4|_________________________________________          |         |         |         |
    '     PORTB.5|_______________________________          |         |         |         |         |
    '     PORTB.6|_____________________          |         |         |         |         |         |  
    '     PORTB.7|___________          |         |         |         |         |         |         |
    '            |           |         |         |         |         |         |         |         |
    'PIC18F25K20 |          _|_       _|_       _|_       _|_       _|_       _|_       _|_       _|_
    '____________|         |330|     |330|     |330|     |330|     |330|     |330|     |330|     |330|
    '                      |_ _|     |_ _|     |_ _|     |_ _|     |_ _|     |_ _|     |_ _|     |_ _|
    '                        |         |         |         |         |         |         |         |
    '                       _|_ LED8  _|_ LED7  _|_ LED6  _|_ LED5  _|_ LED4  _|_ LED3  _|_ LED2  _|_ LED1
    '                      _\_/_     _\_/_     _\_/_     _\_/_     _\_/_     _\_/_     _\_/_     _\_/_
    '                        |         |         |         |         |         |         |         |
    '                        |         |         |         |         |         |         |         |                                  
    '                        |_________|_________|_________|_________|_________|_________|_________|
    '                                                     GND
    '
        Include "Amicus18.inc"                      ' Configure the compiler to use the Amicus18 hardware (18F25K20, 64MHz)
        Include "Amicus18_ADC.inc"                  ' Load the Amicus18 ADC routines into the program
    
        Dim ADC_Result As Byte                      ' Create an 8-bit unsigned variable to hold the result of the ADC
    '
    ' Create variables used within the scaling subroutine
    '
        Dim Map_wTemp As Word                       ' Holds the result of the scale calculation
        Dim Map_bXin As Byte                        ' Holds the value to Scale
        Dim Map_bInMin As Byte                      ' Lower bound of the value's current range
        Dim Map_bInMax As Byte                      ' Upper bound of the value's current range
        Dim Map_bOutMin As Byte                     ' Lower bound of the value's target range
        Dim Map_bOutMax As Byte                     ' Upper bound of the value's target range
        
    '-----------------------------------------------------------------------------------------   
        GoTo Main                                   ' Jump over the subroutines
    '-----------------------------------------------------------------------------------------
    ' Scale one 8-bit value to another 8-bit value
    ' Input     : Map_bXin holds the value to scale
    '           : Map_bInMin is the lower bound of the value's current range
    '           : Map_bInMax is the upper bound of the value's current range
    '           : Map_bOutMin is the lower bound of the value's target range
    '           : Map_bOutMax is the upper bound of the value's target range
    ' Output    : Map_wTemp holds the result
    ' Notes     : None
    '
    $define Map8(pX, pInMin, pInMax, pOutMin, pOutMax, pResult) '
        Map_bXin = pX         '
        Map_bInMin = pInMin   '
        Map_bInMax = pInMax   '
        Map_bOutMin = pOutMin '
        Map_bOutMax = pOutMax '
        _Map8                 '
        pResult = Map_wTemp
    
    _Map8 Macro-
        GoSub __Map8
    Endm
    
    #ifMacro- _Map8
    __Map8:
        If Map_bXin = 0 Then
            Map_wTemp = 0
        Else
            Map_bXin = Map_bXin - Map_bInMin
            Map_bOutMax = Map_bOutMax - Map_bOutMin
            Map_wTemp = Map_bXin * Map_bOutMax
            Map_bXin = Map_bInMax - Map_bInMin
            Map_bOutMax = Map_wTemp / Map_bXin
            Map_wTemp = Map_bOutMax + Map_bOutMin
        EndIf
        Return
    #endIfMacro-
    
    '------------------------------------------------------------------------------------------------
    ' Display the bar on the LEDs
    ' Input     : ADC_Result holds the scaled value 0 to 9
    ' Output    : None
    ' Notes     : None
    '
    Display_LEDs:  
        PORTB = LookUp ADC_Result,[0,1,3,7,15,31,63,127,255,255] 
        DelayMS 1                                           ' Keep the LED illuminated for a small amount of time
        Return
    
    '------------------------------------------------------------------------------------------------
    ' The main program starts here
    ' 
    Main:
        Low PORTB                                           ' Extinguish all the LEDs before we start
    '
    ' Open the Analogue to Digital Converter for 8-bit operation
    '
        OpenADC(ADC_FOSC_32 & ADC_LEFT_JUST & ADC_2_TAD, ADC_REF_VREFPLUS_VSS, ADC_1ANA)
    
        While                                               ' Create an infinite loop
            ADC_Result = ReadADC(ADC_CH0)                   ' Take a reading from AN0 (ADC channel 0)
            Map8(ADC_Result, 0, 255, 0, 9, ADC_Result)      ' Scale a value of 0 to 255 to a value of 0 to 9
            GoSub Display_LEDs                              ' Convert the value into an LED bar
        Wend                                                ' Do it forever
    This article was originally published in forum thread: Simple EMI detector started by Les View original post