/*
This program reads the input from a potentiometer and controls the speed 
and direction of a DC motor connected through a L298N motor driver.
The potentiometer signal input mapped to the motor speed as follows:
55 to 100% commands motor from 0 to 100% forward
45 to 55% commands no speed from motor
45 to 0% commands motor from 0 to 100% reverse

Because of the lack of a DC motor and driver in wokwi, their functions
are emulated using logic gates and LEDs
Green LED is forward
Red LED is reverse

Finally, you can check the serial plotter to monitor the values of potentiometer
input and the PWM duty cycle.
*/


// Define pin numbers
#define PWM 23
#define DIR1 22
#define DIR2 21
#define POT 13

//Define PWM parameters
#define FREQUENCY 1000
#define CHANNEL 0
#define RESOLUTION 10
#define POT 13

//Declare variables
int potInput = 0;
int dutyCycle = 0;

void setup() {
  // configure  PWM output
  ledcSetup(CHANNEL, FREQUENCY, RESOLUTION);
  
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(PWM, CHANNEL);

  //configure direction control pins
  pinMode(DIR1,OUTPUT);
  pinMode(DIR2,OUTPUT);

  //configure potentiometer input pin
  pinMode(POT,INPUT);

  //Start serial port
  Serial.begin(115200);
}

void loop() {
  //Read control potentiometer input
  potInput = analogRead(POT);
  
  //Decide what to do with motor based on potentiometer input

  //Forward
  if(potInput > 2252){
    dutyCycle = map(potInput,2252,4095,0,1023);
    ledcWrite(CHANNEL, dutyCycle);
    digitalWrite(DIR1, HIGH);
    digitalWrite(DIR2, LOW);
  }

  //Reverse
  else if (potInput < 1843){
    dutyCycle = map(potInput,0,1843,1023,0);
    ledcWrite(CHANNEL, dutyCycle);
    digitalWrite(DIR1, LOW);
    digitalWrite(DIR2, HIGH);
  }

  //Stop
  else {
    dutyCycle = 0;
    ledcWrite(CHANNEL, dutyCycle);
    digitalWrite(DIR1, LOW);
    digitalWrite(DIR2, LOW);
  }
  
  //Print values to serial terminal
  Serial.print("Threshold_Forward: ");
  Serial.print(2252);
  Serial.print(" Threshold_Reverse: ");
  Serial.print(1843);
  Serial.print(" Pot: ");
  Serial.print(potInput);
  Serial.print(" Duty_Cycle: ");
  Serial.println(dutyCycle);

  delay(10); // loop delay
}