Загрузка данных


// ===== НАСТРОЙКИ =====
const int sensorPin = A0;
const int threshold = 40;           // Порог детектирования события (подберите опытным путем)
const unsigned long minInterval = 2000;  // Минимальный интервал между событиями (мкс) - защита от шума
const unsigned long maxInterval = 60000000; // Максимальный интервал (60 секунд) - игнорируем слишком редкие

// ===== СТАТИСТИКА =====
unsigned long eventCount = 0;       // Счетчик событий
unsigned long lastEventTime = 0;    // Время последнего события
unsigned long totalInterval = 0;    // Сумма всех интервалов для среднего
unsigned long minIntervalDetected = 999999999;
unsigned long maxIntervalDetected = 0;

// ===== КОЛЬЦЕВОЙ БУФЕР для последних 100 интервалов =====
const int bufferSize = 100;
unsigned long intervalBuffer[bufferSize];
int bufferIndex = 0;
bool bufferFull = false;

// ===== ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЛ =====
unsigned long randomSeedAccumulator = 0;
int randomBitsCollected = 0;
byte randomByte = 0;

// ===== ТАЙМЕР ДЛЯ ВЫВОДА СТАТИСТИКИ =====
unsigned long lastStatsTime = 0;
const unsigned long statsInterval = 30000; // Вывод статистики каждые 30 секунд

void setup() {
  Serial.begin(115200);
  Serial.println("=== RADIATION DETECTOR v2.0 ===");
  Serial.println("Collecting data and analyzing intervals...");
  Serial.println();
  
  delay(1000); // Стабилизация
  
  // Инициализация буфера
  for (int i = 0; i < bufferSize; i++) {
    intervalBuffer[i] = 0;
  }
}

void loop() {
  int currentValue = analogRead(sensorPin);
  static int lastValue = 0;
  
  // Считаем разницу
  int diff = abs(currentValue - lastValue);
  
  // Детектируем событие
  if (diff > threshold) {
    unsigned long currentTime = micros();
    unsigned long interval = currentTime - lastEventTime;
    
    // Проверяем, что интервал в разумных пределах
    if (interval > minInterval && interval < maxInterval) {
      // ===== СОБЫТИЕ ЗАФИКСИРОВАНО =====
      eventCount++;
      totalInterval += interval;
      
      // Обновляем мин/макс
      if (interval < minIntervalDetected) minIntervalDetected = interval;
      if (interval > maxIntervalDetected) maxIntervalDetected = interval;
      
      // Сохраняем в кольцевой буфер
      intervalBuffer[bufferIndex] = interval;
      bufferIndex = (bufferIndex + 1) % bufferSize;
      if (bufferIndex == 0) bufferFull = true;
      
      // ===== ГЕНЕРАЦИЯ СЛУЧАЙНЫХ БИТОВ =====
      // Берем младшие 3 бита интервала (они наиболее хаотичны)
      byte randomBits = interval & 0x07; // 0-7 (3 бита)
      
      // Накапливаем биты в байт
      randomSeedAccumulator = (randomSeedAccumulator << 3) | randomBits;
      randomBitsCollected += 3;
      
      // Если накопили 8+ бит, выводим случайный байт
      if (randomBitsCollected >= 8) {
        randomByte = randomSeedAccumulator & 0xFF;
        randomSeedAccumulator = randomSeedAccumulator >> 8;
        randomBitsCollected -= 8;
        
        Serial.print("RANDOM BYTE: ");
        Serial.print(randomByte);
        Serial.print(" (0x");
        Serial.print(randomByte, HEX);
        Serial.println(")");
      }
      
      // Вывод информации о событии
      Serial.print("EVENT #");
      Serial.print(eventCount);
      Serial.print(" | Interval: ");
      Serial.print(interval);
      Serial.print(" us (");
      Serial.print(interval / 1000.0, 2);
      Serial.println(" ms)");
      
      lastEventTime = currentTime;
    }
  }
  
  lastValue = currentValue;
  
  // ===== ПЕРИОДИЧЕСКИЙ ВЫВОД СТАТИСТИКИ =====
  if (millis() - lastStatsTime >= statsInterval) {
    lastStatsTime = millis();
    
    Serial.println();
    Serial.println("========== STATISTICS ==========");
    Serial.print("Total events: ");
    Serial.println(eventCount);
    
    if (eventCount > 0) {
      unsigned long avgInterval = totalInterval / eventCount;
      Serial.print("Average interval: ");
      Serial.print(avgInterval);
      Serial.print(" us (");
      Serial.print(avgInterval / 1000.0, 2);
      Serial.println(" ms)");
      
      Serial.print("Min interval: ");
      Serial.print(minIntervalDetected);
      Serial.print(" us (");
      Serial.print(minIntervalDetected / 1000.0, 2);
      Serial.println(" ms)");
      
      Serial.print("Max interval: ");
      Serial.print(maxIntervalDetected);
      Serial.print(" us (");
      Serial.print(maxIntervalDetected / 1000.0, 2);
      Serial.println(" ms)");
      
      // Событий в минуту
      float eventsPerMinute = (eventCount * 60000.0) / millis();
      Serial.print("Events per minute: ");
      Serial.println(eventsPerMinute, 2);
    }
    
    // Гистограмма последних интервалов (если буфер заполнен)
    if (bufferFull) {
      Serial.println("\n--- Interval Distribution (last 100) ---");
      int bins[10] = {0}; // 10 корзин для гистограммы
      
      for (int i = 0; i < bufferSize; i++) {
        unsigned long interval = intervalBuffer[i];
        if (interval > 0) {
          int bin = map(interval, 0, 10000000, 0, 10); // Интервалы до 10 секунд
          if (bin >= 10) bin = 9;
          bins[bin]++;
        }
      }
      
      for (int i = 0; i < 10; i++) {
        Serial.print(i);
        Serial.print("-");
        Serial.print(i + 1);
        Serial.print("s: ");
        for (int j = 0; j < bins[i]; j++) Serial.print("#");
        Serial.print(" (");
        Serial.print(bins[i]);
        Serial.println(")");
      }
    }
    
    Serial.println("================================");
    Serial.println();
  }
  
  delay(5); // Небольшая пауза для стабильности
}