Go Down

Topic: EMF meter using Arduino MEGA2650 (Read 1 time) previous topic - next topic

jonrobertd

So I am completely new to Arduino, and figured I would make this project my first, as I will use it a lot. I know I could have bought one cheaper than all I bought for the project, but I love to tinker, and do some coding, plus there is soooo much I can do with Arduino.

My question is this, I know it is as simple as copying the code for the project, pasting it in software, and uploading it, (but what is the fun in that, I will edit it some). I want to know if anyone else has built one and can give me advice on antenna length and sensitivity?

This is the original site I found the meter on, http://www.hyundaiaftermarket.org/forum/index.php?/blog/3/entry-26-arduino-emf-meter/
and here is the code;
Code: [Select]
/*
   Copyright 2010 Adam N. Outler     Licensed under the Apache License, Version 2.0 (the "License");    you may not use this file except in compliance with the License.    You may obtain a copy of the License at         http://www.apache.org/licenses/LICENSE-2.0     Unless required by applicable law or agreed to in writing, software    distributed under the License is distributed on an "AS IS" BASIS,    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.    See the License for the specific language governing permissions and    limitations under the License. */

//A note on HZ, if you notice meter oscillations on a known steady
//  signal increase or decrease hertz by 1.  The oscillations are
//  caused when the signals are in near-perfect resonance.
float FrequencyToMonitor=59; //hertz


//setup pins
#define ANTENNA 31 //antenna pin
//16 LEDs on 16 different pins
int LEDPin[]={ 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52 } ;
int LEDCount=16;    //number of LEDs

//setup initial global values
int LEDCounter=0;               //initial value of LEDs to display
int HalfPeriodMicroseconds=0;// initial value of halfwavelength

/*
   SETUP defines pins and performs POT(Power On Test) on LEDs
*/
void setup()  {
   double HalfPeriod=((1/FrequencyToMonitor)*.5);   //Half-period in seconds from frequency
   HalfPeriodMicroseconds=int(1000000*HalfPeriod);  //Convert period seconds to microseconds integer

   pinMode(ANTENNA, INPUT);                     //set antenna pin
   for (int Pin=0; Pin < LEDCount; Pin++)  { //initialize each LED
    pinMode(LEDPin[Pin], OUTPUT);         
    digitalWrite(LEDPin[Pin], HIGH);          //Turn the LED on
    delay(50);
    digitalWrite(LEDPin[Pin], LOW);          //Turn the LED back off
   }
   swingLEDs();         //perform LED check to verify LED functionality
}


/*
   LOOP checks for value of antenna to go high and then low
   if change is seen, then 2 LEDs are lit, otherwise total number
   of LEDS are decreased.  This allows for a magentic effect when
   near the field.
*/
void loop(){
   int ANTENNAValue=0;    //sets and resets ANTENNAValue
   int OldANTENNAValue=0; // as well as OldANTENNAValue


   for ( int Pass=0; Pass < 4; Pass++ )  {//take 4 readings
    ANTENNAValue=digitalRead(ANTENNA);    //   from the antenna
    if ( ( ANTENNAValue == HIGH ) && ( OldANTENNAValue == LOW ) ) {
        incrementLED(); //If a change is detected increase twice
        incrementLED(); //   4 passes means 3 changes total
    } else if ( ( ANTENNAValue ==  LOW ) && ( OldANTENNAValue == HIGH ) ) {
        incrementLED(); //   This makes the meter rise by
        incrementLED(); //   a total factor of  2 and
    } else {
        decrementLED(); //   if there is no change it falls by 1
    }
        OldANTENNAValue=ANTENNAValue; //Log old value for next pass
        delayMicroseconds(HalfPeriodMicroseconds);  // half-wave pause before next reading
   }
   delayMicroseconds(HalfPeriodMicroseconds); //visual delay between reading passes
   delayMicroseconds(HalfPeriodMicroseconds); //twice to avoid extremely long numbers   
}


/*
FUNCTION swingLEDs tests the LEDs by lighting
them up sequentially.  Each LED is brought high
then low twice.
*/
void swingLEDs(){
        for (int Pin=0; Pin < LEDCount; Pin++)  {
        digitalWrite(LEDPin[Pin], HIGH);  // instantanious full brightness
   }
   for (int Pin=0; Pin < LEDCount; Pin++)  {
        digitalWrite(LEDPin[Pin], LOW);   // clear LEDs from left to right
        delay(20);
   }
   for (int Pin=LEDCount; Pin > -1; Pin--)  {
        digitalWrite(LEDPin[Pin], HIGH);  // light LEDs from right to left
        delay(20);
   }
   for (int Pin=LEDCount; Pin > -1; Pin--)  {
        digitalWrite(LEDPin[Pin], LOW);   // clear LEDs from right to left
        delay(20);
   }
}

/*
FUNCTION incrementLED increases the number
of LEDs lit by 1. 
*/
void incrementLED(){
    if ( LEDCounter <  LEDCount  - 1  ){ LEDCounter++;} //if not max increase
    digitalWrite(LEDPin[LEDCounter], HIGH); //light new LED
}

/*
FUNCTION decrementLED decreases the number
of LEDs lit by 1.
*/
void decrementLED(){
   digitalWrite(LEDPin[LEDCounter], LOW); //turn off current LED
   if ( LEDCounter >= 0 ){ LEDCounter-- ;} // if not zero, decrease}


Thank you for your help and advice!

jonrobertd

#1
Jun 05, 2013, 07:40 pm Last Edit: Jun 05, 2013, 07:55 pm by jonrobertd Reason: 1
So I have built it, and am having issues. it runs through power on test fine, then when I go to use it only some of the LEDs light up and do not reset back to zero, mainly every other LED lights up to one below pegged and just stays there untill I turn it off. Anyone got any ideas?

EDIT: I tried switching led pins to all odd and antenna to pin 22 and get the same results, is there a problem with the code I am missing or is there a problem with my Arduino?

PeterH

Are you using the software and hardware exactly the same as shown?
I only provide help via the forum - please do not contact me for private consultancy.

jonrobertd

Everything is exactly the same. He is using a mega, just not sure if it is a 2650 ver.xxx or an earlier one but it looks just like mine. I don't know what could be wrong.

AWOL

Am I missing something here?
EMF = electromotive force, or, more simply, voltage.

Where does frequency come in to it?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

pito


AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

BillHo

Electro Magnetic Field  or Electro Magnetic Force, normally 60Hz on AC supply with transformer.


Everything is exactly the same. He is using a mega, just not sure if it is a 2650 ver.xxx or an earlier one but it looks just like mine. I don't know what could be wrong.

Can post a picture on how you connect up?

jonrobertd

#8
Jun 06, 2013, 05:52 pm Last Edit: Jun 06, 2013, 06:19 pm by jonrobertd Reason: 1
here is a short video of my meter:
http://youtu.be/P_ysetvrFNE

And his meter:
http://youtu.be/FcFQZP5CyoM

and a pic of wiring and connections:


EDIT: I changed LED pin assignments to pins 6-12 with the antenna on pin 5 with the same results, so it has to be a problem with the code, right?  I hope my board is not messed up as I just bought it.

jonrobertd

I have been doing other projects with my board and they run just fine, so I guess it is the code. I am at a loss as far as fixing it so any help is welcome and appreciated.

jonrobertd

#10
Jun 10, 2013, 03:31 am Last Edit: Jun 10, 2013, 08:37 pm by jonrobertd Reason: 1
Well it turns out it was the code. Still don't understand how or where, but I rewrote another code and it works. Thanks.

jonrobertd

This is the code I tweaked to get my EMF meter working:

Code: [Select]
// EMF Detector for LED Bargraph v1.0
// 5.12.2009
// original code/project by Aaron ALAI - aaronalai1@gmail.com
// modified for use w/ LED bargraph by Collin Cunningham - collin@makezine.com
// modified to use on MEGA with sensitivity and feild detection changes by Jon D.

#define NUMREADINGS 15 // raise this number to increase data smoothing

int senseLimit = 5; // raise this number to decrease sensitivity (up to 1023 max)
int probePin = 5; // analog 5
int val = 0; // reading from probePin

int LED1 = 52; // connections
int LED2 = 50; // to
int LED3 = 48; // LED
int LED4 = 46; // bargraph
int LED5 = 44; // anodes
int LED6 = 42; // with
int LED7 = 40; // resistors
int LED8 = 38; // in
int LED9 = 36; // series
int LED10 = 34; //
int LED11 = 32; //
int LED12 = 30; //
int LED13 = 28; //
int LED14 = 26; //
int LED15 = 24; //
int LED16 = 22; //

// variables for smoothing

int readings[NUMREADINGS];                // the readings from the analog input
int index = 0;                            // the index of the current reading
int total = 0;                            // the running total
int average = 0;                          // final average of the probe reading


void setup() {

pinMode(22, OUTPUT); // specify LED bargraph outputs
pinMode(24, OUTPUT);
pinMode(26, OUTPUT);
pinMode(28, OUTPUT);
pinMode(30, OUTPUT);
pinMode(32, OUTPUT);
pinMode(34, OUTPUT);
pinMode(36, OUTPUT);
pinMode(38, OUTPUT);
pinMode(40, OUTPUT);
pinMode(42, OUTPUT);
pinMode(44, OUTPUT);
pinMode(46, OUTPUT);
pinMode(48, OUTPUT);
pinMode(50, OUTPUT);
pinMode(52, OUTPUT);

  Serial.begin(9600);  // initiate serial connection for debugging/etc

  for (int i = 0; i < NUMREADINGS; i++)
    readings[i] = 0;                      // initialize all the readings to 0
}

void loop() {

  val = analogRead(probePin);  // take a reading from the probe

  if(val >= 1){                // if the reading isn't zero, proceed

    val = constrain(val, 1, senseLimit);  // turn any reading higher than the senseLimit value into the senseLimit value
    val = map(val, 1, senseLimit, 1, 1023);  // remap the constrained value within a 1 to 1023 range

    total -= readings[index];               // subtract the last reading
    readings[index] = val; // read from the sensor
    total += readings[index];               // add the reading to the total
    index = (index + 1);                    // advance to the next index

    if (index >= NUMREADINGS)               // if we're at the end of the array...
      index = 0;                            // ...wrap around to the beginning

    average = total / NUMREADINGS;          // calculate the average


if (average > 50){ // if the average is over 50 …
digitalWrite(LED1, HIGH); // light the first LED
}
else{ // and if it's not …
digitalWrite(LED1, LOW); // turn that LED off
}

if (average > 100){ // and so on …
digitalWrite(LED2, HIGH);
}
else{
digitalWrite(LED2, LOW);
}

if (average > 150){
digitalWrite(LED3, HIGH);
}
else{
digitalWrite(LED3, LOW);
}

if (average > 200){
digitalWrite(LED4, HIGH);
}
else{
digitalWrite(LED4, LOW);
}

if (average > 250){
digitalWrite(LED5, HIGH);
}
else{
digitalWrite(LED5, LOW);
}

if (average > 300){
digitalWrite(LED6, HIGH);
}
else{
digitalWrite(LED6, LOW);
}

if (average > 350){
digitalWrite(LED7, HIGH);
}
else{
digitalWrite(LED7, LOW);
}

if (average > 400){
digitalWrite(LED8, HIGH);
}
else{
digitalWrite(LED8, LOW);
}

if (average > 450){
digitalWrite(LED9, HIGH);
}
else{
digitalWrite(LED9, LOW);
}

if (average > 500){
digitalWrite(LED10, HIGH);
}
else{
digitalWrite(LED10, LOW);
}

if (average > 550){
digitalWrite(LED11, HIGH);
}
else{
digitalWrite(LED11, LOW);
}

if (average > 600){
digitalWrite(LED12, HIGH);
}
else{
digitalWrite(LED12, LOW);
}

if (average > 650){
digitalWrite(LED13, HIGH);
}
else{
digitalWrite(LED13, LOW);
}

if (average > 700){
digitalWrite(LED14, HIGH);
}
else{
digitalWrite(LED14, LOW);
}

if (average > 800){
digitalWrite(LED15, HIGH);
}
else{
digitalWrite(LED15, LOW);
}

if (average > 900){
digitalWrite(LED16, HIGH);
}
else{
digitalWrite(LED16, LOW);
}


    Serial.println(val); // use output to aid in calibrating
  }
}



Now, could someone please help me to get this to play an audible tone on pin 11to an 8 ohm speaker, something simple like a beep, beep every second that the highest pin (LED 16, pin 52) is on. I have the setup from the example tone code with the pitches.h file and am pretty sure I would have to add it to it, but have no Idea how to implement it here. Thank you

jonrobertd

So I have the emf meter working perfectly until I add in the tone. Once it hits the level the tone starts, it hangs, gradually lighting an LED every second beep for a few LEDs then decreases one until it hits LED 8 (the tone LED) and hangs. I modified the tone example to suit my needs in this application, but have no idea why it hangs there once it hits level 8. Any help is greatly appreciated.
Code: [Select]
// EMF Detector for LED Bargraph v1.0
// 5.12.2009
// original code/project by Aaron ALAI - aaronalai1@gmail.com
// modified for use w/ LED bargraph by Collin Cunningham - collin@makezine.com
// modified to use on MEGA with sensitivity and feild detection changes by Jon D.

#include "pitches.h"
#define NUMREADINGS 20// raise this number to increase data smoothing

int senseLimit = 3; // raise this number to decrease sensitivity (up to 1023 max)
int probePin = 5; // analog 5
int val = 0; // reading from probePin

int LED1 = 52; // connections
int LED2 = 50; // to
int LED3 = 48; // LED
int LED4 = 46; // bargraph
int LED5 = 44; // anodes
int LED6 = 42; // with
int LED7 = 40; // resistors
int LED8 = 38; // in
int LED9 = 36; // series
int LED10 = 34; //
int LED11 = 32; //
int LED12 = 30; //
int LED13 = 28; //
int LED14 = 26; //
int LED15 = 24; //
int LED16 = 22; //

// variables for smoothing

int readings[NUMREADINGS];                // the readings from the analog input
int index = 0;                            // the index of the current reading
int total = 0;                            // the running total
int average = 0;                          // final average of the probe reading


void setup() {

pinMode(22, OUTPUT); // specify LED bargraph outputs
pinMode(24, OUTPUT);
pinMode(26, OUTPUT);
pinMode(28, OUTPUT);
pinMode(30, OUTPUT);
pinMode(32, OUTPUT);
pinMode(34, OUTPUT);
pinMode(36, OUTPUT);
pinMode(38, OUTPUT);
pinMode(40, OUTPUT);
pinMode(42, OUTPUT);
pinMode(44, OUTPUT);
pinMode(46, OUTPUT);
pinMode(48, OUTPUT);
pinMode(50, OUTPUT);
pinMode(52, OUTPUT);

  Serial.begin(9600);  // initiate serial connection for debugging/etc

  for (int i = 0; i < NUMREADINGS; i++)
    readings[i] = 0;                      // initialize all the readings to 0
}

void loop() {

  val = analogRead(probePin);  // take a reading from the probe

  if(val >= 1){                // if the reading isn't zero, proceed

    val = constrain(val, 1, senseLimit);  // turn any reading higher than the senseLimit value into the senseLimit value
    val = map(val, 1, senseLimit, 1, 1023);  // remap the constrained value within a 1 to 1023 range

    total -= readings[index];               // subtract the last reading
    readings[index] = val; // read from the sensor
    total += readings[index];               // add the reading to the total
    index = (index + 1);                    // advance to the next index

    if (index >= NUMREADINGS)               // if we're at the end of the array...
      index = 0;                            // ...wrap around to the beginning

    average = total / NUMREADINGS;          // calculate the average


if (average > 50){ // if the average is over 50 …
digitalWrite(LED1, HIGH); // light the first LED
}
else{ // and if it's not …
digitalWrite(LED1, LOW); // turn that LED off
}

if (average > 100){ // and so on …
digitalWrite(LED2, HIGH);
}
else{
digitalWrite(LED2, LOW);
}

if (average > 150){
digitalWrite(LED3, HIGH);
}
else{
digitalWrite(LED3, LOW);
}

if (average > 200){
digitalWrite(LED4, HIGH);
}
else{
digitalWrite(LED4, LOW);
}

if (average > 250){
digitalWrite(LED5, HIGH);
}
else{
digitalWrite(LED5, LOW);
}

if (average > 300){
digitalWrite(LED6, HIGH);
}
else{
digitalWrite(LED6, LOW);
}

if (average > 350){
digitalWrite(LED7, HIGH);
}
else{
digitalWrite(LED7, LOW);
}

if (average > 400){
digitalWrite(LED8, HIGH);
int melody[] = {
  NOTE_C4 };

int noteDurations[] = {
  4 };
 
  for (int thisNote = 0; thisNote < 8; thisNote++) {

    int noteDuration = 1000/noteDurations[thisNote];
    tone(8, melody[thisNote],noteDuration);


    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);
    noTone(8);
  }
}
else{
digitalWrite(LED8, LOW);
}

if (average > 450){
digitalWrite(LED9, HIGH);
}
else{
digitalWrite(LED9, LOW);
}

if (average > 500){
digitalWrite(LED10, HIGH);
}
else{
digitalWrite(LED10, LOW);
}

if (average > 550){
digitalWrite(LED11, HIGH);
}
else{
digitalWrite(LED11, LOW);
}

if (average > 600){
digitalWrite(LED12, HIGH);
}
else{
digitalWrite(LED12, LOW);
}

if (average > 650){
digitalWrite(LED13, HIGH);
}
else{
digitalWrite(LED13, LOW);
}

if (average > 700){
digitalWrite(LED14, HIGH);
}
else{
digitalWrite(LED14, LOW);
}

if (average > 800){
digitalWrite(LED15, HIGH);
}
else{
digitalWrite(LED15, LOW);
}

if (average > 900){
digitalWrite(LED16, HIGH);
}
else{
digitalWrite(LED16, LOW);
}


    Serial.println(val); // use output to aid in calibrating
  }
}

1ChicagoDave

  for (int thisNote = 0; thisNote < 8; thisNote++) {

Should this perhaps be....

  for (int thisNote = 0; thisNote <= 8; thisNote++) {

....instead?

jonrobertd

Thanks for the help, but that's a no go. Still doing same thing. It's weird because it works ok as long as the reading is 7 or below, but as soon as it hits 8 it hangs up like there is something not telling it to turn back off if the reading is lower, or keep lighting up if it is higher.

Go Up