// sketch_prog3p_2k

/*   z.B. für Schwingkreis, periodisch angeregt, 2-kanalig

Verwendet z.B. für Anregung eines Schwingkreises mittels eines Rechteckssignals vom Funktionsgenerator, bei periodisch angeregten Ein-/Ausschaltvorgängen, oder bei anderen periodischen Signalen.   Bei Verwendung der Schülerversuchsspule kann die Schwingkreisspannung auch mittels der 2. Wicklung gemessen werden.

Liest Daten mit Werten im Bereich von 0 bis 1023 vom ANALOG INPUT Kanal A0 (oder optional zusätzlich A2) ein, mit oder ggf. ohne Pegelanhebung für Wechselspannung, und speichert sie schnell im SRAM des Prozessors ab.

Dazu wird durch eine spezielle Triggerung in Kanal A0 dafür gesorgt, dass - nach einem Tastendruck beim PC - der Vorgang mit dem Abfall der Messspannung aus dem Maximalwert (meswmax)  beginnt. Der Maximalwert wird vorher ermittelt.

Die Daten werden als Paket von 300 Werten auf 5000 mV (bzw. an die an PIN18 des ARDUINO
liegende Vergleichsspannung) skaliert und dann seriell an den Serial Monitor ausgegeben.

Basis der Programmierung war ein Beispielprogramm:      http://www.arduino.cc/en/Tutorial/AnalogInOutSerial

*/

// Festlegung von Typ und Wert von Konstanten und Variablen

const int analogInPin = A0;  // Festlegung des Analogeingangs, über den die Messungen vorgenommen werden
const int analogInPin2 = A2; // zusätzlich bei optionaler 2-kanaliger Wechselstrommessung

int trigval = 1 ;   // Triggerschwelle
int null = 490 ;   // Nullspannung bei Pegelanhebung durch Pegelwandler; sonst null = 0
// int mess[300] ;   // Array für 300 INTEGER-Werten (jeweils 2 Bytes) bei einkanaliger Messung

// Stattdessen bei zweikanaliger Messung:

int mess[150] ;   // Array für 150 INTEGER-Werten (2 Bytes); pro Datensatz doppelter Speicherplatz benötigt
int mess2[150] ;   // Array für weitere 150 INTEGER-Werten (2 Bytes)
int mesw = 0 ;  // laufender Messwert x in Triggerschleifen; 0 <= x < 1024
int mesw1 = 0 ;
int meswmax = 0 ;
int meswmin = 1023 ;

int outputValue ;
int outputValue2 ; // optional bei 2-kanaliger Messung

int nullValue ; // int nullValue2 ;  optional
int meswmaxValue ;
int meswminValue ;

char eingabe ;  // ASCII-Wert der Tastatureingabe vom PC


long zeit ;     // Gesamtdauer der Registrierung in mikrosec
long time ;    // laufende Zeit
long av ;       // durchschnittlicher Messwert zur Ermittlung der Nulllinie
int numb ;     // Zahl Messungen pro Periode
//int loop1 = 300 ; // Zahl der Datensätze bei einkanaliger Messung

int loop1 = 150 ; // stattdessen bei 2-kanaliger Messung

long idx1 = 0 ;  // Maximalwert des Laufindexes idx


bool count = true ;
bool bereit = false;  // 0

void setup()

{ Serial.begin(57600);

  // Initialisierung der seriellen Kommunikation mit 57600 bps

  // initialize control over the keyboard:
  //  Keyboard.begin(); Offenbar nicht nötig
}

void loop() // Hauptschleife

{

// Triggerschleife 1: stellt fest, ob Eingabetaste am PC gedrückt. Könnte auch wegfallen.

bereit = true ; // 1


while ( bereit == true or eingabe == !'0' )    // Drehe Schleife bis bereit = false  (bzw. 0): keine Taste gedrückt
{ eingabe = Serial.read();          
   bereit = Serial.available();  Serial.println(bereit); }
 
 bereit = false;
 
while ( bereit == false )  // Drehe Schleife bis bereit = true (bzw. 1): Taste gedrückt
 { bereit = Serial.available();   } // jetzt Taste gedrückt


// Suche Spannungsmaximum und -minimum

meswmax = 0 ;
meswmin = 1023 ;

for (int idx = 1; idx < loop1; idx++)   // Drehe Schleife ohne Registrierung bis maximaler Messwert gefunden
  { mesw = analogRead(analogInPin);
  if (mesw >= meswmax)  meswmax = mesw ;
  if (mesw <= meswmin)  meswmin = mesw ;
  }   // Jetzt Spannungsmaximum und -maximum gefunden


null = (meswmax + meswmin)/2 ;

 nullValue = map(null, 0, 1023, 0, 5000);  // Umwandlung in mV (Skalierung);

Serial.print("Nullinie in mV = "); Serial.print(nullValue); Serial.print(",") ;
Serial.print("  Nullinie = ");  Serial.print(null);  Serial.println(" (von 1023)"); Serial.println(" ") ;


meswmaxValue = map(meswmax, 0, 1023, 0, 5000);  // Umwandlung in mV (Skalierung);
meswminValue = map(meswmin, 0, 1023, 0, 5000);

// Triggerung für Start der Messwertspeicherung aus Maximum:

mesw = analogRead(analogInPin)-10;

while (mesw < meswmax- trigval ) // Drehe Schleife ohne Registrierung bis Messwert mesw >= meswmax-trigval
{ mesw = analogRead(analogInPin); }

  mesw1=mesw ;

 
// jetzt messbereit

zeit = micros();


// Mess-Schleife

  for (int idx = 1; idx < loop1; idx++)
  {mess[idx] = analogRead(analogInPin);    // Messung über Analogeingang, der durch die Konstante analogInPin0 bestimmt ist
   mess2[idx] = analogRead(analogInPin2);  // bei 2-kanaliger Messung
 
   } // Datensätze gemessen

zeit = micros() -zeit;   // Zeitdauer für Messung und Speicherung von loop1 Messdaten

mess[0] = meswmax ;  // erster relevanter Messwert vor Mess-Schleife 1 vor Verlassen des Maximalwerts  ergänzt
mess2[0] = null ;          // bei 2-kanaliger Messung

 
 Serial.print("Maximalwert in mV = "); Serial.print(meswmaxValue); Serial.print(",") ; Serial.print(" Minimalwert in mV = ");  Serial.print(meswminValue);  Serial.println(" "); Serial.println(" ");


// Ausgabeschleife

  for (int idx = 0; idx < loop1; idx++)
  {
 
   int adr=&mess[idx];   // Adresse des Messwerts der Nummer idx

   idx1 = idx ;
   time = (zeit/loop1)*idx1;   //  laufende Zeit

   outputValue = map(mess[idx], 0, 1023, 0, 5000);  // Umwandlung in mV (Skalierung)

   outputValue2 = map(mess2[idx], 0, 1023, 0, 5000); // bei 2-kanaliger Messung


   // Serial.println(nullValue);  // dient zum Zeichnen der Nulllinie


   Serial.print(idx); Serial.print(",");  Serial.print(time); Serial.print(","); Serial.print(outputValue); Serial.print(",");

   Serial.print(nullValue);  Serial.print(","); Serial.println(outputValue2);  // bei 2-kanaliger Messung

   // Serial.print(adr); Serial.print(","); könnte am Zeilenbeginn ergänzt werden zur Kontrolle der SRAM-Adressen, die <= 1999 sein    müssen
  }

Serial.println("") ; Serial.print("Zeitintervall in microsec = "); Serial.print(zeit/loop1); Serial.print(", Maximalwert in mV = "); Serial.print(meswmaxValue); Serial.println(",");

delay(1000); bereit = true ;

Serial.println("") ; Serial.println("Weiter, wenn PC-Taste gedrückt !" ) ; Serial.println("") ;

  // nächste Runde, wenn PC-Taste gedrückt
}