-
AutorePost
-
5 Novembre 2020 alle 13:06 #9702
piero55
PartecipanteBuongiorno a tutti.
Sto realizzando un circuito per controllare una ventola ed un relè su di un alimentatore che finalmente ho terminato.
Avendo un modulo VoltAmpere a display e volendolo utilizzare, per la gestione del relè che commuta il secondario del trasformatore e della ventola in funzione dlla temperatura del dissipatore, ho utilizzato un piccolo 12F683 e il PROTON BASIC. SW molto semplice, creato, simulato con proteus, tutto OK.
Il problema è che nella realtà, ovvero realizzato (su millefori) ma anche su breadboard, non funziona. Naturalmente il circuito è stato verificato ed è corretto, ma non funziona la parte che gestisce la ventola.
La parte funzionante, composta dalla porta analogica GP0 legge la tensione di uscita (diviso 10) e se superiore a 12V, commuta il relè (sulla porta GP4) che fornisce 24Vac all’ alimentatore:perfetto.
La parte NON funzionante è composta dalla porta GP1 anch’essa analogica che legge un LM335 e dopo la conversione in °C, gestisce la ventola in PWM 50Hz (porta GP2), già studiato, verificato e funzionante. Il range è <30° ventola OFF, tra 30 e 50° ventola in funzione da un minimo al massimo della velocità. Se si superano i 50°, uscita PWM fissa a “1” quindi massima velocità e un LED rosso lampeggiate (porta GP5) indica questo evento. Tutto ciò simulato, funziona alla perfezione, nella realtà NO.
Il PWM, non lo creo con il modulo dedicato ma con il TIMER1 che genera un interrupt ogni 200uS ed opportuni conteggi.
Il lampeggio del led rosso, lo creo con il TIMER 0 che genera un interrupt ogni 10mS ed opportuni conteggi.
Se TIMER 1 ON, TIMER 0 OFF e viceversa.
Non riesco a capire dove sia il problema ma non riesco nemmeno a capire come poter verificare il SW visto che nella simulazione, funziona.
Suggerimenti?
Allego il FW abbastanza semplice da interpretare.
Pierluigi'**************************************************************** '* Name : alim_12F683.BAS * '* Author : [select VIEW...EDITOR OPTIONS] * '* Notice : Copyright (c) 2020 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 21/10/2020 * '* Version : 1.0 * '* Notes : * '* : * '**************************************************************** ;------------------------------------------------------------------------------- ;**** Added by Fuse Configurator **** ; Use the Fuse Configurator plug-in to change these settings Device = 12F683 Declare Reminders Off @ CONFIG_REQ = 0 ; Override Compiler's configuration settings Asm- __Config 0x33D4 ;FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_ON & IESO_OFF & FCMEN_OFF Endasm- Declare Reminders On ;**** End of Fuse Configurator Settings **** ;------------------------------------------------------------------------------- On_Hardware_Interrupt GoTo Isr Xtal 8 '****************************************************************************** Symbol OUT = GPIO.2 ' OUT PWM 50Hz Symbol TMR1IF = PIR1.0 ' Timer1 interrupt Flag Symbol TMR1IE = PIE1.0 ' TMR1 Overflow Interrupt Enable Symbol TMR0IF = INTCON.2 ' Timer0 Interrupt Flag Symbol TMR0IE = INTCON.5 ' nome del bit di attivazione Timer0 Symbol TMRSET = 99 ' periodo di conteggio per 10 millisecondi Symbol ADON = ADCON0.0 ' A/D ON bit Symbol RELE = GPIO.4 ' attiva rele Symbol MINTEMP = 30 ' valore minimo di temperatura Symbol MAXTEMP = 50 ' valore massimo di temperatura Symbol MAXDUTY = 100 ' valore massimo di duty cycle Symbol LED = GPIO.5 ' lampeggio LED timer Declare Adin_Res = 10 Declare Adin_Tad = FRC Declare Adin_Stime = 50 ' ****************************************************************************** ' Definizione variabili ' ****************************************************************************** Dim tlong As Dword ' variabile di calcolo di una media Dim tempo_totale As Word ' calcolo del periodo di tempo trascorso Dim cnt4sec As Byte ' contatore di periodo per i secondi Dim v_adc1 As Dword ' Utilizzata per ADC Dim timer As Byte ' Variabile conteggio per durata PWM ON Dim duty As Byte ' Durata PWM Dim var1 As Byte ' Variabile temporanea Dim chnl As Byte ' valore selezione canale analogico Dim temperatura As Byte ' Temperatura Dim V_out As Word ' Tensione uscita alimentatore Dim delta As Byte ' Coefficiente aumento duty da 20° a 50° ' ***************************************************************************** ' MAIN program ' ***************************************************************************** GoSub init While 1 = 1 ' INIZIO Ciclo GoSub leggi_adc_van0 GoSub leggi_adc_t If temperatura > MINTEMP Then ' se la temperatura e' oltre i 30° If temperatura < MAXTEMP Then Clear TMR0IE TMR1IE = 1 ' se e' minore di MAXTEMP TMR1IF = 0 GoSub leggi_adc_van0 If temperatura <= MAXTEMP Then ' <= 50° delta=(temperatura -30)*3 duty = temperatura + delta ' il duty viene controllato ' dalla temperatura Else ' altrimenti se T > 50° TMR1IE = 0 Set OUT End If End If If temperatura >= MAXTEMP Then ' Se T>50° Clear TMR1IE ' Ferma TMR1 Clear TMR1IF Clear T1CON.0 Set OUT ' Uscita fissa a 1 FAN max velocità Set TMR0IE ' Accendi TMR0 Clear TMR0IF ' clear flag TMR0 Else Set T1CON.0 Clear LED Clear TMR0IE Clear TMR0IF End If GoSub leggi_adc_t ' presenta la tensione DelayMS 500 Else duty = 0 ' ferma le ventole GoSub leggi_adc_t ' legge temperatura DelayMS 250 ' aspetta un po End If Wend End ' ***************************************************************************** ' Init ' ***************************************************************************** init: OSCCON=%01110000 DelayMS 20 CMCON0=%00000111 OPTION_REG=%10000110 TRISIO=%00001011 DelayMS 20 ANSEL=%01010011 DelayMS 20 ADCON0=%10000001 DelayMS 20 IOC=0 WPU=0 T1CON = %00000001 TMR1IF = 0 TMR1H = 0xFE TMR1L = 0x6F TMR1IE = 0 INTCON = %11000000 '0xC0 Clear TMR0IE 'Ferma TMR0 Clear RELE Clear OUT Clear duty Clear timer Clear cnt4sec Clear LED Return '***************************************************************************** leggi_adc: ' Legge ADC tlong=0 v_adc1=0 For var1 = 1 To 128 ' Ciclo 32 letture ADC v_adc1 = ADIn chnl ' lettura canale prefissato DelayUS 5 tlong = tlong + v_adc1 Next var1 tlong = tlong / 128 ' valore medio delle 20 letture tlong = (tlong * 5000) / 1023 ' VDD=4,923V Valore finale in 0,1 mV ' VDD 4,923 misurata sul circuito reale: ' in teoria dovrebbe essere 5,000 ' Dipende dalla tolleranza del 7805 Return '************************************************************************ leggi_adc_van0: ' Lettura tensione uscita alimentatore ' su VAN0 chnl = 0 ' assegna per la lettura dal canale 0 DelayMS 50 GoSub leggi_adc ' legge il canale DelayMS 20 var1=0 tlong=tlong / 10 V_out=tlong If V_out>120 Then Set RELE End If If V_out <110 Then Clear RELE End If Return '************************************************************************* leggi_adc_t: ' Legge valore Temperatura su VAN1 chnl = 1 ' assegna per la lettura dal canale 1 DelayMS 50 GoSub leggi_adc Clear var1 DelayMS 50 tlong=(tlong-2731) ' Conversione temperatura ' If tlong <= 20 Or tlong >= 1000 Then ' tlong=20 ' End If tlong = tlong / 10 ' converte in ASCII di 5 cifre temperatura = tlong Return '************************************************************************ ' ***************************************************************************** ' Interrupt Service Routine ' ***************************************************************************** Isr: Context Save ' salva i registri ' ******************* TIMER 1 ************************************************* If TMR1IF = 1 Then ' interrupt ogni 200uS TIMER1 TMR1IF = 0 ' azzera il flag TMR1H = $FE TMR1L = $6F If timer < duty Then ' Se il periodo e minore del Duty OUT = 1 ' Uscita alta Else OUT = 0 ' altrimenti bassa End If If timer > 99 Then ' Se il tempo ha contato 100 timer = 0 ' azzera Else ' oppure Inc timer ' si aumenta End If End If ' ******************* TIMER 0 *********************************************** If TMR0IF = 1 Then ' Interrupt per TIMER0 TMR0IF = 0 ' rimuove il flag TMR0 = TMRSET ' carica 99 su TMR0 per interrupt a 10mS Inc cnt4sec ' aggiorna il contatore ' dopo mezzo secondo e interrupt ON If TMR0IE = 1 Then ' ammesso che e' abilitato il TMR0 If cnt4sec < 50 Then ' e che il cnt4sec e <50 500mS LED = 1 ' uscita alta LED ON Else ' altrimenti LED = 0 ' uscita bassa LED OFF End If End If If cnt4sec >= 100 Then ' passato un secondo..... cnt4sec = 0 ' azzera il cnt4sec End If End If Context Restore ' recupero dei registri ' *************************************************************************
Pierluigi
6 Novembre 2020 alle 6:08 #9704Picmicro675
PartecipanteA mio giudizio non ti conviene usare 32 bit per la lettura del canale analogico, sempre si vuole ottenere una lettura snella meglio indicata per il micro in uso. Se usassi una word potresti ottenere la media di 64 campioni. Anche il ritardo è solo un periodo perso, La lettura avviene in modo corretto con l’hardware e il comando proprio.
In quanto alla compilazione della Configurazione meglio se usi il plugin di Proton IDE. Al limite assicurati che non ha magari il WDTE o MCLRE abilitati.Symbol NUMSAMPLE 40 $if NUMSAMPLE > 63 $ error NUMSAMPLE exceed the maximum $endif Dim Tlong As Word Sub readADC() For var1 = 1 To NUMSAMPLE ' Ciclo 32 letture ADC v_adc1 = ADIn chnl ' lettura canale prefissato tlong = tlong + v_adc1 Next var1 EndSub
Per quello che rigurda il PWM, ho trovato un’ idea dalla rete che ovviamente utilizza solo sul timer0, quindi si avrebbe una frequenza massima di Fosc / 256 = 3906,25 Hz teorici a 4 MHz. Per farlo ti serve solo
If TMR0IF = 1 Then ' Interrupt per TIMER0 TMR0IF = 0 ' rimuove il flag If OUT = 1 Then Clear OUT TMR0 = -PULSE ' carica il periodo basso Else Set OUT TMR0 = PULSE ' carica il periodo basso End If
Se non ti serve tutto un byte di risoluzione allora si può salire di frequenza, solo che comincia a perdere di prontezza nel ricalcolare il periodi. Se ti interessa farò il dovuto rimessaggio.
In quanto a quello che il simulatore ti mostra e quello che succede al reale, ci sono diversi fattori come le sviste (parlando delle mie esperienze) ai collegamenti e disturbi elettrici che il simulatore non tiene conto. Per questo dovresti tener conto il metodo di debug nel software che segnala a che punto si trova nel programma. Per questo la via più spiccia sarebbe di usare la seriale e un piedino assegnato a fare il lavoro. Ma con gli interrupt abilitati, sarebbe meglio che disabiliti il GIE per inviare il messaggio.
Altrimenti se hai bisogno di mantenere la massima velocità allora conviene che utilizzi un piedino per segnalare un certo punto un determinato evento, per quello ti basta tenere sott’occhio con l’oscilloscopio. Sarebbe meglio se hai un analizzatore analogico del tipo
Il prezzo è moderato e non dovrebbe superare i 10€. Ovvio che questo tipo ha solo otto ingressi.
Allora potresti sondare tutti i piedini e vedere se corrisponde a quanto voluto.6 Novembre 2020 alle 15:47 #9708piero55
PartecipanteCiao Picmicro…
Innanzitutto, ho risolto il problema principale…..
Ora funziona bene: ho preso un altro PIC dal cassettino e questo funziona alla perfezione con lo stesso FW… PIC guasto forse l’ingresso analogico AN1 ko, lo verificherò in seguito prima di buttarlo. Entrambi i PIC sono comunque nuovi…. mah!
L’LM335 forniva una tensione corretta, ma le uscite del PIC sempre fisse a zero.
Sto analizzando i tuoi suggerimenti:
quando arriviamo alla riga della sub che legge l’ADC tlong = (tlong * 5000) / 1023 anche facendo solo 32 letture, la WORD non basta più ecco il motivo che mi ha fatto utilizzare una DWORD.
Per il PWM, con il TIMER1, ottengo interrupt ogni 200uS e quindi contandone 100, genero 50Hz circa, non devo ottenere frequenze più alte per controllare la ventola 12V.
Potrei ottenere i 200uS anche con il TIMER 0 ma oramai questo progetto è nato così.
Ok per l’analizzatore logico, mi informo.6 Novembre 2020 alle 15:51 #9710piero55
PartecipantePer curiosità, l’analizzatore logico che hai fatto vedere, con che SW nel PC funziona?
7 Novembre 2020 alle 7:02 #9712Picmicro675
PartecipanteIo uso quello di Saelae
Comunque c’è anche una altra marca alquanto soddisfacente, la Kingst per un modello più elaborato.
Alla fine puoi anche fare una ricerca ai negozi online e si trovano da 8€ in su,
Contento che hai trovato la magagna, per quanto al programma nulla di sovversivo, solo volevo portare a conoscenza di alcuni metodi. In fondo per la regolazione in base alla temperatura basta avere un valore che risponde alla regolazione. In particolar modo se non ti serve visualizzarne il suo valore.
Per quello che riguarda i micro presumibilmente guasti, io non riesco proprio a capire se sono realmente guasti. Ci sono tanti fattori da valutare prima che si possa capire se il micro è fallace. In certe situazioni non rispondono ai requisiti, che poi messi a lavorare per un altro tipo di progetto non danno problemi.7 Novembre 2020 alle 10:58 #9714piero55
PartecipanteInfatti, non lo getto via, lo tengo per altre prove. SOLO per curiosità, parliamo di pochi cent di euro……
Mi era successo qualche anno fa con un paio di 16F819 che non andavano più, poi trovai uno scritto che diceva come verificarli ed infatti vanno alla perfezione: Nel programmatore Pickit2 o 3, impostare “Use Vpp first program entry” . Per l’analizzatore logico, ci studio su, fino ad oggi ho utilizzato l’oscilloscopio, non ho avuto ancora esigenze “superiori”.8 Novembre 2020 alle 12:10 #9719Picmicro675
PartecipantePer analizzare segnali logici, dipende dal tipo di oscilloscopio. Uno digitale richiede anche una certa capacità di memoria per memorizzare il segnale. Magari ci sono quelli che fanno anche le decodifiche dei segnali, ma son già di un certo prezzo.
10 Novembre 2020 alle 21:37 #9721piero55
PartecipanteIl mio oscilloscopio è un vecchio analogico 5″ doppia traccia 15MHz di 40 anni…. lo utilizzo per quello che è. Certamente se dovessi analizzare contemporaneamente più pin di un chip contemporaneamente sarei in difficoltà. Farò probabilmente un pensierino sull’analizzatore logico.
-
AutorePost
- Devi essere connesso per rispondere a questo topic.