Stai visualizzando 8 post - dal 1 a 8 (di 17 totali)
  • Autore
    Post
  • #9702
    piero55
    Partecipante

    Buongiorno 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

    #9704
    Picmicro675
    Partecipante

    A 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
    logic analizer
    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.

    #9708
    piero55
    Partecipante

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

    #9710
    piero55
    Partecipante

    Per curiosità, l’analizzatore logico che hai fatto vedere, con che SW nel PC funziona?

    #9712
    Picmicro675
    Partecipante

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

    #9714
    piero55
    Partecipante

    Infatti, 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”.

    • Questa risposta è stata modificata 3 anni, 1 mese fa da piero55.
    • Questa risposta è stata modificata 3 anni, 1 mese fa da piero55.
    #9719
    Picmicro675
    Partecipante

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

    #9721
    piero55
    Partecipante

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

Stai visualizzando 8 post - dal 1 a 8 (di 17 totali)
  • Devi essere connesso per rispondere a questo topic.