Extremely Low Frequency Electro Magnetic Field Sensing (Part 5)

Part 1234, 5

Time for upgrade. The pretty popular ELFEMF posts were prepared before the obsolescence of PlainADC and PlainFFT libraries.  Next is the revised code for the detection of Extremely Low Frequency Electromagnetic Fields which is compatible with PlainDSP library. So simple and yet powerful application! Enjoy.

/*
 
	MicroELF_EMF: Electrical radiation measurement
	Revision 03

	Applicable license :

	This program and related documentation are owned by HL2 group SAS. 
	The program is subject to the license GNU GPL version 3. This license 
	allows you to use, reproduce and adapt this program for private, 
	educational, research purposes. 
	
*/

#include <PlainDSP.h>

/* Create objects */
PlainDSP DSP;

const uint8_t ctrlLedMask = (1 << PINB5);

/* Acquisition parameters */
const uint16_t _samples = 128; /* Max value depends upon available memory space */
const float _samplingFrequency = 400.0; /* From 0.125 Hz to 80 kHz */
const uint16_t _adcChannel = 0; /* From 0 to 5 on ATmega328 powered Arduino */
const uint16_t _refVoltage = DSP_REF_VOL_INTERNAL; /* Internal: 1.1V */
const uint8_t _options = (DSP_OPT_DIS_TIM_0 | DSP_OPT_DIS_TIM_2 | DSP_OPT_NOI_CANCELLER);
/* Display parameters */
const float _targetFrequency = 50.0;
const float _frequencyTolerance = 5.0;
const uint16_t _maxOnTime = 600;

void setup(void)
{
	/* Initialize serial comm port */
	Serial.begin(115200); 
	/* Set data acquisition parameters */
	DSP.SetAcquisitionEngine(_adcChannel, _refVoltage,  _samplingFrequency, _samples, _options);
	/* Init control LED */
	DDRB |= ctrlLedMask;
}


void loop(void)
{
	/* Acquire data from selected channel */
	DSP.GetScanData(); 
	/* Null offset */
	DSP.ResetOffset();
	/* Weight data */
	DSP.Windowing(DSP_WIN_TYP_HANN, DSP_FORWARD);	
	/* Compute FFT */
	DSP.ComputeForwardFFT();	
	/* Compute amplitudes */
	DSP.ComplexToReal(DSP_SCL_TYP_AMPLITUDE);
	/* Find target peak */
	struct strPeakProperties targetPeak;
	DSP.TargetPeak(_targetFrequency, _frequencyTolerance, &targetPeak);
	/* Compute blink on/off ratio */
	uint16_t onTime = uint16_t(targetPeak.height);
	if (onTime > _maxOnTime) {
		onTime = _maxOnTime;
	}	
	uint16_t offTime = (_maxOnTime - onTime);
	/* Control LED */
	PORTB |= ctrlLedMask; /* Toggle control led on */
	delay(onTime);
	PORTB &= ~ctrlLedMask; /* Toggle control led off */
	delay(offTime);
	/* Optionally print data */
	// Serial.print((millis() / 1000.0), 3);
	// Serial.print(';');
	// Serial.print(targetPeak.height, 2);
	// Serial.println();
}

Reminder: Just insert the bare end from a piece of insulated wire (~20 cm long) in the analog port 0. Power the arduino board, upload the code. The internally built LED (Digital port 13) will blink according to the magnetic field strength… The closer you get from an AC line or a power distribution point, the longer the on state of the LED.

Warning: Do not touch live power lines, sockets or equipment with the wire!

 

 

Leave a Reply

You must be logged in to post a comment.