Adapting code to different diplays

I'm fairly new to Arduino and I'm trying to learn by adapting existing code for my use.
One problem I have had several times now, is that a project uses a type of display that I don't have. This may be a silly question, but is there a good approach to this kind of adaptation?
As an example, I want to use this code for a single axis camera slider, but I don't have a LCD. What I have is a SSD1306 128X64 OLED.

/*
 * Camera slider code for Arduino. Author: ELECTRONOOBS
 * Tutorial: http://www.electronoobs.com/eng_arduino_tut27.php
 * Video: https://www.youtube.com/watch?v=YGbPnAZzEQk
 * 
 * Connect the pins as her: http://www.electronoobs.com/eng_arduino_tut27_sch1.php
 */


//LCD config
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);  //sometimes the LCD adress is not 0x3f. Change to 0x27 if it dosn't work.

//Variables
bool Last_State; 
bool clk_State;
bool dt_State;  
int counter_menu = 0; 
float counter_speed = 3.5; 
int last_counter_menu = 0;
int menu_enter = 0;
bool rotary_push_state = false;
bool last_counter_speed = false;
float Speed = 20;
int just_entered=0;
int homing = 0;
int Position_steps = 0;
bool Slide_left=false;
bool Slide_right=false;
int print_once = 0;

//I/O
#define rotary_button 10
#define left_button 11
#define right_button 12
#define Enable 5
#define Direction 6
#define Step 7
#define end_stop 4


//below read how to calculate the delay for the square wave
float perimeter = 2.5; //in cm
float steps_per_cm = 200/perimeter;
float step_delay = 10/steps_per_cm;



void setup() {
  pinMode (rotary_button,INPUT);       //Define the pin as input
  pinMode (left_button,INPUT);         //Define the pin as input
  pinMode (right_button,INPUT);        //Define the pin as input
  pinMode (end_stop,INPUT);            //Define the pin as input
  pinMode (Enable,OUTPUT);             //Define the pin as OUTPUT
  pinMode (Direction,OUTPUT);          //Define the pin as OUTPUT
  pinMode (Step,OUTPUT);               //Define the pin as OUTPUT
  
  lcd.init();                 //Init the LCD
  lcd.backlight();            //Activate backlight


  PCICR |= (1 << PCIE0);    //enable PCMSK0 scan                                                 
  PCMSK0 |= (1 << PCINT0);  //Set pin D8  trigger an interrupt on state change. 
  PCMSK0 |= (1 << PCINT1);  //Set pin D9  trigger an interrupt on state change.  
  PCMSK0 |= (1 << PCINT2);  //Set pin D10 trigger an interrupt on state change.  
  PCMSK0 |= (1 << PCINT3);  //Set pin D11 trigger an interrupt on state change.  
  PCMSK0 |= (1 << PCINT4);  //Set pin D12 trigger an interrupt on state change.  

  Last_State =   (PINB & B00000001); //pin 8 state (clock pin)? 
  
  
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("    WELCOME!    ");
  delay(1000);
  lcd.setCursor(0,0);
  lcd.print("  ELECTRONOOBS  ");
  lcd.setCursor(0,1);  
  lcd.print(" Camera  SLIDER ");
  delay(2000);

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("     Homing     ");
  
  while (!digitalRead(end_stop))
  {
    digitalWrite(Enable, LOW);      //Negative enabled
    digitalWrite(Direction, LOW);   //Low for Left 
    digitalWrite(Step,HIGH);
    delay(1);
    digitalWrite(Step,LOW);
    delay(1);
  }

  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("     READY!     ");
  delay(1000);
 
}

void loop() {

  /*
   * The speed is seconds per meter, so how many seconds the slider needs to make one meter
   * We know that in my case, each rotation needs 200 steps
   * Also, my pully has a perimeter of 2cm so each 200 steps I make 2cm, so for 1m I need 10.000 steps.
   * That's why below I multiplay the speed in seconds by 10.000 and then divide it by the amount of steps
   * we need for only one cm and the delay is expresed in microseconds. Also see above the perimeter of the pully
   */
   step_delay = (10000 * Speed)/steps_per_cm;   
   if(Slide_left)
   {
    if(print_once)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("  Sliding LEFT  ");
      print_once = 0;
    }
    if(digitalRead(end_stop))
    {
      digitalWrite(Enable, HIGH);      //Disabled
      Slide_left = false;
      Position_steps = 0;
    }
    digitalWrite(Enable, LOW);      //Negative enabled
    digitalWrite(Direction, LOW);   //LOW for Left 
    digitalWrite(Step,HIGH);
    delayMicroseconds(step_delay);
    digitalWrite(Step,LOW);
    delayMicroseconds(step_delay);
   }
   if(Slide_right)
   {
    if(print_once)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print(" Sliding  RIGHT ");
      print_once = 0;
    }
    if(Position_steps > 7500)
    {
      digitalWrite(Enable, HIGH);      //Disabled
      Slide_right = false;
    }
    digitalWrite(Enable, LOW);      //Negative enabled
    digitalWrite(Direction, HIGH);   //GIGH for Right 
    digitalWrite(Step,HIGH);
    delayMicroseconds(step_delay);
    digitalWrite(Step,LOW);
    delayMicroseconds(step_delay);
    Position_steps = Position_steps + 2;
   }

  
  
  if(menu_enter == 0 && !Slide_right && !Slide_left)
  {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" Sliding  speed ");
    lcd.setCursor(0,1);
    lcd.print(Speed);
    lcd.setCursor(13,1);
    lcd.print("s/m");
    delay(200);
  }
  
  
  if(menu_enter == 1)
  {
    if(counter_menu != last_counter_menu)
    {
      if(counter_menu < 4)
      {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(">  Speed");
        lcd.setCursor(0,1);
        lcd.print("  Home");
        delay(10);
      }

      if(counter_menu > 4)
      {
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("  Speed");
        lcd.setCursor(0,1);
        lcd.print(">  Home");
        delay(10);
      }
  
    last_counter_menu = counter_menu;
    }
  }



  if(menu_enter == 2)
  {
    if(counter_speed != last_counter_speed)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Speed: ");
      lcd.setCursor(6,0);
      lcd.print(Speed);
      delay(50);
      
    last_counter_speed = counter_speed;
    }
  }



//This is part 3 of the menu. The homing menu
  if(menu_enter == 3)
  { 
    if(homing)
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("     HOMING     ");
      lcd.setCursor(0,1);
      lcd.print("----------------"); 
      delay(200);
      //Create a while. If the end stop is not pressed, we keep rotating...
      while (!digitalRead(end_stop))
      {
        digitalWrite(Enable, LOW);        //Negative enabled
        digitalWrite(Direction, LOW);     //Low for Left 
        digitalWrite(Step,HIGH);
        delayMicroseconds(700);
        digitalWrite(Step,LOW);
        delayMicroseconds(700);        
      }
      Position_steps = 0;                 //Once we are home, we reset the position to 0
      digitalWrite(Enable, HIGH);         //Disable the step mootr driver
      homing=0;                           //Set the homing variable to 0 or deactivated
      menu_enter=0;                       //The menu position is again the first one
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("     Ready!     ");      //Print ready for 1 seconds
      delay(1000);
    }//end homing    
  }//end menu 3



  
  //We apply ranges for counters
  if(counter_menu > 8)
  {
    counter_menu=9;
  }
  if(counter_menu < 0)
  {
    counter_menu=0;
  }

  if(counter_speed > 9999)
  {
    counter_speed=9999;
  }
  if(counter_speed < 0)
  {
    counter_speed=0;
  }

  if(Speed > 9999)
  {
    Speed=9999;
  }
  if(Speed < 0)
  {
    Speed=0;
  }
  
}//end void






/*Interruption vector triggered by:
 -Data and Clock from encoder
 -Push buttons
 -Encoder push button
*/

ISR(PCINT0_vect){

  delay(4);


   if((PINB & B00001000) && Slide_left)  //Pin 11 was pushed? Left button?
  {
    Slide_left=false;
    delay(200);
  }

  if((PINB & B00010000) && Slide_right)  //Pin 12 was pushed? Right button?
  {
    Slide_right=false;
    delay(200);
  }

  

  if((PINB & B00001000) && !Slide_left)  //Pin 11 was pushed? Left button?
  {
    Slide_left=true;
    Slide_right=false;
    print_once = 1;
    delay(200);
  }

  if((PINB & B00010000) && !Slide_right)  //Pin 12 was pushed? Right button?
  {
    Slide_right=true;
    Slide_left=false;
    print_once = 1;    
    delay(200);
  }
 

  if((PINB & B00000100) && !rotary_push_state)  //Pin 10 was pushed?
  {
    Slide_left  = false;
    Slide_right = false;

    if(menu_enter == 2)
    {
      menu_enter = 0; //first menu;
      just_entered=1;
      delay(500);
    }

    if(menu_enter == 3)
    {
      menu_enter = 0; //first menu;
      just_entered=1;
      homing = 0;
      delay(500);
    }

    
    if(menu_enter == 1)
    {
      if(counter_menu < 4)
      {
        menu_enter = 2; //menu is speed select
        delay(500);
      }
  
      if(counter_menu > 4)
      {
        menu_enter = 3; //menu is homing
        homing = 1;
        delay(500);
      }
    }

    if(menu_enter == 0 && !just_entered)
    {
      menu_enter = 1; //first menu;
      delay(500);
    } 
    just_entered=0;
    rotary_push_state = true;    
    counter_menu ++;
    counter_speed = counter_speed + 0.5;    
  }
  

  if(!(PINB & B00000100) && rotary_push_state)  //Pin 10 was released?
  {
    rotary_push_state = false;    
  }



  if(menu_enter == 2)
  {
    clk_State =   (PINB & B00000001); //pin 8 state, clock pin? 
    dt_State  =   (PINB & B00000010); 
    if (clk_State != Last_State){     
       // If the data state is different to the clock state, that means the encoder is rotating clockwise
       if (dt_State != clk_State) { 
         counter_speed = counter_speed + 0.5;
       }
       else {
         counter_speed = counter_speed - 0.5;
       } 
     } 
     Last_State = clk_State; // Updates the previous state of the data with the current state   
     Speed =  counter_speed;  
  }


  if(menu_enter == 1)
  {
    clk_State =   (PINB & B00000001); //pin 8 state, clock pin? 
    dt_State  =   (PINB & B00000010); 
    if (clk_State != Last_State){     
       // If the data state is different to the clock state, that means the encoder is rotating clockwise
       if (dt_State != clk_State) { 
         counter_menu ++;
       }
       else {
         counter_menu --;
       } 
     } 
     Last_State = clk_State; // Updates the previous state of the data with the current state     
  }
}

Find a library for the display you gave (or write your own), then replace / modify all the existing calls to the LCD with the equivalent for your new library.

your code is typical. there are repeated groups of lcd calls to update the display. 52 of them

i prefer to create a more generic display function that is passed strings for each line of the display. sprintf () can be used to format the strings with multiple values and text. the code then calls display() with the strings. null strings can be passed as well

with this approach, just one function needs to be modified for different displays if they have different interfaces

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