[color=#7E7E7E]//Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *[/color]
[color=#7E7E7E]// *  TCMCA (Tesla Coil Multi Channel Analyzer) versione 0.6 (inizia a stare insieme)          *[/color]
[color=#7E7E7E]//Â *Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *[/color]
[color=#7E7E7E]// *  Analizzatore multicanale portatile open source con microcontrollore ATMEGA328 - ARDUINO  *[/color]
[color=#7E7E7E]// *  e display LCD grafico 128x64 (KS0108 compatibile)                                        *[/color]
[color=#7E7E7E]//Â *Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *[/color]
[color=#7E7E7E]// *  Basato sull' idea del GAMMA GRAPHER nato grazie al gruppo "Geiger Counter Entusiast":    *[/color]
[color=#7E7E7E]//Â *Â Â
http://tech.groups.yahoo.com/group/GeigerCounterEnthusiasts/…[/color]
[color=#7E7E7E]// *  ed ufficialmente sviluppato e supportato nel gruppo italiano "Radioactivity Forum":      *[/color]
[color=#7E7E7E]//Â *Â Â
http://radioactivity.forumcommunity.net/?t=50415955Â Â Â Â Â…[/color]
[color=#7E7E7E]//Â *Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *[/color]
[color=#7E7E7E]//Â *Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â *[/color]
[color=#7E7E7E]// *  La realizzazione dell' apparecchio comporta la costruzione e l' utilizzo di parti di     *[/color]
[color=#7E7E7E]// *  circuito sottoposte ad alte tensioni e il maneggiamento di sostanze radioattive, si      *[/color]
[color=#7E7E7E]// *  declina qualunque tipo di responsabilità  in merito                                       *[/color]
[color=#7E7E7E]// *  Codice sorgente, schemi, PCB, informazioni tecniche e quant' altro e' reso disponibile   *[/color]
[color=#7E7E7E]// *  vengono forniti senza alcuna garanzia implicita o esplicita su licenza creative commons  *[/color]
[color=#7E7E7E]// *  Copyleft 2012 Bragonzi Fabio   www.teslacoil.it                                          *[/color]
[color=#7E7E7E]//Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *Â *[/color]
[color=#7E7E7E]//   Richiede Arduino IDE versione 0023 (attenzione: NON funziona con l' IDE 1.0)[/color]
[color=#7E7E7E]//   Scaricare ed installare la libreria KS0108 [/color]
[color=#7E7E7E]//   Collegare display LCD grafico 128x64 con controller KS0108 ad un microcontrollore ATMEGA328[/color]
[color=#7E7E7E]//   come da istruzioni di libreria[/color]
[color=#7E7E7E]//   realizzare un circuito di condizionamento dei segnali d' uscita dal fotomoltiplicatore con[/color]
[color=#7E7E7E]//   circuito di sample & hold e rilevatore di picco, collegare la sua uscita analogica al pin di [/color]
[color=#7E7E7E]//   ingresso analogico AD5 e il suo ingresso impulsi al pin di ingresso interrupt IO2-INT0.[/color]
[color=#7E7E7E]//   collegare il reset del circuito sample&hold al pin di uscita IO3. [/color]
[color=#7E7E7E]//   il microcontrollore accetta esclusivamente segnali positivi variabili da 0 a +5V nella sezione[/color]
[color=#7E7E7E]//   analogica ed accetta ed emette segnali digitali a livello TTL nei due pin di interrupt e di reset[/color]
[color=#7E7E7E]//   a realizzazione ultimata e' indispensabile procedere alla taratura utilizzando isotopi radioattivi [/color]
[color=#7E7E7E]//   di cui si conosca con certezza la composizione e il livello di emissione.[/color]
[color=#7E7E7E]//Â [/color]
[color=#7E7E7E]//   Storico revisioni:[/color]
[color=#7E7E7E]//   V0.1 --->  wow, disegna una curva sul display in base alla tensione sull' ingresso analogico[/color]
[color=#7E7E7E]//   V0.2 --->  ora crea e memorizza un array di valori letti in analogico e li mostra a display al contrario[/color]
[color=#7E7E7E]//   V0.2_modi --->  modifiche minori e inserimento vari commenti[/color]
[color=#7E7E7E]//   V0.3 --->  corretto senso di scrittura display, inserita visualizzazioe energia massima[/color]
[color=#7E7E7E]//   V0.4 --->  inserito reset automatico delle letture, inserita routine di trasferimento dati via interfaccia[/color]
[color=#7E7E7E]//              seriale-USB, inserito reset del Sample&Hold, correzione bachi minori; prima versione funzionante[/color]
[color=#7E7E7E]//              approvata per il pubblico rilascio.[/color]
[color=#7E7E7E]//   V0.5 --->  corretto baco scrittura da 0 a 127 e lettura/cancellazione da 1 a 128[/color]
[color=#7E7E7E]//   V0.6 --->  iserimento gestione dell' interrupt.[/color]
#include <ks0108.h>  Â
#include <ks0108_Arduino.h>  [color=#7E7E7E]// inclusione delle librerie per display con controller KS0108[/color]
#include <Arial14.h>         [color=#7E7E7E]// inclusione del font Arial 14 in dimensione 5x7[/color]
#include [color=#006699]"SystemFont5x7.h"[/color]
[color=#CC6600]int[/color] x = 0; [color=#7E7E7E]// definisco la variabile X (ascissa display) come intera con valore iniziale 0[/color]
[color=#CC6600]int[/color] y = 0; [color=#7E7E7E]// definisco la variabile Y (ordinata display) come intera con valore iniziale 0[/color]
[color=#CC6600]int[/color] analog = 0; [color=#7E7E7E]// definisco la variabile analog (ampiezza impulso) come intera con valore iniziale 0[/color]
[color=#CC6600]int[/color] energia = 0; [color=#7E7E7E]// definisco la variabile energia (canale scelto) come intera e assegno valore iniziale 0[/color]
[color=#CC6600]int[/color] bin [128]; [color=#7E7E7E]// creo un array di 128 locazioni di memoria dove immagazzinare il numero di impulsi [/color]
                         [color=#7E7E7E]// conteggiati per ciascuno dei 128 valori energie differenti (dette BIN negli MCA).[/color]
[color=#CC6600]int[/color] temporanea = 0; [color=#7E7E7E]// definisco la variabile temporanea (locazione di memoria dove immagazzinare temporaneamente[/color]
                         [color=#7E7E7E]// il valore degli impulsi da manipolare) come intera e assegno valore iniziale 0[/color]
[color=#CC6600]int[/color] ciclo = 0; [color=#7E7E7E]// definisco la variabile ciclo (ascissa display) come intera con valore iniziale 0 [/color]
[color=#CC6600]unsigned[/color] [color=#CC6600]int[/color] ripeti = 1; [color=#7E7E7E]// definisco la variabile cicli come intera senza segno con valore iniziale 1 [/color]
                         [color=#7E7E7E]// (numero massimo di ripetizioni della misurazione prima dell' overflow = 65534) [/color]
[color=#CC6600]boolean[/color] interrupt = 2; [color=#7E7E7E]// assegno la label interrupt al pin digitale 2 definendolo come intero[/color]
[color=#CC6600]int[/color] shrst = 3; [color=#7E7E7E]// assegno la label shrst (Sample e Hold ReSeT) al pin digitale 3 definendolo come intero[/color]
[color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() [color=#7E7E7E]// inizio le operazioni di setup preliminare[/color]
           {
            Â
            [color=#CC6600]GLCD[/color].[color=#CC6600]Init[/color]([color=#CC6600]NON_INVERTED[/color]); [color=#7E7E7E]// inizializzo il display come non invertito[/color]
            [color=#CC6600]GLCD[/color].[color=#CC6600]ClearScreen[/color](); [color=#7E7E7E]// pulisco lo schermo da ogni dato [/color]
            [color=#CC6600]GLCD[/color].[color=#CC6600]SelectFont[/color](System5x7); [color=#7E7E7E]// seleziono il font 5x7[/color]
            [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]begin[/color](9600); [color=#7E7E7E]// abilito la connessione seriale a 9600 baud[/color]
            [color=#CC6600]pinMode[/color](A5, [color=#006699]INPUT[/color]); [color=#7E7E7E]// setto il pin analogico A5 come input[/color]
            [color=#CC6600]pinMode[/color](interrupt, [color=#006699]INPUT[/color]); [color=#7E7E7E]// setto il pin digitale interrupt come input[/color]
            [color=#CC6600]pinMode[/color](shrst, [color=#006699]OUTPUT[/color]); [color=#7E7E7E]// setto il pin digitale shrst (Sample e Hold ReSeT) come output[/color]
            [color=#CC6600]digitalWrite[/color] (shrst, [color=#006699]LOW[/color]); [color=#7E7E7E]// e gli do un livello logico iniziale basso [/color]
Â
            [color=#CC6600]GLCD[/color].[color=#CC6600]DrawRoundRect[/color](0,0,127,63,5,[color=#CC6600]BLACK[/color]); [color=#7E7E7E]// disegno una cornice nera rettangolare con i bordi arrotondati[/color]
            [color=#CC6600]GLCD[/color].[color=#CC6600]GotoXY[/color](20,2); [color=#7E7E7E]// vado alla posizione X20 Y2 sul display[/color]
            [color=#CC6600]GLCD[/color].[color=#CC6600]Puts[/color]([color=#006699]"Test TCMCA V0.6"[/color]); [color=#7E7E7E]// scrivo Test TCMCA V0.6[/color]
            [color=#CC6600]GLCD[/color].[color=#CC6600]GotoXY[/color](15,22); [color=#7E7E7E]// vado alla posizione X15 Y22 sul display[/color]
            [color=#CC6600]GLCD[/color].[color=#CC6600]Puts[/color]([color=#006699]"www.teslacoil.it"[/color]); [color=#7E7E7E]// scrivo www.teslacoil.it[/color]
            [color=#CC6600]delay[/color](3000); [color=#7E7E7E]// mantengo la schermata per 3000 mS per dare il tempo di leggerla[/color]
                                                     [color=#7E7E7E]// verra' cancellata successivamente nel loop principale[/color]
            [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]"TCMCA V0.6 by Fabio Bragonzi www.teslacoil.it "[/color]); [color=#7E7E7E]// invio sulla seriale cio' che e' scritto[/color]
            [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]"Portable multichannel analyzer 128 channel x 64 levels "[/color]); [color=#7E7E7E]// invio sulla seriale cio' che e' scritto[/color]
            [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]""[/color]); [color=#7E7E7E]// invio sulla seriale una riga vuota [/color]
          Â
           }                            [color=#7E7E7E]// termino le operazioni di setup preliminare[/color]
            Â
            Â
Â
[color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]()
           {                            [color=#7E7E7E]// inizia qui il programma principale da ripetere all' infinito[/color]
          Â
            [color=#CC6600]GLCD[/color].[color=#CC6600]ClearScreen[/color](); [color=#7E7E7E]// cancella tutto lo schermo[/color]
[color=#7E7E7E]//          drawaxis();                 // disegno gli assi cartesiani (COMANDO DISABILITATO)[/color]
          Â
            acquisisci:                 [color=#7E7E7E]// inizia qui la routine di acquisizione[/color]
                     [color=#7E7E7E]// delay (10); // questo ritardo di 10mS mi serve solo per il debug, va poi tolto[/color]
                 Â
                       [color=#CC6600]if[/color] ([color=#CC6600]digitalRead[/color] (interrupt) == 1) [color=#7E7E7E]// leggi lo stato logico di interrupt se interrupt e' alto (nessun impulso rilevato)[/color]
                                            {
                                          goto acquisisci;  [color=#7E7E7E]// ritorna indietro ad acquisisci (continua a ciclare all' infinito[/color]
                                                            [color=#7E7E7E]// fino a quando arriva un impulso) [/color]
                                            }               [color=#7E7E7E]// altrimenti continua ad eseguire il codice qua sotto[/color]
                      Â
                       analog = [color=#CC6600]analogRead[/color](A5); [color=#7E7E7E]// leggo il valore di A5 e lo piazzo in analog (1024 valori da 0 a 1023)[/color]
                       [color=#CC6600]digitalWrite[/color] (shrst, [color=#006699]HIGH[/color]);
                       [color=#CC6600]digitalWrite[/color] (shrst, [color=#006699]LOW[/color]); [color=#7E7E7E]// resetto il Sample & Hold esterno mandando un rapido impulso sul pin shrst[/color]
                      Â
                       [color=#CC6600]if[/color] (analog < 2) [color=#7E7E7E]// se analog e' inferiore a 2 (solo rumore, nessun impulso rilevato)[/color]
                                     {
                                      goto acquisisci;      [color=#7E7E7E]// ritorna indietro ad acquisisci[/color]
                                     }                      [color=#7E7E7E]// altrimenti continua ad eseguire il codice qua sotto[/color]
                      Â
                       energia = [color=#CC6600]map[/color](analog,0,1023,0,127); [color=#7E7E7E]// trasformo il valore di analog in energia (128 valori da 0 a 127)[/color]
                       temporanea = bin [energia];          [color=#7E7E7E]// leggo il valore del bin corrispondente al valore di energia appena [/color]
                                                            [color=#7E7E7E]// misurato e lo scrivo in temporanea[/color]
                       temporanea++;                        [color=#7E7E7E]// incremento di uno il valore di temporanea[/color]
                      Â
                       [color=#CC6600]if[/color] ( temporanea > 64 ) [color=#7E7E7E]// se temporanea e' maggiore di 64 questo bin ha raggiunto il massimo [/color]
                                             {              [color=#7E7E7E]// valore visualizzabile sullo schermo, l' acquisizione e' finita,[/color]
                                              goto esci;    [color=#7E7E7E]// salto tutto il resto del programma e vado diretto ad esci[/color]
                                             }              [color=#7E7E7E]// altrimenti continua ad eseguire il codice qua sotto[/color]
                                            Â
                       bin [energia] = temporanea;          [color=#7E7E7E]// scrivo il valore di temporanea all' interno del bin corrispondente [/color]
                                                            [color=#7E7E7E]// al valore di energia misurato poco fa (ho memorizzato il conteggio di[/color]
                                                            [color=#7E7E7E]// un impulso!)[/color]
                       x = energia;                         [color=#7E7E7E]// assegno alla ascissa il valore di energia[/color]
                       y = 64-temporanea;                   [color=#7E7E7E]// assegno alla ordinata il valore della sottrazione 64 - temporanea[/color]
                                                            [color=#7E7E7E]// (serve per risolvere il problema della visualizzazione invertita causa[/color]
                                                            [color=#7E7E7E]// display che ha lo zero degli assi in alto a destra anziche' in basso a[/color]
                                                            [color=#7E7E7E]// destra come un comune grafico cartesiano)[/color]
                       [color=#CC6600]GLCD[/color].[color=#CC6600]SetDot[/color](x,y,[color=#CC6600]BLACK[/color]); [color=#7E7E7E]// annerisco il pixel sul display avente ascissa x ed ordinata y[/color]
                       goto acquisisci;                     [color=#7E7E7E]// ritorna indietro alla routine acquisisci per ricevere un nuovo impulso[/color]
         Â
         Â
            esci:                       [color=#7E7E7E]// al termine della procedura di acquisizione il programma arriva qui[/color]
           Â
                Â
                 [color=#CC6600]delay[/color] (5000); [color=#7E7E7E]// attendi 5 secondi senza fare nulla per permettere la visione dello spettro[/color]
                Â
                 [color=#CC6600]GLCD[/color].[color=#CC6600]FillRect[/color](1,51,125,14, [color=#CC6600]WHITE[/color]); [color=#7E7E7E]// disegna un rettangolo bianco nella parte piu' bassa dello schermo(cancellando [/color]
                                                      [color=#7E7E7E]// la porzione di schermo interessata) dal pixel X1-Y51 al pixel X125-Y14[/color]
                 [color=#CC6600]GLCD[/color].[color=#CC6600]GotoXY[/color](1,61); [color=#7E7E7E]// vai al pixel X1-Y61[/color]
                 [color=#CC6600]GLCD[/color].[color=#CC6600]Puts[/color]([color=#006699]"picco massimo: "[/color]); [color=#7E7E7E]// scrivi la parola picco massimo: lasciando uno spazio vuoto dopo la scritta[/color]
                 [color=#CC6600]GLCD[/color].[color=#CC6600]PrintNumber[/color](energia); [color=#7E7E7E]// scrivi il valore di energia[/color]
                Â
                 [color=#CC6600]delay[/color] (5000); [color=#7E7E7E]// attendi 5 secondi senza fare nulla per permettere la lettura del numero[/color]
                Â
                Â
                 [color=#7E7E7E]// in questo punto ci starebbe proprio bene una eventuale futura routine di riconoscimento automatico degli isotopi ;-)[/color]
Â
Â
                 [color=#7E7E7E]// inizio della procedura di invio dati al PC via interfaccia seriale-USB separati da virgole in formato compatibile CSV [/color]
                 [color=#7E7E7E]// facilmente importabile da MS Excel, OOo CALC e altri e successiva cancellazione dei dati dalla RAM del micro.[/color]
                 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]""[/color]); [color=#7E7E7E]// invio sulla seriale una riga vuota [/color]
                 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]"Acquisizione numero, "[/color]); [color=#7E7E7E]// invio sulla seriale cio' che e' scritto[/color]
                 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color](ripeti); [color=#7E7E7E]// invio sulla seriale il valore della variabile ripeti[/color]
                 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]"Picco massimo rilevato sul canale, "[/color]); [color=#7E7E7E]// invio sulla seriale cio' che e' scritto[/color]
                 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color](energia); [color=#7E7E7E]// invio sulla seriale il valore della variabile ripeti[/color]
                 [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]"canale n°,numero impulsi"[/color]); [color=#7E7E7E]// invio sulla seriale cio' che e' scritto[/color]
               Â
                 [color=#CC6600]for[/color] (ciclo=0; ciclo<128; ciclo++) [color=#7E7E7E]// esegui la subroutine qua sotto per 128 volte incrementando di volta in volta ciclo[/color]
                                                 {
                                                  [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color](ciclo); [color=#7E7E7E]// invio sulla seriale il valore della variabile ciclo[/color]
                                                  [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color]([color=#006699]","[/color]); [color=#7E7E7E]// invio sulla seriale una virgola (carattere separatore nel CSV) [/color]
                                                  temporanea = bin [ciclo];    [color=#7E7E7E]// leggo il valore del bin corrispondente al ciclo di lettura[/color]
                                                                               [color=#7E7E7E]// e lo scrivo in temporanea[/color]
                                                  [color=#CC6600][b]Serial[/b][/color].[color=#CC6600]println[/color](temporanea); [color=#7E7E7E]// invio sulla seriale il valore della variabile temporanea [/color]
                                                  bin [ciclo] = 0;             [color=#7E7E7E]// resetto a zero il valore del bin corrispondente al ciclo di lettura[/color]
                                                 }                             [color=#7E7E7E]// fine della subroutine [/color]
               Â
                 ripeti++;    [color=#7E7E7E]// incrementa di uno la variabile ripeti (numero di ripetizioni dell' acquisizione di uno spettro)[/color]
           }                  [color=#7E7E7E]// qui termina il programma principale e si va a ripartire dall' inizio[/color]
          Â
[color=#7E7E7E]//void drawaxis()                                    // inizio subroutine di disegno degli assi cartesiani (COMANDO DISABILITATO)[/color]
[color=#7E7E7E]//Â Â Â Â Â Â Â Â Â Â Â Â Â Â {Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â [/color]
[color=#7E7E7E]//               GLCD.ClearScreen();                 // cancellazione dello schermo (COMANDO DISABILITATO)[/color]
[color=#7E7E7E]//               GLCD.DrawVertLine(0,0,63,BLACK);    // disegno linea verticale per l' asse Y (COMANDO DISABILITATO)[/color]
[color=#7E7E7E]//               GLCD.DrawHoriLine(0,0,128,BLACK);   // disegno linea orizzontale per l' asse X (COMANDO DISABILITATO)[/color]
[color=#7E7E7E]//              }                                    // fine subroutine di disegno degli assi cartesiani (COMANDO DISABILITATO)[/color]
 Â
 Â
           Â