Code for Multi turn Pot

Hello to everyone. To briefly explain my problem, the multi-turn potentiometer I used to make my own car steering which wants 6 to 7 turns wiper servo.
I use FlySky I6B Remot control and reciever
I copy code from @James_Bruton youtube channel he used normarl pot for his project and it is only 180 degree turn.
Here his project link
How to Make an R/C Servo from a Wiper Motor | James Bruton - YouTube

The potentiometer I used is 10k 3590s. I want to please change in this code for multiturn pot I would be very happy if he shared his opinion with me. Thanks in advance.
Here is the code he used

#include <PID_v1.h>  //PID loop from http://playground.arduino.cc/Code/PIDLibrary

double Pk1 = 1;  //speed it gets there
double Ik1 = 0;
double Dk1 = 0;

double Setpoint1, Input1, Output1, Output1a;    // PID variables

PID PID1(&Input1, &Output1, &Setpoint1, Pk1, Ik1 , Dk1, DIRECT);    // PID Setup

volatile unsigned long pwm;
volatile boolean done;
unsigned long start;

int pot;

unsigned long currentMillis;

long previousMillis = 0;    // set up timers
long interval = 20;        // time constant for timers

void setup() {
  pinMode(2, INPUT);
  pinMode(A0, INPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  attachInterrupt(0, timeit, CHANGE);

  Serial.begin(115200);

  PID1.SetMode(AUTOMATIC);              // PID Setup - trousers SERVO
  PID1.SetOutputLimits(-255, 255);
  PID1.SetSampleTime(20);

}


void timeit() {
  if (digitalRead(2) == HIGH) {
    start = micros();
  }
  else {
    pwm = micros() - start;
    done = true;
  }
}


void loop() {

  currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {  //start timed event
    previousMillis = currentMillis;

    pot = analogRead(A0);
    Serial.print(pot);
    Serial.print(" , ");
    Serial.print (pwm);
    Serial.print(" , ");

    Setpoint1 = map(pwm, 1000, 2000, -255, 255);
    Input1 = map(pot, 0, 1023, -255, 255);
    PID1.Compute();

    Serial.println(Output1);

    if (Output1 > 0) {
      analogWrite(5, Output1);
      analogWrite(6, 0);
    }
    else if (Output1 < 0) {
      Output1a = abs(Output1);
      analogWrite(5, 0);
      analogWrite(6, Output1a);
    }



    if (!done)
      return;
    done = false;

  } // end of timed event

}



Hello, do yourself a favour and please read How to get the best out of this forum and modify your post accordingly (including code tags and necessary documentation of your ask).

Hello
What are the electrical differences between a "normal" pot and a "multi turn" pot?

:cold_sweat:
I will follow the roll.
Sir I'm newbie in Arduino and my English is not so strong, If wrote some inappropriate word sorry for it.

image

I mean he used a common potentiometer.

@J-M-L

#include <PID_v1.h>  //PID loop from http://playground.arduino.cc/Code/PIDLibrary

double Pk1 = 1;  //speed it gets there
double Ik1 = 0;
double Dk1 = 0;

double Setpoint1, Input1, Output1, Output1a;    // PID variables

PID PID1(&Input1, &Output1, &Setpoint1, Pk1, Ik1 , Dk1, DIRECT);    // PID Setup

volatile unsigned long pwm;
volatile boolean done;
unsigned long start;

int pot;

unsigned long currentMillis;

long previousMillis = 0;    // set up timers
long interval = 20;        // time constant for timers

void setup() {
  pinMode(2, INPUT);
  pinMode(A0, INPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  attachInterrupt(0, timeit, CHANGE);
  
  Serial.begin(115200);

  PID1.SetMode(AUTOMATIC);              // PID Setup - trousers SERVO
  PID1.SetOutputLimits(-255, 255);
  PID1.SetSampleTime(20);

}


void timeit() {
    if (digitalRead(2) == HIGH) {
      start = micros();
    }
    else {
      pwm = micros() - start;
      done = true;
    }
  }


void loop() {

  currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {  //start timed event
      previousMillis = currentMillis;

      pot = analogRead(A0);
      Serial.print(pot);
      Serial.print(" , ");
      Serial.print (pwm);
      Serial.print(" , ");

      Setpoint1 = map(pwm,1000,2000,-255,255);
      Input1 = map(pot,0,1023,-255,255);
      PID1.Compute();

      Serial.println(Output1);    

      if (Output1 > 0) {
        analogWrite(5, Output1);
        analogWrite(6, 0);
      }
      else if (Output1 < 0) {
        Output1a = abs(Output1);
        analogWrite(5, 0);
        analogWrite(6, Output1a);
      }

      
      
      if (!done)
            return;               
            done = false;   
     
  } // end of timed event

}

What are the electrical differences between a "normal" pot and a "multi turn" pot?

That’s not the issue, it’s how your post looks like. Please read how to use the forum and how to post code,

➜ please edit your post, select the code part and press the </> icon in the tool bar to mark it as cod (also make sure you indented the code in the IDE before copying, that’s done by pressing ctrlT on a PC or cmdT on a Mac).

1 Like

I edited the code.

1 Like

@paulpaulson
This the difference.
Rotary potentiometer (the most common type) vary their resistive value as a result of an angular movement. Rotating a knob or dial attached to the shaft causes the internal wiper to sweep around a curved resistive element. The most common use of a rotary potentiometer is the volume-control pot.
Multi-turn potentiometers allow for a shaft rotation of more than 360 degrees of mechanical travel from one end of the resistive track to the other.

Understood
An why do you have the change the sketch now?

Cause this normal pot has less movement you can see in the pictures below.
1

2

So you want less voltage changes to drive the same movement? Have you checked how the pot data is mapped into a target range?

I think the biggest problem is that you are not calling timeit() to get the pulse length from the radio. I recommend you replace 'timeit()' with 'pulseIn()':

    pot = analogRead(A0);
    pwm = pulseIn(2, HIGH, 30000);

Note: Input and Setpoint just have to be in the same units. They don't have to be related to Output. I would use the analog input range:

    Setpoint1 = constrain(map(pwm, 1000, 2000, 0, 1023), 0, 1023);
    Input1 = pot;

The map() can go out of range so the 'constrain()' is used to make sure the values don't go below 0 or above 1023.

I am more confused, why do you want to use a multi-turn pot? Electrically, there is no difference, so what code needs to change?

Hello
At this position I gave up, due to the unreflected answers I have received.

What answers? We don't understand the question.

I believe Mr. @paulpaulson was asking this rhetorical manner, that is to say there is no electrical difference, therefor it seems like the code woukd not need to change.

Except for some constants and the assumptions that they imply.

a7

My mistake. I missed the attachInterrupt() that connected 'timeit()' to a CHANGE interrupt on Pin 2.

Here is how I would write the sketch. I added names for the pins and removed some global variables that would be better as local variables.

#include <PID_v1.h>  //PID loop from http://playground.arduino.cc/Code/PIDLibrary

const byte RadioControlPin = 2;
const byte MotorPinA = 5;
const byte MotorPinB = 6;
const byte FeedbackPotPin = A0;

double Pk1 = 1;  //speed it gets there
double Ik1 = 0;
double Dk1 = 0;

double Setpoint1, Input1, Output1;    // PID variables

PID PID1(&Input1, &Output1, &Setpoint1, Pk1, Ik1 , Dk1, DIRECT);    // PID Setup

volatile unsigned long RadioControlPulseMicros;

unsigned long LastPrintTime = 0;
const unsigned long PrintInterval = 1000;

void setup()
{
  Serial.begin(115200);

  pinMode(RadioControlPin, INPUT);
  pinMode(MotorPinA, OUTPUT);
  pinMode(MotorPinB, OUTPUT);

  attachInterrupt(digitalPinToInterrupt(RadioControlPin), RadioControlISR, CHANGE);

  PID1.SetMode(AUTOMATIC);              // PID Setup - trousers SERVO
  PID1.SetOutputLimits(-255, 255);
  PID1.SetSampleTime(20);
}

// Called when RadioControlPin changes state
void RadioControlISR()
{
  static unsigned long start;
  if (digitalRead(RadioControlPin) == HIGH)
  {
    start = micros();  // Pin just started a pulse
  }
  else
  {
    // Pin just ended a pulse
    RadioControlPulseMicros = micros() - start;
  }
}

void loop()
{
  unsigned long currentMillis = millis();

  noInterrupts();
  unsigned long rcPulseMicros = RadioControlPulseMicros;
  interrupts();

  Input1 = analogRead(FeedbackPotPin);

  // Match setpoint to range of feedbck pot
  Setpoint1 = map(rcPulseMicros, 1000, 2000, 0, 1023);
  Setpoint1 = constrain(Setpoint1, 0, 1023);

  PID1.Compute();

  if (currentMillis - LastPrintTime > - PrintInterval)
  {
    LastPrintTime = currentMillis;

    Serial.print(rcPulseMicros);
    Serial.print(", ");
    Serial.print(Setpoint1);
    Serial.print(", ");
    Serial.print(Input1);
    Serial.print(", ");
    Serial.println(Output1);
  }

  if (Output1 < 0)
  {
    // Backward
    analogWrite(MotorPinA, 0);
    analogWrite(MotorPinB, -Output1);
  }
  else
  {
    // Forward (or stopped)
    analogWrite(MotorPinA, Output1);
    analogWrite(MotorPinB, 0);
  }
}

Thanks all of You, for giving me time and answers.
I try more than ten times in different ways but it didnt works,
I dont know why?