/*-----------------------------------------------------------------------------------------
 *  This software is in the public domain, furnished "as is", without technical
 *  support, and with no warranty, express or implied, as to its usefulness for
 *  any purpose.
 *
 *  Hallsensor.ino
 *
 *  Function to read digital/analouge hall sensor as measurement device for positioning finding
 *  of turntable. A magnet attached to the stepper axis/turntable is needed.
 *
 *
 *  Author: Volker Frauenstein
 *  Date: 04/05/2021 Version: 1.2 auto limit finding functions added findMinMax(),setHallLimit()
 *
 *  Date: 04/05/2021 Version: 1.1 implementation changed to analouge interface to sensor
 *                                due to missing robustnes of digital readings.
 *  Date: 02/03/2021 Version: 1.0 implementation for digital interface of sensor
 */


// definition for pinout to hall sennsor modul
const int Pin_a = 14;                        // definition of analouge input pin for hall sensor modul

// generig definitions for debug
//#define DEBUG_HALL 1                         // set activ if debuging of hall sensor function is needed

// definitions for adjustable values
int alimit = 3080;                           // measuered limit for hall sensor defined as triggerd
const int limitquot = 5;                     // quotient for limit calculaten (5 means 20% of band)

// generig definitions
int HallBand [] = {0,0};

void setup_hall() {                          // set up function to enable input pin for hall sensor modul
  pinMode(Pin_a,INPUT);
 }

bool read_hall(bool meas) {                  // function to read out hall sensor analouge value
                                             // and return digital result
  bool hallout;                              // return value, digital readout based on analouge sensor reading
  int aread = analogRead(Pin_a);             // analouge readout of sensor

  #ifdef DEBUG_HALL
   Serial.print(", hall sensor anlouge read: ");Serial.print(aread);
  #endif

  if (meas) {                                // check if limit band should be used
   findMinMax(aread);                        // yes, find min and max values of analoug readings
  }

  if (aread > alimit) {                      // check if analoug reading is in or out off limit
    hallout = false;                         // magnetic fild is near sensor position
  }
  else {
    hallout = true;                          // to low magnetic fild seen from sensor
  }

  #ifdef DEBUG_HALL
   Serial.print("-> sensor return: ");Serial.print(hallout);
  #endif
  return hallout;                            // return digital value
}                                            // end function read_hall

void findMinMax(int input) {                 // function to find and store min and max values of analoug readings

  if (HallBand[0] == 0) {                    // init band values with actual reading
    HallBand[0] = input;
    HallBand[1] = input;
  }
  else {                                     // check if actual reading is lower / higer as stored
    if (input < HallBand[0]) {HallBand[0] = input;}
    if (input > HallBand[1]) {HallBand[1] = input;}
  }
  #ifdef DEBUG_HALL
   Serial.print(", HallBand: [");Serial.print(HallBand[0]);
   Serial.print(",");Serial.print(HallBand[1]);;Serial.println("]");
  #endif
}                                            // end function findMinMax

bool setHallLimit(){                         // function to reset limit for anloug hall sensor readings

  if (HallBand[0] < HallBand[1]) {           // check if min and max values are existent
    int newLimit = HallBand[1]-HallBand[0];  // calc delta of readings
    newLimit = newLimit/limitquot;           // take quotiation of delta
    alimit = HallBand[1] - newLimit;         // and calc new limit inside the found readings
    #ifdef DEBUG_HALL
     Serial.println("-> new Limit set: ");Serial.print(alimit);
    #endif
    return true;                             // return success
  }
  else {
    #ifdef DEBUG_HALL
     Serial.println("-> Warning: No new Limit set! ");
    #endif
    return false;                            // return error
  }
}                                            // end function setHallLimit

/* digital readout not used due to unstable readout

const int Pin_h = 14;                        // definition of digital input pin for hall sensor modul

bool read_hall() {

  bool readout = digitalRead(Pin_h);
  int aread = analogRead(Pin_a);
  #ifdef DEBUG_HALL
   Serial.print("hall sensor read: ");Serial.print(readout);Serial.print(", analog: ");Serial.print(aread);
  #endif

  if (readout) {
    if (HallLow[0] == 0) {
      HallLow[0] = aread;
      HallLow[1] = aread;
    }
    else {
      if (aread < HallLow[0]) {HallLow[0] = aread;}
      if (aread > HallLow[1]) {HallLow[1] = aread;}
    }
  }
  else {
    if (HallHigh[0] == 0) {
      HallHigh[0] = aread;
      HallHigh[1] = aread;
    }
    else {
      if (aread < HallHigh[0]) {HallHigh[0] = aread;}
      if (aread > HallHigh[1]) {HallHigh[1] = aread;}
    }
  }

  if (aread > alimit) {
    readout = false;
  }
  else {readout = true;}

  #ifdef DEBUG_HALL
   Serial.print("-> sensor return: ");Serial.print(readout);
   Serial.print(", HallLow: [");Serial.print(HallLow[0]);Serial.print(",");Serial.print(HallLow[1]);
   Serial.print("], HallHigh: [");Serial.print(HallHigh[0]);Serial.print(",");Serial.print(HallHigh[1]);Serial.println("]");
  #endif
  return readout;
} /*