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
}
}