How to convert servo angle to percentage on oled display

So I am brand new to arduino. I have put together a few different projects found online to meet my need. I am assuming the code is not very neat or efficient but it does work how I need it to.

I am using an a generic NANO to run the code.

I have a rotary encoder that moves a servo between 0-65 degrees. The current angle is then displayed on a ssd1306 display. I would like the display to show a 0-100 percent instead of the 0-65 degree angle. I think I can use a map function but dont really understand how for the rotary encoder. I did it when I used a Variable pot but this seems different.

Someone may also be able to help make the code run more efficiently. when I just use the rotary encoder to adjust the servo it moves smoothly. When I added the oled display it made the encoder move one degree at a time so I added the millis function to refresh the display less. That helped some but its still slightly rough and the encoder doesn't seem to be as precise

Also I know there is a spelling mistake but its from code I borrowed and never corrected it.

Thanks in advance.

Here is my code

#include <Servo.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <SPI.h>
#include <Encoder.h>






const int SW_PIN = 4;//define a pin for rotary encode switch
const int PIN_A =2;
const int PIN_B =3;

//oled refresh milis setting
const unsigned long eventInterval = 1000;
unsigned long previousTime = 0;



// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capabilitym
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
Encoder myEnc(2, 3);
//   avoid using pins with LEDs attached

const int home = 65; //initial position


const int homePosition = 65; //initial position
const int stepValue = 1;//how fast the servo should rotate when turning the knob
const int servoPin = 9;//~must be a pin that that is labeled with ~


Servo myservo;  // create servo object to control a servo
int servoAngel =homePosition;




#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);



/*
 * PIN connection:
 * pin connection see: https://www.arduino.cc/en/Reference/Wire
 * for UNO: SDA to A4, SCL to A5
 * VCC to 5V
 * GND to GND :-)
 */


// this is the Width and Height of Display which is 128 xy 32 
#define LOGO16_GLCD_HEIGHT 32
#define LOGO16_GLCD_WIDTH  128 



void setup() {
  Serial.begin(9600);
  pinMode(SW_PIN, INPUT);
  Serial.println("Basic Encoder Test:");
   myservo.attach(servoPin);  // attaches the servo on pin
   myservo.write(servoAngel);//move servo to initial position
   
   
   display.begin(SSD1306_SWITCHCAPVCC,  0x3C);
   display.display();
   display.clearDisplay();
   display.setTextSize(2);
   display.setTextColor(WHITE);
   
 
}

long oldPosition  = -999;

void loop() {

 
  long newPosition = myEnc.read();
  if (newPosition != oldPosition) {
   
 
   
   if(newPosition >  oldPosition)
    {
    int newStep = abs(newPosition - oldPosition);
      Serial.print("Angle ");
      Serial.println(servoAngel);
    

      servoAngel -= stepValue;
      if(servoAngel <0)
          servoAngel =0;      
      myservo.write(servoAngel); //move servo to new angel
      

    }

    if(newPosition <  oldPosition )
    {
    int newStep = abs(newPosition - oldPosition);
      Serial.print("Angle ");
      Serial.println(servoAngel);
      servoAngel += stepValue;
      if(servoAngel >65)
          servoAngel =65;
      myservo.write(servoAngel); //move servo to new angle
     

    }
   oldPosition = newPosition;//remember the new position
  }

     /* Updates frequently */
  unsigned long currentTime = millis();

  /* This is screen refresh */
  if (currentTime - previousTime >= eventInterval) {
    /* Event code */
    Serial.println("refresh screen");
    
   /* Update the timing for the next time around */
    previousTime = currentTime;

    display.clearDisplay();     
    display.setCursor(0,0);
    display.setTextSize(2);
    display.println(" Angle");
    display.setCursor(80,0);
    display.setTextSize(4);
    display.println(servoAngel);
    display.display();
  }

  if( digitalRead(SW_PIN) == LOW)
   {
    Serial.print("Home: ");
    Serial.println(homePosition);
    servoAngel =home;
      myservo.write(servoAngel); //move servo to new angle

  }

 
  

   
}


You know the current angle. You know the range of possible angles so it is trivial to calculate what percentage the current angle is of the possible range

Suppose I said that the current angle was 45 degrees and the possible range was 180 degrees. How would you calculate the percentage ?

1 Like

If the range is 0 - 65 and never go beyond those values ​​you can do

display.println(map(servoAngel, 0, 65, 0, 100));

// or directly

display.println(servoAngel * 100 / 65);

Regards

1 Like

Thank you very much, I was trying to understand how to use the map function that way but could not picture it. The second option simplifies it very nicely. Thank you again.

Google: "map() arduino". :wink:

I was but I thought I had to create an int that was a map of the servoangel and then print that to the display. I knew I was over complicating it. It didnt help that every example uses a variable pot and maps that. I thought I needed to do it differently.

What about the other five degrees?

I went back and corrected the error. I did want the full range.

As I said, trivial

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.