#include <EEPROM.h>
#include <TimerOne.h>
// Variablen für Timing *********************************************************************************************************
long DisplayTimer; long DisplayTimerZeit = 500; //Ausgabe alle 1000ms
long MessTimer; long MessTimerZeit = 100; //Messen alle 100µs
// ------------------------------------------------------------------------------------------------------------------------------
// Variablen für Messwerterfassung **********************************************************************************************
byte MessCounter = 0;
int MessEingang[4] = {A0,A2,A4,A6}; long MessWert[4] = {0,0,0,0}; long MessTemp[4] ={0,0,0,0};
// ------------------------------------------------------------------------------------------------------------------------------
const int RMS1 = 200; int RMSCounter1 = 1;
int MessCounterTemp;
const int RMS2 = 128; int RMSCounter2 = 1;
long RMSWertTemp[4] = {0.1234,1.2345,12.345,123.45}; long RMSArray[4][RMS2]; long PeakTemp[4]= {0.1234,1.2345,12.345,123.45}; long MaxTemp[4] = {0.1234,1.2345,12.345,123.45};
float RMSWert[4] = {0.1234,1.2345,12.345,123.45}; float Peak[4] = {0.1234,1.2345,12.345,123.45}; float Max[4] = {0.1234,1.2345,12.345,123.45};
// ------------------------------------------------------------------------------------------------------------------------------
// Variablen für Display ********************************************************************************************************
char DisplayZeile[4][20] = {"01234567890123456789","abcdefghijklmnopqrst","ABCDEFGHIJKLMNOPQRST","!§$%&/()[]ÖÜÄ,.-;:_#"}; //Text nach Start festlegen
// ------------------------------------------------------------------------------------------------------------------------------
// Variablen für die Einstellungen **********************************************************************************************
int MessBereich[4] ={10,10,10,10};
// ------------------------------------------------------------------------------------------------------------------------------
String TempString;
void setup() {
noInterrupts();
// Ports setzen
DDRD = B11111111; // Datenbus auf Ausgang
PORTD = B00000000; // Daten = 0
DDRB = B00001111; // RS, R/W, E1, E2 auf Ausgang
PORTB = B00000000; // Steuerleitungen = 0
// Variablen setzen
// 1. Ausgabe auf dem Display *************************************************************************************************
strcpy(DisplayZeile[0], "01234567890123456789"); strcpy(DisplayZeile[1], "abcdefghijklmnopqrst"); strcpy(DisplayZeile[2], "ABCDEFGHIJKLMNOPQRST"); strcpy(DisplayZeile[3], "!§$%&/()[]ÖÜÄ,.-;:_#");
analogReference(INTERNAL);
// Einstellungen aus EEPORM lesen
// ADC einstellen
// Arrays löschen
DisplayReset();
// IRQ-Timer vorbereiten ******************************************************************************************************
Timer1.initialize(MessTimerZeit);
Timer1.attachInterrupt(MessenIRQ);
delay(40);
// AD-Wandler vorbereiten *****************************************************************************************************
MessWert[0] = analogRead(MessEingang[0]);
AufDisplayAusgeben();
DisplayTimer = millis();
//MessTimer = micros();
interrupts();
}
void loop() {
// Daten auf Display ausgeben *************************************************************************************************
if (millis() > DisplayTimer + DisplayTimerZeit ) {
DisplayTimer = millis();
for (int Counter = 0; Counter < 4; Counter++) {
RMSWert[Counter] = RMSWertTemp[Counter];
Peak[Counter] = PeakTemp[Counter];
Max[Counter] = MaxTemp[Counter];
MesswerteZusammenstellen(Counter);
}
AufDisplayAusgeben();
// Peakmessung reduzieren, -10% nach der Ausgabe auf dem Display **************************************************************
for(int Counter =0; Counter < 4; Counter++){PeakTemp[Counter] = PeakTemp[Counter]*90/100;}
}
// Messung alle XXXµs Test bevor IRQ aktiviert wird ***************************************************************************
//if (micros() > MessTimer + MessTimerZeit ) {
// MessTimer = micros();
// MessenIRQ();
//}
// ------------------------------------------------------------------------------------------------------------------------------
}
//void EinstellungSpeichern(byte Messbereich1, byte Messbereich2, byte Messbereich3, byte Messbereich4){
float Skaliere(int messung, float Endwert) {
long temp; float result;
temp = messung * 1000 / 1023;
result = temp * Endwert /1000;
return result;
}
// IRQ-für Messungen ************************************************************************************************************
void MessenIRQ(void){
// Messungen durchführen ******************************************************************************************************
// Die messungen der 4 Spannungen werden nacheinander durchgeführt. Das "Durchschalten" übernimmt der "MessCounter"
// Da direkt nach dem auslesen des Messwertes auf den nächsten eingang geschaltet wird, wir der derzeit zu messende Kanal
// in MessCounterTemp gespeichert.
MessCounterTemp = MessCounter;
// ADCs auslesen ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MessWert[MessCounterTemp] = analogRead(MessEingang[MessCounterTemp]); // MessWert auslesen
MessCounter ++;if(MessCounter > 3){MessCounter = 0;} // Auf nächsten Eingang schalten
MessWert[MessCounter] = analogRead(MessEingang[MessCounter]); // AD-Wandler "Reset"
// Peak detekt ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (MessWert[MessCounterTemp] > PeakTemp[MessCounterTemp]) {PeakTemp[MessCounterTemp] = MessWert[MessCounterTemp];}
// Max detekt +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (MessWert[MessCounterTemp] > MaxTemp[MessCounterTemp]) { MaxTemp[MessCounterTemp] = MessWert[MessCounterTemp];}
// RMS1- Schleife Messwerte "RMS1" X Aufaddieren ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MessTemp[MessCounterTemp] = MessTemp[MessCounterTemp]+ MessWert[MessCounterTemp];
if (RMSCounter1 > RMS1){ // Wenn der RMSCounter seinen Wert erreicht hat, wird der Mittelwert berechnet und gespeichert.
RMSWertTemp[MessCounterTemp] = MessTemp[MessCounterTemp]/RMS1;
MessTemp[MessCounterTemp] = 0;
if (MessCounterTemp > 2) {RMSCounter1=1;}
}
if (MessCounterTemp > 2){RMSCounter1++;} // Nächster RMS-Schritt
// ------------------------------------------------------------------------------------------------------------------------------
}
// Display reset ****************************************************************************************************************
void DisplayReset(){
DisplaySchreibeRegister (0x38);// B0011 1000 Function Set 8 Bit; 2 Zeilen; 5x8
DisplaySchreibeRegister (0x39);// B0011 1001 Function Set 8 Bit; 2 Zeilen; 5x8; instruction table select
DisplaySchreibeRegister (0x14);// B0001 0100 Frequenz Wert aus Datenblatt für 5V
DisplaySchreibeRegister (0x79);// B0111 1001 Contrast set Wert aus Datenblatt für 5V
DisplaySchreibeRegister (0x50);// B0101 0000 Power/ICON Wert aus Datenblatt für 5V
DisplaySchreibeRegister (0x6C);// B0110 1100 Follower control Wert aus Datenblatt für 5V
DisplaySchreibeRegister (0x0C);// B0000 1100 Display On; Curser Off; Blink Off
DisplaySchreibeRegister (0x01);// B0000 0001 Clear Display
delay( 1);
}
void DisplaySchreibeRegister(byte Daten) { // RS und R/W sind L
PORTB |= B00000011; // E1 & E2 auf H
delayMicroseconds(1); // ev unnötig
PORTD = Daten; // Daten Schreiben
delayMicroseconds(40); // ev unnötig
PORTB &= B11111100; // E1 & E2 auf L
}
// ------------------------------------------------------------------------------------------------------------------------------
// Display Zeichen Schreiben ****************************************************************************************************
void DisplaySchreibeZeichen(char Zeichen){
PORTB |= B00001000; // RS auf H (H:Data.L:Instruction code)
PORTB |= B00001011; // E1 & E2 auf H
PORTD = Zeichen; // Zeichen; //Zeichen; // Daten Schreiben
delayMicroseconds(40);
PORTB &= B11111100; // E1 & E2 auf L
}
// Display Zeile Schreiben ******************************************************************************************************
void AufDisplayAusgeben(){
for (byte Zeichen = 0; Zeichen < 20; Zeichen++){ DisplaySchreibeZeichen(DisplayZeile[0][Zeichen]); }
for (byte Zeichen = 0; Zeichen < 20; Zeichen++){ DisplaySchreibeZeichen(DisplayZeile[2][Zeichen]); }
for (byte Zeichen = 0; Zeichen < 20; Zeichen++){ DisplaySchreibeZeichen(DisplayZeile[1][Zeichen]); }
for (byte Zeichen = 0; Zeichen < 20; Zeichen++){ DisplaySchreibeZeichen(DisplayZeile[3][Zeichen]); }
}
// ------------------------------------------------------------------------------------------------------------------------------
// Messwerte für Anzeige zusammenstellen ****************************************************************************************
void MesswerteZusammenstellen(byte Messwert){
TempString = String(RMSWert[Messwert], 4);
for(byte Counter = 0; Counter < 5; Counter++){DisplayZeile[Messwert] [Counter] = TempString[Counter];}
for(byte Counter = 5; Counter < 7; Counter++){DisplayZeile[Messwert] [Counter] = 32;}
TempString = String(Peak[Messwert], 4);
for(byte Counter = 7; Counter < 12; Counter++){DisplayZeile[Messwert] [Counter] = TempString[Counter-7];}
for(byte Counter = 12; Counter < 14; Counter++){DisplayZeile[Messwert] [Counter] = 32;}
TempString = String(Max[Messwert], 4);
for(byte Counter = 14; Counter < 19; Counter++){DisplayZeile[Messwert] [Counter] = TempString[Counter-14];}
DisplayZeile[Messwert][19] = 32;
}
Sobald ich in Zeile 43 / 44 den Timer aktiviere, läuft die Display-Ausgabe in Zeile 58 nicht mehr.
Danke
Peter