#include <U8glib.h>
U8GLIB_ST7920_128X64 u8g(13, 11, 12, U8G_PIN_NONE);
// Einstellungs-Tabelle für die Erhöhung der Taktfrequenz
// ======================================================
// ADPS2 ADPS1 ADPS0 Division factor
// 0 0 0 2
// 0 0 1 2
// 0 1 0 4
// 0 1 1 8
// 1 0 0 16
// 1 0 1 32
// 1 1 0 64
// 1 1 1 128 (Standard)
#define FASTADC 1
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
// Variablendeklaration
// ====================
const int analogInPin = A0; // Analog input pin für die Pulshöhe
const int pin_verzoegerung = A1; // Analog input pin für die über ein Poti einstellbare variable Verzögerung
const int pin_entleeren = 3; // Digital output pin für das Entleeren des Speicherkondensators
const int pin_treffer = 4; // Digital input pin für vom Monoflop kommenden treffer
const int pin_switch = 5; // Digital output pin für switch
const int pin_test = 7; // Digital output pin um zu überprüfen, in welcher Phase der Entladekurve von C die Spannungsmessung erfolgt
const int pin_reset = 8; // Digital input pin für das Leeren des Pulshöhenarrays um eine neue Messung zu starten
int U_puls = 0; // aktuelle gemessene Pulshöhe
float Spannung; // aktuelle gemessene Pulsspannung
int Index = 0; // Index der gemessenen Pulshöhe im Intervall [0,127]
float Faktor = 1; // Vergrößerungs- bzw. Verkleinerungsfaktor
int Pulshoehen[128]; // array mit der Anzahl der jeweils 128 verschiedenen Pulshöhen
int reset_time; // Zeitdauer in ms der U-Max-Speicherentleerung
int j; // Zählvariable als Maß für die Schnelligkeit der Pulsabfrage
int time_alt, time_neu; // Variablen zur Ermittlung der Schleifendauer
int Verzoegerung; // Verzögerungszeit in µs
// ===========================
// ========== SETUP ==========
// ===========================
void setup(void)
{
Serial.begin(9600);
pinMode(pin_entleeren, OUTPUT); // U-Speicher-Entleer-pin als output deklariert
pinMode(pin_switch, OUTPUT); // switch-pin als output deklariert
pinMode(pin_test, OUTPUT); // test-pin als output deklariert
pinMode(pin_treffer, INPUT); // treffer-pin als input deklariert
pinMode(pin_reset, INPUT); // reset-pin für die Anzeige als input deklariert
digitalWrite(pin_entleeren, HIGH); // U_max-Speicher entleeren
digitalWrite(pin_switch, HIGH); // Schalter für U-Zuleitung
digitalWrite(pin_test, LOW); // Test-pin auf 0 setzen
for (int i = 0; i < 128; i++)
{
Pulshoehen[i] = 0; // alle Pulshöhentreffer auf 0 setzen
}
Faktor = 1; // Startvergrößerung für die graphische Darstellung
reset_time = 5; // Zeitdauer in ms der U-Max-Speicherentleerung
#if FASTADC
// set prescale to 16
sbi(ADCSRA,ADPS2) ; // ADPS2 auf 1 gesetzt
cbi(ADCSRA,ADPS1) ; // ADPS1 auf 0 gesetzt
cbi(ADCSRA,ADPS0) ; // ADPS0 auf 0 gesetzt
// cbi = 0; sbi = 1
#endif
// Zeichnen der Achsen
// ===================
u8g.firstPage();
do
{
u8g.drawLine(0, 63, 127, 63);
u8g.drawLine(0, 0, 0, 63);
}
while( u8g.nextPage() );
}
// ===================================
// ========== HAUPTSCHLEIFE ==========
// ===================================
void loop(void)
{
/*
Verzoegerung = analogRead(pin_verzoegerung);
Verzoegerung = Verzoegerung * 10; // Verzögerungsintervall 0 bis 1023 * 10 µs
Serial.print("Verzoegerung im µs = ");
Serial.println(Verzoegerung);
*/
digitalWrite(pin_entleeren, HIGH); // U_max-Speicher gelöscht
delay(reset_time); // reset_time ms Wartezeit zum ausreichenden Löschen des U_max-Speichers
digitalWrite(pin_entleeren, LOW); // U_max-Speicher bereit
digitalWrite(pin_switch, HIGH); // Schalter für U-Zuleitung geschlossen; Messung startet... eigentlich unnötig, da ja eh der Kondensator gelöscht wird und auf den ersten Puls gewartet wird
// Warte bis ein vom Monoflop verlängerter Puls über DIGITAL-IN registriert wird!
// ==============================================================================
while(digitalRead(pin_treffer) == LOW)
{
}
//delayMicroseconds(Verzoegerung); // übers Poti variable Verzögerung, damit der Zuleitungsschalter nicht schon schließt obwohl der Spannungspuls noch nicht sein Maximum erreicht hat!
delayMicroseconds(10); // fixe Verzögerung, damit der Zuleitungsschalter nicht zu früh schließt und der Spannungspuls auch zu seinem Maximum anwachsen kann!
digitalWrite(pin_switch, LOW); // Puls wurde registriert --> Schalter für U-Zuleitung offen; Messung gestoppt
// Pulshöhe wird eingelesen
// ========================
U_puls = analogRead(analogInPin); // Einlesen der Pulshöhe 0-5V
// digitale Ausgabe über den Test-Pin unmittelbar nach Einlesen der Spannung um festzustellen, "wo" in der Entladekurve die Spannung gemessen wird. Soll ja genau im Maximum erfolgen!
// -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/*
digitalWrite(pin_test, HIGH); // Test-pin auf 1 setzen
delay(5); // Verzögerung
digitalWrite(pin_test, LOW); // Test-pin auf 0 setzen
*/
// graphische und Speicher-Verarbeitung der registrierten Pulshöhe
// ---------------------------------------------------------------
Index = map(U_puls, 0, 1023, 0, 127); // Index der aktuell gemessenen Pulshöhe im Intervall [0,127]
Pulshoehen[Index] = Pulshoehen[Index] + 1; // aktuelle Pulshöhe erhält einen Treffer
//Spannung = U_puls * 5.0 / 1023;
//Serial.print("Pulshoehe = "); // serielle Ausgabe der aktuellen Pulshöhe 0-5V
//Serial.println(Spannung,2);
// ==============================================
// ============ graphische Ausgabe ==============
// ==============================================
u8g.firstPage();
if (int(Faktor * Pulshoehen[Index]) > 63) // Zuviele Treffer für die ausreichende y-Darstellung ---> Stauchung um Faktor 2
{
Faktor = Faktor / 2;
}
do
{
u8g.drawLine(0, 63, 127, 63);
u8g.drawLine(0, 0, 0, 63);
for (int i = 0; i < 128; i++)
{
u8g.drawLine(0+i, 63, 0+i, 63 - int(Faktor * Pulshoehen[i])); // zeichnen aller Treffer
}
}
while( u8g.nextPage() );
// Abfrage, ob der Reset-Knopf betätigt wurde
// ------------------------------------------
if (digitalRead(pin_reset) == HIGH)
{
// Spektrum an den Computer senden
// ===============================
for (int i = 0; i < 128; i++)
{
Serial.println(Pulshoehen[i]);
}
// Spektrum löschen
// ================
for (int i = 0; i < 128; i++)
{
Pulshoehen[i] = 0; // alle Pulshöhentreffer auf 0 setzen
}
Faktor = 1; // Startvergrößerung für die graphische Darstellung
}
//delay(2); // optionale Zeitverzögerung
}