070914

Dependencies:   FreescaleIAP MODSERIAL mbed monitor timer0

Fork of 17_PT1000 by Temp27

main.cpp

Committer:
rs27
Date:
2014-08-18
Revision:
12:d5a745de5380
Parent:
11:7bc691148135
Child:
13:a44b80b168b2

File content as of revision 12:d5a745de5380:

// Version 17 08.08.2014
// die Ausgabe auf das Format #nr val umgestellt
// 03.08.14 Monitorbefehle hinzugefügt
// 08.08.14 Programm um Tropfenerfassung erweitert

#include "mbed.h"
#include "ConfigFile.h"
#include "SDFileSystem.h"
//#include "DS2482.h"
#include "timer0.h"
#include "Buffer.h"
#include "monitor.h"
#include "ventiel.h"

#define CR 13

#define SOLL_WERT 27.0          // Sollwert für den Fühler in der Flüssigkeit
#define R_TEMP_MAX 40.0         // Maximaltermperatur für den Widerstand
#define OFFSET_0 28330          // AD Wert für 0° Abgleich Kanal 0
#define OFFSET_1 28560          // AD Wert für 0° Abgleich Kanal 1
//#define OFFSET 27100          // AD Wert für 0° Abgleich Steuerung Flosrian
#define GAIN 113                // Digit pro °C  >> 112.3 Steuerung Florian
//#define GAIN 112.3            // Digit pro °C  >> 112.3 Steuerung Florian

//------------------------------------------------------------------------------
// Anlegen von Klassen

SDFileSystem sd(PTD2, PTD3, PTC5, PTD0, "sd");  // The pinout (MOSI, MISO, SCLK, CS)
timer0 down_timer;                              // Zeitsteuerung
Serial pc(USBTX, USBRX);                        // tx, rx
Serial com(PTC4, PTC3);                         
Buffer <char> buf;                              // Ringbuffer für ankommende Zeichen
// DS2482 ow(PTE0,PTE1,0x30);                   //        sda, scl, adr

ventiel magnet;                                 // Klasse Ventiele anlegen

Timer t;                                        // Zeitmessung für Entprellen

//------------------------------------------------------------------------------
// Zuordnung von Eingängen und Ausgängen

DigitalIn in1(PTA16);
InterruptIn tropfen(PTA16);                     // Eingang für Tropfensensor >> nur Port A und D

PwmOut heizung(PTA13);                          // Ausgang für den PWM der die Heizung steuert

DigitalOut r(LED_RED);
DigitalOut g(LED_GREEN);
DigitalOut b(LED_BLUE);

DigitalOut led1(LED1);
//DigitalOut LED2(PTA2);
DigitalOut LED5(PTA4);
DigitalOut LED_4(PTA12);
DigitalOut LED6(PTA5);

// Schalter 4051 weden in der Andwendung nicht benötigt           
DigitalOut DC_A(PTE2);
DigitalOut DC_B(PTE3);
DigitalOut DC_C(PTE4);
DigitalOut DC_EN(PTE5);

// PT1000 Karte 1 >> Analogeingänge auf der Grundkarte
AnalogIn an1(PTC0);
AnalogIn an2(PTB1);
AnalogIn an3(PTB2);
AnalogIn an4(PTB3);
AnalogIn an5(PTC2);
AnalogIn an6(PTD5);

// 0 bis 5V 
// AnalogIn an13(PTD6);

// Analog pins
/*
1   PTE20, ADC0_SE0,  0}, k2.2
2   PTE22, ADC0_SE3,  0}, k2.3
3   PTE21, ADC0_SE4a, 0},
4   PTE29, ADC0_SE4b, 0}, k2,4
5   PTE30, ADC0_SE23, 0}, k2.5
6   PTE23, ADC0_SE7a, 0},
7   PTB0,  ADC0_SE8,  0}, k2.1
8   PTB1,  ADC0_SE9,  0}, k1.2
9   PTB2,  ADC0_SE12, 0}, k1.3
10  PTB3,  ADC0_SE13, 0}, k1.4
11  PTC0,  ADC0_SE14, 0}, k1.1
12  PTC1,  ADC0_SE15, 0}, k2.6
13  PTC2,  ADC0_SE11, 0}, k1.5
14  PTD1,  ADC0_SE5b, 0},
15  PTD5,  ADC0_SE6b, 0}, k1.6
16  PTD6,  ADC0_SE7b, 0}, k3.1
*/


//------------------------------------------------------------------------------
// Globale Variablen

float temp1, temp_mw;
uint16_t temp_word;
uint8_t n, y, status, ds1820_status;

int tropfen_anz = 10;       // zulässige Anzahl Tropfen pro Periode
int tropfperiode = 60;      // in Sekunden
bool send_flag = true;

float temp_float, temp_diff, temp_neu, esum, temp_soll;


//------------------------------------------------------------------------------
// Definitionen und Variablen für das Config File
ConfigFile cfg;
char value[BUFSIZ];         // Variablen für das Config file 

bool t_flag = true;         // Heizung aus / ein
bool f_flag = true;         // Tropfen sperren / freigeben

int drops = 10;             // Anzahl Tropfen pro Zeiteinheit

//float offset = 0.0;
float soll_wert = 27.0;     // Sollwert für den Temperaturfühler in der Flüssigkeit

//------------------------------------------------------------------------------
// Interruptroutine wird bei jedem Tropfen aufgerufen
// Pulse die in einem Abstand kleine 1ms sind werden nicht gezählt
//
void tropfen_handler()
{
    if(t.read_us() > 10000) //falls Tropfen weniger als 1 ms Lichtschranke blockiert, wird er nicht gewertet.
    {
        if (in1 == 0)
        {
            tropfen_anz++;
        }
    }
    t.reset();
    t.start();    
}
    
//------------------------------------------------------------------------------
// Interruptroutine wird bei jedem ankommenden Zeichen aufgerufen
void rx_handler(void)
{
    // Note: you need to actually read from the serial to clear the RX interrupt
    
    char ch;
    
    while (pc.readable()) 
    {   
      ch = pc.getc();
      buf.put(ch);
    }
}

//------------------------------------------------------------------------------
// lesen der PT1000 AD-Werte
//
// Um Störungen zu reduzieren werden 16 Werte gelesen und daraus wird der
// Mittelwert berechnet. Eine Messung dauert ca. 30µs. Somit wird für eine Messung
// ca. eine Zeit von 0,5ms benötigt.
//
int read_mw(uint8_t pos)
{
    uint8_t n;
    
    int val = 0;
    int mw = 0;
    
    LED_4 = 0;
    
    // 16 Messungen für eine bessere Mittelung durchführen
    
    for (n = 0; n < 16; n++)
    {
         switch (pos)
         {      
            // PT1000 Karte 1
            case 0:  val = an1.read_u16(); break;
            case 1:  val = an2.read_u16(); break;
            case 2:  val = an3.read_u16(); break;
            case 3:  val = an4.read_u16(); break;
            case 4:  val = an5.read_u16(); break;
            case 5:  val = an6.read_u16(); break;         
         }
         mw += val;
    } // end for
    
    // Temperatur berechnen
    // Wert durch 16 teilen
    
    mw = mw >> 4;
    
    LED_4 = 1;
    
    return mw;
}

//------------------------------------------------------------------------------
//

int main() 
{
    //------------------------------------------------------------------------------
    
    heizung.period(0.020);          //  requires a 20ms period
    heizung.pulsewidth(0.005);
    esum = 0.0;
    
    tropfen.fall(&tropfen_handler);
    t.reset();
    t.start();
    
    //------------------------------------------------------------------------------
    // RS232 Schnittstellt welche auf den CMSIS-DAP (USB Port) weitergeleitet wird
    //
    pc.baud(115200);
    pc.attach(&rx_handler, Serial::RxIrq);
    pc.printf("\n V08 was compiled on %s  %s \n", __DATE__,__TIME__);

    mon_init();

    //------------------------------------------------------------------------------
    // RS232 Schnittstellt zum Ansteuern der Magnetventile
    //
    com.baud(9600);
    com.printf("\n V08 was compiled on %s  %s \n", __DATE__,__TIME__);
        
    //------------------------------------------------------------------------------
    // Timer für die Zeitsteuerung
    //
    down_timer.SetCountdownTimer(0,1,50);  // Timer für die LED
    down_timer.SetCountdownTimer(1,1,500); // Timer für die Tropfensteuerung
    down_timer.SetCountdownTimer(2,1,1000);// Timer für die Ausgabe der Daten
    
    r = g = b = 1;                          // RGB LED ausschalten
    
    //--------------------------------------------------------------------
    // Variablen von der SD Karte initialisieren
    
    cfg.read("/sd/input.cfg");
 
     if (cfg.getValue("t_flag", &value[0], sizeof(value))) 
    {
        if (atoi(value) == 1)
        {
            t_flag = true;
            pc.printf("\nHeizung aktiviert");    
        }
        else
        {
            t_flag = false;
            pc.printf("\nHeizung deaktiviert");             
        }
    }

    if (cfg.getValue("f_flag", &value[0], sizeof(value))) 
    {
        if (atoi(value) == 1)
        {
            f_flag = true;
            pc.printf("\nTrofen aktiviert");    
        }
        else
        {
            f_flag = false;
            pc.printf("\nTropfen deaktiviert");             
        }
    }

    if (cfg.getValue("drops", &value[0], sizeof(value))) 
    {
        drops = atoi(value);
        pc.printf("\nAnzahl Tropfen = %d", drops); 
    }

    if (cfg.getValue("cycle", &value[0], sizeof(value))) 
    {
        tropfperiode = atoi(value);
        pc.printf("\nPeriodenzeit fuer die Tropfen = %d", tropfperiode); 
    } 
                     
    if (cfg.getValue("soll", &value[0], sizeof(value))) 
    {
        soll_wert = atof(value);
        pc.printf("\nsoll_wert = %f\n", soll_wert); 
    }
    
    //--------------------------------------------------------------------
    // Anfangswert bestimmen
    
    temp_mw = read_mw(0);
    
    
    //--------------------------------------------------------------------
    // Schleife fuer die Datenerfassung
    
    while(1) 
    {
       //-------------------------------------------
       // Prüfen ob Zeichen eingegeben wurden
       
       get_line();
 
       //-------------------------------------------
       // Prüfen ob Tropfenzahl erreicht
       
       if (f_flag)
       {
           if (tropfen_anz >= drops){
           
                // mit einer 9 die Tropfen sperren
                if(send_flag){   
                    // com.putc('9');       // Trofensteuerung wird ausgeschaltet
                    magnet.reset(0);
                    send_flag = false;      // Flag zur Programmsteuerung
                    LED6 = 1;               // zeigt Status Tropfensteuerung aus
                }
            }
       }
                 
       //-------------------------------------------
       // timer 0 steuert die LED
       
       if (down_timer.GetTimerStatus(0) == 0)
       {
          down_timer.SetCountdownTimer(0,1,500);
          LED5 = !LED5;
       }
       
       //-------------------------------------------
       // Tropfensteuerung freigeben
       // down
       
       if (down_timer.GetTimerStatus(1) == 0)
       {
          //down_timer.SetCountdownTimer(timer nr,Zeiteinheit: 1 = ms o. 2 = s,tropfperiode);
          down_timer.SetCountdownTimer(1,2,tropfperiode);
          
          //-------------------------------------------
          // nur freigeben, wenn nicht über monitor gesperrt
          if (f_flag)
          {
              tropfen_anz = 0;
              
              // mit einer 1 die Tropfen freigeben
              if (~send_flag){ 
                //com.putc('1');         // Tropfensteuerung freigeben von Magnetventil 1
                magnet.set(0);
                send_flag=true;          // Flag zum Status der Tropfensteuerung
                LED6 = 0;                // Anzeige zum Status der Tropfensteuerung
              }
          }
       }
       
       //-------------------------------------------
       // timer 2 steuert das Messen der Temperaturen und gibt die Leistung für
       // die Heizung vor
       
       if (down_timer.GetTimerStatus(2) == 0)
       {
            down_timer.SetCountdownTimer(2,1,1000);
            
            //------------------------------------------------------
            // PT1000 Kanal 1 ( Fühler in Flüssigkeit) lesen und die Temperatur berechnen
        
           
           temp_word = read_mw(1);
           temp_soll = (temp_word - OFFSET_1);
           temp_soll /= GAIN;
 
            //pc.printf("%d;",temp_word);                           // Rohwert ausgeben
            pc.printf("Soll %2.2f; Soll ist %2.2f; ",soll_wert, temp_soll);                     // Temperaturwert soll Flüssigkeit   
            
            //------------------------------------------------------
            // PT1000 Kanal 0 ( Fühler am Heizwiderstand ) lesen und die Temperatur berechnen       
            
            temp_word = read_mw(0);
            temp_float = (temp_word - OFFSET_0);
            temp_float /= GAIN;  
            
            //pc.printf("%d;",temp_word);                           // Rohwert ausgeben
            pc.printf("Temp-R %0.2f; ",temp_float);                     

            //------------------------------------------------------
            // Regelabweichung berechnen
            
            temp_diff = (soll_wert - temp_soll);
            
            //------------------------------------------------------
            // Begrenzen der Eingangsgröße
                     
            if(temp_diff > soll_wert)temp_diff = soll_wert;
                
            //temp_neu = ((temp_diff*0.0005) + (temp_alt*0.9));
 
            //------------------------------------------------------
            // bei geringen Abweichungen ein I-Anteil berechnen, damit Regelabweichung
            // auf 0 gefahren werden 
            if(temp_diff < 3){
                esum += temp_diff * 0.00001;
            }
            
            //------------------------------------------------------
            // berechnen der Steuergröße
            
            temp_neu = (temp_diff*0.0005) + esum;
            
            //------------------------------------------------------
            // Regler nach oben begrezen
            
            if(temp_neu > 0.02){
                temp_neu = 0.02;
            }            
 
            //------------------------------------------------------
            // Regler nach unten begrezen       
            
            if(temp_soll > soll_wert){
                temp_neu = 0.0;
                esum = 0.0;
            }
            
            //------------------------------------------------------
            // Zulössige Temperatur für den Heizwiderstand begrezen            
            
            if(temp_float > R_TEMP_MAX){
                temp_neu = 0.0;
                esum = 0.0;
            }
            
            //------------------------------------------------------
            // Heizwiederstand ansteuern >> 0,02 entspricht 100%
            
            if (t_flag)
            {
                heizung.pulsewidth(0.0001 + temp_neu);
                //pc.printf("%0.4f;",temp_alt);
            }
            else
            {
                heizung.pulsewidth(0.000000);      
            }
            pc.printf("%0.4f; ",temp_neu); 
            if(t_flag)
            pc.printf("on;");
            else
            pc.printf("off;");
            pc.printf(" %d;", tropfen_anz);
            
            for (uint8_t n = 0; n < 8; n++)
            {
                if(magnet.get(n)) pc.putc('1');
                else              pc.putc('0');              
            }

            pc.printf(";\n");
       } // end if(down_timer ...
                           
    } // end while
}