Untitled

 avatar
unknown
plain_text
2 months ago
13 kB
3
Indexable
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SD.h>
#include <SoftwareSerial.h>
#include <EEPROM.h>

// LCD ekran tanımlaması (I2C adresi 0x27, 16x2)
LiquidCrystal_I2C lcd(0x27, 16, 2);

// Bluetooth modülü için yazılımsal seri port (RX, TX)
SoftwareSerial bluetooth(5, 6);

// Kalibrasyon verilerini tutacak yapı
struct CalibrationData {
  int whiteRed;
  int whiteGreen;
  int whiteBlue;
  int blackRed;
  int blackGreen;
  int blackBlue;
  byte magic;   // Kalibrasyon yapıldıysa 0x55 değeri
};

CalibrationData calib;

// EEPROM'da geçerli kalibrasyon var mı kontrol etmek için sabit
#define CALIB_MAGIC 0x55

// Pin tanımlamaları
#define S0 4
#define S1 3
#define S2 9
#define S3 8
#define sensorOut 2
#define LED_PIN 10         // LED, 10 numaralı pinde
#define BUZZER_PIN 7
#define BUTTON1_PIN A0     // Ölçüm başlatma butonu
#define BUTTON2_PIN A1     // LED parlaklık ayarı butonu
#define SD_CS A2           // SD kart modülünün CS pini A2
#define BUTTON3_PIN A3     // Kalibrasyon modu için buton

// Renk değişkenleri (ölçüm sonrası)
int redValue = 0;
int greenValue = 0;
int blueValue = 0;

// SD kart durumu
bool sdCardOK = false;
bool sdErrorShown = false;  // SD kart hatasını yalnızca bir kere gösterilecek

// LED parlaklık seçenekleri (7 seviye: LED 0 = kapalı, LED 6 = tam parlaklık)
int brightnessLevels[7] = {0, 43, 85, 128, 170, 213, 255};
int brightnessIndex = 1;   // Başlangıçta LED 1 (örneğin: 43)
int currentBrightness = 43;

// Melodi notaları
#define NOTE_C4  262
#define NOTE_D4  294
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_G3  196
#define NOTE_A3  220
#define NOTE_B3  247

// Fonksiyon prototipleri
void adjustBrightness();
void measureColor();
void updateDisplay(bool basic, const char* hex, int r, int g, int b);
void displayResults(const char* hex, int r, int g, int b);
void sendBluetoothData(const char* hex, int r, int g, int b);
void saveToSD(const char* hex, int r, int g, int b);
void checkSDCard();
void handleError(const char* errorMsg);
void playStartupMelody();
void playSuccessMelody();
void playBeep(int note, int duration);
void startupAnimation();
void calibrateMapping();
void measureCalibration(bool isWhite);
void loadCalibration();
void saveCalibration();

void setup() {
  Serial.begin(9600);
  bluetooth.begin(9600);
  
  lcd.init();
  lcd.backlight();
  startupAnimation();  // Hareketli animasyonlu giriş
  
  // EEPROM'dan kalibrasyon verilerini yükle ve LCD'de bilgi göster
  loadCalibration();
  
  // Sensör ve diğer pin ayarları
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);
  pinMode(LED_PIN, OUTPUT);
  
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);
  
  pinMode(BUTTON1_PIN, INPUT_PULLUP);
  pinMode(BUTTON2_PIN, INPUT_PULLUP);
  pinMode(BUTTON3_PIN, INPUT_PULLUP);  // Kalibrasyon butonu
  pinMode(BUZZER_PIN, OUTPUT);
  
  playStartupMelody();
  
  sdCardOK = SD.begin(SD_CS);
  checkSDCard();
}

void loop() {
  // Eğer BUTTON3'e basılırsa, kalibrasyon moduna gir ve yeni kalibrasyon işlemini yap
  if (digitalRead(BUTTON3_PIN) == LOW) {
    delay(50); // Debounce
    if (digitalRead(BUTTON3_PIN) == LOW) {
      calibrateMapping();
    }
  }
  
  // Ana ekran: sabit mesaj
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Renk Olcum");
  lcd.setCursor(0, 1);
  lcd.print("Hazir");
  
  // LED parlaklık ayarı için BUTTON2 kontrolü
  if (digitalRead(BUTTON2_PIN) == LOW) {
    delay(50);
    if (digitalRead(BUTTON2_PIN) == LOW) {
      adjustBrightness();
    }
  }
  
  // Ölçüm başlatma butonu (BUTTON1)
  if (digitalRead(BUTTON1_PIN) == LOW) {
    delay(50);
    if (digitalRead(BUTTON1_PIN) == LOW) {
      measureColor();
    }
  }
  delay(100);
}

void calibrateMapping() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Kalibrasyon");
  lcd.setCursor(0, 1);
  lcd.print("Modu Acildi");
  delay(1500);
  
  // Beyaz referans için
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Beyaz Olcum");
  lcd.setCursor(0, 1);
  lcd.print("B3'e bas");
  // Kullanıcı beyaz ölçümü için butona basana kadar bekle
  while(digitalRead(BUTTON3_PIN) == HIGH) {}
  delay(50);
  while(digitalRead(BUTTON3_PIN) == LOW) {}
  measureCalibration(true);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Beyaz tamam");
  delay(1000);
  
  // Siyah referans için
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Siyah Olcum");
  lcd.setCursor(0, 1);
  lcd.print("B3'e bas");
  while(digitalRead(BUTTON3_PIN) == HIGH) {}
  delay(50);
  while(digitalRead(BUTTON3_PIN) == LOW) {}
  measureCalibration(false);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Kalibrasyon");
  lcd.setCursor(0, 1);
  lcd.print("Tamam");
  delay(2000);
  
  // Yeni kalibrasyon değerlerini EEPROM'a kaydet
  saveCalibration();
}

void measureCalibration(bool isWhite) {
  long sumRed = 0, sumGreen = 0, sumBlue = 0;
  // Kalibrasyon sırasında LED tam parlaklıkta açılır
  analogWrite(LED_PIN, 255);
  delay(100);
  
  // 50 ölçüm yapılarak aritmetik ortalama alınır
  for (int i = 0; i < 50; i++) {
    digitalWrite(S2, LOW);
    digitalWrite(S3, LOW);
    sumRed += pulseIn(sensorOut, LOW);
    
    digitalWrite(S2, HIGH);
    digitalWrite(S3, HIGH);
    sumGreen += pulseIn(sensorOut, LOW);
    
    digitalWrite(S2, LOW);
    digitalWrite(S3, HIGH);
    sumBlue += pulseIn(sensorOut, LOW);
    
    delay(100);
  }
  
  analogWrite(LED_PIN, 0);
  
  int avgRed = sumRed / 50;
  int avgGreen = sumGreen / 50;
  int avgBlue = sumBlue / 50;
  
  if (isWhite) {
    calib.whiteRed = avgRed;
    calib.whiteGreen = avgGreen;
    calib.whiteBlue = avgBlue;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Beyaz Ayar:");
  } else {
    calib.blackRed = avgRed;
    calib.blackGreen = avgGreen;
    calib.blackBlue = avgBlue;
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Siyah Ayar:");
  }
  lcd.setCursor(0, 1);
  char buf[17];
  sprintf(buf, "%3d,%3d,%3d", avgRed, avgGreen, avgBlue);
  lcd.print(buf);
  delay(2000);
}

void adjustBrightness() {
  brightnessIndex = (brightnessIndex + 1) % 7;
  currentBrightness = brightnessLevels[brightnessIndex];
  
  analogWrite(LED_PIN, currentBrightness);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  char buf[17];
  sprintf(buf, "LED %d", brightnessIndex);  // 0: kapali, 1: LED 1, vs.
  lcd.print(buf);
  lcd.setCursor(0, 1);
  lcd.print("Parlaklik Ayari");
  
  delay(2000);
  analogWrite(LED_PIN, 0);
}

void measureColor() {
  playBeep(NOTE_C4, 100);
  
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Renk Olcum");
  lcd.setCursor(0, 1);
  lcd.print("Olcum Yapiliyor");
  
  long sumRed = 0, sumGreen = 0, sumBlue = 0;
  
  analogWrite(LED_PIN, currentBrightness);
  delay(100);
  
  for (int i = 0; i < 50; i++) {
    digitalWrite(S2, LOW);
    digitalWrite(S3, LOW);
    sumRed += pulseIn(sensorOut, LOW);
    
    digitalWrite(S2, HIGH);
    digitalWrite(S3, HIGH);
    sumGreen += pulseIn(sensorOut, LOW);
    
    digitalWrite(S2, LOW);
    digitalWrite(S3, HIGH);
    sumBlue += pulseIn(sensorOut, LOW);
    
    delay(100);
  }
  
  analogWrite(LED_PIN, 0);
  
  redValue = sumRed / 50;
  greenValue = sumGreen / 50;
  blueValue = sumBlue / 50;
  
  // Kalibrasyon yapıldıysa, referanslara göre haritalama yapılıyor
  redValue   = constrain(map(redValue,   calib.whiteRed, calib.blackRed, 255, 0), 0, 255);
  greenValue = constrain(map(greenValue, calib.whiteGreen, calib.blackGreen, 255, 0), 0, 255);
  blueValue  = constrain(map(blueValue,  calib.whiteBlue, calib.blackBlue, 255, 0), 0, 255);
  
  char hexColor[8] = {0};
  sprintf(hexColor, "#%02X%02X%02X", redValue, greenValue, blueValue);
  
  // Renk tespiti: en yüksek değere göre basit karşılaştırma
  char colorName[10];
  if (redValue > greenValue && redValue > blueValue)
    strcpy(colorName, "KIRMIZI");
  else if (greenValue > redValue && greenValue > blueValue)
    strcpy(colorName, "YESIL");
  else if (blueValue > redValue && blueValue > greenValue)
    strcpy(colorName, "MAVI");
  else
    strcpy(colorName, "KARISIK");
  
  // Kısa süre ekranda hangi renk olduğu gösterilsin (1 saniye)
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(colorName);
  delay(1000);
  
  displayResults(hexColor, redValue, greenValue, blueValue);
  sendBluetoothData(hexColor, redValue, greenValue, blueValue);
  saveToSD(hexColor, redValue, greenValue, blueValue);
  
  playSuccessMelody();
}

void updateDisplay(bool basic, const char* hex, int r, int g, int b) {
  char line0[17];
  char line1[17];
  
  if (basic) {
    sprintf(line0, "%-16s", hex);
    sprintf(line1, "RGB:%3d,%3d,%3d", r, g, b);
  } else {
    sprintf(line0, "HEX:%-10s", hex);
    sprintf(line1, "RGB:%3d,%3d,%3d", r, g, b);
  }
  lcd.setCursor(0, 0);
  lcd.print(line0);
  lcd.setCursor(0, 1);
  lcd.print(line1);
}

void displayResults(const char* hex, int r, int g, int b) {
  bool display = true;
  unsigned long startTime = millis();
  bool basicDisplay = true;
  
  updateDisplay(basicDisplay, hex, r, g, b);
  
  while (display) {
    if (millis() - startTime > 3000) {
      startTime = millis();
      basicDisplay = !basicDisplay;
      updateDisplay(basicDisplay, hex, r, g, b);
    }
    if (digitalRead(BUTTON1_PIN) == LOW) {
      delay(50);
      if (digitalRead(BUTTON1_PIN) == LOW) {
        display = false;
      }
    }
  }
}

void handleError(const char* errorMsg) {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("HATA:");
  lcd.setCursor(0, 1);
  lcd.print(errorMsg);
  playBeep(NOTE_B3, 300);
  delay(2000);
}

void sendBluetoothData(const char* hex, int r, int g, int b) {
  bluetooth.print("HEX:");
  bluetooth.println(hex);
  bluetooth.print("RGB:");
  bluetooth.print(r);
  bluetooth.print(",");
  bluetooth.print(g);
  bluetooth.print(",");
  bluetooth.println(b);
}

void saveToSD(const char* hex, int r, int g, int b) {
  if (!sdCardOK) {
    if (!sdErrorShown) {
      handleError("SD Kart Hata");
      sdErrorShown = true;
    }
    return;
  }
  
  File dataFile = SD.open("renk_log.txt", FILE_WRITE);
  if (dataFile) {
    dataFile.print("HEX:");
    dataFile.print(hex);
    dataFile.print(" RGB:");
    dataFile.print(r);
    dataFile.print(",");
    dataFile.print(g);
    dataFile.print(",");
    dataFile.println(b);
    dataFile.close();
  } else {
    if (!sdErrorShown) {
      handleError("Dosya Acilamadi");
      sdErrorShown = true;
    }
  }
}

void checkSDCard() {
  lcd.clear();
  if (sdCardOK) {
    lcd.setCursor(0, 0);
    lcd.print("SD Kart Hazir");
    delay(1000);
  } else {
    handleError("SD Kart Yok");
  }
}

void playStartupMelody() {
  tone(BUZZER_PIN, NOTE_C4, 100);
  delay(150);
  tone(BUZZER_PIN, NOTE_D4, 100);
  delay(150);
  tone(BUZZER_PIN, NOTE_E4, 100);
  delay(150);
  tone(BUZZER_PIN, NOTE_F4, 100);
  delay(150);
  noTone(BUZZER_PIN);
}

void playSuccessMelody() {
  tone(BUZZER_PIN, NOTE_C4, 100);
  delay(100);
  tone(BUZZER_PIN, NOTE_D4, 100);
  delay(100);
  noTone(BUZZER_PIN);
}

void playBeep(int note, int duration) {
  tone(BUZZER_PIN, note, duration);
  delay(duration);
  noTone(BUZZER_PIN);
}

void startupAnimation() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Yukleniyor");
  
  int centerCol = 7;
  char spinnerFrames[4] = {'|', '/', '-', '\\'};
  int delayTime = 80;
  
  for (int cycle = 0; cycle < 8; cycle++) {
    lcd.setCursor(centerCol, 0);
    lcd.print(spinnerFrames[cycle % 4]);
    tone(BUZZER_PIN, (cycle % 4 == 0) ? NOTE_C4 : 
         (cycle % 4 == 1) ? NOTE_D4 : 
         (cycle % 4 == 2) ? NOTE_E4 : NOTE_F4, 100);
    
    int barPos = cycle % 16;
    lcd.setCursor(0, 1);
    for (int i = 0; i < 16; i++) {
      lcd.print(" ");
    }
    lcd.setCursor(barPos, 1);
    lcd.print("*");
    
    delay(delayTime);
    noTone(BUZZER_PIN);
  }
  delay(500);
  lcd.clear();
}

void loadCalibration() {
  EEPROM.get(0, calib);
  if (calib.magic == CALIB_MAGIC) {
    Serial.println("Kalibrasyon EEPROM'dan yüklendi.");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Kalibrasyon");
    lcd.setCursor(0, 1);
    lcd.print("yuklendi");
    delay(2000);
  } else {
    Serial.println("Kalibrasyon yok. Varsayilan degerler kullaniliyor.");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Kalibrasyon");
    lcd.setCursor(0, 1);
    lcd.print("yok");
    delay(2000);
    // Varsayılan değerler atanır
    calib.whiteRed = 50;
    calib.whiteGreen = 50;
    calib.whiteBlue = 50;
    calib.blackRed = 970;
    calib.blackGreen = 970;
    calib.blackBlue = 970;
    calib.magic = CALIB_MAGIC; // İleride kaydedilmek üzere
  }
}

void saveCalibration() {
  calib.magic = CALIB_MAGIC;
  EEPROM.put(0, calib);
  Serial.println("Yeni kalibrasyon EEPROM'a kaydedildi.");
}
Editor is loading...
Leave a Comment