Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FreescaleIAP MODSERIAL mbed monitor timer0
Fork of 17_PT1000 by
main.cpp
- Committer:
- Sven3010
- Date:
- 2014-09-07
- Revision:
- 18:939d3df56218
- Parent:
- 17:c307f8c96ab1
- Child:
- 19:8e4e6fe34857
File content as of revision 18:939d3df56218:
// 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
// 30.08.14 die Temperaturbegrenzung bei ausgeschaltert Tropfensteuerung geändert
#include "mbed.h"
#include "ConfigFile.h"
#include "SDFileSystem.h"
//#include "DS2482.h"
#include "timer0.h"
#include "Buffer.h"
#include "monitor.h"
#include "ventiel.h"
#include "MODSERIAL.h"
#define CR 13
#define SOLL_WERT 32.0 // Sollwert für den Fühler in der Flüssigkeit
#define R_TEMP_MAX 60.0 // Maximaltermperatur für den Widerstand
#define R_OFFSET 0.0 // wird bei abgeschaltetert Trofpensteuerung zum Haltetemperatur addiert
#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
#define BOOL_FMT(bool_expr) (bool_expr) ? "ein" : "aus"
//------------------------------------------------------------------------------
// 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
MODSERIAL com(PTC4, PTC3);
//MODSERIAL com(PTC4, PTC3);
Buffer <char> buf; // Ringbuffer für ankommende Zeichen
// DS2482 ow(PTE0,PTE1,0x30); // sda, scl, adr
ventiel magnet; // Klasse Ventiele anlegen
char lcd_text[25];
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, temp_r_max, temp_r_ist;
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, regelwert;
//------------------------------------------------------------------------------
// 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
float korr_wert = R_OFFSET; // Korrekturwert bei abgeschalteter Heizung
//------------------------------------------------------------------------------
// 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(57600);
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(57600);
//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
down_timer.SetCountdownTimer(3,1,100); // Timer für Taster
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", soll_wert);
}
if (cfg.getValue("korr", &value[0], sizeof(value)))
{
korr_wert = atof(value);
pc.printf("\nkorrektur_wert = %f\n", korr_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_r_ist = temp_float / GAIN;
//pc.printf("%d;",temp_word); // Rohwert ausgeben
pc.printf("Temp-R %0.2f; ",temp_r_ist);
// die Temperaturregelung ist nur bei aktiver Tropfensteuerung eingeschaltet
//
if (f_flag)
{
//------------------------------------------------------
// 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;
}
}
regelwert = temp_neu;
//------------------------------------------------------
// Zulässige Temperatur für den Heizwiderstand begrezen
// bei eingeschalteter Trofensteuerung wird die Temperatur
// auf T_TEMP_MAX und bei ausgeschalteter Tropfensteuerung
// auf soll_wert begrenzt
if (f_flag)
{
temp_r_max = R_TEMP_MAX;
}
else
{
temp_r_max = soll_wert + korr_wert;
}
if(temp_float > temp_r_max)
{
regelwert = 0.0;
esum = 0.0;
}
//------------------------------------------------------
// Heizwiederstand ansteuern >> 0,02 entspricht 100%
if (t_flag)
{
heizung.pulsewidth(0.0001 + regelwert);
//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; Magnete :", tropfen_anz);
for (uint8_t n = 0; n < 8; n++)
{
if(magnet.get(n)) pc.putc('1');
else pc.putc('0');
}
pc.printf("; verbleibende Zeit %02d; ",down_timer.GetTimerZeit(1));
if(f_flag)
pc.printf("on;");
else
pc.printf("off;");
pc.printf("\n");
// LCD String zusammensetzen und ausgeben
for (int i = 0; i < 25; i++) lcd_text[i] = 0;
//01234567890123456789
sprintf(lcd_text,"TR %3.1f / %3.1f ",temp_r_ist,temp_r_max);
//sprintf(lcd_text,"erste Zeile");
uint8_t len = strlen(lcd_text);
uint8_t anz = len + 3;
com.printf(":AA%02x020000",anz); //Zeile 1 Temps
for (int i = 0; i < len; i++)
{
com.printf("%02x",lcd_text[i]);
}
com.printf("A5\n");
//wait_ms(100);
for (int i = 0; i < 25; i++) lcd_text[i] = 0;
//01234567890123456789
sprintf(lcd_text,"TK %3.1f / %3.1f ",temp_soll,soll_wert);
//sprintf(lcd_text,"Heizung %s " ,BOOL_FMT(t_flag));
len = strlen(lcd_text);
anz = len + 3;
com.printf(":AA%02x020001",anz); //Zeile 2 Heizung (ein/aus)
for (int i = 0; i < len; i++)
{
com.printf("%02x",lcd_text[i]);
}
com.printf("A5\n");
//wait_ms(100);
for (int i = 0; i < 25; i++) lcd_text[i] = 0;
//01234567890123456789
sprintf(lcd_text,"temp. %s flow %s ",BOOL_FMT(t_flag) ,BOOL_FMT(f_flag));
len = strlen(lcd_text);
anz = len + 3;
com.printf(":AA%02x020002",anz); //Zeile 3 Tropfensteuerung (ein/aus)
for (int i = 0; i < len; i++)
{
com.printf("%02x",lcd_text[i]);
}
com.printf("A5\n");
//wait_ms(100);
for (int i = 0; i < 25; i++) lcd_text[i] = 0;
//01234567890123456789
sprintf(lcd_text,"Zeit %3d Tropfen %3d" ,down_timer.GetTimerZeit(1),tropfen_anz);
len = strlen(lcd_text);
anz = len + 3;
com.printf(":AA%02x020003",anz); //Zeile 4 Anz. Zeit+Tropfen
for (int i = 0; i < len; i++)
{
com.printf("%02x",lcd_text[i]);
}
com.printf("A5\n");
//wait_ms(100);
} // end if(down_timer ...
// timer 3
if (com.readable()) {
int ch = com.getc();
// pc.printf("\nzeichen=%c %x",ch,ch);
switch (ch){
case '1': magnet.toggle (0);
break;
case '2': magnet.toggle (1);
break;
case '3': magnet.toggle (2);
break;
case '4': magnet.toggle (3);
break;
case '5': if (t_flag)
{
t_flag = false;
pc.printf("\nHeizung durch externen Taster deaktiviert\n");
}
else
{
t_flag = true;
pc.printf("\nHeizung durch externen Tastet aktiviert\n");
}
break;
case '6': if (f_flag)
{
f_flag = false;
pc.printf("\nTropfensteuerung durch externen Taster deaktiviert\n");
}
else
{
f_flag = true;
pc.printf("\nTropfensteuerung durch externen Taster aktiviert\n");
}
break;
}
}
} // end while
}
