Problems with the code to use a Uno to control a servo using a potentiometer

The code to do this with a "regular " potentiometer is pretty straightforward, but the potentiometer I'm using is on a steering wheel from a video game, and the 10K potentiometer has the signal wire connected to the 5K position on the potentiometer which serves as the "straight ahead" position. The steering wheel is spring- loaded to return to the straight ahead position when not being turned. I'm using the steering wheel to control the rudder of a small boat, but am having problems coming up with the code and associated potentiometer map which which results in the rudder being in the neutral (straight ahead) position when the Arduino is powered up, and stays there until the steering wheel is turned and then allows the rudder to travel 30 degrees in each direction when the steering wheel is turned. I've tried to solve the problem using Tinkercad, but so far haven't come up with a code that does what I want - I'm starting to think that the map is not the whole problem . Here's one of them:

#include <Servo.h>
Servo myservo;  // create servo object to control a servo
int potpin = A0;  // analog pin used to connect the potentiometer
int val;          // variable to read the value from the analog pin

void setup() {
  myservo.write(0); // Initialize the servo to the center position
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  delay(1000); // Small delay to ensure the servo reaches the center position
}

void loop() {
  val = analogRead(potpin); // reads the value from the sensor
  
  // Map the potentiometer value (0-1023) to a specific angle range.
  // Example: 90 degrees is center. To move 30 degrees each way,
  // we map the input from 0-1023 to a range from 60 to 120.
  int degree = map(val, 0, 1023, 60, 120); 
  
  myservo.write(degree);  // sets the servo position
  delay(15); // Small delay to make the servo movement smoother
}`

To add code tags, edit the post, select the code section with the mouse, and hit the <code> editor button.

Start by leaving out the servo commands, and just print out the values returned by analogRead() for various positions of the pot (right, left and neutral).

Then you can plan out how to transform the numbers into servo commands.

How is the servo powered? Not by any UNO pin I hope.

Many servos expect the pulse width telling “how much” at the rate of 50 times per second. Hope I remember. Start testing with a longer delay, say 100 ms. If that works decrease the delay but not below 20.

Thanks for your response, Railroader - I started out using actual hardware ( with the servo powered by it's own battery ), but then went to just simulating things on Tinkercad as my wife needed the dining room table :grinning_face:. I assume (but don't know) that Tinkercad doesn't care about pulse width. This raises the question " Is it a good idea to simulate on Tinkercad - does it give "true life" results ?

Always power servos, motors, solenoids from a separate power supply.

No knowledge about Tinkercad but I’ve ween simulators don't consider everything. The need for current is one poor aspect. Be prepared for some surprice.

Does the Tinkercad manual tell about its limitations?

No simulator does.
Which Arduino are you using?

 myservo.write(0); // Initialize the servo to the center position

No that moves it to one end
myservo.write(90) will put it in the center

Hi, @eclecticeric

How does the signal wire vary if it is connected to the midpoint of the 10K track?

Can you please post some images of the pot?

Tom.... :smiley: :+1: :coffee: :australia:

I've decided I need to forget about Tinkercad and go back to the real hardware, because I'm sure that the potentiometer that Tinkercad simulates is a typical one with a wiper that goes from 0 to 10K (or whatever), and not like the one I have, which is centered at 5000 ohms when the steering wheel is set "straight ahead" and then can go from 5000 up to 10000 ohms when turned in one direction, and from 5000 ohms down to zero when turned in the other direction.

I should have said that when the steering wheel is at "straight ahead", the wiper is at 5000 ohms, and full left is 10,000 ohms and "full right" is 0 ohms. The pot looks like any other pot, with the two outer terminals for power and the center terminal is the wiper.

And the ADC won't know the difference. It's only what you do with the readings that give them any particular meaning.

As @jim-p said in post #7, try

#include <Servo.h>
Servo myservo;  // create servo object to control a servo
int potpin = A0;  // analog pin used to connect the potentiometer
int val;          // variable to read the value from the analog pin

void setup() {
  myservo.write(90); // Initialize the servo to the center position
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  delay(1000); // Small delay to ensure the servo reaches the center position
}

void loop() {
  val = analogRead(potpin); // reads the value from the sensor
  
  // Map the potentiometer value (0-1023) to a specific angle range.
  // Example: 90 degrees is center. To move 30 degrees each way,
  // we map the input from 0-1023 to a range from 60 to 120.
  int degree = map(val, 0, 1023, 60, 120); 
  
  myservo.write(degree);  // sets the servo position
  delay(15); // Small delay to make the servo movement smoother
}`

If that doesn't work, we'll need to see how you've really got it wired, because as described. that should work.

Did you make the correction I suggested?

Not yet, but I will later today, although I'm pretty sure I've tried that before.

I'll try that today !

That would be surprising and make it nearly worthless.

This simulator def does potentiometers and servos very faithfully:

The only real no matter real life or simulation is the starting position. The servo is operated open loop, can't say where it is, so your first command to it will might mean a motion from where it was left to where you are saying you want it.

The fact that your potentiometer has a return to neutral mechanism is immaterial.

a7

We recently got Wokwi fixed in this regard - sure, the first time you run your code, it can’t know where the servos should be, but it now knows where you left them when your previous run was terminated, so it’s much more ‘useful’ when testing servo code now.

@eclecticeric

Good luck!

That works ! Pretty sure I tried that before, but it was after I had "zero" as the start position, and when I initially powered everything up, the servo and rudder tried to move 90 degrees, which it isn't designed to do , and it jammed up, and this led to subsequent problems until I realised that it was jammed up and couldn't move - discovered the problem when I found that the servo (35 Kg) was very hot.
Thank you everyone for your help, and thank you Alto777 for introducing me to Wokw !i

@jim-p , post#7, was your first correct answer. All the rest was open-loop embellishment.
Wokwi is a treat for a lot of simpler codes.