Notifications
Clear all

2 Coniditions to be satisfied to move servo - unsuccessful  

  RSS

ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-07-28 12:11 pm  

This is a sketch for a servo to move the lever on an automatic transmission.For the most part my sketch runs and works as I intended. My problem is a) I only want my servo to move from reverse to park and must not shift to park from any other gear, b) may shift to reverse from park or neutral. (basically as the original shift lever works. the built in solenoids that operate the transmission will take care of this via the vehicles ETC. However, I don't what the servo to try and shift when it shouldn't, as this may cause the servo to burn out.

I attempted to use the if else statements below, my sketch returned with no errors, uploaded fine. But I can still shift to park from any gear.

Since I know the positions I want the servo to be moved to, I haven't utilized the analogue feed back from the servo. Would it be an option to analogue read from the AO pin and write the this value.

  if (digitalRead(buttonPark) == LOW && servoPosReverse == 68)
  {
    myServo.write(servoPosPark);
}
else
{
}
delay(sampleDelay);

 

This is my code:

//This Sketch was cretated by Ishwar Siriram for 8xPush Button Shifter for Auto Transmission
// Revision D
// This is a prototype not ready for field test. Saftey features not yet built in.
// To be verified by Professional prior to commissioning. This is serious business.

#include <Servo.h>

int servoPin = 9;
int sampleDelay = 50;

int buttonPark = 7;
int buttonReverse = 6;
int buttonNeutral = 5;
int buttonDrive = 4;
int button3rdGear = 3;
int button2ndGear = 2;

const int servoPosPark = 80;
const int servoPosReverse = 68;
const int servoPosNeutral = 61;
const int servoPosDrive = 54;
const int servoPos3rdGear = 47;
const int servoPos2ndGear = 40;

Servo myServo;

 

void setup() {
  // put your setup code here, to run once:

  pinMode(buttonPark, INPUT_PULLUP);
  pinMode(buttonReverse, INPUT_PULLUP);
  pinMode(buttonNeutral, INPUT_PULLUP);
  pinMode(buttonDrive, INPUT_PULLUP);
  pinMode(button3rdGear, INPUT_PULLUP);
  pinMode(button2ndGear, INPUT_PULLUP);

  myServo.attach(servoPin);
  myServo.write(servoPosPark);            //sets default start position to park

 

}

 

void loop() {
  // put your main code here, to run repeatedly:

  if (digitalRead(buttonPark) == LOW && servoPosReverse == 68)
  {
    myServo.write(servoPosPark);
}
else
{
}
delay(sampleDelay);

if (digitalRead(buttonReverse) == LOW)
{
  myServo.write(servoPosReverse);
}
else
{
}
delay(sampleDelay);

if (digitalRead(buttonNeutral) == LOW)
{
  myServo.write(servoPosNeutral);
}
else
{
}
delay(sampleDelay);

if (digitalRead(buttonDrive) == LOW)
{
  myServo.write(servoPosDrive);
}
else
{
}
delay(sampleDelay);

if (digitalRead(button3rdGear) == LOW)
{
  myServo.write(servoPos3rdGear);
}
else
{
}
delay(sampleDelay);

if (digitalRead(button2ndGear) == LOW)
{
  myServo.write(servoPos2ndGear);
}
else
{
}
delay(sampleDelay);

}

// end of code

ISH


Quote
Ruplicator
(@ruplicator)
Estimable Member
Joined: 8 months ago
Posts: 111
2020-07-29 8:59 pm  
Posted by: @ish

if (digitalRead(buttonPark) == LOW && servoPosReverse == 68)

Since you set servoPosReverse as a constant with a value of 68, the second half of your if statement will always be true and allow shifting to park from any gear.

You might define a variable bool lastGearRev = false;

Then only set this variable true when the reverse button has been pushed and false in all other gears.

You could then test with the statement if (digitalRead(parkButton) == LOW &&  lastGearRev)


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-07-31 6:05 am  

Thank you Ruplicator,

Much appreciated response. I have only been doing this a few weeks. Learning everyday. I will be sure to try this a revert back.

"Since you set servoPosReverse as a constant with a value of 68, the second half of your if statement will always be true and allow shifting to park from any gear." - I could see this in my sketch but had no idea how to fix it.

Please forgive the breaks between my replies / responses. The covid has hit us hard here in South Africa (as it has many places) so we only working on certain days.  I will generally reply on the days when I am not working.

ISH


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-08-19 9:38 am  

Good day,

 

I have tried the suggestion above by Ruplicator. It works well for the most part(I can shift through all gears forwards and backwards). However I ran into another problem.

Take note of my truth table:

The problem I now have is that when I am in drive I satisfy the conditions required for park. This allows shifting from drive to park and part to drive, which I don't want. I want to be able to only shift to the adjacent gear. (P,R,N,D.3rd,2nd or 2nd,3rd, D,N,R,P)

 

I am busy trying to introduce more bool variables to cater for what I am trying to do. (In doing this I will only use lasteGearState up to say Neutral but still switch to !lastGearState at drive so that I may shift back to neutral. Then I will use the next bool variable for the next gear, and so forth.)This is proving to be quiet challenging to say the least. A problem I encountered with this is that keeping track of the state of each bool is essential. However using the lastGearState=!lastGearState to switch the state of a bool variable and using && to add more conditions before shifting is made possible has left me going around in circles and back in the same situation as I was with only one bool variable.

I hope this makes sense. Please is you can help steer me in the right direction.

I haven't failed as yet, but if I am approaching this the wrong way I will be grateful to know that.

 

Kind Regards

ISH

 

 

 

 

 

ISH


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-08-20 8:07 am  

Good Morning,

 

This is what I came up with:

 

I would really appreciate some feedback to steer me in the right direction

 

//This Sketch was cretated by Ishwar Siriram for 8xPush Button Shifter for Auto Transmission
// Revision E (4/08/2020)
// Revision E_1 (15/08/2020)
// Revision E_2 (19/08/2020)- Intoduced more bool variables to avoid jump shifting due to repeated favourable conditions
// This is a prototype not ready for field test. Saftey features, partly built in 2/08/2020.
// 2nd bool variable is required to prevent being able to shift between 3rd and revervse as each provides the correct conditions for the other (4/08/2020).
// bool variables introduced to toggle so as to control when shifting is allowed.
// To be verified by Professional prior to commissioning. This is serious business.

#include <Servo.h>

int servoPin = 9;
int sampleDelay = 50;

int buttonPark = 7;
int buttonReverse = 6;
int buttonNeutral = 5;
int buttonDrive = 4;
int button3rdGear = 3;
int button2ndGear = 2;

const int servoPosPark = 80;
const int servoPosReverse = 68;
const int servoPosNeutral = 61;
const int servoPosDrive = 54;
const int servoPos3rdGear = 47;
const int servoPos2ndGear = 40;

bool lastGearState = false;
bool safetyGear1 = false;             //Drive Gear Safety
bool safetyGear3 = false;             //3rd Gear Safety
bool safetyGear2 = false;             //2nd Gear Safety

Servo myServo;

void setup() {
  // put your setup code here, to run once:

  pinMode(buttonPark, INPUT_PULLUP);
  pinMode(buttonReverse, INPUT_PULLUP);
  pinMode(buttonNeutral, INPUT_PULLUP);
  pinMode(buttonDrive, INPUT_PULLUP);
  pinMode(button3rdGear, INPUT_PULLUP);
  pinMode(button2ndGear, INPUT_PULLUP);

  myServo.attach(servoPin);
  myServo.write(servoPosPark);            //sets default start position to park

}

void loop() {
  // put your main code here, to run repeatedly:

  //for up & down shift
  if (digitalRead(buttonPark) == LOW && lastGearState) // may only shift from reverse into park : Read lastGearState==true
  {
    myServo.write(servoPosPark);
    lastGearState = !lastGearState;                   //lastGearState switched to false
  }
  else
  {
  }
  delay(sampleDelay);
  //for up & down shift
  if (digitalRead(buttonReverse) == LOW && lastGearState == false)
  {
    myServo.write(servoPosReverse);
    lastGearState = !lastGearState;                 //lastGearState switched to true
  }
  else
  {
  }
  delay(sampleDelay);
  //for up shift reverse to neutral only
  //Read lastGearState==true
  if (digitalRead(buttonNeutral) == LOW && lastGearState)
  {
    myServo.write(servoPosNeutral);
    lastGearState = !lastGearState;                //lastGearState switched to false
    safetyGear1 = !safetyGear1;                 //find default !safetyGear1 and switch to true
  }
    delay(sampleDelay);
  //for down shift drive to neutral
  //Read lastGearState==false
  if (digitalRead(buttonNeutral) == LOW && lastGearState == false && safetyGear1 == false)
  {
    myServo.write(servoPosNeutral);
    lastGearState = !lastGearState;                //lastGearState switched to true

  }
  else
  {
  }
  delay(sampleDelay);
  // upshift to drive
  if (digitalRead(buttonDrive) == LOW && safetyGear1)
  {
    myServo.write(servoPosDrive);
    safetyGear1 = !safetyGear1;                 //safetyGear1 switched to false
    safetyGear3 = !safetyGear3;                 //find default !safetyGear3 and switch to true
  }
    delay(sampleDelay);
  // downshift 3rd to drive only
  if (digitalRead(buttonDrive) == LOW && safetyGear3 == false && safetyGear1 == false)
  {
    myServo.write(servoPosDrive);
    safetyGear1 = !safetyGear1;                 //safetyGear1 switched to false
    safetyGear3 = !safetyGear3;                 //find default !safetyGear3 and switch to true
  }
  else
  {
  }
  delay(sampleDelay);

  //upshift 3rd Gear

  if (digitalRead(button3rdGear) == LOW && safetyGear3)
  {
    myServo.write(servoPos3rdGear);
    safetyGear3 = !safetyGear3;                 //safetyGear3 switched to false
    safetyGear2 = !safetyGear2;                 //find default !safetyGear2 and switch to true

  }
    delay(sampleDelay);
  //down shift to 3rd Gear only

  if (digitalRead(button3rdGear) == LOW && safetyGear3 == false && safetyGear2 == false)
  {
    myServo.write(servoPos3rdGear);
    safetyGear3 = !safetyGear3;                 //safetyGear3 switched to false
    safetyGear2 = !safetyGear2;                 //find default !safetyGear2 and switch to true

  }
  else
  {
  }
  delay(sampleDelay);

  // upshift to 2nd Gear
  if (digitalRead(button2ndGear) == LOW && safetyGear2)
  {
    myServo.write(servoPos2ndGear);
    safetyGear2 = !safetyGear2;                 //safetyGear3 switched to false

  }
  else
  {
  }
  delay(sampleDelay);

}

// End of Code :
// Ref Ishwar Siriram - Mech Eng Tech.

 

ISH


ReplyQuote
Ruplicator
(@ruplicator)
Estimable Member
Joined: 8 months ago
Posts: 111
2020-08-21 3:07 pm  

The new requirement is a little more than was originally requested. You may want to read up on using ARRAYS to store and manage the different valid states (your truth table) rather than continuing to expand if statements. 

You could assign numbers to each gear position, use that number to index into an array to determine the valid gears that can be moved to. It will simplify the logic, make the code more concise and easier to debug.

Also you may want to look at why you are adding this complexity. In a car with an automatic transmission you can actually shift to any rear from any other gear. The driver may not want to because of the damage it can cause but it still can be done. If you are driving and want to park the car, do you really want to press the the "N", then the "R" and the the "P" to just park the car? 

This post was modified 3 months ago by Ruplicator

ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-08-23 3:15 am  

Thank you for your response. Will be sure to read up on arrays, and check out your other recommendations.

The new requirement is a little more than was originally requested.

Yes, I was merely trying to build my way up, to what I wanted  to achieve, in small bites. Sorry if this was misleading.

"Also you may want to look at why you are adding this complexity."

Its the safety I am trying to achieve. I don't want to be able to shift from drive to reverse say why doing 100 down the highway for example. I think the transmission may already have this built into its logic via the ETC. however I don't  want the servo to try and shift if the transmission wont allow it, This will be a sure way to let the smoke out. And if the transmission doesn't have some sort of safety build-in then all the more reason.

 "If you are driving and want to park the car, do you really want to press the the "N", then the "R" and the the "P" to just park the car? "

You are quiet right, you would not necessarily want to do this. However, if you consider how a gear lever works in a automatic vehicle, you will have to shift from D,N,R, P, in that order - without a choice. Now that you mentioned it, in my case with the push button shifter, I can write my sketch to shift from drive directly to park as well, or from reverse to park for that matter.

Your points are well received thank you. Back to the drawing board.

Will report back soon.

 

 

ISH


ReplyQuote
frogandtoad
(@frogandtoad)
Honorable Member
Joined: 1 year ago
Posts: 540
2020-08-23 8:56 am  

@ish

I'm not sure if I understood you correctly, but it appears to me that you're having some trouble with implementing the transitions for your state machine?

If that is the case (and I may well be wrong), you could try implementing something like the following:

enum STATES {S_PARK, S_REVERSE, S_NEUTRAL, S_DRIVE, S_SECOND, S_THIRD};
int NOT_ALLOWED[] = {S_PARK + S_NEUTRAL, S_PARK + S_DRIVE, S_PARK + S_SECOND, S_PARK + S_THIRD,
                     /*add in the remaining dissallowed states*/};

// Function to control transmission from one state to another...
bool transitionAllowed(int currentState, int targetState) {
  
  for(int idx(0); idx < sizeof(*NOT_ALLOWED/NOT_ALLOWED[0]); idx++) {
    if(currentState + targetState == int(NOT_ALLOWED[idx])) {
      return false;
     }
   }

  return true;
 }

Cheers!


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-08-24 5:19 am  

@frogandtoad,

Thank you for your response.

Very interesting concept you raise. This may very well be what I need.

I am busy planning around with arrays as well, as suggest above by Ruplicator. This does help make things a lot simpler, but the am still not familiar with how to achieve the restrictions/disallowed states as you put it.

Also re-evaluating the complexity.

Very interesting concept you raise. This may very well be what I need.

I will feedback to let you all know how this turns out.

Thank you kindly for your time and consideration.

I have only been doing this for a few months...very interesting and exciting. I am really enjoying it.

Cheers!

ISH


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-09-15 6:08 am  

Hi Guys,

Thank you I sorted this out. Removed much of the complexity. Used another switch to supplement shifting into park and reverse. (This other switch resembles the brake light being pressed).

This works well on the bench, started fabrication on the actual parts that will be installed in the vehicle.

Regards

 

 

 

 

 

This post was modified 2 months ago by ISH

ISH


ReplyQuote
frogandtoad
(@frogandtoad)
Honorable Member
Joined: 1 year ago
Posts: 540
2020-09-15 8:38 am  

@ish

Posted by: @ish

Thank you I sorted this out. Removed much of the complexity. Used another switch to supplement shifting into park and reverse. (This other switch resembles the brake light being pressed).

Glad you got it working.

It's always good to post your final code, as it can help others with similar problems, and you might also recieve some suggestions of improvement too - Win win for everyone.

Cheers.


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-09-16 7:00 am  

@ frogandtoad,

I will. I am busy putting a package together with a video and a drawing. Will post in a few days.

I don't know yet if this will be the final "FINAL", but it will be that latest I have.

Should there be any changes I will definitely share.

 

Cheers

ISH


ReplyQuote
ISH
 ISH
(@ish)
Active Member
Joined: 5 months ago
Posts: 14
2020-09-21 12:53 pm  
Hi Guys,
This is my code up to now. All works well.

I have a new issue.
Is it possible to have a led that is built-into a momentary switch to stay on
after being pressed, and only turn off when another button has been pressed.

My shifter works fine(servo moves like it should)the switch on-board-led lights up when the
switch is pressed then goes off when released,as expected since I am using a momentary switch.
If I can get the led to stay on after pressing the a switch (and only switch off
until another switch is pressed) I can avoid having a separate
display to show what gear the vehicle is currently in.

I have switches with the letters on them - "D" for drive for example.

I did experiment with connecting a 330 ohm resistor to the switches on-board-leds
normally closed pins, so when the vehicle is running the leds light up (@ reduced brightness)
so you can see the switches. When a button is pressed that leds lights up full brightness.


I was thinking that I could use the remaining (available) Arduino pins to control the led,
keep it on as required.
(Maybe introduce a bool statement or two to achieve this.)


Thank you...some guidance will be appreciated.
DRIVE

 drive switch

 

 

 
Cheers




 

ISH


ReplyQuote