Tecnicamente's Weblog

Just another WordPress.com weblog

Archivi delle etichette: Arduino

Arduino and EMF detector

Usually I write my short note in italian, but I guess that sometime is better switch to english due to the fact that I can “improve” and I can reach more people in the web, so why do not start to write my post in english? (or better, I’m try to do that 😉 ).

OK let’s go, in some of my previous post I described my little project around an EMF detector using arduino, please read this, this and this.

Thanks to this project I had the opportunity to investigate some interesting things like:

  • Theory of antenna;
  • Digital filters;
  • The use of millis() in order to emulate a multitasking on my Arduino Uno;
  • Fourier transform.

Very interesting topics, so I can say that my project isn’t completed, but it gave me a lot of points where I can study and enlarge my knoledge.

Coming to the project I can write a simple sentence that can summarize the result: “ALL EMF DETECTOR PROJECTS THAT USE ARDUINO, WIRES AND RESISTORS ARE BULLSHIT”

First of all you cannot read or measure MAGNETIC FIELS, but only ELECTRIC FIELDS, so what you can see directly whit you arduino is the variation of the electric field in the enviroment.

Here in Italy the frequency of the electric lines is 50Hz, so I guess that the variation of the EF is reletad to this frequency, but please look at next picture:

5msYou can see the measurement with different antennas, the results is that the antenna is not so importat about the frequency, and that the frequencies are quite far from 50Hz, very strange. I’m aquiring the data at 200Hz in order to avoid the aliasing with a signal of 50Hz.

In the next picture you can see the aquisition of data near to electric light, the variation of the EF is measured but there is no changes on the FFT analysis, so the main frequency of the field is  about 250 Hz as before

5ms-sorgente

The question is what is the reason for a EF at 250Hz? Nice to investigate.

Now what appen if I change the sample rate from 200Hz to 100Hz.

Here the result:

10ms

And now what I find at 50Hz of sample rate:

20ms

Someone can suggest howto detect the field at 50Hz?

I used different leght for antennas and impedence, but the only thing that seems focus on the EF frequency is the sample rate.
Here the code, very raw 😉

#include <Arduino.h>
#define VERSIONE 4.01-27/10/2014
#define C 0.0048828125
#define T1 20
#define T2 60000

int flag = 0;

void waitForFlush(void){
/*******************************************
* scopo di questa funzione e non impegnare *
* la comunicazione seriale nei primi X *
* secondi. In tal modo il flush e sempre *
* facilmente realizzabile. *
*******************************************/
#define TIMETOWAIT 5000 /* ms */
unsigned long t0,t1;

t0 = millis();
t1 = millis();

while( t1-t0 < TIMETOWAIT){
   t1 = millis();
}
}
void setup(){
/*attivo la comunicazione seriale */
Serial.begin(57600);

/*do disponibilità a flush del controllore*/
waitForFlush();

/*Intezzazione del programma */
Serial.print("EMF DETECTOR V. ");
Serial.println(VERSIONE);
}
float valore, valore1;

void loop(void){
unsigned long t;

t = millis();
/* con t%10 campiono 100 volte al secondo, quindi a 100 Hz
con t%5 campiono 200 volte al secondo, quindi a 200 Hz
*/

if(t%T1 == 0){

valore = analogRead(A0)*C;
valore1 = analogRead(A5)*C;

/*
Serial.print(t);
Serial.print("\t");
*/

Serial.print(valore,5);
Serial.print("\t");
Serial.print(valore1,5);
Serial.println();
}
}

[UPDATE 9-Nov-2014]

I spent last days, to be honest the last free hours, investigating about the source of the signal and how to apply a filter.
So it was good, I opened a new door about digital filters and at the I discovered some important things:

  1. Low and High pass filters are interesting, but to much resource are necessary, due to this in mandatory leave the arduino IDE and use a pure C or Assembler approach to the controller, but I’m not sure about the results.
  2. There are others more simple approach to filter the input signal:
    1. moving average
    2. slide window average.

I tried to implement both, sorry for the dirty code, I will arrange it better in a second life 😉

 

#include <Arduino.h>
#define VERSIONE "4.03-09/11/2014"

#define C 0.0048828125

#define T1 5
#define T2 60000

#define NCAMPIONI 10

//int flag = 0;

void waitForFlush(void){
/*******************************************
* scopo di questa funzione e non impegnare *
* la comunicazione seriale nei primi X *
* secondi. In tal modo il flush e sempre *
* facilmente realizzabile. *
*******************************************/
#define TIMETOWAIT 5000 /* ms */
unsigned long t0,t1;

t0 = millis();
t1 = millis();

while( t1-t0 < TIMETOWAIT){
   t1 = millis();
}
}

void setup(){

/*attivo la comunicazione seriale */
Serial.begin(57600);

/*do disponibilità a flush del controllore*/
waitForFlush();

/*Intestazione del programma */
Serial.print("EMF DETECTOR V. ");
Serial.println(VERSIONE);
}


float valore;
float campioni[NCAMPIONI];
float campioniSlideWindow[NCAMPIONI];

float somma=0;
float sommaSlideWindow=0;

float mediaMobile = 0;
float mediaSlideWindow = 0;

short int contatore = 0;
short int flag = 0;
short int i;

void loop(void){
unsigned long t;

t = millis();
/**********************************************************
 *con t%10 campiono 100 volte al secondo, quindi a 100 Hz *
 *con t%5 campiono 200 volte al secondo, quindi a 200 Hz  *
 *Applicano il fitro i campionamenti avvengono ogni 10*T  *
 *********************************************************/

if(t%T1 == 0){
  valore = analogRead(A0)*C;
  
  if (contatore < 10){
    campioni[contatore] = valore;
    //somma = somma + campione[contatore];
    contatore++;
  }


  
  if (contatore < NCAMPIONI && flag ==0){
    flag = 1;
    for (i=0; i<NCAMPIONI; i++){
      sommaSlideWindow = campioniSlideWindow[contatore]+sommaSlideWindow;
    }
    sommaSlideWindow = 0;
  }

  if (contatore < NCAMPIONI && flag !=0){
    campioniSlideWindow[contatore] = valore;
   
   for (i=0; i<NCAMPIONI; i++){     sommaSlideWindow = sommaSlideWindow + campioniSlideWindow[i];    }       mediaSlideWindow = sommaSlideWindow/NCAMPIONI;    sommaSlideWindow = 0;   }   if ( contatore >= NCAMPIONI){
      contatore =0;
      for (i=0; i<NCAMPIONI; i++){
         somma = somma + campioni[i];
      }
      mediaMobile = somma/NCAMPIONI;
      somma = 0;
  }
  

  Serial.print(t);
  Serial.print("\t");
  Serial.print(valore,5);
  Serial.print("\t");
  Serial.print(mediaMobile,5);
  Serial.print("\t");
  Serial.print(mediaSlideWindow,5);
  Serial.println();

}
}


In the next picture you can see the graphical results of the filters.
The filter based on the simple moving average seems better (2nd col).

20141106_5ms

and after some minutes:

20141106_5mmms

 

Annunci

Prepariamoci a realizzare un rilevatore di campi elettrici con Arduino

Il motivo dei due articoli precedenti, “Utilizzo di un diplay 7 segmenti con Arduino” e ” Grafici in tempo reale con Arduino o altro dispositivo su porta seriale“, è molto semplice… volevo realizzare un rilevatore di campi elettro-magnetici.

In giro trovate diverse guide, come ad esempio questa o meglio ancora  quest’altro video.

Quindi ravanando nella “scatola delle cose elettroniche” ho trovato tutto in necessario per avviare il progetto.

La cosa bella degli hobby è che ti mettono di fronte a cose non conosciute e chi è affetto da nerdite non può fare a meno che perdere di vista il progetto e cominciare a sforzarsi di capire perchè c’è questo o quello, e perchè si fa così, ecc..

Alla fine ho fatto interessanti scoperte:

  1. Tutti i progetti che usano Arduino, una antenna e una resistenza non rilevano nessun campo elettromagnetico
  2. Le antenne sono un modo meraviglioso da esplorare… mettere una cavetto a caso può solo peggiorare i risultati del progetto
  3. Arduino è sensibile in modo naturale ai campi elettrici (OK facciamo un rilevatore di campi elettrici 🙂 )
  4. La teoria dei segnali è veramente affascinante.

Che dire lo scopo di un progetto è imparare ed ho imparato e continuo ad imparare veramente tanto, mi pare giusto condividere parte delle cose che ho trovato in rete nella speranza che siano utili anche al altri che stanno facendo la mia stessa esperienza.

Per le antenne vi suggerisco questa semplice guida introduttiva, cliccate qui.

Per quanto riguarda l’acquisizione dati vi consiglio questi due link:

https://sites.google.com/site/measuringstuff/the-arduino

conversione AD

In merito alla sensibilità natura di Arduino ai campi elettrici fate la prova usando un semplice analogRead(A0) o qualsiasi altra porta senza collegare nulla al PIN, avvicinate Arduino ad una presa o lampade e niente di strano che vi troviate delle misure di questo tipo:

Campionamento del campo elettrico con arduino

Campionamento del campo elettrico con arduino

Introdurre una antenna nel sistema per quanto essa sia mal fatta aiuta ad aumentare il valore della grandezza campionata, qui di seguito le immagini e lo schema di come ho fatto io:

emf_bbSchema corrispondente:

Schema rilevatore campi elettrici

Schema rilevatore campi elettrici

Qui vi mostro l’ultima misura fatta che riporta i valori in Volt, una frequenza di campionamento pari a 200Hz, il codice usato lo trovate qui. Le variazioni sono date dalla variazione delle utenze collegate alla presa elettrica, presa che dista circa 10-15 cm dall’antenna.

Valori di tensione indotte sull'antenna dal campo elettrico

Valori di tensione indotte sull’antenna dal campo elettrico

Ok, questo è tutto, per un po’ di tempo credo non avrò la possibilità di andare avanti con l’attività.

Utilizzo di un display 7 segmenti con Arduino

In questi giorni di vacanza provo a rilassarmi ravanando nella scatole di pezzi sparsi, nella scatola dove tengo ormai fermo da quasi un anno il mio vecchio Arduino.

Ravanando cosa mi trovo?

Delle resistenze, un po’ di fili, un display a 7 segmenti… Ok facciamo un misuratore di campi elettromagnetici, ma avanziamo per passi, prima proviamo ad usare il display.

Quindi il display è un TDSR3150, la disposizione dei pin è la seguente (tratto dal datasheet della VISHAY):

pin_7s

L’idea iniziale è di misurare il campo elettromagnetico e poi proporre in uscita un range di valore da 0 a 10, dove il dieci è rappresentato dall’accensione dei segmenti: “b”, “c” e “DP”.

Per ora tralascio il progetto del misurare il campo elettromagnetico dato che merita un pesante approfondimento su come progettare l’antenna 🙂 e passo direttamente all’uso del display in questione che può tornare utilie per altre applicazioni.

Per governare il display occore che uno dei PIN 3 o 8 sia collegato al “catodo”, quindi all’alimentazione +5v del nostro arduino, i restanti pin sono stati collegati alle uscite della scheda. Tali uscite sono state configurate tutte come  “digitali”.

Qui le funzioni definite per stampare i numeri:

/* ld7.h v1.0
 La funzione
 void writeDiplay(int) permette di rapresentare i seguenti numeri e simboli sul display:
 0 --> 0
 1 --> 1
 2 --> 2
 3 --> 3
 4 --> 4
 5 --> 5
 6 --> 6
 7 --> 7
 8 --> 8
 9 --> 9
 10 --> 1.

 Se in ingresso è fornito un valore <0 il dato visualizzato è 0, se è fornito
 un valore >10 il dato vizualizzato è 1.
*/

/* definizione dei pin di collegamento */
/* Il progetto usa un display a 7 segmenti con il seguente pinout:

     +------------+
 1---|            |---10
     |     a      |
 2---|   +---+    |---9
     |  f| g |b   |
 3---|   +---+    |---8
     |  e| d |c DP|
 4---|   +---+  * |---7
     |            |
 5---|            |---6
     +------------+

 1 g
 2 f
 3 A(C)
 4 e
 5 d
 6 DP
 7 c
 8 A(C)
 9 b
 10 a
 con la funzione void setPinDisplay(int pinDisplay, int pinArduino)
 è possibile abbinare i pin tra arduino e diplay
*/

/* definisco ON e OFF per rendere più facile la lettura dello stato led */
/* in quanto di mio diplay ha un collegamento al CATODO                 */
#define ON LOW
#define OFF HIGH

static unsigned short int LedPin1;
static unsigned short int LedPin2;
static unsigned short int LedPin3;
static unsigned short int LedPin4;
static unsigned short int LedPin5;
static unsigned short int LedPin6;
static unsigned short int LedPin7;
static unsigned short int LedPin8;
static unsigned short int LedPin9;
static unsigned short int LedPin10;

void LD_setPinDisplay(int pinDisplay, int pinArduino){
 if (pinDisplay == 1) LedPin1 = pinArduino;
 if (pinDisplay == 2) LedPin2 = pinArduino;
 if (pinDisplay == 3) LedPin3 = pinArduino;
 if (pinDisplay == 4) LedPin4 = pinArduino;
 if (pinDisplay == 5) LedPin5 = pinArduino;
 if (pinDisplay == 6) LedPin6 = pinArduino;
 if (pinDisplay == 7) LedPin7 = pinArduino;
 if (pinDisplay == 8) LedPin8 = pinArduino;
 if (pinDisplay == 9) LedPin9 = pinArduino;
 if (pinDisplay == 10) LedPin10 = pinArduino;
}

/* definizione delle funzioni di visualizzazione*/
void LD_writeDisplay(int numero){
 /* questa è solo una funzione di test */
 if (numero == 0){
 digitalWrite(LedPin1,OFF);
 digitalWrite(LedPin2,ON);
 digitalWrite(LedPin4,ON);
 digitalWrite(LedPin5,ON);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,ON);
 }
 if (numero == 1){
 digitalWrite(LedPin1,OFF);
 digitalWrite(LedPin2,OFF);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,OFF);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,OFF);
 }
 if (numero == 2){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,OFF);
 digitalWrite(LedPin4,ON);
 digitalWrite(LedPin5,ON);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,OFF);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,ON);
 }
 if (numero == 3){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,OFF);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,ON);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,ON);
 }
 if (numero == 4){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,ON);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,OFF);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,OFF);
 }
 if(numero == 5){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,ON);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,ON);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,OFF);
 digitalWrite(LedPin10,ON);
 }
 if(numero == 6){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,ON);
 digitalWrite(LedPin4,ON);
 digitalWrite(LedPin5,ON);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,OFF);
 digitalWrite(LedPin10,ON);
 }
 if(numero == 7){
 digitalWrite(LedPin1,OFF);
 digitalWrite(LedPin2,OFF);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,OFF);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,ON);
 }
 if(numero == 8){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,ON);
 digitalWrite(LedPin4,ON);
 digitalWrite(LedPin5,ON);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,ON);
 }
 if(numero ==9){
 digitalWrite(LedPin1,ON);
 digitalWrite(LedPin2,ON);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,OFF);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,ON);
 }
 if (numero == 10){
 digitalWrite(LedPin1,OFF);
 digitalWrite(LedPin2,OFF);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,OFF);
 digitalWrite(LedPin6,ON);
 digitalWrite(LedPin7,ON);
 digitalWrite(LedPin9,ON);
 digitalWrite(LedPin10,OFF);
 }
}

void LD_resetDisplay(void){
 digitalWrite(LedPin1,OFF);
 digitalWrite(LedPin2,OFF);
 digitalWrite(LedPin4,OFF);
 digitalWrite(LedPin5,OFF);
 digitalWrite(LedPin6,OFF);
 digitalWrite(LedPin7,OFF);
 digitalWrite(LedPin9,OFF);
 digitalWrite(LedPin10,OFF);
}

void LD_setArduinoOutDisplay(void){
 pinMode(LedPin1,OUTPUT);
 pinMode(LedPin2,OUTPUT);
 pinMode(LedPin4,OUTPUT);
 pinMode(LedPin5,OUTPUT);
 pinMode(LedPin6,OUTPUT);
 pinMode(LedPin7,OUTPUT);
 pinMode(LedPin9,OUTPUT);
 pinMode(LedPin10,OUTPUT);
}

 

Qui il codice principale

/* 18/04/2014
 prima stesura della funzione che permette di visualizzare a display la scala da 0-9 e il lampeggio DP
 in fase di accensione
18/04/2014
 aggiunta la lettura dei valori dall'antenna
25/04/2014
 Codice organizzato in modo modulare e testato con code::blocks 12.11 per arduino
 */
#include <Arduino.h> /* Necessario se usate code::blocks come ambiente di sviluppo, diversamente rimuvere */
#include "ld7.h"
/* definizione PIN antenna
\/
 |
 |
 +--a0
 |
 R3M3K
 |
 GND
 */
#define analogIn A0
#define FQ 1/(50.) /* frequenza di campionamento pari al doppio della frequenza che mi interessa (50 Hz) */
void setup(){
 /*attivo la comunicazione seriale */
 Serial.begin(57600);
/* definizione PIN display 7 segmenti */
 LD_setPinDisplay(1,2);
 LD_setPinDisplay(2,3);
 LD_setPinDisplay(4,4);
 LD_setPinDisplay(5,5);
 LD_setPinDisplay(6,6);
 LD_setPinDisplay(7,7);
 LD_setPinDisplay(9,8);
 LD_setPinDisplay(10,9);
/*configurazione dei PIN */
 LD_setArduinoOutDisplay();
/* setto tutti i pin LOW affinche siano spenti */
 LD_resetDisplay();
}
int flag = 0;
void test(void){
 /* ciclo di test solo per verificare che i numeri siano
 rappresentati correttamente
 */
 for(int i=0;i<11;i++){
 LD_writeDisplay(i);
 delay(2000);
 }
}
int segnaleAntenna(void){
 /* definisco la sensibilità minima della conversione A/D */
 //const double c = 0.0048875855;
 return analogRead(analogIn);
}
void loop(void){
 unsigned long t;
 int valore;
if (flag ==0){
 test();
 LD_resetDisplay();
 flag=1;
 }
 //resetDisplay();
 t = millis();
 if(t%100 ==0){
 delay(1);
 valore = segnaleAntenna();
 Serial.print(valore);
 Serial.print(" ");
 Serial.println(analogRead(A1));
 }
 if(t%1000 == 0){
 valore = map(valore,0,100,0,10);
 LD_writeDisplay(valore);
 delay(1);
 }
}

Arduino, si comincia

Questa sera mi sono finalmente convinto a comprare uno starter Kit per Arduino UNO.

Prossimamente su questi schermi 🙂