Tecnicamente's Weblog

Just another WordPress.com weblog

Archivi Mensili: aprile 2014

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à.

Grafici in tempo reale con Arduino o altro dispositivo su porta seriale

Un secondo pezzo utile per il progetto a cui sto lavorando da qualche giorno è la rappresentazione grafica dei dati campionati con Arduino.

Tale attività è facilmente realizzabile sia su Windows che su Linux o OSX, vediamo cosa ci occorre.

Procuratevi il software KST, e scaricate la versione adeguata al mostro sistema operativo da qui.

Per poter usare KST è necessario che i dati provenienti dalla comunicazione seriale siano salvati su un file, per fare ciò uso i seguenti software:

Entrambi i software permettono di stabilire una comunicazione su porta seriale e di salvare tutti i contenuti su un file.

Tralascio come fare in quanto i due software sono molto intuitivi e passo direttamente a KST.

Quindi dopo aver lanciato Realterm/GTKterm o altro programma che salva la comunicazione su un file testo avviate KST.

Cliccate sulla bacchetta magica:

Immagine1

Nella finestra “Data Wizard” indicate il nome del file e la voce “Time Interval“:

Immagine2

Selezionate i dati che volete riportare sul grafico, nel mio caso sto usando un formato dovhe ho un “INDEX” automatico e sulla stessa riga il campionamento di due segnali, quindi ho un file testo con due colonne di numeri campionati.

Immagine3Cliccate Next e nella schemata successiva mettete le seguenti impostazioni:

Immagine4

Ed ecco il risultato, un bel grafico che si aggiorna in tempo reale:

Immagine5

Buon lavoro 😉

 

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);
 }
}