INTRO
Molte volte su siti internet, compreso NE555.IT, potete trovare schemi elettrici di vario genere dove viene indicato il range di tensione con il quale il circuito funziona senza però fornire molte informazioni sul tipo di alimentatore da usare. Nel mio caso, quando non lo specifico, è perché un qualsiasi alimentatore che fornisca la tensione indicata va bene. Solitamente cerco di fornire la corrente assorbita e quando questa non è indicata vuol dire che è qualche decina di mA, quindi un qualsiasi alimentatore va bene.
Proviamo però ad essere più precisi e illustrare i vari parametri e tipologie di alimentatori cercando di abbinare il tipo di alimentatore ad ogni tipo di progetto che stiamo realizzando. In particolare cercherò di aiutarvi a scegliere tra gli alimentatori switching e gli alimentatori lineari. Inoltre, per quanto riguarda gli alimentatori lineari, cercherò di illustrare le caratteristiche del trasformatore da usare. Non ci occuperemo dei raddrizzatori in quanto sono stati discussi in modo abbondante in un precedente articolo ( https://www.ne555.it/trasformatori-tensione-raddrizzatori-calcolo-capacita/ ).
CLASSIFICAZIONE DEGLI ALIMENTATORI
La classificazione fatta in questo articolo è ad alto livello e differenzia gli alimentatori in base al loro funzionamento interno. In particolare si avrà:
PARAMETRI DEGLI ALIMENTATORI
COME SCEGLIERE UN ALIMENTATORE PER I NOSTRI PROGETTI
Possiamo prima di tutto suddividere i nostri progetti in 3 grandi blocchi; progetti digitali, ovvero che usano microcontrollori e tutti i segnali sono di tipo digitale, progetti analogici come ad esempio preamplificatori ed amplificatori oppure progetti a segnale misto come ad esempio un progetto che usa microcontrollore e sensori con segnali analogici.
Ad esempio nei progetti puramente digitali la tensione di ripple e il rumore non sono parametri molto importanti in quanto i circuiti digitali sono robusti. Ovviamente un ripple molto elevato però può creare problemi. Per un progetto Hi-Fi o per un progetto a segnali misti dove vi sono sensori con basse tensioni di uscita il ripple potrebbe creare rumore sull’impianto o errore nella lettura del sensore.
Regolazione di linea | Regolazione di carico | Ripple | Rumore e emissioni EM | Efficienza | |
Alimentatori switching (step-up, step-down, AC-DC) | Buona | Buona | Basso | Alti | Alto |
Alimentatori lineari (trasformatore, raddrizzatore filtro capacitivo) | Scarsa | Scarsa | Basso se ben progettato | Bassi | Bassa |
Alimentatori lineari stabilizzati | Buona | Buona se ben progettato | Nullo | Bassi | Scarsa |
Ad esempio se dobbiamo realizzare un progetto con Arduino o microcontrollore possiamo riciclare un caricabatteria del cellulare, infatti questi garantiscono 5V con una corrente massima di 1A. Non usate alimentatori di basso costo oppure molto vecchi perché rischiano di avere un ripple e rumore elevato. Inoltre controllate la tensione a vuoto, senza carico con un multimetro. Se4 la tensione supera i 5.5V rischiate di bruciare il microcontrollore.
Ad esempio usiamo il sito RS per fare un esempio di acquisto. Supponiamo che mi serve un alimentatore per caricare un pacco batterie da 8.2V. vista l’applicazione posso sceglierne uno switching da 12V. Prima di tutto trovo la sezione alimentatori AC/DC (1), poi imposto qualche filtro che mi aiuta nella ricerca, come il tipo di spina (2) e la tensione di uscita (3). Attenzione che alcune volte stessi valori sono indicati in modo diverso. Impostiamo qualche altro filtro come il tipo di uscita (4) e la regolazione di carico (5). Trovato qualcosa che ci sembra giusto entriamo e leggiamo il datasheet. (6) indica la tensione di ingresso, questo alimentatore funziona anche con la tensione americana di 120V. (7) è la massima corrente che si può assorbire garantendo 12V mentre se si vogliono 12V e non una tensione superiore bisogna assorbire (8) almeno 50mA, altrimenti non è garantita la regolazione. (9) indica il rumore e il ripple e in particolare è il 2.5%. visto il regolatore di carica non è un problema questo valore di ripple. (10) indica l’efficienza mentre (11) è la tensione alla quale interviene la protezione interna da sovratensione.
Invece supponiamo di dover realizzare un controllo dei toni per audio, gli audiofili diranno di usare un alimentatore lineare però teoricamente potremmo usare anche un alimentatore switching a basso rumore e ripple e con frequenza di switching elevata in modo tale che con crei problemi con il segnale audio. Supponiamo però di usare un alimentatore lineare e quindi di dover cercare un trasformatore da comprare. Supponiamo che il circuito abbia bisogno di 15V duali e che assorba 150mA. Prima di tutto visto che la potenza non è elevata possiamo scegliere un trasformatore di quelli classici quadrati invece che uno toroidale. I discorsi che faremo sul trasformatore e i parametri non cambiano tra le due versioni.
Sul sito RS questi trasformatori vengono chiamati “Trasformatori per PCB” (1). Visto che il circuito si alimenta a tensione duale 15V DC e -15V DC ci serve un trasformatore a presa centrale o con due uscite e la tensione alternata in uscita deve essere almeno 15V ac (la formula del raddrizzatore a singola semionda ci dice che con 15V ac in ingresso avrò (15-1.4)*1.41= 19V).
In commercio non ci sono tutti i valori di tensione del secondario, il valore più piccolo di 15V ac è 12V ac ma applicando la formula avremmo una tensione di 14.9V dc in uscita dal ponte. Questa tensione è appena sufficiente e potrebbe andarci bene ma vista l’applicazione audio conviene comprare quello da 15V ac e usare uno stabilizzatore di tensione come il 7815 e il 7915 per arrivare esattamente a 15V dc.
Abbiamo solo 3scelte una volta scelta la tensione di ingresso (2) e di uscita (3). Andiamo quindi a vedere la potenza che ci serve. Sappiamo che la corrente continua assorbita è 150mA, in prima approssimazione possiamo considerare quindi (correggetemi se sbaglio) la corrente alternata come 0.15*1.41 dove 1.41 è la radice di due. Così facendo il nostro trasformatore deve avere una potenza di 3.2VA per ogni secondario, visto che è duale allora ci servono 6.4VA. Sceglieremo quindi il trasformatore da 8.07 euro.
The post COME SCEGLIERE L’ALIMENTATORE PER I PROGETTI first appeared on NE555.]]>
INTRODUZIONE.
Nella microspia che vi presento mi sono posto l’obiettivo di realizzarla utilizzando due modulini in smd già assemblati sia per quanto riguarda la sezione del preamplificatore microfonico come pure la sezione trasmittente a PLL in gamma UHF, anche perché ormai i minuscoli integrati di ultima generazione che servono a realizzare una moderna microspia sono così piccoli da non consentirne l’uso a livello amatoriale. Dopo aver visionato su internet diversi moduli ne ho acquistati alcuni e testati praticamente scegliendo poi i due che hanno dato i risultati migliori. Specifico che entrambi i moduli necessitano di qualche piccola modifica per adattarli al nostro scopo, all’esterno dei due moduli abbiamo bisogno solo di pochi componenti fra cui due varicap che realizzano la modulazione FM a banda stretta ( NFM ) del segnale audio. Vediamo ora nel dettaglio i due moduli che compongono la microspia analizzando le loro caratteristiche. La mia scelta come modulo preamplificatore del segnale microfonico è stata di uno che impiega un microfono KNOWLES di ultima generazione con successivo integrato TDA1308 che ne amplifica l’audio. La preferenza per questo modulo è stata per il suo audio nitido e cristallino senza il minimo rumore di fondo decisamente superiore ai moduli che utilizzano gli ormai superati microfoni electret a condensatore, non sarà un caso se questi moderni microfoni vengono utilizzati oggi nei nostri smartphone. All’inizio ero orientato verso l’utilizzo del modulo MAX9814 dotato di controllo automatico del guadagno ( CAG ) ma devo dire che mi ha deluso come qualità audio rispetto a quello che ho utilizzato. Un altro modulino molto valido alla pari di quello utilizzato è l’ ADMP401 dotato invece di microfono MEMS che addirittura assorbe solo 2 mA, ma ho preferito utilizzare quello presentato in quanto esso permette di regolare la sua amplificazione variando il valore della resistenza R5 che ho fissato a 22 Kohm come valore ottimale, in parallelo ad essa ho inserito due diodi BAT41 in opposizione che costituiscono il classico sistema di clipping che limita l’ampiezza del segnale audio ad un valore di 0.37 v pari alla soglia di conduzione di questi diodi. Questo sistema limita il livello dell’audio quando si parla troppo vicino al microfono oppure a voce alta che comporterebbe una forte distorsione del segnale poi ricevuto dalla radio ricevente, non possiamo certo considerare perfetto questo sistema ma è il meglio che si possa ottenere visto che questo modulo purtroppo non è dotato di controllo automatico del guadagno sempre utile per una microspia di buon livello qualitativo. Come modulo trasmettitore ho scelto questo modello siglato RFM68W-433-S2 che è un completo trasmettitore controllato a PLL sui 433.92 Mhz con modulazione ASK per dati digitali utilizzato nei radiocomandi che con opportune modifiche può essere adattato per la trasmissione FM a banda stretta ( NFM ). La modifica da effettuare consiste nel tagliare il collegamento del quarzo verso la massa, isolando bene la pista, e collegarlo invece verso l’induttanza da 3.3 microH ed i diodi varicap BB831 che fanno da stadio modulatore FM come visibile molto chiaramente nello schema. Ho sostuito anche il quarzo da 26 Mhz con uno sempre in smd ma di tipo tradizionale perché si adattano meglio alla modulazione FM audio per una questione del loro fattore Q mentre quello originale che c’era sul modulino era più idoneo alla trasmissione di dati digitali per cui il modulo è costruito. Bisogna poi effettuare un piccolo ponticello dal piedino del quarzo all’uscita 14 del modulo che originariamente era libera ma che adesso utilizziamo come ingresso della modulazione FM che ho chiamato “ AUDIO FM “ l’altro piedino del quarzo andrà saldato alla pista che porta al piedino 3 dell’integrato senza fare nessuna modifica. Per tenere il modulo in trasmissione continuativa dobbiamo collegare i piedini 9 e 10 ( DATA e CTRL ) al positivo di alimentazione, dallo schema si possono vedere inoltre le altre uscite collegate e quelle da lasciare libere. L’uscita 6 è l’antenna alla quale saldiamo uno spezzone di filo da 16.5 cm, questo modulino eroga una potenza RF dichiarata di 10 mW alimentandolo a 3.3 v, ne esistono anche con frequenze diverse di 315 – 433 – 868 – 915 Mhz.MONTAGGIO DELLA MICROSPIA.
I due modulini trovano posto su un PCB dalle dimensioni di 56 x 32 mm così da poter entrare nel piccolo contenitore plastico previsto, ho inserito un deviatore a slitta per l’accensione ed un plug da 3.5 mm per la ricarica della batteria che può avvenire solo quando il deviatore è in posizione OFF a microspia spenta, l’accendino visibile in foto rende l’idea delle dimensioni contenute della microspia, a dire il vero se consideriamo le dimensioni dei modulini si potrebbe costruire di dimensioni ancora più ridotte. Sotto il deviatore sul PCB bisogna mettere un pezzettino di nastro isolante in modo che il suo involucro metallico non possa cortocircuitare le piste sottostanti. La batteria al litio ricaricabile è incollata sul retro del PCB , ho trovato due batterie che entrano bene in questo contenitore ( del vecchio telefonino motorola C330 ) o di telefoni cordless ( tipo 603048 ) ma credo che ci siano altri modelli idonei. Per la ricarica della batteria bisogna utilizzare un caricabatteria idoneo per una cella litio 3.7 v e potrebbe andar bene un apposito modulino siglato TP4056 alla quale possiamo regolare la corrente di carica variando il valore di una resistenza, da alimentare poi attraverso la sua presa micro usb e dotato di due led di segnalazione dello stato di carica.CONCLUSIONI.
Come ricevitore è opportuno utilizzare una radio ricevente dotata di una buona antenna, non ho previsto un sistema VOX ( attivazione solo in presenza di voce ) perché ho potuto verificare che non si attivano con voce bassa o lontana dal microfono e quindi si perderebbero gran parte delle conversazioni. Una caratteristica molto importante per una microspia è la sua deviazione FM del segnale audio ottenuta ma posso assicurare che è molto buona perchè anch’essa, come pure la frequenza del quarzo, viene moltiplicata di 16 volte dall’integrato PLL, ma non posso determinare di quanti Khz sia effettivamente non avendo la strumentazione adeguata per misurarla. Per chi volesse fare delle prove, come ho fatto io, puo’ realizzare solo la sezione trasmittente compreso il modulatore FM a varicap al cui ingresso AUDIO IN possiamo collegare il nostro smartphone prelevando l’audio dal jack cuffia e trasmettere magari la radio FM oppure della musica in mp3, o scaricando l’APP “ microphone “ simulare una microspia, quest’app consente di regolare l’audio del microfono in modo ottimale con diversi parametri come equalizzatore ecc…. ovviamente dobbiamo regolare il volume per una giusta trasmissione. Se proprio vogliamo fare un appunto a questa microspia beh quello sarebbe l’assorbimento di corrente un pochino elevato di 21 mA perché altri modelli con 10 mW di potenza RF assorbono sui 12 -13 mA ma non sono riuscito a trovare, almeno per adesso, moduli così efficienti.PRINCIPALI CARATTERISTICHE :
Alimentazione : batteria litio ricaricabile 3.7 v – Potenza RF dichiarata : 10 mW ( a 3.3 v ) Assorbimento : 21 mA (il modulo TX assorbe 18 mA) – Portata in campo aperto : circa 300 m. Frequenza di trasmissione : 434.040 Mhz – Deviazione FM : banda stretta ( NFM ) Durata batteria : circa 40 ore con batteria 900 mA/HNOTA IMPORTANTE.
La legge sulla privacy vieta l’uso di tali dispositivi a scopo di intercettazione ambientale, la presente microspia è stata realizzata al solo scopo didattico sperimentale. The post MICROSPIA FM 434 MHZ CON DUE MODULI SMD. first appeared on NE555.]]>
INTRO
In questo articolo vedremo come realizzare una stazione saldante a partire da uno stelo saldante di qualsiasi marca. Potremmo realizzare in modo economico una stazione saldante di alta qualità in quanto il saldatore ovviamente va acquistato mentre possiamo risparmiare sul sistema di controllo realizzandolo noi.
Io ho usato una versione economica di un saldatore a 24V per HAKKO 907, ESD 936, 937, 928 oppure 926. Potete usare un qualsiasi saldatore a 24V con connettore GX16 che dispone di termocoppia di tipo k internamente.
Potete capire dove si trova la termocoppia misurando la resistenza tra i diversi pin del connettore. La termocoppia avrà una resistenza di 4 Ohm mentre la resistenza che riscalda avrà una resistenza di circa 12 Ohm se il saldatore ha una potenza di 50W. Per quanto riguarda la termocoppia potete fare dei test per capire quale è il positivo e il negativo.
Detto questo potete usare qualsiasi tipo di stelo, io vi consiglio di comprarne uno decente perché quelli da 5 euro di ebay durano 5 giorni. Anche con connettore diverso o di potenza maggiore, l’importante è la termocoppia.
Per alimentare questo progetto ho usato un alimentatore switching 24V 3A. se usate un saldatore di maggiore potenza ovviamente serviranno 5A.
CODICE
La base per il codice è il PID con microcontrollore realizzato al seguente articolo https://www.ne555.it/controllo-pid-pi-microcontrollore/ inoltre ho scelto di usare un display 7 segmenti a 3 cifre per la visualizzazione della temperatura.
Il codice è il seguente:
#define CS portc.f3 //Definisci CS PORTC.F3
#define DT 0.2 //Tempo di ripetizione PID (non più piccolo altrimenti il max6675 non funziona)
#define Kp 2 //Costante proporzionale (2 1 1)
#define Ki 1 //Costante integrale
#define Kd 2 //Costante derivativa
#define MAXout 255 //Massimo valore uscita
#define MINout 1 //Minimo valore uscita
#define Epsilon 2 //Errore massimo tra setpoint e input
int prev_error = 0; //Variabile errore iterazione precedente
int integrale = 0; //Variabile azione integrale
int error, derivata, output, abserror, input; //Variabili utili
sbit SoftSpi_SDI at RC4_bit; //Definisci connessione SPI
sbit SoftSpi_SDO at RA4_bit;
sbit SoftSpi_CLK at RC5_bit;
sbit SoftSpi_SDI_Direction at TRISC4_bit;
sbit SoftSpi_SDO_Direction at TRISA4_bit;
sbit SoftSpi_CLK_Direction at TRISC5_bit; //Fine connessione SPI
char temp_lsb=0, temp_msb=0, DutyCycle=0, i; //Variabili provvisore
unsigned int temp=0, temperatura=0, temp_display=0, temp_set=350; //Variabili temp
char text[5]; //Variabile testo
unsigned short int cifra; //iniz. variabile cifra
char segm[10] = {0b10000001, 0b11110011, 0b01001001, 0b01100001, //iniz. il vettore segmenti
0b00110011, 0b00100101, 0b00000101, 0b11110001,
0b00000001, 0b00100001};
void tre_cifre(unsigned int numero){ //sottoprogramma (dura 16.76mS)
cifra = numero % 10u; //estrae dal numero le unità
PORTA = 0b00000010; //accensione unità con buffer(con transistor 0b00000100)
PORTB = segm[cifra]; //inizializza la cifra unità
delay_ms(5);
cifra = (numero / 10u) % 10u; //estrae dal numero le decine
PORTA = 0b00000100; //accensione decine con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra decine
delay_ms(5);
cifra = (numero / 100u) % 10u; //estrae dal numero le centinaia
PORTA = 0b00001000; //accensione centinaia con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra centinaia
delay_ms(5);
}
unsigned int arrotonda (unsigned int numero){ //numero = valore da arrotondare
short resto = 0; //inizializza resto a 0
resto = numero % 10; //trova il resto della divisione per 10
if (resto > 5) numero = numero + (10 - resto); //se resto > 5 approssima per eccesso
else numero = numero - resto; //altrimenti approssima per difetto
return numero; //ritorna il valore arrotondato
}
int PID(int setpoint, int input){ //Funzione PID
error = setpoint - input; //calcola l'errore tra input e setpoint
if(abs(error) > Epsilon){ //Se l'errore è maggiore di epsilon
integrale = integrale + error*DT; //Calcola l'azione integrale
}
derivata = (error - prev_error)/DT; //Calcola l'azione derivativa
output = Kp*error + Ki*integrale + Kd*derivata; //Calcola output PID
if(output > MAXout) { //Se l'uscita supera il valore massimo
output = MAXout; //Satura l'uscita
integrale=0; //Azzera l'azione integrale
}
else if(output < MINout) { //Se l'uscita invece è troppo piccola
output = MINout; //Satura alla minima uscita
integrale=0; //Azzera anche in questo caso l'azione integrale
}
prev_error = error; //Salva il valore dell'uscita
return output; //Restituisci uscita PID
}
void EXT_INT() iv 0x0004 ics ICS_AUTO { //0018h per bassa priorità, 0008h per alta priorità
for(i=0; i < 100; i++){
if((temp_set < 450) && (PORTC.F6 == 1)){
delay_ms(200);
temp_set += 10;}
if((temp_set > 200) && (PORTC.F7 == 1)){
delay_ms(200);
temp_set -= 10;}
cifra = temp_set % 10u; //estrae dal numero le unità
PORTA = 0b00000010; //accensione unità con buffer(con transistor 0b00000100)
PORTB = segm[cifra]; //inizializza la cifra unità
delay_ms(5);
cifra = (temp_set / 10u) % 10u; //estrae dal numero le decine
PORTA = 0b00000100; //accensione decine con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra decine
delay_ms(5);
cifra = (temp_set / 100u) % 10u; //estrae dal numero le centinaia
PORTA = 0b00001000; //accensione centinaia con buffer(con transistor 0b00000010)
PORTB = segm[cifra]; //inizializza la cifra centinaia
delay_ms(5);
}
INTCON.INTF = 0;
}
void main(){ //Programma principale
INTCON.GIE = 1; //attivo gli interrupt
OPTION_REG.INTEDG = 1; //interrupt sul fronte di salita
INTCON.INTE = 1; //interrupt attivo
TRISA = 0; //ingressi e uscite
TRISB = 0x01;
TRISC.F3 = 0; //CS chip select uscita
Soft_SPI_Init(); //Inizializza SPI
PWM1_Init(271); //Inizializzazione pwm
PWM1_Start();
PWM1_Set_Duty(255);
while (1) { //Ciclo infinito
CS=0; //CS=0 avvia lettura
temp_msb = Soft_SPI_Read(170); //Leggi MSB temperatura
temp_lsb = Soft_SPI_Read(170); //Leggi LSB temperatura
temp =((unsigned int )temp_msb <<5) | (temp_lsb>>3 ); //Unisci LSB e MSB
CS=1;
temperatura = (temp >> 2)/2; //Condiziona temperatura
temp_display = arrotonda(temperatura);
output = PID(temp_set, temperatura); //Richiama la funzione PID
PWM1_Set_Duty(output);
for(i=0; i < 12; i++){ //Mostra temperatura
tre_cifre(temp_display);
}
}
}
Prima di tutto definisco le costanti del PID, variabili, e connessioni del protocollo SPI per il sensore di temperatura. La funzione tre_cifre riceve il numero da visualizzare sul display 7-segmenti, lo divide in unità decine e centinaia e li visualizza uno per volta.
La funzione arrotonda serve solo per arrotondare la temperatura in multipli interi di 5. La funzione PID genera il valore da inviare al PWM ed il suo funzionamento è spiegato nella guida sul PID. La funzione di interrupt EXT_INT serve per incrementare o decrementare la temperatura di settaggio del saldatore. Con il pulsante su PORTC.F6 si incrementa e con il pulsante su PORTC.F7 si decrementa. Ho discretizzato a passi da 10, è inutile controllare con precisione di 1 grado. Inoltre quando si preme uno dei pulsanti si va a visualizzare la temperatura di set sul display.
Nel main inizializzo interrupt, ingressi e uscite, la comunicazione SPI software e il PWM. Nel ciclo infinito vado a leggere la temperatura e la condiziono in modo tale che sia correttamente visualizzata, e la invio alla funzione di arrotondamento. Richiamo poi la funzione del PID dalla quale ottengo il valore di PWM d inviare sul PWM1 e vado a richiamare per 12 volte la funzione di stampa su display. 12 volte in modo tale che la funzione funga da delay di 200mS come specificato nel PID.
SCHEMA
Lo schema è il seguente:
Nello schema è rappresentato un display 7 segmenti a 4 cifre, a noi ne basta uno a 3 cifre. Bisogna usare un display a basso consumo, con corrente di funzionamento di qualche mA per ogni segmento visto che non ho usato un buffer ma il pin (1, 2 o 3) in comune è direttamente connesso al PIC. Io ho usato un display ad anodo comune.
Vi sono 7 resistori da 1.5KOhm sui 7 segmenti in modo tale da avere una corrente di circa 2mA per ogni segmento. Non ridurre questo valore o rischiate di bruciare il PIC. Cambiando il codice si può usare un display a catodo comune senza cambiare lo schema.
La tensione di alimentazione a 5V per il circuito di controllo viene generata da un 7805 che trasforma i 24V in 5V. Il positivo dei 5V va connesso al pin 20 del microcontrollore mentre il pin 8 e 19 del microcontrollore sono connessi a massa. Il pin 1 del microcontrollore è connesso a 5V tramite la resistenza di pull-up R3 mentre il circuito di oscillazione è formato da un quarzo da 4MHz e due condensatori da 22pF.
D1, D2 ed R6 formano una porta or in modo tale che quando premo uno dei pulsanti si attiva l’interrupt. Mentre R4 ed R5 sono i resistori di pull-down che mantengono a 0 gli ingressi PORTC.B6 e B7 se non si preme il pulsante.
La termocoppia va connessa al modulo MAX6675 con la giusta polarità. R1 ed R2 potrebbero essere interne al modulo, quindi controllate bene il modulo e se sono già presenti non le aggiungete anche esternamente. Il condensatore C4 da 220p l’ho aggiunto io per ridurre possibile rumore sulla tensione della termocoppia.
La resistenza del saldatore va connessa con un capo ai 24V positivi e l’altro capo al drain del MOSFET Q1 che funge da switch per il PWM. Il PIN 3 del saldatore andrebbe connesso a massa visto che è il case.
Ho realizzato il controller per il saldatore ma purtroppo ho perso il disegno del PCB. Potete realizzarne uno migliore del mio e con la forma del case che andrete ad usare. L’ho realizzato molto piccolo ma non guasterebbe avere una dimensione maggiore ma con più ordine. In foto potete vedere il mio controller per saldatore prima di essere inscatolato con saldatore e con l’oscilloscopio connessi per controllarne il funzionamento.
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS e il codice scritto con MIKROC al seguente LINK!!!
The post STAZIONE SALDANTE CON CONTROLLO DI TEMPERATURA first appeared on NE555.]]>
INTRO
La breadboard è uno dei più famosi strumenti di prototipazione e permette di realizzare quasi qualsiasi tipo di circuito, testarlo e poi smontare tutto per ricominciare. Se siete lettori affezionati di questo sito avrete notato che tutti i progetti, prima di essere pubblicati, vengono testati su breadboard.
Letteralmente significa tavola per il pane perché le prime versioni, quando ancora si usavo le valvole e l’elettronica era ingombrante era formate da tavole che ricordavano taglieri per il pane con dei chiodi inseriti al suo interno. Le connessioni erano fatte sui chiodi, ora invece ci sono i vari buchini.
Essendo molto versatile e permettendo la modifica rapida del circuito è il primo step prima di procedere su PCB. Purtroppo però non è adatta a tutti i tipi di circuito, infatti non si riescono a raggiungere frequenze elevate (anche se io su una breadboard nuova ho anche realizzato un trasmettitore FM) e non si riescono a far funzionare bene i circuiti di potenza (correnti maggiori di 2-3A).
In questa guida vedremo come le breadboard funzionano e come realizzare un circuito su di esse, cercando di fornirvi qualche trucchetto e dritta per velocizzare le vostre prototipizzazioni. Inoltre andremo ad analizzare gli effetti parassiti che ne limitano l’utilizzo.
CONNESSIONI INTERNE DELLA BREADBOARD
Vi sono in commercio diversi tipi di breadboard con diverse connessioni interne e diverso aspetto anche se il principio di funzionamento rimane invariato. Usiamo come esempio una breadboard classica con doppia linea di alimentazione.
In questo caso tutta la linea di “buchini” nel quadrato blu sono connessi insieme anche se in alcune breadboard vi può essere una interruzione a metà. Stessa cosa per la linea nel quadrato rosso e per le altre due di alimentazione non evidenziate.
Le colonne invece sono collegate insieme a gruppi da 5 “buchini”. Quindi si avrà che il buchino 1a è connesso con 1b, 1c, 1d ed 1e mentre 2a è connesso con 2b, 2c, 2d ed 2e e così via per le altre colonne, non solo quelle che ho evidenziato.
Guardando la breadboard da sotto credo diventerà tutto più chiaro è immediato:
Quando inseriamo un componente va ad inserirsi tra le due linguette di metallo indicate dalla freccia in nero. Se colleghiamo due terminali sulla stessa colonna le linguette metalliche andranno a cortocircuitare i due terminali sulla stessa colonna.
TRUCHETTI PER VELOCIZZARE E MIGLIORARE LA PROTOTIPIZZAZIONE
La prima cosa quando compriamo una breadboard è isolare la parte di sotto se questa ha i contatti metallici scoperti. Si può usare del normale nastro adesivo in modo tale da evitare cortocircuiti. La seconda cosa che ci conviene fare è quella di collegare insieme le due linee di positivo insieme e le due linee di negativo insieme. Terzo trucchetto per velocizzare la prototipizzazione è quello di realizzare dei ponticelli di varia misura in modo tale da avere pronti i ponticelli per connettere le varie colonne o righe con colonne.
Ad esempio io ne ho realizzati di diversa dimensione con diversi colori; il giallo ha la dimensione di 3 buchini, il blu di 4, il rosso di 5 e così via.
Parliamo ora dei jumper. I jumper economici e con filo morbido di spessore ridotto e sono la rovina della prototipizzazione su breadboard. Infatti è capitato parecchie volte che il circuito non funzionasse proprio perché jumper di scarsa qualità erano internamente rotti e non permettevano il passaggio di corrente. Quindi o usate jumper di filo rigido oppure jumper di buona qualità con filo spesso come vedete in foto (Blu scarsa qualità spessore minore rispetto al jumper arancione).
L’ultimo trucchetto è quello di usare componenti con terminali lunghi e non tagliati, in modo tale da collegare i componenti direttamente dove ci servono senza ulteriori jumper.
ESEMPIO SU COME UTILIZZARE LA BREADBOARD
Penso che il modo migliore per spiegare come utilizzare la breadboard sia con degli esempi, quindi proviamo a realizzare un amplificatore per segnale alternato in configurazione non invertente con guadagno 11. Avremo:
Iniziamo prima di tutto nel piazzare i circuiti integrati e la loro alimentazione, la connessione delle righe di alimentazione ci semplifica il lavoro. Successivamente possiamo collegare la porzione di ingresso o il feedback, l’importante è dividersi il circuito in piccole parti per facilitare la prototipizzazione.
Nello step 2 andiamo a collegare la porzione di ingresso formata da R1, R2 e C1. R2 potrebbe essere collegata al di sopra di R1 se questa ha i terminali lunghi. Anche C1 potrebbe essere collegato direttamente alla colonna 21 e il terminale positivo collegato in una colonna libera dove poi inseriremo il filo di ingresso.
Nello step 3 andiamo a collegare il feedback e l’uscita amplificata. C2 è volante e collegato al resistore R4 sulla colonna 14. Possiamo anche avere una connessione alternativa per lo step 3 come nell’immagine sottostante.
Il circuito potrebbe essere montato in 100 modi diversi l’importante e collegare prima l’elemento con più pin e poi controllando lo schema andare a collegare alla colonna i vari elementi che sono connessi insieme.
ELEMENTI PARASSITI CHE LIMITANO IL FUNZIONAMENTO SU BREADBOARD
Come abbiamo visto i nostri componenti quando vengono infilati nel “buchino” della breadboard vanno a creare un contatto tra due lamelle di metallo. Queste lamelle di metallo oppure il terminale del nostro componente possono essere ossidati creando quindi una certa resistenza di contatto.
Ad esempio, utilizzando due fili di rame perfettamente puliti, la resistenza dovuto al contatto tra il primo filo e le lamelle metalliche più la resistenza tra le lamelle e il secondo filo è pari a R=2.4 Ohm nel mio caso. In precedenza ho provato con i fili leggermente ossidati e la resistenza saliva addirittura a R=700 Ohm.
Anche nel caso migliore una corrente di 1A creerebbe una caduta di 2.4V pregiudicando le funzioni del circuito. Ovviamente potremmo andare a inserire il jumper nello stesso “buchino” del componente che riceve la corrente elevata migliorando la situazione.
Il problema principale però rimane quando utilizziamo componenti non molto nuovi quindi fate attenzione ai terminali ossidati.
Un problema secondario e trascurabile è la capacità parassita tra due colonne adiacenti. Infatti abbiamo le due piastre di metallo con le linguette poste faccia a faccia una con l’altra formando un condensatore a piastre piane e parallele. Considerando però la distanza tra le due piastre metalliche dubito che si raggiunga un valore di capacita parassita maggiore di 1pF.
The post COME USARE LA BREADBOARD first appeared on NE555.]]>
INTRO
Quando realizziamo un progetto è un peccato portarsi dietro tutta la scheda Arduino, prima di tutto per il suo elevato costo e anche per questioni di ingombro e di energia consumata dagli altri componenti sulla scheda. La soluzione più elegante e migliore sotto svariati aspetti è quella di utilizzare il solo microcontrollore ATMEGA, però molte volte questo è fisicamente saldato sulla board quindi diventa rischioso dissaldarlo.
In questa guida verrà illustrato come programmare un microcontrollore ATMEGA senza dover utilizzare un PICKIT4 (ormai gli ATMEGA vengono realizzati dalla Microchip, stessa casa produttrice dei PIC) o un vecchio programmatore ATMEL.
In particolare si possono programmare i microcontrollori ATMEGA della famiglia ATmega48A/88A/168A/328/P/PA (potete scaricare il datasheet al seguente LINK!!! https://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061B.pdf) . In questa guida verrà mostrato come programmare un ATMEGA328P DIP con un Arduino UNO R3. Il codice ovviamente viene scritto come per i normali Arduino però la programmazione avviene in modo differente come vedremo.
La modalità bootloader è leggermente diversa da una normale programmazione di microcontrollore però; Lo Sketch viene inserito nella memoria Flash, in una apposita sezione, e viene letta dal microcontrollore ad ogni reset o accensione. Viene usata la programmazione ISP ovvero In-circuit Serial Programmer che permette anche di programmare i fuses.
Per usare la programmazione SPI si usano i pin MISO, MOSI ed SCK.
Board | MOSI | MISO | SCK |
UNO & 2019 (5V) | 11 o ICSP-4 | 12 o ICSP-1 | 13 o ICSP-3 |
MEGA1280 & MEGA2560 (5V) | 51 o ICSP-4 | 50 o ICSP-1 | 52 o ICSP-3 |
Leonardo (5V) | ICSP-4 | ICSP-1 | ICSP-3 |
101 (3.3V) | 11 o ICSP-4 | 12 o ICSP-1 | 13 o ICSP-3 |
Per quanto riguarda il microcontrollore ATMEGA dobbiamo cercare i pin MISO, MOSI ed SCK e il pin RESET.
Ovviamente essendo senza board Arduino il microcontrollore ha bisogno di essere alimentato e in particolare si può usare l’alimentazione dalla board Arduino che useremo per la programmazione. Ho scelto di presentare la modalità di programmazione che non necessita di un quarzo per il circuito di oscillazione. Basterà collegare il pin 7 e 20 ai 5V mentre i pin 8 e 22 a GND.
Abbiamo bisogno di configurare il nostro ARDUINO IDE e in particolare dobbiamo eseguire le seguenti azioni:
CONNETTERE L’ATMEGA ALL’ARDUINO UNO E PROGRAMMAZIONE
Prima di tutto dobbiamo trasformare il nostro ARDUINO UNO in un programmatore ISP. Questo sarà possibile caricando al suo interno uno Sketch presente tra gli esempi e programmando ARDUINO.
Fatto ciò si va a caricare su ARDUINO UNO lo Sketch di esempio che lo trasformerà in un programmatore ISP.
Come detto in precedenza dobbiamo connettere l’alimentazione, MISO, MOSI, SCK e RESET come indicato in tabella. Quindi si avrà:
Ora dobbiamo collegare ARDUINO UNO all’USB. Una volta collegato e dopo aver configurato l’ARDUINO IDE dobbiamo selezionare la seguente board:
Ci sono ancora alcuni passi da fare:
Io ho creato un semplice lampeggio LED da caricare sul microcontrollore ATMEGA.
void setup() { pinMode(8, OUTPUT); //Pin 8 dell'arduino uno corrisponde al pin 14 del microcontrollore } void loop() { digitalWrite(8, HIGH); //Accendi il LED sul pin 14 del uc delay(1000); //Aspetta 1 sec digitalWrite(8, LOW); //Spegni il LED sul pin 14 del uc delay(1000); //Aspetta 1 sec }
Dobbiamo ricordarci che i pin ARDUINO non corrispondono ai pin del microcontrollore, ovvero il pin 13 di ARDUINO UNO non è il pin 13 del microcontrollore ma è il pin 19 ovvero PB5. Possiamo trovare lo schema di ARDUINO UNO al seguente LINK!!! Alla fine della pagina nei download. (https://www.ne555.it/guida-arduino-scheda-uno/).
Ora l’unica cosa che manca è caricare lo sketch nella porzione di memoria del nostro microcontrollore che contiene il bootloader. Per fare questo, se tutto è configurato come istruzioni basterà cliccare sul normale bottone per caricare gli sketch.
Nella GIF sovrastante potete vedere il circuito realizzato con il LED che lampeggia e ARDUINO ancora connesso al microcontrollore.
The post BOOTLOADER SU ATMEGA USANDO ARDUINO first appeared on NE555.]]>
INTRO
Come visto in precedenza (https://www.ne555.it/scrittura-file-csv-dati-temperatura-sd-card/) è possibile scrivere un file .CSV che contiene dei dati acquisiti dal microcontrollore. Grazie alla scheda SD e è possibile memorizzare una grande quantità di dati.
In questo caso utilizzeremo un sensore DHT22 che misura temperatura e umidità dell’aria come sensore, quindi andremo a scrivere su due colonne i dati, sulla prima colonna la temperatura, sulla seconda l’umidità.
Estraendo i dati dalla memori card collegandola al PC è possibile creare grafici oppure analizzare i valori memorizzati.
Il sensore DHT22 è simile al sensore DHT11 (https://www.ne555.it/sensore-dht11-temperatura-umidita/) solo che alcune caratteristiche sono migliori. Inoltre il modo di trasmettere i dati e calcolare i risultati sono leggermente diversi. Il pin out del DHT22 è il seguente:
Le differenze sono le seguenti:
Utilizzeremo un file driver per leggere i dati da questo sensore, quindi non mi dilungo su questo argomento in quanto useremo la libreria.
CODICE
Il codice è il seguente:
sbit Mmc_Chip_Select at LATC0_bit; //chip select memory card
sbit Mmc_Chip_Select_Direction at TRISC0_bit; //RCO
sbit LCD_RS at RB0_bit; //connessione LCD
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
int temperatura; //variabile temperatura
unsigned int umidita; //variabile umidità (solo valori positivi)
char buffer[16]; //char display
char carr_ret_nl[]="\r\n"; //char a capo su SD
char filename[12] = "TempHum.csv"; //Nome del file su SD
char temp[5]; //Variabile scrittura SD
#define DHT22_PIN RC7_bit //Connessione DHT22 RC7
#define DHT22_PIN_DIR TRISC7_bit
#include "DHT22_driver.c" //includi driver DHT22 (stessa cartella del progetto)
//sottoprogramma per creare un nuovo file e scrivere la prima riga
void M_Create_New_File() {
Mmc_Fat_Set_File_Date(2020, 6, 3, 22, 0, 0); //anno, mese, giorno, ora, minuti, secondi
Mmc_Fat_Assign(&filename, 0xA0); //Cerca il file o ne crea uno nuovo
Mmc_Fat_Append(); //Aggiungi al file
Mmc_Fat_Write("Temperatura °C", 14); //Scrivi stringa
Mmc_Fat_Write(";", 2); //Scrivi stringa
Mmc_Fat_Write("Umidità %r", 10); //Scrivi stringa
Mmc_Fat_Write(carr_ret_nl, 3); //Vai a capo
}
void write_int_to_float(int dataIN){ //Programma scrittura dati su SD, steso formato LCD
Mmc_Fat_Assign(&filename, 0xA0); //Cerca il file o ne crea uno nuovo
Mmc_Fat_Append(); //Aggiungi al file
if(dataIN < 0) Mmc_Fat_Write("-", 1); //Scrivi su SD il simbolo - se il valore è minore di 0
sprinti(temp, "%02u.%02u%c", (unsigned int)(abs(dataIN)/100), (unsigned int)(abs(dataIN)%100)); //crea stringa da intero che rappresenta un floating point
Mmc_Fat_Write(temp, 5); //Scrivi stringa su SD
}
void main(){ //main
delay_ms(10); //aspetta sesstamento pic
dht22_init(); //inizializza dht22 dura 2 secondi per dare tempo al dht di poter avviare una successiva misura
//Va inizializzato ad ogni riaccensione del dht22
Lcd_Init(); //initializza LCD
Lcd_Cmd(_LCD_CURSOR_OFF); //cursore off
Lcd_Cmd(_LCD_CLEAR); //pulisci LCD
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH); //Inizializza SPI
if(Mmc_Fat_Init() == 0) { //Se la SD è stata rilevata
M_Create_New_File();
}
while(1){ //ciclo infinito
dht22_read(&umidita, &temperatura); //leggi da dht22 ù
umidita = umidita * 10;
temperatura = temperatura * 10;
write_int_to_float(temperatura); //scrivi prima variabile
Mmc_Fat_Write(";", 1); //punto e virgola per avere su un altra colonna
write_int_to_float(umidita); //la seconda variabile
Mmc_Fat_Write(carr_ret_nl, 3); //Vai a capo come formato csv 2 colonne
//dal sensore leggo 2540 per 25.4 gradi, diviso 100 avrò la parte intera, %100 avrò .4
//la temperatura massima e umidità massima sono rispettivamente 80°C e 99.9% umidità relativa
//anche il sottoprogramma per la scrittura su sd converte allo stesso modo
Lcd_Cmd(_LCD_CLEAR); // clear LCD
if(temperatura < 0) //Mostra temperatura con visualizzazione numeri negativi
sprinti(buffer, "Temp:-%02u.%02u%cC ", (unsigned int)(abs(temperatura)/100), (unsigned int)(abs(temperatura)%100), 223);
else //Mostra temperatura con visualizzazione numeri positivi
sprinti(buffer, "Temp: %02u.%02u%cC ", (unsigned int)(abs(temperatura)/100), (unsigned int)(abs(temperatura)%100), 223);
lcd_out(1, 1, buffer);
sprinti(buffer, "Umid: %02u.%02u%cr ", (unsigned int)(abs(umidita)/100), (unsigned int)(abs(umidita)%100), 37);
lcd_out(2, 1, buffer); //Mostra umidità con visualizzazione solo numeri positivi
delay_ms(2000); //aspetta 10 secondi
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
}
}
Prima di tutto definiamo le connessioni della memory card e dell’LCD con il microcontrollore. Inizializziamo le variabili e definiamo la connessione del pin data del sensore DHT22. In particolare la variabile “\r\n” serve per mandare a capo durante la scrittura su scheda SD. Bisogna includere il file di driver del DHT22 e oltre a definirlo nel codice bisogna inserire il file driver nella cartella dove vi è il nostro codice.
Il sottoprogramma “M_create_new_file()” serve per creare il file e in particolare definiamo la data di creazione, poi cerchiamo un il file e se non esiste lo creiamo, altrimenti si vanno a scrivere i nuovi dati in coda.
Il sottoprogramma “write_int_to_float” serve a scrivere il dato floating di temperatura o umidità sulla memory card. Nel programma principale inizializzo il DHT22,il display LCD e la comunicazione SPI. Se la memory card è presente creo il file e nel ciclo infinito leggo umidità e temperatura, vado a scriverli sul file CSV e infine mostro le stringhe su display.
Il tutto si ripete ogni 10 secondi.
SCHEMA
Lo schema è il seguente:
La tensione di alimentazione è 5V continui e tutto il circuito assorbe circa 25mA che aumentano a 30mA durante la fase di scrittura su memory card. Il condensatore C1 è un condensatore di filtraggio per ridurre il ripple della tensione di alimentazione.
Il display LCD e la board della scheda sd sono alimentati anche con i 5V. Il microcontrollore è un PIC18F252 con il pin 20 alla tensione positiva e i pin 8 e 19 alla tensione di alimentazione.
Il circuito di oscillazione è formato da un quarzo da 8MHz e due condensatori da 22pF. Il pin MCLR viene tenuto a 5V tramite il resistore R3
Il trimmer RV1 serve a regolare il contrasto del display LCD. Il resistore R1 è un resistore di pull-up perché l’uscita del sensore DHT22 è open collector.
Il circuito non funziona se non vi è una memory card inserita.
Lo schema montato su breadboard appane come da immagine sovrastante.
DOWNLOAD
Potete scaricare la simulazione del circuito con Proteus, il driver del sensore DHT22 e le simulazioni per il PIC18F252 e 18F458 al seguente LINK!!!
The post DATALOGGER CON DHT22 PER TEMPERATURA E UMIDITÀ first appeared on NE555.]]>
INTRO
I moduli RTC come il DS3231 o altri hanno solitamente l’alloggiamento per una cella CR2032 da 3V. Questa cella è detta batteria di back-up e permette al modulo di continuare a contare lo scorrere del tempo anche se il nostro circuito non è alimentato.
In questo articolo mostreremo come utilizzare un supercondensatore (o supercapacitore) da circa 2.5-7.5F (si avete capito bene sono unità di Farad) al posto di questa batteria di back-up. Mostreremo il circuito di carica e diverse soluzioni adoperabili. Verrà illustrato inoltre come la batteria di back-up è connessa e come regolare la corrente di carica.
DS3231 E MODULO RTC
Il DS3231 è un chip economico che realizza un Real Time Clock con comunicazione I2C, ovvero se interrogato da un microcontrollore invia l’ora e la data oppure se configurato come source di interrupt può inviare al microcontrollore un segnale con un tempo ben preciso. Utilizza un oscillatore interno e un sensore di temperatura per calibrarsi. Dispone di un pin di ingresso per la batteria e uno per la tensione di alimentazione dell’intero circuito. Le tensioni di funzionamento sono per entrambi i pin tra 2.3V e 5.5V.
Guardando lo schema del modulo DS3231 appare chiara la presenza di due terminali separati, uno per VCC e l’altro per l’alimentazione dalla batteria VBAT. La batteria viene ricaricata da VCC con una corrente pari a (VCC-0.7-VBAT)/200 quindi con alimentazione a 5V, supponendo la tensione della batteria a 2.5V , si avrà una corrente di carica di 9mA. Questo resistore serve anche come protezione e limite di corrente nel caso la batteria fosse a 0V.
SOSTITUIZIONE CON SUPERCONDENSATORE
Considerando il circuito di carica presente, ovvero un diodo in modo tale che la corrente scorra solo nel verso entrante quindi nella batteria e un resistore di protezione, si potrebbe saldate al posto dell’alloggiamento porta batteria direttamente un supercondensatore da qualche Farad. La corrente massima in questo caso sarà (5-0.6)/200 = 22mA quando il condensatore è completamente scarico. Il condensatore si caricherà al suo valore massimo di 4.4V circa ovvero VCC-0.6 dove 0.6V è la caduta sul diodo.
Facciamo due calcoli sul tempo di carica e scarica supponendo il circuito di carica presente e il consumo in stand-by di 3µA con tensione massima di carica 4.4V e minima di funzionamento di 2.3V (rimaniamo larghi su 2.4V).
Bisogna stare attenti alla corrente di autoscarica del supercondensatore. Come si vede dall’esempio aumentando la capacità aumenta anche l’autoscarica rendendo meno efficace l’uso di un supercondensatore da 2.5F invece di uno da 1F.
Inoltre potete variare il tempo di carica se ad esempio non avete a disposizione una corrente elevata di carica.
Ad esempio nel mio caso ho utilizzato un resistore da 820 Ohm in modo tale che la corrente massima sia circa 5mA. Inoltre si può sostituire il diodo 1N4148 con uno a giunzione Schottky in modo tale che si perdano soli 0.35V e avere una tensione massima sul condensatore di 4.65V invece di 4.3V quando il modulo è alimentato a 5V.
CARICA CON CARICABATTERIA TP5100
I supercondensatori possono essere trattati come normali batterie agli ioni di litio e possono essere quindi caricati molto velocemente utilizzando lo stesso principio della carica delle celle al litio. Si possono caricare quindi con una corrente costante in una prima fase e poi caricati a tensione costante.
Considerando che le celle al litio hanno tensioni di 4.2V, questo sistema può essere usato benissimo per i supercondensatori da 5V. La soluzione più semplice è usare un modulo TP5100 ovvero un modulo caricatore per 1 o due celle agli ioni di litio.
Senza collegare i pin di SET la tensione di uscita è 4.2V quindi si riesce a caricare perfettamente un supercondensatore. La corrente di carica dipende dal valore dei due resistori nel cerchio viola (Rsense). Vi sono due resistori da 0.1 Ohm quindi in parallelo 0.05 Ohm.
Il valore della corrente di carica è (0.1/Rsense) 0.1/0.05=2A. I supercondensatori hanno una corrente massima che dipende dalla sua capacità. Quelli a valori bassi hanno correnti basse intorno 0.5A. bisogna quindi usare un Rsense di 0.2 Ohm.
Questo circuito è perfetto se si vuole una carica veloce e controllabile
The post MODULO RTC CON SUPERCONDENSATORE first appeared on NE555.]]>
INTRO
Il regolatore di tensione più conosciuto ed usato è il 78xx come il 7805 se si vogliono 5v in uscita oppure il 7833 se si vogliono 3.3v di uscita. Questo regolatore di tensione soffre di due problemi principale. La differenza tra la tensione di ingresso è uscita (chiamata in inglese drop-out) è di circa 1.5V. Questo significa che se voglio in uscita 5V non posso avere in ingresso meno di 6.5V. Se alimento il mio circuito con una batteria a 9V, quando la tensione raggiunge 6.5V il circuito funzionerà a minore tensione o non funzionerà.
Il secondo problema, relativo ad applicazioni a batteria con bassissimo consumo, è la corrente di quiescenza ovvero la corrente assorbita dai circuiti interni del regolatore di tensione. Infatti questo integrato consuma 5mA. Se ad esempio ho un microcontrollore che esegue operazioni a 4MHz esso consuma circa 4mA, sarebbe uno spreco consumare più potenza sul regolatore che sul microcontrollore, specialmente se alimento il tutto con una batteria.
In commercio esistono diversi LDO con bassa corrente di quiescenza come il MAX1659 con 45uA di corrente di quiescenza, MCP1702 con ben 4uA oppure il LM2936 con 1mA di quiescenza.
In questo articolo vedremo un regolatore LDO con corrente di quiescenza di circa 800uA realizzato con 3 transistor e un diodo zenner utile per piccoli progetti alimentati a batteria. I transistor usati e il diodo zenner sono sempre presenti in discreto laboratorio di elettronica, inoltre qualsiasi transistor a disposizione può essere usato, riducendo o annullando del tutto l’acquisto di componenti.
SCHEMA
Lo schema è il seguente:
La tensione di ingresso può andare da 15V ad un minimo di 5V. La tensione di uscita dipende dal diodo zenner D2, in questo caso sarà circa 4.7V.
Il transistor Q2 e Q3 generano una corrente che pilota il transistor PNP stabilizzatore Q1. Questa corrente dipende dalla corrente che fluisce nel diodo D2 quindi vi è una retroazione sulla tensione di uscita. Se la tensione Vout tende ad aumentare, la corrente in D2 aumenta, quindi la corrente in Q3 aumenta spegnendo Q2, scorre meno corrente quindi nella base di Q1 riducendo la tensione.
Sulla tensione di uscita si possono assorbire un massimo di 100mA e inoltre può essere piazzato un condensatore di filtraggio da 47uF 16V.
La corrente di quiescenza può essere ridotta aumentando il valore di R1 ma ovviamente si riduce la corrente di uscita.
CARATTERISTICHE E REALIZZAZIONE
I grafici della corrente di quiescenza sono i seguenti:
La corrente di quiescenza dipende dalla corrente assorbita in uscita e dalla tensione di ingresso. Il primo grafico mostra la corrente di quiescenza al variare della corrente di uscita a 25°C e vin=9V mentre il secondo grafico mostra sempre la stessa corrente ma al variare di vin con la corrente di uscita fissata a 10mA.
La tensione di uscita mostra un coefficiente di temperatura un po’ alto di circa 1000ppm/°C ovvero varia di 4.5mV per ogni grado centigrado. La tensione di uscita invece varia di poco al variare della tensione di ingresso e mostra una line sensitivity di 0.2%/V.
Il circuito realizzato su breadbord è il seguente:
La tensione di uscita corrisponde a quella misurata ed è stata misurata su un carico pari a 2.2k ohm ovvero 2mA. Considerando i 9V di ingresso e gli 800uA della corrente di quiescenza l’efficienza sarà Eff=(4.45*2m)/(9*2.8m)=35%. Usando un 7805 sarebbe stata del 12%.
Nella breadbord è presente anche un LM35 per misurare il coefficiente di temperatura e in effetti la simulazione corrisponde con la misura (variazione di 140mV tra 25°C e 55°C quindi 4.6mV/°C). Il coefficiente di temperatura dipende molto dal diodo zenner usato.
DOWNLOAD
Potete scaricare la simulazione del circuito con MULTISIM14 al seguente LINK!!!
The post STABILIZZATORE LDO PER APPLICAZIONI A BATTERIA first appeared on NE555.]]>
INTRO
Molte volte per i nostri circuiti vi è la necessità di regolare una tensione proveniente da una pacco batterie in una tensione stabilizzata con valore fisso. Il problema principale in questa applicazione è l’efficienza, specialmente quando il circuito da alimentare assorbe pochi mA. Nel caso in cui il consumo di potenza sia elevato un semplice DC/DC converter tra batteria è circuito da alimentare è perfetto, se ben scelto si possono raggiungere efficienze superiori al 90%.
Quando però il consumo di potenza è molto piccolo (qualche mW) i DC/DC converter switching perdono in efficienza e inoltre hanno bisogno di una tensione di ingresso superiore di circa 1V rispetto a quella di uscita. Questa differenza tra Vin e Vout si chiama dropout e solitamente indica il valore minimo di questa differenza di tensione.
Un altro parametro importante in questo campo di applicazione è la corrente di quiescenza ovvero la corrente assorbita dai circuiti interni del regolatore. Ovviamente sarebbe molto inefficiente se il regolatore di tensione assorbisse più corrente del nostro circuito da alimentare.
Dobbiamo cercare tra i tanti stabilizzatori lineari con basso dropout e bassa corrente di quiescenza come l’integrato prodotto dalla microchip MCP1702.
CARATTERISTICHE ELETTRICHE
Lo schema a blocchi del regolatore è il seguente:
Dispone di un controllo di temperatura massima che disattiva l’uscita se si raggiungono i 150°C, un voltage reference e un amplificatore d’errore che controlla il mosfet serie di uscita. I resistori e il condensatore formano con l’amplificatore il sistema di retroazione.
Le caratteristiche salienti sono le seguenti:
La tensione di dropout dipende dalla corrente di uscita dal regolatore, in particolare la tensione di dropout dipende anche dalla temperatura secondo il seguente grafico:
L’ideale è usare il regolatore con corrente massima di 100mA per non avere un dropout elevato. Questo grafico è valido per una tensione di uscita di 5V, se si usa un regolatore con tensione di uscita minore il dropout è maggiore
I vari modelli sono con le diverse tensioni di uscita sono:
CIRCUITI E APPLICAZIONI
Il più comune circuito realizzabile è un regolatore di tensione, con il regolatore MCP1702 e due condensatori possiamo ottenere in uscita una tensione stabile a partire da una tensione di ingresso non regolata.
I due condensatori servono come filtro per il rumore o per livellare il ripple. Per applicazioni a batteria si può evitare il condensatore Cin.
DOWNLOAD
Potete scaricare il datasheet del componente al seguente LINK!!!
The post MCP1702 LDO PER APPLICAZIONI A BATTERIA first appeared on NE555.]]>
INTRODUZIONE
In questo articolo viene presentata una semplice libreria che effettua la conversione da un numero float ad una stringa di testo, così da poterlo stampare su un display LCD. Questa libreria è pensata per poter lavorare con quella relativa agli LCD presentata in XC8 – #3 – Parte 1. La libreria è stata realizzata avendo come obiettivo principale il contenimento dell’occupazione di memoria, così da poter essere usata all’interno di altri codici senza incidere eccessivamente sulle risorse, caratteristica però che ne riduce la versatilità e i campi di utilizzo.
NUMERI FLOATING POINT
In diversi casi può essere utile o necessario lavorare con numeri reali rappresentati tramite i floating point.
Un floating point è composto da due parti, la mantissa e l’esponente, in maniera da avere:
\(Floating Point = Mantissa * Base^{Esponente}\)
La base è 2 e permette la conversione in bit così da poter memorizzare il numero in un sistema digitale. All’aumentare del numero di bit della mantissa aumenta la precisione con cui si rappresenta il valore, mentre all’aumentare del numero di bit della mantissa aumenta il range di valori che possono essere rappresentati.
Come riportato nella sezione 5.4.3 di “XC8 C Compiler User’s Guide” della Microchip, il compilatore XC8 dispone di 3 tipi per poter rappresentare un floating point e sono float, double e long double.
Un numero floating point è solitamente rappresentato con 32 bit, di cui 24 per la mantissa e 8 per l’esponente. Nel compilatore XC8 di default i tipi float e double hanno 24 bit, 16 per la mantissa e 8 per l’esponente, ma è possibile portarli a 32 bit (24+8) selezionando nel riquadro del progetto “Properties >> Conf >> XC8 Global Options >> XC8 Linker”, selezionare nel menu a tendina “option categories” la voce “Memory Model” e scegliere il numero di bit (24 o 32) con cui rappresentare i tipi float e double (in XC8 long double ha stessa dimensione del double).
STAMPA NUMERI FLOATING POINT SU LCD
Utilizzando la libreria per LCD presentata in XC8 – #3 – Parte 1 si riesce a stampare un carattere o un testo. Se però si vuole stampare un numero è necessario passare dal valore numerico ad un valore interpretabile dal codice.
Se il numero da stampare è rappresentato da una singola cifra è possibile sfruttare la relazione tra valore numerico e carattere ASCII. Le cifre da 0 a 9 rientrano nel set di caratteri ASCII e hanno valori che vanno da 48 per la cifra 0 fino a 57 per la cifra 9. Sfruttando questa relazione è possibile convertire una cifra in carattere semplicemente sommando 48 al valore del numero che si intende rappresentare. Quindi, passando alle funzioni Lcd_Char o Lcd_CharCP la somma tra il numero da stampare e 48 è possibile rappresentare il numero sul display LCD. Il comando diventa:
Lcd_CharCP(Cifra + 48);
Questo approccio può essere utilizzato anche per stampare numeri composti da più cifre, a patto di scomporre le une dalle altre.
Con questo approccio è però impossibile rappresentare numeri negativi in quanto non sarebbe più rispettata la relazione tra valore numerico e carattere. Per aggirare il problema sarebbe necessario determinare e stampare prima il segno del numero e successivamente i vari caratteri che lo compongono.
Un metodo più veloce per poter stampare un numero intero, sia positivo che negativo, è quello di usare la funzione itoa (per numeri positivi si può usare anche utoa) che converte un numero intero in una stringa. Tale funzione è presente nella libreria stdlib e può essere inclusa nel progetto tramite il comando:
#include <stdlib.h>
Per effettuare la conversione da numero intero a stringa è necessario passare alla funzione la variabile di tipo stringa in cui salvare il risultato della conversione, il valore da convertire e la base usata per rappresentare il numero. Stesso discorso vale per la utoa. Volendo convertire il numero 12345, espresso in base 10, nella stringa str e poi stampare il risultato, si avrebbe un codice del tipo:
itoa(str,12345,10);
Lcd_TextCP(str);
Quando si determina la dimensione della stringa si deve considerare che oltre al numero di caratteri desiderati si deve considerare anche quello relativo al terminatore /0, quindi la dimensione va estesa di 1.
Per convertire un numero da float a string esistono diverse librerie che includono anche delle funzioni speciali per adattare al meglio la conversione. Per esempio la funzione sprintf permette di ricevere in ingresso diversi parametri aggiuntivi che agiscono sul formato e sulla rappresentazione del numero convertito. Il problema di queste funzioni sono l’occupazione di memoria richiesta. In alcuni casi, con microcontrollori aventi poca memoria o con codici particolarmente pesanti, l’occupazione è tale da sforare i limiti.
LIBRERIA Float2String
Viene presentata una semplice libreria che permette di convertire un numero reale, rappresentato tramite una variabile float, in una stringa di testo, senza opzioni aggiuntive e avendo come obiettivo principale una bassa occupazione di memoria.
La libreria è composta da un file Float2String.c che contiene le istruzioni per eseguire la conversione e un file Float2String.h per l’header.
Float2String.h
Le prime due righe del file Float2String.h controllano che la libreria non sia già stata chiamata all’interno del progetto, evitando di includerla più volte.
#ifndef Float2String_H
#define Float2String_H
...
#endif
Seguono le inclusioni delle librerie necessarie, che permettono di usare valori mnenmonici per indicare i tipi delle variabili (stdint.h), la funzione per convertire da intero a stringa (stdlib) e le funzioni necessarie per la gestione delle stringhe (string.h).
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
Segue infine il prototipo della funzione, che riceve in ingresso un valore float, il numero di cifre decimali con cui rappresentare il numero e la stringa nella quale inserire il risultato della conversione.
char* Float2String(float value, uint8_t decimal, char* str);
Float2String.c
Per prima cosa si include l’header file della libreria.
#include "Float2String.h"
All’interno della funzione, dopo aver dichiarato le variabili, vengono svolte le varie operazioni necessarie alla conversione, prima fra tutte il reset della stringa str passata alla funzione, impedendo così che la nuova conversione venga messa in coda alla precedente stringa.
char* Float2String(float value, uint8_t decimal, char* str){
const uint8_t base = 10;
uint8_t i;
uint8_t temp_str[21];
uint8_t digit;
uint16_t dt_int;
uint16_t dt_dec;
uint16_t power = 1;
strcpy(str, "");
...
return str;
}
Segue la conversione della parte intera in stringa. Per far ciò si associa il valore del numero reale ad una variabile uint16_t, così da associare la sola parte intera, mentre il segno viene determinato dalla variabile di tipo float, infatti se value è negativa viene concatenato alla stringa il segno “-“. La variabile contenente la parte intera viene convertita in stringa tramite la funzione utoa e concatenata alla stringa str che, essendo stata ripulita, contiene il solo valore intero del numero reale e l’eventuale segno. La funzione utoa ammette valori unsigned a 16 bit.
// Conversione parte intera
if(value >= 0){
dt_int = (uint16_t)value;
}
else{
dt_int = -(uint16_t)value;
strcat(str,"-");
}
utoa(temp_str,dt_int,base);
strcat(str,temp_str);
Segue la conversione della parte decimale, che avviene esclusivamente se il numero di cifre decimali desiderate è superiore a 0, pertanto la prima istruzione è un if che controlla il valore della variabile decimal e, in caso positivo, viene concatenato il punto alla stringa.
Segue quindi un ciclo for che ha lo scopo di eseguire il calcolo della potenza necessario ad eseguire la convertire da valore decimale ad intero (parzialmente o totalmente a seconda del valore reale e del numero di cifre richieste). Per l’elevamento a potenza si sarebbe potuto utilizzare la funzione pow() ma da alcune prove effettuate la soluzione che richiede meno occupazione di memoria è risultata essere quella calcolata tramite ciclo for.
Segue il calcolo della parte decimale ottenuta tramite la differenza tra il valore reale moltiplicato per la potenza e il valore della parte intera moltiplicato per la potenza. La differenza tra i due valori tiene conto del segno della variabile di tipo float e del fatto che la parte intera viene memorizzata come valore senza segno.
Segue quindi la conversione della parte decimale in stringa. Si utilizza la funzione utoa che converte un numero positivo in stringa.
Prima di concatenare la stringa temp_str con la stringa str, si esegue uno zero-padding, che consiste nel riempire di ‘0’ le posizioni delle cifre decimali non occupate da alcun valore. Questa operazione è ottenuta tramite la funzione strlen() che restituisce la lunghezza della stringa temp_str (che in quel punto di codice rappresenta la parte decimale del numero) che, confrontata con la variabile decimal, determina il numero di cifre da riempire con ‘0’.
Come ultima operazione si concatena la stringa così ottenuta con la parte già determinata di str e se ne restituisce il valore.
// Conversione parte decimale
if(decimal> 0){
strcat(str,".");
for(i=0; i<decimal; i++){
power *= 10;
}
if(value>= 0){
dt_dec = (uint16_t)( value*power - dt_int*power);
}
else{
dt_dec = (uint16_t)(-value*power - dt_int*power);
}
utoa(temp_str,dt_dec,base);
digit = decimal-strlen(temp_str);
if(digit){
for(i=0; i<digit; i++){
strcat(temp_str,"0");
}
}
strcat(str,temp_str);
strcat(str," ");
}
La funzione Float2String ha due limitazioni sulle conversioni da floating point a stringa. Sia la parte intera che decimale sono convertite tramite la funzione utoa che accetta valori rappresentati tramite uint16_t a cui è associato il range [0; 65535]. Ciò comporta che:
La libreria è pensata per funzionare in codici che sfruttano il modulo ADC o con sensori che richiedono numeri reali che normalmente ricadono in tali range.
Se il numero reale non dovesse ricadere in tale range è possibile utilizzare funzioni più precise per eseguire la conversione.
DOWNLOAD
Al seguente link è possibile scaricare i file Float2String.c e Float2String.h relativi alla libreria per la conversione da float a stringa: DOWNLOAD.
The post MPLAB X & XC8 – #3: Libreria Float2String per LCD – Parte 3 first appeared on NE555.]]>
INTRO E CARATTERISTICHE
Il componente siglato TEMT6000 è un fototransistor di tipo NPN inserito in un package in miniatura con montaggio superficiale di tipo 1206. Il vantaggio di questo sensore è il fatto che è sensibile alla luce quasi nello stesso modo l’occhio lo è, ovvero lo spettro visibile è circa uguale.
Può essere utilizzato in molte applicazioni, ad esempio regolare la luminosità di una stanza, in un interruttore crepuscolare oppure per misurare l’irradiazione solare. Su ebay questo componente è disponibile sia a se stante sia come modulino con PCB, pin di connessione e un resistore di pull-down come da immagine.
Le caratteristiche sono le seguenti:
In dettaglio la corrente di collettore in funzione della luminosità e lo spettro di sensibilità hanno le seguenti caratteristiche:
Quindi il sensore fornisce una corrente che dipende dalla luminosità.
Il primo grafico mostra la corrente in funzione della luminosità in un grafico logaritmico a 5 divisioni, quindi tra 10 e 100 Lux avremo le linee su 20, 40, 60 e 80 Lux.
MODULO SENSORE
Come visto nell’immagine precedente il modulo con il sensore saldato dispone di un resistore da 10K. Questo ci permette di avere in uscita una tensione che dipende dalla luminosità. Con la semplice legge di Ohm possiamo trasformare l’informazione in corrente in tensione, in modo tale che sia leggibile semplice da un ADC o microcontrollore.
Quindi avremo:
Possiamo estrapolare l’equazione della retta di tensione e ottenere la seguente funzione:
Quindi possiamo conoscere quanto è illuminata una stanza conoscendo la tensione del sensore.
Per avere una idea qualitativa dei Lux possiamo considerare questa tabella:
Collegando il terminale S all’ADC del microcontrollore possiamo leggere la luminosità
DATASHEET
Potete scaricare il datasheet al seguente LINK!!!
The post SENSORE DI LUMINOSITÀ AMBIENTALE TEMT6000 first appeared on NE555.]]>
INTRO
In commercio esistono diversi display OLED, quasi tutti basati sulla stessa logica di controllo e sull’integrato SSD1306. OLED significa Organic LED, ovvero viene utilizzata la proprietà di materiali organici bioluminescenti che se eccitati sono in grado di generare luce.
Vi sono i display OLED 128×64 pixel, 64×32 e 96×16 e sono disponibili con diversi colori e diversi pin. Sono programmati con protocollo I2C quindi il display con minor numero di pin ne ha 4, 2 per l’alimentazione, e due per la comunicazione, ovvero SCL ed SDA.
Vi è la versione a 4 pin come detto ma vi è anche la versione a 7 pin. Cambia leggermente la connessione visto che va connesso al microcontrollore anche il pin RES. Inoltre cambia l’indirizzo I2C tra le due versioni come vedremo nel codice.
LIBRERIA SSD1306
La libreria è strutturata come un file driver .c da caricare all’interno del progetto. Quindi basterà copiare il driver nella cartella del nostro progetto e aprirlo in una finestra di mikroc. Dopo di che possiamo richiamare le funzioni che ci servono per far funzionare il display. Le funzioni sono le seguenti:
SSD1306_Init(vccstate, i2caddr); //inizializza display, specificando il tipo di alimentazione e l'indirizzo (0x78 per il 4 pin, 0x7A per l'altro)
SSD1306_StartScrollRight(start, stop); //scroll a destra
SSD1306_StartScrollLeft(start, stop); //scroll a sinistra
SSD1306_StartScrollDiagRight(start, stop); //muovi sulla diagonale verso destra
SSD1306_StartScrollDiagLeft(start, stop); //muovi sulla diagonale verso sinistra
SSD1306_StopScroll(); //ferma ogni movimento
SSD1306_ClearDisplay(); //pulisci il display
SSD1306_FillScreen(); //accendi tutti i pixel
SSD1306_Dim(dim); //aggiusta luminosità, dim può essere 0 o 1
SSD1306_InvertDisplay(i); //inverte display, i può essere 1 o 0
SSD1306_GotoXY(colonna, riga); //vai alla posizione colonna-riga
SSD1306_PutC(c); //scrivi un char nella posizione colonna-riga specificata sopra
SSD1306_PutCustomC(char *c); //scrivi un char 5x7 realizzat da noi
SSD1306_Print(char *s); //scrive una stringa di caratteri
Bisogna inizializzare il display specificando il tipo di tensione di alimentazione e l’indirizzo del display, 0x78 per il 4 pin e 0x7A per il 7 pin. In caso provate entrambi le soluzioni se non funziona.
Vi sono poi le istruzioni per muovere il testo in diverse posizioni, le istruzioni per controllare il display, spegnerlo, pulirlo o muovere il cursore. Infine ci sono le stringhe per la scrittura su display.
Il display OLED richiede una ram di buffer con dimensione 1024 bytes (128×64/8) quindi se si vuole scrivere un pixel bisogna scriverne 8, uno solo non è possibile. Questo driver ci permette di scrivere solo stringe di testo sul display. Il display 128×64 è diviso in 21 colonne e 8 righe, quello 128×32 sarà diviso in 21 colonne e 4 righe, quello 96×16 avrà 16 colonne e 2 righe. Questo perché i char hanno dimensione 5×7 quindi avrò 128/6 (5 pixel più uno di spazio) per le colonne e 64/8.
La libreria dispone di una matrice con i caratteri all’interno.
CODICE
Il codice è il seguente:
#include "SSD1306_driver.c" //includi il driver del display
#define SSD1306_I2C_ADDRESS 0x78 //0x7A per display con pin RES (reset) e DC pin
#define SSD1306_128_64 //128 pixel per 64 pixel ogni char è 5x7
char *text = "000\0"; //terminatore di stringa
unsigned short i = 100;
void main() {
delay_ms(5); //aspetta 5ms
I2C1_Init(100000); //Inizializza il modulo I2C 1
SSD1306_Init(SSD1306_SWITCHCAPVCC, SSD1306_I2C_ADDRESS);
//_EXTERNALVCC, _SWITCHCAPVC oppure _CHARGEPUMP tipo di connessione VCC, indirizzo (inizializzazione display)
SSD1306_ClearDisplay(); //pulisci display
SSD1306_GotoXY(1, 1); //prima riga prima colonna
SSD1306_Print("NE555.IT"); //scrivi stringa
delay_ms(5000); // wait 5 seconds
SSD1306_GotoXY(1, 2); //seconda riga prima colonna
SSD1306_Print("Display OLED"); //scrivi stringa
delay_ms(5000); // wait 5 seconds
SSD1306_StartScrollRight(1, 1); //Muovi a destra per 3 secondi
delay_ms(3000);
SSD1306_StopScroll();
SSD1306_StartScrollLeft(1, 2); //Muovi a destra per 3 secondi
delay_ms(3000);
SSD1306_StopScroll();
SSD1306_StartScrollDiagRight(1, 1); //Muovi lungo la diagonale a destra
delay_ms(3000);
SSD1306_StopScroll();
SSD1306_StartScrollDiagLeft(1, 2); //Muovi lungo la diagonale a sinistra
delay_ms(3000);
SSD1306_StopScroll();
while(i > 0) {
text[0] = (i / 100) % 10 + '0'; //estrai centinaia
text[1] = (i / 10) % 10 + '0'; //estrai decine
text[2] = i % 10 + '0'; //estrai unità
SSD1306_GotoXY(10, 5);
SSD1306_Print(text);
i -= 1; //decrementa i
delay_ms(1000); //aspetta 1 secondo
}
}
Includo il driver del display, scelgo come indirizzo 0x78 e definisco come display il 128×64. Inizializzo una variabile short al valore di 100, userò questa variabile per scrivere un numero sul display.
Bisogna inizializzare il modulo I2C e inizializzeremo il modulo 1. Successivamente si inizializza il display e lo si pulisce. Scriviamo una stringa sulla prima riga e prima colonna e poi un’altra sulla seconda riga. Quando andremo a muovere a destra e sinistra il testo si muoverà solo la seconda stringa scritta. Sulla diagonale si sposterà anche solo la seconda riga ma la prima seguirà sopra e sotto la seconda riga senza muoversi in diagonale.
Stoppato il movimento andremo a scrivere il valore della variabile sulla quinta riga decima colonna e ogni secondo questa variabile viene decrementata fino a raggiungere 0.
SCHEMA
Lo schema è il seguente:
La tensione di ingresso è 5V e l’assorbimento è di circa 5mA. Il display andrebbe alimentato a 3.3V come si descritto nel datasheet. In realtà ho provato ad alimentarlo a 5V per 2-3 minuti e non si è bruciato, però ovviamente non vi garantisco nulla e consiglio di alimentarlo a 3.3V. La tensione 3.3V viene generata da uno stabilizzatore lineare 7833 o 78l33 e viene filtrata da un condensatore a 100uF.
Il circuito di oscillazione viene realizzato con due condensatori da 22pF e un quarzo da 8MHz. R1 mantiene il PIC18F non resettato.
Il PIC18F458 viene alimentato con i 3.3V positivi al pin 11 e 32 e con il negativo ai pin 12 e 31. Il positivo dei 3.3V va connesso anche a VCC del display e il negativo a GND. SCL va connesso al pin 18 mentre SDA al pin 23 del microcontrollore con due resistori di pull-up connessi a VCC.
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS, Il codice scritto con MIKROC e i file della LIBRERIA SSD1306 al seguente LINK!!!
The post 0.96″ I2C OLED SSD1306 LCD CON PIC18F first appeared on NE555.]]>
INTRO
L’idea per questo progetto nasce dalla curiosità di monitorare le condizioni ambientali per lunghi periodi e poi andare a creare grafici per la temperatura, umidità, vento, e altre variabili. La memoria più semplice da utilizzare in questo caso è la scheda SD ed andare a scrivere i valori in un file CSV. In questo modo si possono andare a scrivere moltissimi valori senza preoccuparsi dello spazio occupato.
In questo esempio si va a leggere la temperatura da un sensore LM35 e visto che vi è una sola variabile da tenere in considerazione i dati vengono messi uno per uno in colonna ogni 10 secondi. Lo spegnimento del sistema comporta l’automatica chiusura del file .CSV permettendo quindi di rimuovere la scheda SD.
Inserita su un PC con installato microsoft excell sarà possibile realizzare il grafico con l’andamento della temperatura.
Ad esempio la temperatura della mia stanza monitorata per alcuni minuti è la seguente:
I picchi potrebbero essere fluttuazioni dovute al rumore, inaccuratezza dello strumento, errore di conversione o altri fattori. Una volta che i dati sono su excell si potrebbe anche eseguire un filtraggio oppure una media. Inoltre i dati sono accessibili anche su matlab.
CODICE
Il codice è il seguente:
sbit Mmc_Chip_Select at LATC0_bit; //CS modulo SD card
sbit Mmc_Chip_Select_Direction at TRISC0_bit; //RCO
char filename[9] = "Temp.csv"; //Nome del file
char temp[5]; //Stringa valore temperatura
float temperatura; //valore temperatura
char carr_ret_nl[]="\r\n"; //Stringa per andare a capo
//sottoprogramma per creare un nuovo file e scrivere la prima riga
void M_Create_New_File() {
Mmc_Fat_Set_File_Date(2020, 6, 3, 22, 0, 0); //anno, mese, giorno, ora, minuti, secondi
Mmc_Fat_Assign(&filename, 0xA0); //Cerca il file o ne crea uno nuovo
Mmc_Fat_Append(); //Aggiungi al file
Mmc_Fat_Write("Temperatura °C", 14); //Scrivi stringa
Mmc_Fat_Write(carr_ret_nl, 3); //Vai a capo
}
//sottoprogramma per aggiungere una nuova riga al file
void File_Open_Append(float tempIN){ //ricevi il float con la temperatura
Mmc_Fat_Assign(&filename, 0xA0); //Cerca il file o ne crea uno nuovo
Mmc_Fat_Append(); //Aggiungi al file
FloatToStr_FixLen(tempIN, temp, 5); //Converti la temperatura in stringa a 5 caratteri
Mmc_Fat_Write(temp, 5); //Scrivi la stringa con la temperatura (5byte)
Mmc_Fat_Write(carr_ret_nl, 3); //Vai a capo
}
void main() {
TRISB.B0 = 0; //PORTB LED
ADC_Init(); //Inizializza ADC
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH); //Inizializza SPI
if(Mmc_Fat_Init() == 0) { //Se la SD è stata rilevata
M_Create_New_File(); //Crea nuovo file
while(1){ //Ciclo infinito
temperatura = ADC_Read(0); //Leggi canale 0 ADC
temperatura = temperatura * 0.4882; //Converti temperatura
File_Open_Append(temperatura); //Scrivi temperatura
PORTB.B0 = 1;
delay_ms(2000); //Lampeggio led acceso 2 secondi
PORTB.B0 = 0;
delay_ms(2000); //Altri 8 secondi di delay
delay_ms(2000);
delay_ms(2000);
delay_ms(2000);
}
}
}
Prima di tutto indico nel codice dove è connesso il Chip Select della scheda SD, poi inizializzo alcune variabile che mi serviranno nel codice e alcune sottofunzioni. La prima sottofunzione crea il file con una determinata data di creazione e si va a scrivere la prima stringa ovvero “Temperatura °C”. Nella seconda sottofunzione si va a riprendere il file e si aggiunge una riga contenente la temperatura. Nel codice principale si inizializzano l’ADC e le porte B come uscite.
Si inizializza il protocollo di comunicazione SPI. Usare una frequenza di Fcristallo/64 va bene per un quarzo da 4MHz. Se si usa un quarzo più piccolo bisogna usare _SPI_MASTER_OSC_DIV64 diverso. Dopo di che se la scheda SD viene rilevata, quindi la comunicazione funziona e la scheda SD è inserita si va a creare il file. Nel ciclo infinito si va a leggere la temperatura, la si converte in gradi e poi si richiama la routine di scrittura di una nuova riga. Si accende il LED, lo si rispegne dopo due secondi e poi vi sono altri 4 delay da 2 secondi in modo tale che la temperatura venga letta ogni 10 secondi circa.
Le routine utilizzate della libreria SD card sono le seguenti:
Vi sono molte altre funzioni per la scrittura su scheda SD ma non sono state usate per questo progetto.
SCHEMA
Lo schema è il seguente:
Il cristallo X1 è un quarzo da 4MHz e con i due condensatori da 22pF formano il circuito di oscillazione. La resistenza R1 serve per evitare che il PIC18F458 si resetti, mentre ai pin 11 e 32 si hanno 5V e ai pin 12 e 31 la massa dell’alimentazione. C3 è un condensatore di filtraggio.
Il modulo SD CARD è alimentato anch’esso a 5V anche se internamente funziona a 3.3V.
Il sensore di temperatura è un LM35 e il LED di segnalazione ha un resistore da 1K come limitatore di corrente. Il chip select del modulo è connesso a RC0 e la comunicazione è effettuata in SPI.
Lo schema montato su breadboard ha l’aspetto mostrato in foto. L’alimentatore del circuito è formato da un vecchio alimentatore 5V 1A caricabatteria per cellulare.
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS e i file MIKROC al seguente LINK!!!
The post SCRITTURA FILE CSV CON DATI TEMPERATURA SU SD CARD first appeared on NE555.]]>
INTRO
Come illustrato nella guida sui servomotori (https://www.ne555.it/i-servomotori/) i servomotori hanno bisogno di un impulso di durata determinata per mettersi nella posizione desiderata. Arduino dispone di una libreria per il controllo dei servomotori e un singolo Arduino può controllare fino a 12 servi e fino a 48 sull’Arduino mega.
La libreria ha le seguenti funzioni:
A meno di applicazioni particolari si usano solo le prime 4 funzioni. La funzione di lettura ritorna semplicemente il valore scritto in precedenza, ma se il servo ha subito variazioni esterne non riesce a leggerle.
CODICE E SCHEMA DI ESEMPIO
Andiamo a realizzare un esempio semplice, un pulsante che controlla lo stato del servocomando. Se premuto il servo va in posizione 0° altrimenti sta in posizione 90°. Il tutto si aggiorna ogni secondo.
Prima di tutto con la funzione servo.attach(pin, min, max) vado a trovare i valori di minimo e massimo controllando il motore e il suo angolo. 500ms di impulso corrispondono a 0 gradi mentre per raggiungere i 180° l’impulso deve durare 2600ms.
Il codice è il seguente:
#include <Servo.h> //richiama la libreria servo Servo servo1; //ogetto servo1 const int pulsante = 2; //variabile pulsante uguale 2 int statopulsante = 0; void setup() { servo1.attach(9, 500, 2600); //Servo connesso al pin9 pinMode(pulsante, INPUT); //Pin 2 assegnato come ingresso } void loop() { statopulsante = digitalRead(pulsante); //Leggi stato pulsante if (statopulsante == HIGH) { //Se il pulsante è premuto servo1.write(0);} //Servo impostato a 0° else{servo1.write(90);} //Altrimenti 180° delay(1000); //Aggiorna ogni secondo }
Includo la libreria del servo, creo l’oggetto servo1, il pulsante e lo stato del pulsante. Nel setup inizializzo il servo sul pin9 e con minima e massima durata dell’impulso. Inizializzo il pin 2 come ingresso del pulsante.
Nel ciclo infinito controllo se il pulsante è premuto o no e in base allo stato del pulsante metto in posizione 0° se è allo stato alto, ovvero premuto, altrimenti 90°. Questo ciclo si ripete ogni secondo.
Lo schema è il seguente:
Il servo è connesso con il filo rosso alla tensione 5V, il marrone a GND e il giallo è connesso al pin 9 di Arduino. R1 è un resistore di pull-down che mantiene il pin 2 a GND quando il pulsante non è premuto. Premendolo avrò 5V sul pin 2 di Arduino.
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS e lo Sketch Arduino al seguente LINK!!!
INTRO
Il sensore BMP280 è un sensore barometrico di pressione a bassa potenza che permette inoltre di misurare la temperatura. Può essere usato a bordo di droni oppure per stazioni di rilevazione meteo visto il suo basso errore nel rilevare la pressione. Il funzionamento di questo sensore è descritto nella guida presente su questo sito (https://www.ne555.it/sensore-pressione-bmp280/).
In questo articolo verrà mostrata come utilizzare la libreria scritta da me (più che una libreria è un file driver che contiene le sotto funzioni per la comunicazione) e inoltre verrà mostrato un esempio che utilizza un LCD per mostrare i valori di temperatura e pressione letti.
Per la comunicazione verrà usato l’I2C anche se il modulo dispone di una comunicazione SPI. Ho scelto questa modalità perché funziona con soli 2 fili invece dei 3 richiesti dall’SPI.
int ret;
void main() {
TRISB.RB0 = 0;
I2C1_Init(100000);
delay_ms(1000);
while(1){
I2C1_Start();
I2C1_Wr(0xEE);
I2C1_Wr(0xD0);
I2C1_Repeated_Start();
I2C1_Wr(0xEF);
ret = I2C1_Rd(0);
I2C1_Stop();
if(ret == 0x58) PORTB.RB0 =1;
else PORTB.RB0 =0;
delay_ms(1000);
}
}
//esegui comunicazione come da datasheet pagina 30 e semplicemente verifica se il valore nel registro Id corrisponde
//se corrisponde la comunicazione è ok e accende il led
Iniziamo con un codice molto semplice che semplicemente legge un registro interno al BMP280 controlla se il valore di questo registro è corretto e in caso accende un LED.
Inizializzo l’I2C a 100kHz, inizio la comunicazione I2C, scrivo l’indirizzo del modulo (0xEE), poi l’indirizzo del registro (0xD0), poi ripeto lo start della comunicazione I2C, scrivo l’indirizzo con l’ultimo bit =1 per avvertire che voglio leggere e poi leggo il dato restituito dal sensore. Se è uguale a 0x58 ovvero l’ID del dispositivo allora accendo il LED.
Nel driver si hanno sotto funzioni simili a questa per eseguire le varie comunicazioni. Il driver è simile ad uno presente su internet ma non funzionava con il PIC18F. Potete scaricare il driver nella sezione download.
CODICE
Il codice è il seguente:
sbit LCD_RS at RB0_bit; //connessione LCD
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
#include "BMP280def.c" //Includi il driver del sensore che contiene le routine
//driver con bug risolto rispetto a quello presentato da altri siti
long temperatura; //valore floating point temperatura
unsigned long pressione; //Valore floating pressione se si vuole cifre dopo la virgola
char buffer[17];
void main(){
I2C1_Init(100000); //inizializza I2C a 100kHz
delay_ms(500); //aspetta mezzo secondo
Lcd_Init(); //inizializza LCD
Lcd_Cmd(_LCD_CURSOR_OFF); //cursor off
Lcd_Cmd(_LCD_CLEAR); // clear LCD
//inizializza il sensore in modalità normale, campionamento T 16 (1, 2, 4, 8, 16)
//Campionamento pressione x4 (stesse posibilità della temp)
//filtro misura disattivato (coefficienti 2, 4, 8, 16) e standby 0.5ms (0.5, 1, 2, 4)
// BMP280_begin(modalità, campionamento t, campionamento p, filtraggio, standby_time)
if(BMP280_begin(MODE_NORMAL, SAMPLING_X16, SAMPLING_X4, FILTER_OFF, STANDBY_0_5) == 0){
lcd_out(1, 1, "Errore"); //Se la funziona restituisce 0 c'è un problema
lcd_out(2, 1, "Connessione!"); //di connessione
while(1); //rimani qui e va controllata la connessione
}
while(1){
// leggi temperatura in °C e la pressione in hPa
BMP280_readTemperature(&temperatura); //leggi temp
BMP280_readPressure(&pressione); //leggi pressione
if(temperatura < 0) //Mostra temperatura
sprinti(buffer, "Temp:-%02u.%02u%cC ", (unsigned int)(abs(temperatura)/100), (unsigned int)(abs(temperatura)%100), 223);
else
sprinti(buffer, "Temp: %02u.%02u%cC ", (unsigned int)(temperatura/100), (unsigned int)(temperatura%100), 223);
lcd_out(1, 1, buffer);
//mostra pressione in kPa chilopascal
sprinti(buffer, "Pres: %04u.%02uhPa", (unsigned int)(pressione/100), (unsigned int)(pressione%100));
lcd_out(2, 1, buffer);
delay_ms(2000); //aspetta 2 minuti
}
}
// end of code.
Prima di tutto inizializzo la connessione dell’LCD, includo il driver del sensore (BMP280def.c) che dovrà essere inserito nella stessa cartella del vostro progetto e definisco alcune variabili utili.
Nel main inizializzo la comunicazione I2C, l’LCD e poi vado ad inizializzare il sensore BMP280. Posso scegliere la modalità di funzionamento normale o in standby, il campionamento, ovvero quante misure effettuare e poi mediare per la temperatura e la pressione, il coefficiente del filtro e per quanto tempo avere lo standby del sensore dopo la misura. Questa funzione oltre a settare il sensore restituisce 1 o 0. Se restituisce 0 allora c’è un problema con la comunicazione, non riesce a leggere l’ID del sensore. Mostra quindi a display la scritta “errore connessione”. Se la funzione ritorna 1 continua l’esecuzione del codice.
Nel ciclo infinito leggo la temperatura con la funzione “BMP280_readTemperature(&temperatura);” e la pressione con la funzione “BMP280_readPressure(&pressione);” dove temperatura e pressione sono le due variabili dove inserire il valore.
Se la temperatura è minore di 0 uso la stringa per i numeri negativi che mostra la stringa “Temp: -“ un intero a 2 cifre, un punto, un altro intero a due cifre e poi un char C che sta per grado centigrado. Il primo intero è la Temperatura modulo 100 per avere le cifre prima della virgola, il secondo intero è la cifra dopo la virgola e infine 223 è il char per il simbolo °.
Se la temperatura è positiva si fa la stessa cosa ma senza il meno ovviamente. Per la pressione invece si va a visualizzare a display un interno a 4 cifre, un punto, un decimale a due cifre e poi il char hPa. La funzione riceve la pressione/100 e la pressione modulo 100.
Vi è un delay di 2 secondi e poi ricomincia tutto.
SCHEMA
Lo schema è il seguente:
La tensione di ingresso è 5V e l’assorbimento è di circa 30mA. Il sensore BMP280 andrebbe alimentato a 3.3V come si vede nel datasheet. In realtà ho provato ad alimentarlo a 5V per 2 minuti e non si è bruciato, però ovviamente non vi garantisco nulla e consiglio di alimentarlo a 3.3V. La tensione a 3.3 viene generata da uno stabilizzatore lineare 7833 o 78l33 e viene filtrata da un condensatore a 10uF.
Anche il microcontrollore va alimentato a 3.3V mentre il display deve essere alimentato a 5V. Il resistore R3 mantiene il microcontrollore attivo ed RV1 è la regolazione del contrasto. Il PIC18F458 viene alimentato con i 3.3V positivi al pin 11 e 32 e con il negativo ai pin 12 e 31. Il positivo dei 3.3V va connesso anche a VCC del modulo e al pin SDO. SCL va connesso al pin 18 mentre SDA al pin 23. Non ci è alcun resistore di pull-up perche sono integrate nel modulo da me usato e disponibile a meno di un euro su ebay.
Il display è connesso come da schema alle PORTB del microcontrollore.
Il circuito realizzato su breadboard è il seguente:
DOWNLOAD
Potete scaricare la simulazione del circuito con PROTEUS, i codici per MIKROC e la libreria al seguente LINK!!!
INTRO
Per tutte quelle applicazioni dove si ha bisogno di un segnale di ingresso digitale controllabile da operatore bisogna utilizzare un pulsante o simili. In questo tutorial vedremo come utilizzare il modulo bottone touch che permette di avere un pulsante a sfioramento su una board molto piccola. Il modulo è il seguente:
La parte dove vi è scritto “TOUCH” va a formare un condensatore con il dito quando questo è vicino. Questa capacità viene letta dall’integrato TTP233 (quello a 6 pin) che svolge la funzione di touch PAD detector.
Il modulo ha 3 PIN, uno per la tensione VCC positiva, uno per l’uscita ovvero il pin I/0 e infine la massa ovvero il negativo GND. Lo schema del modulo è il seguente:
TP è la piazzola di metallo sulla board dove si poggia il dito. L’uscita I/O va a livello alto (VCC) quando il dito è poggiato sulla piazzola, inoltre il LED si accende e rimane acceso finchè non si toglie il dito.
MODIFICA FUNZIONE DI USCITA E CARATTERISTICHE
Con i ponticelli A e B si può modificare il comportamento dell’uscita.
Le caratteristiche principali sono:
INTRO
Pur non essendo un “fan” dei PIC devo ammettere che il PIC18F47Q10 ha una serie di caratteristiche veramente notevoli anche considerando il costo abbastanza basso (circa 1.7€ + tasse per la versione DIL).
Qui di seguito le caratteristiche principali (prese dal datasheet):
In particolare si noti che a differenza dei suoi predecessori ha ben 2 unità I2C/SPI e 2 EUSART, senza parlare del modulo CLC che in pratica è una sorta piccola CPLD che permette di sintetizzare 8 funzioni logiche e di associarle anche ai pin esterni.
Ho così deciso di realizzare una piccola scheda (PicOne) per poter eseguire dei test, una sorta di “dev board” a modo mio.
Come ho già fatto in precedenza per altre MCU ho utilizzato un “form factor” che mi permettesse anche l’inserimento diretto nelle breadboard. Ho anche aggiunto la possibilità di alimentare il PIC sia a 5V che a 3.3V, due led utente, due tasti utente, un convertitore USB-seriale e un socket per microSD con relativo traslatore di livelli logici (necessario quando la MCU lavora a 5V).
Per programmare la MCU sarà necessario disporre di un programmatore come il PicKit4 da collegare al connettore ICSP (J2) posto sulla scheda stessa.
SCHEMA
Lo schema elettrico è disponibile insieme al resto della documentazione allegata nella sezione DOWNLOAD. Per comodità comunque inserisco qui le due immagini che lo compongono:
L’alimentazione è fornita direttamente dal connettore USB (USB mini) che provvede anche a collegare il convertitore USB-seriale realizzato con un CH340G (U2).
I vari segnali disponibili su J4 e J5 sono duplicati su JB1 e JB2 (posti sul lato inferiore del PCB) per fornire accesso agli stessi da breadboard.
Sulla scheda è presente un regolatore AMS1117-3.3 (U1) per l’alimentazione della microSD e del relativo traslatore di livelli logici (U4). Inoltre, attraverso il doppio deviatore SW1 (PWR-SEL), è possibile scegliere se alimentare la MCU (U3) ed i pin di I/O del CH340G (U2) a 5V o a 3.3V, permettendo in questo ultimo caso di collegare la scheda a logiche operanti a 3.3V senza problemi. In ogni caso la microSD sarà comunque sempre alimentata a 3.3V e con i relativi segnali anch’essi a 3.3V attraverso U4.
L1 insieme a C13 hanno lo scopo di evitare che un eventuale inserimento di una microSD quando la scheda è alimentata (hot plug) e SW1 è posto a 3.3V, possa generare un reset della MCU. Le SD in generale hanno una certa capacità interna sull’alimentazione, per cui il picco di corrente che si crea quando si inserisce la microSD a scheda alimentata potrebbe mandare “in crisi” l’alimentazione con conseguente reset della MCU per alimentazione non sufficiente.
Sono inoltre presenti i due led utente LED1 e LED2, il led dell’alimentazione PWR, i due led del convertitore USB-seriale RX e TX, ed il led SD che indica attività sulla microSD.
Per quanto riguarda i tasti, troviamo i due tasti utente USR1 e USR2 ed il tasto RST di reset della MCU.
Nel seguito alcuni punti di attenzione.
Il deviatore SW1 permette di selezionare la tensione di lavoro della MCU e del convertitore USB-seriale tra 5V e 3.3V. Ciò si riflette naturalmente sui livelli logici dei relativi pin di I/O. In ogni caso è garantito il corretto utilizzo della microSD (attraverso U4) indipendentemente dalla posizione di SW1.
ATTENZIONE!: Il deviatore SW1 deve essere azionato solo quando la scheda non è alimentata.
Se viene utilizzato uno zoccolo ZIF per la MCU (U3) C6 e C7 devono essere da 22pF. Se viene invece utilizzato uno zoccolo “normale” C6 e C7 devono essere da 27pF. Ciò tiene conto della maggior capacità parassita tra pin dello zoccolo ZIF rispetto a quello standard (non ZIF).
Nella foto seguente una scheda PicOne con uno zoccolo standard (precedente revisione del PCB):
Per rendere operativi i due led utente LED1 e LED2 devono essere chiusi i due jumper a saldare SJ1 e SJ2 posti sul lato inferiore del PCB:
Per abilitare la microSD è necessario chiudere il jumper JP1 (SD-EN).
Se si vogliono utilizzare i pin della MCU RA4, RC5, RC3, RC4 come normali pin (non collegati alla microSD) è necessario aprire il jumper JP1. Questo disabiliterà il traslatore di livelli U4 ponendo le relative uscite in alta impedenza.
Si noti che in questo caso (JP1 aperto) attraverso la resistenza R9 (connessa a RC4) potrebbe scorrere una corrente di circa 3mA nel caso in cui la MCU fosse alimentata a 5V ed un eventuale logica esterna (o la stessa MCU) presentassero un segnale HIGH (circa 5V) su RC4. Questo è dovuto alla presenza dei diodi di protezione (clamp diode) sui pin di uscita di U4 la cui alimentazione è connessa a 3.3V, attivi anche quando l’uscita di U4 è disabilitata. Di conseguenza una eventuale logica esterna deve essere in grado di fornire una tale corrente.
Per programmare la MCU (U3) è necessario utilizzare un programmatore esterno (come il PicKit4) da collegare al connettore ICSP (J2). Si noti che sul PCB è presente un piccolo triangolo che indica il pin 1 e che deve corrispondere con l’analogo presente sul PicKit come mostrato nella foto seguente:
ATTENZIONE!: quando si collega o scollega il PicKit assicurarsi che la scheda non sia alimentata (per maggiori informazioni si veda il manuale del PicKit).
ATTENZIONE!: il programmatore deve essere configurato per non fornire alcuna alimentazione al target (power the targed from the board):
INSERIMENTO DELLA MCU NELLO ZOCCOLO ZIF
Quando si inserisce la MCU (U3) nello zoccolo ZIF assicurarsi che il pin 1 della MCU sia in corrispondenza dell’apposito segno triangolare posto sul PCB (che indica il pin 1) come mostrato nella foto seguente:
ESEMPI SW
Nella sezione DOWNLOAD sono presenti alcuni esempi che ho utilizzato per testare la scheda stessa. Tutti gli esempi sono stati realizzati con MPLABX v5.40 utilizzando il Code Configurator (MCC) che deve essere installato da MPLABX (menu Tools -> Plugins. Il PC deve essere connesso ad internet):
Quando li provate per la prima volta sarà necessario selezionare da MPLABX il programmatore da utilizzare (PicKit4).
Se la prima volta avete degli errori di compilazione attivate MCC e fategli installare i plugin che richiede (il PC deve essere connesso ad internet).
DOWNLOAD
Tutta la documentazione necessaria per realizzare la scheda (file Gerber per la produzione del PCB, schema elettrico, guida del layout del PCB per l’assemblaggio, lista componenti, esempi con MPLABX) è disponibile qui.
Inoltre ho preparato un link “rapido” per ordinare direttamente un piccolo lotto di PCB (min. 5 pezzi) qui.
CONSIGLI PER L’ASSEMBLAGGIO
L’assemblaggio della scheda richiede una certa dimestichezza con i componenti SMD ed un minimo di attrezzatura. Ciò non significa che chi non ha mai provato a cimentarsi con una scheda SMD non possa provare a realizzarla…
Nel seguito elenco alcuni suggerimenti per chi è alle prime armi con gli SMD, o vorrebbe provare ma non sa da dove iniziare. Questo non vuole essere una corso di saldatura ma solo uno spunto per iniziare.
Per la saldatura dei componenti SMD consiglio di usare un saldatore ad aria calda (hot air gun).
Ovviamente sarà necessaria anche la pasta di stagno (solder paste), possibilmente una confezione a siringa in modo da semplificare la fase di stesura.
ed un flussante anch’esso in siringa:
Ovviamente non possono mancare delle pinzette per SMD:
Consiglio fortemente anche un “estrattore di fumi” almeno come questo (i vostri polmoni ringrazieranno):
Inoltre un microscopio ottico per ispezioni come questo (AmScope SE400Z) renderà l’assemblaggio molto più agievole:
Vale la pena anche di citare anche un saldatore TS100 con punta BC2 per poter saldare gli integrati SMD con la tecnica del “drag soldering“:
Una scheda come PicOne presenta sia componenti classici TH (through holes) che SMD. In questo caso bisogna dividere l’assemblaggio in due parti. Nella prima saranno saldati prima i componenti SMD con il saldatore ad aria calda e poi quelli “classici” con un normale saldatore a punta.
Per quanto riguarda la saldatura dei componenti SMD, se avete a disposizione un saldatore TS100 (o comunque uno con punta “piatta”) consiglio di utilizzarlo con la tecnica del “drag soldering” per tutti gli integrati SMD tranne i regolatori (come U1) e per i connettori SMD come J1 e J3.
Per gli altri componenti SMD (compreso U1) useremo il saldatore ad aria calda con la pasta di stagno. Consiglio di saldare prima i componenti che richiedono il saldatore ad aria calda e successivamente i componenti SMD rimanenti con il saldatore TS100 usando il “drag soldering”, avendo cura di “fissare” preventivamente il componente con un paio di saldature a due pin “estremi” e successivamente i rimanenti pin.
Ricordo che per il “drag soldering” è fondamentale l’uso del flussante che deve essere distribuito sui pin prima della saldatura.
Come mostrato la saldatura di componenti SMD (ma anche “normali”) richiede l’uso di attrezzature potenzialmente pericolose per le elevate temperature di esercizio come saldatori tradizionali o ad aria calda. Bisogna quindi prestare molta attenzione nella organizzazione del “banco di lavoro” ed in genere nell’uso.
lo stesso vale per i prodotti chimici utilizzati come pasta di stagno ed il flussante (ma anche il classico rocchetto di stagno). Quando maneggiate la pasta di stagno usate dei guanti in lattice per evitare che residui di pasta saldante (micro sfere di stagno immerse in flussante gelatinoso) possano inserirsi sotto le vostre unghie con il rischio di poter essere ingeriti successivamente quando maneggiate dei cibi.
Deve essere prestata attenzione anche ai residui gassosi che si formano (fumi) mettendo possibilmente in campo le accortezze necessarie come l’uso di un estrattore di fumi e areazione periodica del locale dove si opera. L’uso di una mascherina durante le fasi di saldatura è sicuramente consigliato.
Per nessun motivo il locale dove operate deve essere raggiungibile da bambini, che come è noto, sono imprevedibili. Conservate tutte le sostanze chimiche in contenitori di plastica chiusi ed in luogo sicuro, ed apponete delle etichette opportune per evidenziare il pericolo.
In rete si vedono filmati di individui che usano queste sostanze come se fossero marmellata. Evitate assolutamente di seguire questi esempi sconsiderati!
INTRODUZIONE
In questo articolo viene riportato un codice di esempio che fa uso della libreria per display LCD basati sull’integrato HD44780 presentata in XC8 – #3 – Parte 1.
I passi eseguiti per importare la libreria per il display sono valide per tutte le librerie.
CREAZIONE PROGETTO
Il primo passo da eseguire è la creazione del progetto, per il quale vale la stessa procedura utilizzata XC8 – #1.
IMPORTARE LIBRERIA NEL PROGETTO
Dopo aver creato il progetto è possibile importare la libreria così da poterla utilizzare all’interno del progetto. Per fare questo è sufficiente selezionare il nome del progetto nella scheda Projects in alto a sinistra, fare tasto destro >> Properties >> XC8 Compiler e selezionare il tasto “…” alla voce “Include directories“.
Nella schermata che compare selezionare “Browse” e navigare fino alla cartella contenete il file LCD_HD44780.h e LCD_HD44780.c. Questi file possono essere contenuti nella stessa cartella o in cartelle separate. La cosa più pratica sarebbe usare una sola cartella, chiamata per esempio Library o con altro nome, contente tutte le librerie suddivise in due cartelle separate, una per gli header file ed una per i source file. In questo modo si ha il vantaggio di avere tutte le librerie in un solo punto e poterle modificare senza il rischio di avere diverse versioni nei vari progetti. Infatti se si dovesse modificare la libreria definita nella cartella comune Library, tutti i progetti che puntano a quel percorso verrebbero aggiornati alla prima ricompilazione. Se invece si dovesse usare una stessa libreria ma salvata in diverse cartelle sparse sul computer si avrebbe il problema di dover aggiornare le copie locali ad ogni modifica.
Dopo aver incluso il percorso o i percorsi dei due file .h e .c premere “Apply” e quindi “OK“.
Le operazioni sopra riportate sono valide per qualunque libreria voglia essere importata in un progetto.
CODICE ESEMPIO
Viene proposto un codice di esempio che fa uso di un microcontrollore PIC18F252 per pilotare un display LCD 20×4. Lo schema elettrico è il seguente:
Il progetto fa uso di 4 file, il file main.c che contiene il codice che determina ciò che viene visualizzato sul display, il file config.h per la configurazione del microcontrollore, il file config_LCD.h per la configurazione del display e il file LCD_CustomChar per definire alcuni caratteri personalizzati.
Header Files
Il file config.h è scritto utilizzando la Configuration Bits accessibile dalla toolbar selezionando Window >> Target Memory Views >> Configuration Bits. Seguire la procedura riportata in XC8 – #1 che è valida anche in questo caso. Il file config.h appare così:
#define _XTAL_FREQ 8000000 // PIC18F252 Configuration Bit Settings // 'C' source line config statements // CONFIG1H #pragma config OSC = HS // Oscillator Selection bits (HS oscillator) #pragma config OSCS = OFF // Oscillator System Clock Switch Enable bit (Oscillator system clock switch option is disabled (main oscillator is source)) // CONFIG2L #pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOR = OFF // Brown-out Reset Enable bit (Brown-out Reset disabled) #pragma config BORV = 20 // Brown-out Reset Voltage bits (VBOR set to 2.0V) // CONFIG2H #pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit)) #pragma config WDTPS = 128 // Watchdog Timer Postscale Select bits (1:128) // CONFIG3H #pragma config CCP2MUX = OFF // CCP2 Mux bit (CCP2 input/output is multiplexed with RB3) // CONFIG4L #pragma config STVR = OFF // Stack Full/Underflow Reset Enable bit (Stack Full/Underflow will not cause RESET) #pragma config LVP = OFF // Low Voltage ICSP Enable bit (Low Voltage ICSP disabled) // CONFIG5L #pragma config CP0 = OFF // Code Protection bit (Block 0 (000200-001FFFh) not code protected) #pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code protected) #pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code protected) #pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code protected) // CONFIG5H #pragma config CPB = OFF // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code protected) #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code protected) // CONFIG6L #pragma config WRT0 = OFF // Write Protection bit (Block 0 (000200-001FFFh) not write protected) #pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write protected) #pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write protected) #pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write protected) // CONFIG6H #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write protected) #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write protected) #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write protected) // CONFIG7L #pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000200-001FFFh) not protected from Table Reads executed in other blocks) #pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from Table Reads executed in other blocks) #pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from Table Reads executed in other blocks) #pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from Table Reads executed in other blocks) // CONFIG7H #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from Table Reads executed in other blocks) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF.
Si passa al file config_LCD.h che permette di specificare le connessioni con il microcontrollore. Questo è il file che deve essere modificato quando si vuole utilizzare un diverso interfacciamento con il microcontrollore.
Tramite le define TRIS_pin e LCD_pin si stabilisce a quali pin del microcontrollore sono connessi i pin del display. Il file risulta essere:
#ifndef config_LCD_H
#define config_LCD_H
// LCD Display Initialization
#define TRIS_D7 TRISBbits.TRISB5 // D7
#define TRIS_D6 TRISBbits.TRISB4 // D6
#define TRIS_D5 TRISBbits.TRISB3 // D5
#define TRIS_D4 TRISBbits.TRISB2 // D4
#define TRIS_EN TRISBbits.TRISB1 // EN
#define TRIS_RS TRISBbits.TRISB0 // RS
#define LCD_D7 LATBbits.LATB5 // D7
#define LCD_D6 LATBbits.LATB4 // D6
#define LCD_D5 LATBbits.LATB3 // D5
#define LCD_D4 LATBbits.LATB2 // D4
#define LCD_EN LATBbits.LATB1 // EN
#define LCD_RS LATBbits.LATB0 // RS
#endif
Le prime due righe controllano che non sia già stato chiamato il file config_LCD_H all’interno del progetto, mentre l’ultima chiude il blocco if.
#ifndef config_LCD_H
#define config_LCD_H
...
#endif
All’interno del blocco if si trova una serie di define che stabiliscono le connessioni tra microcontrollore e display e permettono di settarle correttamente come output. Inoltre permettono di usare i nomi mnemonici all’interno della libreria senza che questa sappia a priori quale pin del PIC fa capo a un dato pin del display.
Modificando i valori associati ad ogni define si stabilisce quale pin deve essere collegato al display. Ogni pin è associato a due define, una che stabilisce la direzione, TRIS_pin, e una che stabilisce lo stato, LCD_pin, che devono ovviamente avere lo stesso pin. Per esempio volendo associare il pin EN non più al pin RB1 ma al pin RC5 si dovranno modificare le due righe corrispondenti in:
#define TRIS_EN TRISCbits.TRISC5 // EN
#define LCD_EN LATCbits.LATC5 // EN
Si passa infine all’ultimo header file, il LCD_CustomChar che deve essere aggiunto solo se si vuole far uso di un carattere speciale non inserito fra il set standard del display.
Per poter utilizzare dei caratteri personalizzati si deve passare alla funzione Lcd_CustomChar() il numero di caratteri che si vogliono memorizzare nel registro CGRAM e il carattere espresso come un array di 8 elementi, ognuno dei quali rappresenta una delle 8 righe che formano il carattere, avente 1 o 0 a seconda se il pixel corrispondente deve essere rispettivamente acceso o spento. Volendo riprodurre il fantasma di Pac-Man si avrebbe una cosa del genere:
Un altro carattere che si può inserire è una matrice vuota, formata da tutti i pixel spenti, a cui è associato un array di ‘0’.
Il file risulterà essere una cosa del genere:
#ifndef LCD_CustomChar_H
#define LCD_CustomChar_H
const uint8_t Custom_Char[] = {
0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,0b00000,
0b01110,0b11111,0b11010,0b11111,0b11111,0b10101,0b00000,0b00000
};
#endif
Per poter utilizzare uno dei caratteri memorizzati nel registro CGRAM è sufficiente indicare la posizione di memoria occupata, che va da 0 a 7. Per il primo carattere si usa quindi 0, 1 per il secondo e così via. In questo caso si utilizzerà 0 per il carattere “vuoto” ed 1 per il fantasma.
Source File
Si passa quindi al file main.c che inizia con le include di xc.h che contiene le informazioni relative al microcontrollore e di stdint.h che permette di definire il tipo di variabile con un nome mnemonico combinazione del segno e della dimensione della variabile.
Seguono quindi gli include dei file di configurazione config.h e config_LCD.h, il file contenete i caratteri personalizzati.
Le ultime due infine permettono di aggiungere i file LCD_HD44780.h e LCD_HD44780.c della libreria per il display tra quelli da compilare. Con le operazioni eseguite all’inizio subito dopo la creazione del progetto si erano solamente aggiunti i percorsi della libreria al progetto, mentre ora si sta specificando che i due file della libreria devono essere compilati e diventare parte integrante del progetto che verrà caricato sul microcontrollore.
#include <xc.h>
#include <stdint.h>
#include "config.h"
#include "config_LCD.h"
#include "LCD_CustomChar.h"
#include "LCD_HD44780.h"
#include "LCD_HD44780.c"
Viene quindi definita la variabile usata nel ciclo for e le costanti contenti una serie di numeri e lettere per testare il display.
uint8_t i;
const uint8_t word1 [] = {'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0'};
const uint8_t word2 [] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T'};
Segue la funzione CFG_Init() che contiene la configurazione delle direzioni e degli stati delle PORTA e PORTC. La PORTB non è settata in quanto a questo provvede il file config_LCD.h.
void CFG_Init(void){
TRISA = 0b11111111;
TRISC = 0b11111111;
LATA = 0b00000000;
LATC = 0b00000000;
}
Si ha quindi la funzione Display_Init() che inizializza il display LCD.
Per prima cosa si utilizza la funzione di libreria Lcd_Init() che permette di settare la libreria a funzionare con display LCD da 20 colonne e 4 righe. Segue il comando di pulizia del display e di abilitazione del display.
Tramite la funzione Lcd_CustomChar() si memorizzano nella CGRAM i caratteri speciali definiti in LCD_CustomChar.
Infine si ha il comando che riporta il cursore alla posizione iniziale.
void Display_Init(void){
Lcd_Init(LCD_20x4);
Lcd_Command(LCD_CLEAR);
Lcd_Command(LCD_D1_C0_B0);
__delay_ms(100);
Lcd_CustomChar(2,(uint8_t *)Custom_Char);
Lcd_Command(LCD_RETURN_HOME);
}
Segue la funzione main() che per prima cosa richiama le funzioni di inizializzazione CFG_Init e Display_Init(), seguite dal corpo del while infinito all’interno del quale si eseguono le operazioni per stampare a display caratteri e testi.
Il codice è intuitivo e non viene fatto altro che utilizzare le funzioni presentate in XC8 – #3 – Parte 1, a cui si passano carattere o testo voluti. L’unica accortezza è usare (uint8_t *) che permette di interpretare la variabile che lo segue come un dato tipo, che in questo caso è un intero ad 8 bit di tipo unsigned, che corrisponde al tipo char.
Il file main.c completo risulta essere:
#include <xc.h>
#include <stdint.h>
#include "config.h"
#include "config_LCD.h"
#include "LCD_CustomChar.h"
#include "LCD_HD44780.h"
#include "LCD_HD44780.c"
uint8_t i;
const uint8_t word1 [] = {'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0'};
const uint8_t word2 [] = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T'};
void CFG_Init(void){
TRISA = 0b11111111;
TRISC = 0b11111111;
LATA = 0b00000000;
LATC = 0b00000000;
}
void Display_Init(void){
Lcd_Init(LCD_20x4);
Lcd_Command(LCD_CLEAR);
Lcd_Command(LCD_D1_C0_B0);
__delay_ms(100);
Lcd_CustomChar(2,(uint8_t *)Custom_Char);
Lcd_Command(LCD_RETURN_HOME);
}
void main (void){
CFG_Init();
Display_Init();
while(1){
Lcd_Command(LCD_CLEAR);
Lcd_Text(1,5,(uint8_t *)"www.NE555.it");
__delay_ms(1000);
Lcd_Text(2,5,(uint8_t *)"XC8 - #3");
__delay_ms(1000);
Lcd_Command(LCD_CLEAR);
Lcd_Command(LCD_RETURN_HOME);
Lcd_TextCP((uint8_t *)"Display 20x4");
__delay_ms(1000);
Lcd_Command(LCD_CLEAR);
Lcd_Text(1,1,(uint8_t *)"Row 1");
__delay_ms(250);
Lcd_Text(2,1,(uint8_t *)"Row 2");
__delay_ms(250);
Lcd_Text(3,1,(uint8_t *)"Row 3");
__delay_ms(250);
Lcd_Text(4,1,(uint8_t *)"Row 4");
__delay_ms(1000);
Lcd_Command(LCD_CLEAR);
Lcd_Command(LCD_RETURN_HOME);
for(i = 0; i <= 19 ; i++){
Lcd_CharCP(word1[i]);
__delay_ms(100);
}
for(i = 0; i <= 19 ; i++){
Lcd_Char(2,(uint8_t)(i+1),word2[i]);
__delay_ms(100);
}
Lcd_Text(3,4,(uint8_t *)"R = ");
Lcd_CharCP(0b11100110);
Lcd_CharCP((uint8_t)'x');
Lcd_TextCP((uint8_t *)"l/A [");
Lcd_CharCP(0b11110100);
Lcd_CharCP((uint8_t)']');
__delay_ms(1000);
for(i = 3; i <= 17 ; i++){
Lcd_Char(4,(uint8_t)i,0);
Lcd_Char(4,(uint8_t)(i+1),1);
__delay_ms(500);
}
__delay_ms(5000);
}
}
PROGRAMMAZIONE
Per programmare il microcontrollore usando un programmatore Microchip, per esempio tramite il PICkit3, si può usare l’ambiente di sviluppo MPLAB X IDE oppure MPLAB X IPE. Per i vari step da seguire si rimanda a XC8 – #1.
DOWNLOAD
Al seguente link è possibile scaricare i file .c e .h utilizzati (la libreria è scaricabile da XC8 – #3 – Parte 1): DOWNLOAD.
The post MPLAB X & XC8 – #3: Display LCD – Parte 2 first appeared on NE555.]]>