/********************************************************
** Download from:                                      **
** http://www.alhin.de/arduino/index.php?n=44          **
********************************************************/

#include <AH_EasyDriver.h>
#include <UTFT.h>

// Declare which fonts we will be using
extern uint8_t SmallFont[];

UTFT myGLCD(ILI9486,38,39,40,41);

//AH_EasyDriver(int RES, int DIR, int STEP);
// RES -> RESOLUTION per full revolve
// DIR -> DIRECTION PIN
// STEP -> STEPPING PIN

AH_EasyDriver stepper_x(200,9,8);   // Initialisation
AH_EasyDriver stepper_y(200,11,10);   // Initialisation

// x-Stepper:
// ===============
// DIR-Pin = Pin 9
// STEP-Pin = Pin 8

// y-Stepper:
// ===============
// DIR-Pin = Pin 11
// STEP-Pin = Pin 10

const int buttonPin = 12;   // button-pin
int i,j,k,l,m,n;            // Zählvariablen
int xPos, yPos;             // Bildschirmposition
int value;                  // grey-value

#define clockPin     2       // clock
#define siPin        3       // Start Integration
#define VOUT         A0      // pixel intensity in the analog channel A0

long exposure;
int Helligkeiten[128];
int Pixel_max, Helligkeit_max;

// ================
// ===  SETUP   ===
// ================

void setup()
   {
    //  Serial.begin(9600);
    
    pinMode(buttonPin, INPUT);
    pinMode(siPin, OUTPUT);
    pinMode(clockPin, OUTPUT);
    
    Serial.begin(115200);
    
    myGLCD.InitLCD();
    myGLCD.setFont(SmallFont);    
    myGLCD.clrScr();

    myGLCD.setColor(255, 255, 0);
    myGLCD.fillRect(0, 0, 479, 13);
    myGLCD.setColor(0, 0, 0);
    myGLCD.setBackColor(255, 255, 0);
    myGLCD.print("Atomic Force Microscope - stoppi", CENTER, 1); 

    
    stepper_x.setSpeedRPM(20);          // RPM , rotations per minute
    stepper_y.setSpeedRPM(20);          // RPM , rotations per minute

    // RPM = 1 entspricht einer Umlaufszeit von 30 Sekunden!!!
    // RPM = 10 entspricht einer Umlaufszeit von 3 Sekunden!!!
    // RPM = 20 entspricht einer Umlaufszeit von 1.5 Sekunden!!!
    // =======================================================

    //stepper.setMicrostepping(3);            // 0 -> Full Step                                
                                              // 1 -> 1/2 microstepping
                                              // 2 -> 1/4 microstepping
                                              // 3 -> 1/8 microstepping
  
    //stepper.setSpeedHz(100);           // Hz, steps per second

    stepper_x.move(200,1);      // Heimposition
    stepper_y.move(200,1);      // Heimposition

    exposure = 0;      // Belichtungszeit in ms
   }


// ===============
// ===  LOOP   ===
// ===============

void loop()
   {
    /*
    stepper_x.move(1000,0);    // 0 = im Uhrzeigersinn, 1 = gegen Uhrzeigersinn
    stepper_x.move(1000,1);    // 0 = im Uhrzeigersinn, 1 = gegen Uhrzeigersinn
    */

    // move = 800 entspricht einer vollen Umdrehung!!!
    // ===============================================

    //stepper.rotate(180.0);  // Rotiert um einen bestimmten Winkel, wobei 180 = eine volle Umdrehung!!!
    //stepper.revolve(1.0);   // Rotiert vollständig herum eine bestimmte Anzahl, wobei 1 = 2 volle Umdrehungen!!!
    
  
    //delay(100);
    
    
    while(digitalRead(buttonPin))
       {
        // wait for push start-button
        
        myGLCD.clrScr();
        
        myGLCD.setColor(255, 255, 0);
        myGLCD.fillRect(0, 0, 479, 13);
        myGLCD.setColor(0, 0, 0);
        myGLCD.setBackColor(255, 255, 0);
        myGLCD.print("Atomic Force Microscope - stoppi", CENTER, 1); 

        myGLCD.setColor(255, 255, 255);
        myGLCD.setBackColor(0, 0, 0);
        
        myGLCD.drawLine(10, 300, 400, 300);
        myGLCD.drawLine(10,300,10,305);
        myGLCD.drawLine(70,300,70,305);
        myGLCD.drawLine(130,300,130,305);
        myGLCD.drawLine(190,300,190,305);
        myGLCD.drawLine(250,300,250,305);
        myGLCD.drawLine(310,300,310,305);
        myGLCD.drawLine(370,300,370,305);
    
        myGLCD.drawLine(10, 40, 10, 300);
        
        myGLCD.printNumI(0, 7, 310);
        myGLCD.printNumI(20, 65, 310);
        myGLCD.printNumI(40, 125, 310);
        myGLCD.printNumI(60, 185, 310);
        myGLCD.printNumI(80, 245, 310);
        myGLCD.printNumI(100, 300, 310);
        myGLCD.printNumI(120, 360, 310);

        getCamera();

        myGLCD.setColor(0, 255, 0);

        for(m = 0; m < 127; m++)
           {
            myGLCD.drawLine(10 + 3*m, 299 - 0.25 * Helligkeiten[m], 10 + 3*m + 3, 299 - 0.25 * Helligkeiten[m+1]);                   
           }

        delay(1000);
        
       }

    // Start des Scans
    // ===============

    myGLCD.clrScr();

    myGLCD.setColor(255, 255, 0);
    myGLCD.fillRect(0, 0, 479, 13);
    myGLCD.setColor(0, 0, 0);
    myGLCD.setBackColor(255, 255, 0);
    myGLCD.print("Atomic Force Microscope - stoppi", CENTER, 1); 

    for (j = 0; j <= 149; j++)
       {
        for (i = 0; i <= 199; i++)
           {
            getCamera();

            Pixel_max = 0;         // Pixel-Nummer mit der größten Helligkeit
            Helligkeit_max = 0;    // maximale Helligkeit

            for (k = 0; k < 128; k++)
               {
                if (Helligkeiten[k] > Helligkeit_max)
                   {
                    Helligkeit_max = Helligkeiten[k];
                    Pixel_max = k;
                   }                
               }
                        
            //value = random(1023);
            //value = map(value,0,1023,0,255);

            value = Pixel_max * 2;     // grey-values between 0 and 254
            
            myGLCD.setColor(value, value, value);
            myGLCD.fillRect(i * 2, 15 + j * 2, i * 2 + 1, 15 + j * 2 + 1);

            stepper_x.move(1,0);
            
            delay(2);
           }

        stepper_x.move(200,1);
        stepper_y.move(1,0);
        
       }

    stepper_x.move(200,1);   // homing
    stepper_y.move(200,1);   // homing

    while(digitalRead(buttonPin))
       {
        // Wait for push button
       }  
       
    myGLCD.clrScr();
    delay(1000);
    
   }



// ================================
// ===== Helligkeiten einlesen ====
// ================================

void getCamera()
   {
    digitalWrite(clockPin, LOW);
    digitalWrite(siPin, HIGH);
    digitalWrite(clockPin, HIGH);
    digitalWrite(siPin, LOW);
    digitalWrite(clockPin, LOW);
 
    for (l = 0; l < 128; l++)
       {
        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
       }
 
    //delayMicroseconds(exposure);    // Belichtungszeit = Verzögerung in µs
    
    delay(exposure);    // Belichtungszeit = Verzögerung in ms
 
    digitalWrite(siPin, HIGH);
    digitalWrite(clockPin, HIGH);
    digitalWrite(siPin, LOW);
    digitalWrite(clockPin, LOW);
    
    for (l = 0; l < 128; l++)   
       {
        delayMicroseconds(20);
        
        Helligkeiten[l] = analogRead(VOUT);    // Wertebereich [0,1023]
        
        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
       }
 
    delayMicroseconds(20);
   }
