Toyota Hybrid gear shifters (Prius, Auris, etc)

Topics concerning the Toyota and Lexus inverter drop in boards
Post Reply
xp677
Posts: 436
Joined: Sat Jul 27, 2019 10:53 am
Location: UK
Has thanked: 1 time
Been thanked: 13 times

Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by xp677 »

Most recent Toyota hybrids come with a dual hall-effect shifter, which feeds back x and y positions, similar to a computer joystick.

This can be tricky to get a gear shift reading from. I've created the circuit and code below to interface with this shifter. This works well on my project.

Note that this setup uses a digital input for the left/right position, I have chosen resistor values to trigger a high<>low transition on a 3.3V MCU (ATSAM3x8E) at the "70% to the right" point. This may vary with other setups, and definitely will for 5V MCUs. I recommend using an analog input for this if available (or even better, two inputs to give a comparison).

I do not have the wiring diagram/pinout for this shifter, I normally make a note of things like this but can't find anything. I recall it being pretty straightforward. I just have the attached drawings. I commoned the two GNDs, and the 5V/B+ inputs (I used 5V for everything).

This is based on the shifter from a 2017 Auris. Other shifters will work fine, they may need some tweaking to the code or resistor values.

In this code and diagrams, "shifter pos" is for up/down, and "shifter sel" is for left/right.

Code: Select all

//2017 Auris shifter
//Returns prnd_gear when shifter moves back to left hand side
//Regen available using the "B" position when in "Drive"
//This code is snippets only to insert into your project.
//park_notify is intended to trigger a light, beep, dash message, etc.
//E&OE. Use at your own risk.

//gears
#define GEAR_NONE 0
#define GEAR_PARK 1
#define GEAR_REVERSE 2
#define GEAR_NEUTRAL 3
#define GEAR_D_HIGH 4
#define GEAR_DRIVE 5
#define GEAR_SHIFTING 6

//shifter positions
#define SHIFT_L 0 //side to side on the shifter
#define SHIFT_R 1
#define SHIFT_REVERSE 270 //pass this point to be considered in gear
#define SHIFT_DRIVE 820 //pass this point to be considered in gear
#define SHIFT_NEUTRAL 534 //centre point
#define SHIFT_REGEN 878

#define SHIFT_MIN 120
#define SHIFT_MAX 1000
#define SHIFT_DELTA 50

#define SHIFT_HYST 40
#define REGEN_DEADZONE 80
#define PARK_DELAY 900

//pins
#define pin_shift_sel 41
#define pin_shift_pos1 A1
#define pin_shift_pos2 A2

bool shift_sel = 0; //side to side on the shifter
short shift_pos1 = 0, shift_pos2 = 0, shift_pos = 0, shiftcheck = 0; //forward and back on the shifter
byte nextgear = GEAR_NONE, prnd_gear = GEAR_PARK, shiftgood = 0;
short regen_level = 0;
unsigned long park_timer = 0;
bool park_timer_on = 1;
bool park_notify = 0; //show alert that park timer is reached

void setup()
{
pinMode(pin_shift_sel, INPUT);
pinMode(pin_shift_pos1, INPUT);
pinMode(pin_shift_pos2, INPUT);
}

void get_prnd()
{
//do something to not allow us to leave park if we aren't in DRIVE state
//  if (pcm_state != PCM_STATE_DRIVE) 
//  {
//    prnd_gear = GEAR_PARK;
//    return;
//  }

  shift_sel = digitalRead(pin_shift_sel);
  shift_pos1 = analogRead(pin_shift_pos1);
  shift_pos2 = analogRead(pin_shift_pos2);

  shiftcheck = shift_pos1 - shift_pos2;

  if ((shiftcheck >= -SHIFT_DELTA) && (shiftcheck <= SHIFT_DELTA) && (shift_pos1 >= SHIFT_MIN) && (shift_pos1 <= SHIFT_MAX) && (shift_pos2 >= SHIFT_MIN) && (shift_pos2 <= SHIFT_MAX)) //normal
  {
    shiftgood = 3;
    shift_pos = shift_pos1;
  }
  else if ((shift_pos1 >= SHIFT_MIN) && (shift_pos1 <= SHIFT_MAX)) //1 stil valid
  {
    shiftgood = 1;
    shift_pos = shift_pos1;
  }
  else if ((shift_pos2 >= SHIFT_MIN) && (shift_pos2 <= SHIFT_MAX)) //2 still valid
  {
    shiftgood = 2;
    shift_pos = shift_pos2;
  }
  else //cant use regen
  {
    shiftgood = 0;
    shift_pos = shift_pos1;
  }

  switch (shift_sel)
  {
    case SHIFT_L:
      switch (nextgear)
      {
        case GEAR_NONE: //regen mode
          if (prnd_gear == GEAR_DRIVE && shiftgood != 0)
          {
            regen_level = map(shift_pos, SHIFT_NEUTRAL + REGEN_DEADZONE, SHIFT_REGEN, 0, 255);
            if (regen_level < 0)regen_level = 0;
            if (regen_level > 255)regen_level = 255;
          }
          else regen_level = 0;
          break;

        case GEAR_REVERSE:
          prnd_gear = GEAR_REVERSE;
          nextgear = GEAR_NONE;
          break;

        case GEAR_DRIVE:
          prnd_gear = GEAR_DRIVE;
          nextgear = GEAR_NONE;
          break;

        case GEAR_NEUTRAL:
          prnd_gear = GEAR_NEUTRAL;
          nextgear = GEAR_NONE;
          break;

        case GEAR_PARK:
          prnd_gear = GEAR_PARK;
          nextgear = GEAR_NONE;
          break;

        default:
          break;
      }
      nextgear = GEAR_NONE;
      park_timer_on = 0;
      break;

    case SHIFT_R:
      regen_level = 0;
      if (nextgear == GEAR_DRIVE || nextgear == GEAR_REVERSE)break;

      else if (shift_pos >= SHIFT_DRIVE + SHIFT_HYST)
      {
        nextgear = GEAR_DRIVE;
        park_timer_on = 0;
        break;
      }
      else if (shift_pos <= SHIFT_REVERSE - SHIFT_HYST)
      {
        nextgear = GEAR_REVERSE;
        park_timer_on = 0;
        break;
      }
      else
      {
        if (park_timer_on == 0)
        {
          nextgear = GEAR_NEUTRAL;
          park_timer = millis();
          park_timer_on = 1;
          break;
        }
        else
        {
          if (millis() - park_timer > PARK_DELAY)
          {
            nextgear = GEAR_PARK;
            break;
          }
        }
      }
      break;

    default:
      break;
  }
  if (nextgear == GEAR_PARK && prnd_gear != GEAR_PARK)park_notify = 1; else park_notify = 0;
}


void diag_shifter()
{
  Serial.print("Shifter: \t1: "); Serial.print(shift_pos1); Serial.print("\t2: "); Serial.print(shift_pos2); Serial.print("\tSel: "); Serial.println(shift_sel ? "Right" : "Left");
  Serial.print("\t\tCheck: "); Serial.print(shiftcheck);
  Serial.print(" - ");
  switch (shiftgood)
  {
    case 3: Serial.print("Normal"); break;
    case 1: Serial.print("Limp-Pos1"); break;
    case 2: Serial.print("Limp-Pos2");  break;
    case 0: Serial.print("Bad"); break;
    default: Serial.print("ERROR"); break;
  }
  Serial.print("\nNext Gear: ");
  switch (nextgear)
  {
    case GEAR_PARK: Serial.print("Park"); break;
    case GEAR_REVERSE: Serial.print("Reverse"); break;
    case GEAR_NEUTRAL: Serial.print("Neutral"); break;
    case GEAR_DRIVE: Serial.print("Drive"); break;
    case GEAR_NONE: Serial.print("None");  break;
    default: Serial.print("Error"); break;
  }
  Serial.print("\nSelected Gear: ");
  switch (prnd_gear)
  {
    case GEAR_PARK: Serial.print("Park"); break;
    case GEAR_REVERSE: Serial.print("Reverse"); break;
    case GEAR_NEUTRAL: Serial.print("Neutral"); break;
    case GEAR_DRIVE: Serial.print("Drive"); break;
    case GEAR_NONE: Serial.print("None");  break;
    default: Serial.print("Error"); break;
  }

  Serial.print("\nRegen level: "); Serial.print(regen_level);

  Serial.print("\nPark Notify: "); Serial.print(park_notify ? "On" : "Off"); Serial.print("\tTimer: "); Serial.print(park_timer_on ? "On - " : "Off"); if (park_timer_on)Serial.println(millis() - park_timer);

  Serial.println();
}
Image

Image

Image

Image
damian.lo
Posts: 123
Joined: Sat Dec 22, 2018 12:46 pm
Location: Poland

Re: Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by damian.lo »

Hello,

Good, that someone else was also thinking about the same thing :)
I bought this, because was thinking, that it's multi-stabile-positions like normal car shifter and then I was really surprised, that it's hall+analog. Did You cut everything, what was unnecessary or You leave like it was?
I will put here pictures - maybe will be usefull for someone. Good is, that it's not expensive - mine costs about 5Euro :)
Can You maybe share hardware+software for this?
Attachments
IMG_2400.JPG
IMG_2399.JPG
IMG_2397.JPG
IMG_2396.JPG
IMG_2395.JPG
xp677
Posts: 436
Joined: Sat Jul 27, 2019 10:53 am
Location: UK
Has thanked: 1 time
Been thanked: 13 times

Re: Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by xp677 »

damian.lo wrote: Tue Apr 07, 2020 9:46 am Can You maybe share hardware+software for this?
HI, yes I shared the hardware and software in my first post above.

The only information which I don't have is the type of connector (I just removed mine and fitted my own) and the pinout for the sensors (can be discovered).

I didn't modify the shifter at all. Mine is the same as in your pictures.
damian.lo
Posts: 123
Joined: Sat Dec 22, 2018 12:46 pm
Location: Poland

Re: Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by damian.lo »

Thanks :)
I wrote post and then look above and of course hardware + code was :) Mine brain had probably some reset.
First I will try to run shifter like it is, but then probably I will cut it and make some smaller - like resized version of bottom.
You will have also normal gearbox with normal mechanical shifter?
xp677
Posts: 436
Joined: Sat Jul 27, 2019 10:53 am
Location: UK
Has thanked: 1 time
Been thanked: 13 times

Re: Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by xp677 »

I thought about cutting mine smaller, but I couldn't find a way to do it without damaging the mechanism.

I am running this shifter on a GS450h hybrid transmission. The shifter controls the motor direction, variable regen (towards the B position when in Drive), and parking pawl using a solenoid.
kalebludlow
Posts: 21
Joined: Mon Apr 13, 2020 5:17 am
Location: Geelong, Australia

Re: Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by kalebludlow »

This project has gotten my interest because the shifter was one part of my project that I was unsure of. I am currently in the planning stages of putting a Gen 3 Prius inverter with gen2 transaxle in a Mazda 323, and was just wanting to know how this shifter interfaces with the transmission, unless it's blatantly obvious from the prior posts in which case tell me I'm an idiot 😋
xp677
Posts: 436
Joined: Sat Jul 27, 2019 10:53 am
Location: UK
Has thanked: 1 time
Been thanked: 13 times

Re: Toyota Hybrid gear shifters (Prius, Auris, etc)

Post by xp677 »

This code just outputs the shifter selection via the "prnd_gear" variable, the possible outputs are listed at the top of the code, and can be changed to suit your requirements.

You would then use this variable within the programming for your inverter controller. If you are unsure of how to do this, I would suggest contacting the supplier of the controller for support.
Post Reply