how can i send 2 variables to a motor + encoder via h bridge

Hi,

I am currently undertaking a project where i need to store variables for time and variables from a incremental encoder connected to the shaft of a DC motor driven via a h bridge l298n.

i have so far managed to store the variables.. i.e time and displacement for four different points.

the problem i now have is for the "playback" subroutine.

I will have four buttons one for each point and when pressed they will need to rotate the motor to the required preset encoder position and stop. However the duration taken to preform this will be the 'time' variable which is pre stored.

----->>>>>> Motor rotation = time variable + encoder position variable

how can i do this?? :~

However the duration taken to preform this will be the 'time' variable which is pre stored.

If that is really what you want then I think you are in trouble. It means you will have to calculate the distance the motor needs to go and to set the speed of the motor so that it moves that distance in the time allotted. Speed control of a DC motor is not very accurate and is highly dependent on a lot of factors including the load.

To do this sort of problem you need to use a stepping motor where you can accurately control the speed and use the rotary encoder to measure the distance moved.

Or is the time to move to the position not important, if so forget that and run the motor until it reaches the required position.

the device is to be used to control the focus on a dslr camera when recording video...

therefore there will not be much load on the motor as the max load is 1nm, determined from testing.

as i will be using it to record video both of the variables are important.

So I think you will struggle to get this work as you don't have a calibration between the PWM value you need to feed to the motor and the speed that the motor moves.

i have pwm from the encoder attached to the motor therefore can stop the motor at a particular value..

however i do not now how i can link the time varaible with this.

Speed = distance / time

If you know the distance to move, call it d You know how long you have to do the move, call it t then you need to move at a speed of d / t So you set your PWM to give you this speed.

here is the code i have created to solve the problem...

however the playback function doesnt seem to function as required.. as well as this when in the playback subroutine the lcd clears however the pots are still displayed from the enter data 1 subroutine.. how can i remove them.. i thought lcd clear would do this :~

/*

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 13
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 * Pot to Analog 0
 * enable pin 8
 * motor 1 pin 9
 * motor 2 pin 10
 */

#include                           // include the library code:

LiquidCrystal lcd(12, 11, 5, 13, 3, 2);             // initialize the library with the numbers of the interface pins
  
        int sensorPin = A1;                         // select the input pin for the potentiometer for time
        int sensorValue = 0;                        // variable to store the value coming from the sensor

  const int motor1Pin = 9;                          // H-bridge leg 1 (pin 9, 1A)
  const int motor2Pin = 10;                         // H-bridge leg 2 (pin 10, 2A)
  const int enablePin =8;                           // H-bridge enable pin 8
  const int PotPin = A0;                            // input pin for the potentiometer for speed/direction
  
        int x = 10;
        int zero_speed;
        int Reverse;
        int Forward;
        int sensorValue2 = 1;                       // variable to store the value coming from the sensor
  
        int value = analogRead(PotPin);
        int speed = abs(value - 512)/2 ;            // 0..1023 -> -512.0..+512 -> 512..0..512 -> 256..0..256
        int direction = value < 512;                // or "value > 512" to reverse the action of the pot

        char flag;
        
        int count1 = 0;
        int time_1;
        int speed1;
        int drive1;
        
 //*************************************************************************************

 void enter_point_a()                               // Subroutime "enter_point_a"
{
  
  
  lcd.clear();                                      // Clear Screen 
  lcd.setCursor(1, 0);                              // set the cursor to column 0, line 0
  lcd.print("Enter Data for");                      // Print "Enter Data for"
  lcd.setCursor(4, 1);                              // set the cursor to column 4, line 1
  lcd.print("Point A");                             // Print "Point A"
  delay(3000);                                      // Delay
  lcd.clear();                                      // Clear Screen
  
  enter_data_1();
}
 //*************************************************************************************
void enter_data_1()                                   // Subroutime "enter_data_1"                 
{  
  digitalWrite(7, HIGH);                            // set the LED on
  
  lcd.setCursor(0, 0);                              // set the cursor to column 0, line 0 
  lcd.print("Time");                                // Print "Time"
  lcd.setCursor(4, 0);                              // set the cursor to column 4, line 0
  lcd.print(":");                                   // Print ":"
  lcd.setCursor(8, 0);                              // set the cursor to column 8, line 0
  lcd.print(".");                                   // Print ":"
  lcd.setCursor(12, 0);                             // set the cursor to column 12, line 0
  lcd.print("Min");                                 // Print "Min"
  lcd.setCursor(0, 1);                              // set the cursor to column 0, line 1
  lcd.print("Rotation");                            // Print "Rotation"
  lcd.setCursor(8,1);                               // set the cursor to column 8, line 0
  lcd.print(":");                                   //Print ":"
  

  Pot_Speed_Time_1();                                 // go to sub routine "Pot_Speed_Time"

  digitalWrite(7, LOW);                             // set the LED off
}

 //*************************************************************************************
   
  void Pot_Speed_Time_1()
  {
  
    while(1)
    {
    digitalWrite (enablePin, HIGH);
    int retval = analogRead(value);
      
      if (retval < 510)
        {
        Reverse = map(retval, 0, 510, 255, 0);
        analogWrite (motor1Pin, Reverse);
        count_pulse_neg_1();
        }
        else if(retval > 518)
          {
          Forward = map(retval, 518, 1023, 0, 255);
          analogWrite (motor2Pin, Forward);
          count_pulse_pos_1();
          }
        else
          {
          analogWrite (motor1Pin, 0);
          analogWrite (motor2Pin, 0);
          }

  int val = analogRead(sensorPin);            // read value from pot at sensorPin
      time_1 = map(val, 0, 1023, 0, 600);     // map function

    lcd.setCursor(6,0);                       // set the cursor to column 0, line 1
    lcd.print(time_1/60);                     // Print "val/100"  

    lcd.setCursor(8, 0);                      // set the cursor to column 2, line 1
    lcd.print(":");                           // Print ":"
  
    lcd.setCursor(9,0);                       // set the cursor to column 3, line 1
    lcd.print(time_1/10);                     // Print "val/10"
       
      
  if (digitalRead(1) == HIGH)                 // if button is pressed 
    {                                         // then go to sub routine
    lcd.clear();                              // Clear Screen
    playback();                               // go to sub routine "enter_point_b"
    }
   }
 }

//*****************************************************************************************  

void count_pulse_pos_1()
{
  if((digitalRead(4) == HIGH) && (flag == 0))
    {
    count1 ++ ;
    flag = 1;
    }
   if(digitalRead(4) == LOW)
      {
      flag = 0;
      }  
      lcd.setCursor(10,1);    
      lcd.print((count1/1.4));

}

//***********************************************************************  

void count_pulse_neg_1()

{
  if((digitalRead(4) == HIGH) && (flag == 0))
    {
    count1 --;
    flag = 1;
    }
   if(digitalRead(4) == LOW)
      {
      flag = 0;
      }  
      lcd.setCursor(10,1);    
      lcd.print((count1/1.4));
}

//***********************************************************************

void zero_motor()
{
 zero_speed= map(x, 0,50,0, 255);
 lcd.setCursor(1,0);    
 lcd.print("Configuration"); 
 lcd.setCursor(2,1);    
 lcd.print("In Progress"); 
  while(1)
 {

   
     digitalWrite(enablePin, HIGH);
   
     analogWrite (motor1Pin, zero_speed);  
     digitalWrite(motor2Pin, LOW); 


  if(digitalRead(6) == HIGH)
    {
     digitalWrite(motor1Pin, LOW);  
     digitalWrite(motor2Pin, LOW); 
     lcd.clear();
     return; 
    }  
  } 
lcd.clear();
} 

 //*************************************************************************************

 void playback()
{

lcd.setCursor (4,0);
lcd.print("PLAYBACK"); 
 if (analogRead (16), HIGH);
   {
    lcd.setCursor (4,0);
    lcd.print("POINT A");
    speed1 = count1/time_1;
    digitalWrite (enablePin, HIGH);
    int val = analogRead(sensorPin);                    // read value from pot at sensorPin
    drive1 = map(speed1, 0, 500, 0, 225);     
    
    if (count1 >(0));
      {
      digitalWrite(motor1Pin, drive1); 
      digitalWrite(motor2Pin, LOW);
      }
    if (count1 <(0));
      {
      digitalWrite(motor1Pin, LOW); 
      digitalWrite(motor2Pin, drive1);
      }
    if (count1 == count1);
      {
      digitalWrite(motor1Pin, LOW);
      digitalWrite(motor2Pin, LOW);
      }
   }
 }
//*********************************************************************** 

void setup() 
{
lcd.begin(16, 2);       // set up the LCD's number of columns and rows: 

zero_motor();
enter_point_a();        // go to sub routine "enter_point_a"
}

void loop()
{
playback();             // go to sub routine "enter_point_a_data"  
}

however the playback function doesnt seem to function as required

So how does it function and how is this different from what you expect?

well when the subroutine is in playback...

and analog Pin 16 = high

the motor does not rotate at all and stands still :~

(this is when data is entered in enter data 1 subroutine)

any idea why the pots are displayed on the lcd when in the playback subroutine ??

the lcd doesnt display POINT A either..

You have:- if (analogRead (16), HIGH); I don't think you mean that, the six analogue inputs are from 0 to 5, referring to it as 16 is what you do when dealing with digital inputs on those pins.

There is no LCD clear function at the start of playback is that what you want. I have found that the LCDs I have tested don't actually work as expected, there is a gap between position 8 and 9 of 8 characters so I end up keeping track of what I write to it and using the set cursor to pull it back to where it needs to go. Try a simple sketch just to test out the functionality of your display.

i have dealt with the issue of the pot values being displayed in the playback subroutine... a while(1) was missing...

however i am using switches connected to the analog pins as i have run out of digital inputs.. is this the correct way to use them??

 if (analogRead (16), HIGH);

however i am using switches connected to the analog pins as i have run out of digital inputs.. is this the correct way to use them??

No, just use "digitalRead(16)", but never, ever put a semicolon on an "if"

i have amended the code... however the playback subroutine doesnt seem to read the pin 16 as it does not display "point A", when the switch is pressed.

/*

  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 13
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)
 * Pot to Analog 0
 * enable pin 8
 * motor 1 pin 9
 * motor 2 pin 10
 */

#include                           // include the library code:

LiquidCrystal lcd(12, 11, 5, 13, 3, 2);             // initialize the library with the numbers of the interface pins
  
        int sensorPin = A1;                         // select the input pin for the potentiometer for time
        int sensorValue = 0;                        // variable to store the value coming from the sensor

  const int motor1Pin = 9;                          // H-bridge leg 1 (pin 9, 1A)
  const int motor2Pin = 10;                         // H-bridge leg 2 (pin 10, 2A)
  const int enablePin =8;                           // H-bridge enable pin 8
  const int PotPin = A0;                            // input pin for the potentiometer for speed/direction
  
        int x = 10;
        int zero_speed;
        int Reverse;
        int Forward;
        int sensorValue2 = 1;                       // variable to store the value coming from the sensor
  
        int value = analogRead(PotPin);
        int speed = abs(value - 512)/2 ;            // 0..1023 -> -512.0..+512 -> 512..0..512 -> 256..0..256
        int direction = value < 512;                // or "value > 512" to reverse the action of the pot

        char flag;
        
        int count1 = 0;
        int time_1;
        int speed1;
        int drive1;
        
 //*************************************************************************************

 void enter_point_a()                               // Subroutime "enter_point_a"
{
  
  
  lcd.clear();                                      // Clear Screen 
  lcd.setCursor(1, 0);                              // set the cursor to column 0, line 0
  lcd.print("Enter Data for");                      // Print "Enter Data for"
  lcd.setCursor(4, 1);                              // set the cursor to column 4, line 1
  lcd.print("Point A");                             // Print "Point A"
  delay(3000);                                      // Delay
  lcd.clear();                                      // Clear Screen
  
  enter_data_1();
}
 //*************************************************************************************
void enter_data_1()                                   // Subroutime "enter_data_1"                 
{  
  digitalWrite(7, HIGH);                            // set the LED on
  
  lcd.setCursor(0, 0);                              // set the cursor to column 0, line 0 
  lcd.print("Time");                                // Print "Time"
  lcd.setCursor(4, 0);                              // set the cursor to column 4, line 0
  lcd.print(":");                                   // Print ":"
  lcd.setCursor(8, 0);                              // set the cursor to column 8, line 0
  lcd.print(".");                                   // Print ":"
  lcd.setCursor(12, 0);                             // set the cursor to column 12, line 0
  lcd.print("Min");                                 // Print "Min"
  lcd.setCursor(0, 1);                              // set the cursor to column 0, line 1
  lcd.print("Rotation");                            // Print "Rotation"
  lcd.setCursor(8,1);                               // set the cursor to column 8, line 0
  lcd.print(":");                                   //Print ":"
  

  Pot_Speed_Time_1();                                 // go to sub routine "Pot_Speed_Time"

  digitalWrite(7, LOW);                             // set the LED off
}

 //*************************************************************************************
   
  void Pot_Speed_Time_1()
  {
  
    while(1)
    {
    digitalWrite (enablePin, HIGH);
    int retval = analogRead(value);
      
      if (retval < 510)
        {
        Reverse = map(retval, 0, 510, 255, 0);
        analogWrite (motor1Pin, Reverse);
        count_pulse_neg_1();
        }
        else if(retval > 518)
          {
          Forward = map(retval, 518, 1023, 0, 255);
          analogWrite (motor2Pin, Forward);
          count_pulse_pos_1();
          }
        else
          {
          analogWrite (motor1Pin, 0);
          analogWrite (motor2Pin, 0);
          }

  int val = analogRead(sensorPin);            // read value from pot at sensorPin
      time_1 = map(val, 0, 1023, 0, 600);     // map function

    lcd.setCursor(6,0);                       // set the cursor to column 0, line 1
    lcd.print(time_1/60);                     // Print "val/100"  

    lcd.setCursor(8, 0);                      // set the cursor to column 2, line 1
    lcd.print(":");                           // Print ":"
  
    lcd.setCursor(9,0);                       // set the cursor to column 3, line 1
    lcd.print(time_1/10);                     // Print "val/10"
       
      
  if (digitalRead(1) == HIGH)                 // if button is pressed 
    {                                         // then go to sub routine
    lcd.clear();                              // Clear Screen
    playback();                               // go to sub routine "enter_point_b"
    }
   }
 }

//*****************************************************************************************  

void count_pulse_pos_1()
{
  if((digitalRead(4) == HIGH) && (flag == 0))
    {
    count1 ++ ;
    flag = 1;
    }
   if(digitalRead(4) == LOW)
      {
      flag = 0;
      }  
      lcd.setCursor(10,1);    
      lcd.print((count1/1.4));

}

//***********************************************************************  

void count_pulse_neg_1()

{
  if((digitalRead(4) == HIGH) && (flag == 0))
    {
    count1 --;
    flag = 1;
    }
   if(digitalRead(4) == LOW)
      {
      flag = 0;
      }  
      lcd.setCursor(10,1);    
      lcd.print((count1/1.4));
}

//***********************************************************************

void zero_motor()
{
 zero_speed= map(x, 0,50,0, 255);
 lcd.setCursor(1,0);    
 lcd.print("Configuration"); 
 lcd.setCursor(2,1);    
 lcd.print("In Progress"); 
  while(1)
 {

   
     digitalWrite(enablePin, HIGH);
   
     analogWrite (motor1Pin, zero_speed);  
     digitalWrite(motor2Pin, LOW); 


  if(digitalRead(6) == HIGH)
    {
     digitalWrite(motor1Pin, LOW);  
     digitalWrite(motor2Pin, LOW); 
     lcd.clear();
     return; 
    }  
  } 
lcd.clear();
} 

 //*************************************************************************************

 void playback()
{

lcd.setCursor (4,0);
lcd.print("PLAYBACK"); 

 while(1);

 if (digitalRead(16), HIGH)
   {
    lcd.setCursor (4,0);
    lcd.print("POINT A");
    speed1 = count1/time_1;
    digitalWrite (enablePin, HIGH);
    int val = analogRead(sensorPin);                    // read value from pot at sensorPin
    drive1 = map(speed1, 0, 500, 0, 225);     
    
    if (count1 >(0))
      {
      digitalWrite(motor1Pin, drive1); 
      digitalWrite(motor2Pin, LOW);
      }
    if (count1 <(0))
      {
      digitalWrite(motor1Pin, LOW); 
      digitalWrite(motor2Pin, drive1);
      }
    if (count1 == count1)
      {
      digitalWrite(motor1Pin, LOW);
      digitalWrite(motor2Pin, LOW);
      }
   }
 }
//*********************************************************************** 

void setup() 
{
lcd.begin(16, 2);       // set up the LCD's number of columns and rows: 

zero_motor();
enter_point_a();        // go to sub routine "enter_point_a"
}

void loop()
{
playback();             // go to sub routine "enter_point_a_data"  
}

It never gets past:- while(1); This just loops forever.

k.. having this while one helped to stop the lcd display of displaying the pot values from the previous subroutine...

can you please help me to amend the subroutine...

thanks for helping...

Use a delay() instead of while(1);

The former allows you to specify a period of time to delay before continuing on.

the latter effectively delays forever.

the delay() doesnt work as it only carrys out the function, once finished the lcd displays Playback as required but with pot values from the previous subroutine..

even now iv ammended the code..

 void playback()
{
lcd.clear();
lcd.setCursor (4,0);
lcd.print("PLAYBACK");

having this while one helped to stop the lcd display of displaying the pot values from the previous subroutine..

Yes but all it does is to freeze the computer, that is no help at all.

i understand completely what you mean.. the while(1) is not an appropriate function here.. however i am :~ about what to do instead...