Automatically switching of blinker with steering angle sensor

I have the following snippet of code for activating a blinker by using a virtual button displayed on a nextion display. I get the value 0 or 1 which is than written to br3s. HIGH means button has 1 value. If the vehicle has centered steering angle is zero. Now I activate blinke by pressing the button. If I steer at least by 10 degrees and return to center the blinker is switched off and the button state is overwritten to 0. This works fine for the first time but after I need to turn the steering angle above 10 degrees for activating the blinker. If not blinker button gets immediately reset to 0 again. What do I need to change?

 //routine for automated right blinker set and reset    
    if (br3s == HIGH && br3son == false){
     br3son = true;
     hazardon = false;
     digitalWrite(rightblinkerPin, HIGH); //switch on right blinker and
     digitalWrite(leftblinkerPin, LOW); //left blinker off
    } 
    if(br3son == true && delta_deg > 10 && turned_right == false)
    {
     turned_right = true;
     }
    if(delta_deg <= 10 && turned_right == true)
    {
     turned_right == false;
     turned_from_right_to_center = true;
    } 
    if (br3son == true && turned_from_right_to_center == true)
    {
     turned_from_right_to_center = false;
     digitalWrite(rightblinkerPin, LOW);//switch off right blinker
     bt8_1.setValue(0);
     br3son = false;
    }

The first thing to change is to post the complete sketch.
In 90% of all cases the bug that causes a different code-behaviour than wanted is outside the lines you think the bug is.

You are using variables in the posted code-snippet that get assigned values outside the presented code-snippet. delta_deg
It might be that other variables get values assigned outside the presented code-snippet.

How should anybody analyse your code-logic if you present only a part of your code?

Your code uses a lot of boolean flag-variables which where set true / false to make it work.
There is a different approach for programming such functionalities.
This approach is called state-machine.
state1: steering is centered checking for is blinker switched on?
if yes change to state2

state2: check if steering-angle is above 10 degrees?
if yes change to state3

state3: check if steering-angle is below 10 degrees?
if yes switch blinker off and change to state1

the state-machine-approach minimises the flag-variables to the nescessary minimum.
because in each state only that part of the code is executed that is relevant for this state

The total code has 1264 lines. Ok I will post it then.

Ok. I will only show the Procedures which handling the blinker actions.

 
void blinker()
{
  leftb.getValue(&gpio_3);
  rightb.getValue(&gpio_1);
  bt11_1.getValue(&bl3s);
  bt8_1.getValue(&br3s);

  if ( gpio_3 == LOW  && blinkerlefton == false) { 
    blinkerlefton = true;
    hazardon = false;
    digitalWrite(leftblinkerPin, HIGH);
    digitalWrite(rightblinkerPin, LOW);
  }
  if (gpio_3 == HIGH  && blinkerlefton == true) { 
    blinkerlefton = false;
    digitalWrite(leftblinkerPin, LOW);
  }
  if (( gpio_1 == LOW ) && blinkerrighton == false) {
    blinkerrighton = true;
    hazardon = false;
    digitalWrite(rightblinkerPin, HIGH);
    digitalWrite(leftblinkerPin, LOW);
  }
  if ((gpio_1 == HIGH ) && blinkerrighton == true) {
    blinkerrighton = false;
    digitalWrite(rightblinkerPin, LOW);
  }
//blinker activated by screen buttons 
  if(gpio_3 == HIGH && gpio_1 == HIGH){
  
  //routine for automated left blinker set and reset   
    if (bl3s == HIGH && bl3son == false){ 
     bl3son = true;
     hazardon = false;
     digitalWrite(leftblinkerPin, HIGH);//switch on left blinker and
     digitalWrite(rightblinkerPin, LOW);// right blinker off
    } 
    if(bl3son == true && delta_deg < -10 && turned_left == false)//if steering turned to left more than 10°
    {
     turned_left = true;
    } 
    if(delta_deg >= -10 && turned_left == true)//if steering returned back   to center
    {
     turned_left == false;
     turned_from_left_to_center = true;
    }  
    if (bl3son == true && turned_from_left_to_center == true)
    {
      turned_from_left_to_center = false;
      digitalWrite(leftblinkerPin, LOW);// switch off left blinker
      bt11_1.setValue(0);
      bl3son= false;
     }
     
  //routine for automated right blinker set and reset    
    if (br3s == HIGH && br3son == false){
     br3son = true;
     hazardon = false;
     digitalWrite(rightblinkerPin, HIGH); //switch on right blinker and
     digitalWrite(leftblinkerPin, LOW); //left blinker off
    } 
    if(br3son == true && delta_deg > 10 && turned_right == false)
    {
     turned_right = true;
     }
    if(delta_deg <= 10 && turned_right == true)
    {
     turned_right == false;
     turned_from_right_to_center = true;
    } 
    if (br3son == true && turned_from_right_to_center == true)
    {
     turned_from_right_to_center = false;
     digitalWrite(rightblinkerPin, LOW);//switch off right blinker
     bt8_1.setValue(0);
     br3son = false;
    }
  }
}
void hazardlights()
{
  int hazardState = analogRead(hazardswitchPin);
  bool hazardon;
  if (blinkerlefton == false && blinkerrighton == false && bl3son == false && br3son == false){  
    if ( hazardState > 5 && hazardon == false) {
      hazardon = true; 
      digitalWrite(rightblinkerPin, HIGH);
      digitalWrite(leftblinkerPin, HIGH);
     if( pId == 1){ 
      warn.setValue(0);//tell the display hazard lights off
     }
    }
  
    if ( hazardState <= 5 && hazardon == true) {
      hazardon = false;
      digitalWrite(rightblinkerPin, LOW);
      digitalWrite(leftblinkerPin, LOW);
     if( pId == 1){ 
      warn.setValue(1);//tell the display hazard lights on
     }
    }
   }
}
void emergencybrake()
{ int timerH, timerHold;
     // turn on hazard lights in case of emergency brake if not already hazard lights on
    if( velocitychange < -3.5 && emergencybrakeon == false){ 
     emergencybrakeon = true; 
     hazardon = false;
     timerHold = millis();
     digitalWrite(rightblinkerPin, HIGH);
     digitalWrite(leftblinkerPin, HIGH);
     warn.setValue(0);//tell the display hazard lights off
    }
    if ( emergencybrakeon == true){
     timerH = millis();
    }
    if (emergencybrakeon == true && (timerH - timerHold)>= 5000){
     emergencybrakeon = false;
     timerHold =timerH;
     digitalWrite(rightblinkerPin, LOW);
     digitalWrite(leftblinkerPin, LOW);
     warn.setValue(1);//tell the display hazard lights on
    }
}

Can you reassure that ALL variables used in these blinker-logic are only modified in the posted functions?

Will everybody be able to see when and how these functions are called?

I moved your topic to an appropriate forum category @marcel00.

In the future, please take some time to pick the forum category that best suits the subject of your topic. There is an "About the _____ category" topic at the top of each category that explains its purpose.

This is an important part of responsible forum usage, as explained in the "How to get the best out of this forum" guide. The guide contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

I can reassure that all variables used are only modified in the posted funktions.
the functions are called in the loop

void loop() {

 if(emergencybrakeon == false){
   hazardlights();
  }
  
  switchonoff = analogRead(keyswitchPin);//12 V are passed through key switch towards AI1 of Maxi Automation 
  electric_current_voltage_and_charge();
  if( battery_recovery == false)
   {
    recovery_timer = millis();
    delta_recovery = recovery_timer - recovery_timer_old;
    if ( delta_recovery >= 1800000)
    {
     battery_recovery = true;
    }
   }
    

  if ((switchonoff > 200 ) && initialized == false) { 
    //calibrate current sensor
  /* float mVi = 0.0;
    for (int i = 0; i<10; i++){
    mVi = mVi+ analogRead(vitotalPin);
    delay(100);
    }
    mVi = mVi / 10;
    mVitotal = (mVi / 1023.0) * 5000.0; 
    ACSoffset = mVitotal - i_tot * mVperAmp;
    Serial.println(ACSoffset);
    delay(500);*/
    if(battery_recovery == true){
     state_of_charge_estimation();
     battery_recovery = false;
    } 
    digitalWrite(currentlimiterPin, HIGH);//engage 200 ohm resistor for limiting current due to high capacity load
    delay(1000);
    digitalWrite(ssrswitchPin, HIGH);//turn on SSR and bridge 200 ohm resistor
    digitalWrite(currentlimiterPin, LOW);//disable 200 ohm resistor
    delay(500);
    digitalWrite(switchauxiliarysupplies5VPin, HIGH);
    delay(1000);
    digitalWrite(switchauxiliarysupplies12VPin, HIGH);//switch on auxiliary voltage supplies
    delay(100);
    if(plc_turned_off == true)
    {
     get_stored_values();
     plc_turned_off == false;
    }

    nexInit();//initialize Nextion display
    bme.begin();
    t_vold = t_v;
    delta_trip = 0; 
    initialized = true;
    turning_grip_signal_offset = analogRead(turning_grip_signalPin);
    // set turning grip signal to throttle input of controllers
    digitalWrite(manualthrottlePin, HIGH);
  }

  if ( initialized == true) {
    nexLoop(nex_listen_list);
    pageid.getValue(&pId);
    delay(5);
    if (pId == 1) 
    {    
     if (controller_activated == false)
      {
        digitalWrite(activationPin, HIGH); // motor controllers are activated by High signal
        digitalWrite(forwardPin, HIGH);
        delay(5);
        sendCommand("p4.pic=80");
        delay(5);
        sendCommand("p5.pic=79");
        delay(5);
        controller_activated = true;   
      }    
      btx_state_page1(); 
      autocruise(); 
      brake();
      lightonoff(); 
      blinker();
      emergencybrake();
      soc_and_range();
      energyversustrip();
      rearwheelsvelocity();
      //frontwheelvelocity();
      odometer();
      pressure_temperature_humidity(); 
      turning_angle();  
      setpoint_angular_velocities();
      honkonoff();  
    }
    if (pId == 2) {
      btx_state_page2();
    }
    /*if (pId == 3) {
      btx_state_page3();
    }*/
  }

If you wrote this code in stages, getting each stage to work then combining all the stages one at a time, you should know what you did to make this fault occur.

Now if you didn't and have written the code as one lump, then STOP.
Forget you main code for the while and write code just to do what you want to happen.

That is code that JUST reads the steering angle an the button and produces the turn indicator responses.

That way you can be assured that the bug is in this bit of code and not caused by the rest that we cannot see or want to read.

So start coding for thee steering angle, buttons and direction indicators.

Also a simple schematic of your hardware and link to data/spec of the turn angle sensor.

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

1 Like

there's a couple logic errors, but i'm not sure i understand what you're trying to do and can't say these fix your problem.

  • you ment turned_right = false;
  • you set turned_from_right_to_center = true; and then immediately check if it is true (it's always true
  • seems like there should be a greater difference in angle

presuambly you set a turn indicator (right or left), recognize that you're in a turn and turn off the blinker when the wheel is centered.

  • i would consider any < 10 degrees as centered and probably something > 30 as turned.
  • i would look at the absolute angle so that it works regardless of turning right/left
  • turn both indicators off, avoid the need to know if turning right/left

what about

enum { Idle, Blinking, Turning };
int state = Idle;

const int AngTurn = 20;
const int AngCntr = 10;

void blinke ()
{
    switch (state) {
    case Idle:
        if (br3s)  {
            state = Blinking;
            digitalWrite (leftblinkerPin, On);
            Serial.println ("  Blinking");
        }
        break;

    case Blinking:
        if (AngTurn < delta_deg)  {
            state = Turning;
            Serial.println ("  Turning");
        }
        break;

    case Turning:
        if (AngCntr > delta_deg)  {
            state = Idle;
            digitalWrite (rightblinkerPin, Off);
            digitalWrite (leftblinkerPin,  Off);
            Serial.println ("  Off");
        }
        break;
    }
}

The only places where I have found the variable

delta_deg

is inside function blinker().

I haven't found any value-assigning to this variable in the code that you have posted so far.

So if this variable

delta_deg

is nowhere assigned any value
how can you expect that your code works?

I am very sure that you assign variable

delta_deg

values anywhere else than in the lines of code that you have posted.

So don't you think it makes sense to post your complete sketch?
What will happen if you post your complete sketch?

Does this violate a non-disclosure-agreement?
Do you get a heavy headache from it?
Will your bankaccount become empty if you post your complete sketch?
Will you run out of datatransmission-volume for your internetconnection?

Well to state the obvious

in your code in line 3489 you have to assign variable

delta_deg

a negative value then everything will work.
(no just kidding)

The following code for function blinker works for my application. The step markers are set to false if the blinker for left or right is switched off in the last step. For example for left turn:

      bl3son = false; 
      turned_left = false;
      turned_from_left_to_center = false;

The angle sensor has got zero at the center and turns negative to the left and positive to the right up to +-25°. It is a AMS5600 above a oriented permanent magnet situated above the steering axis.

void blinker()
{
  leftb.getValue(&gpio_3);
  rightb.getValue(&gpio_1);
  bt11_1.getValue(&bl3s);
  bt8_1.getValue(&br3s);

  if ( gpio_3 == LOW  && blinkerlefton == false) { 
    blinkerlefton = true;
    hazardon = false;
    digitalWrite(leftblinkerPin, HIGH);
    digitalWrite(rightblinkerPin, LOW);
  }
  if (gpio_3 == HIGH  && blinkerlefton == true) { 
    blinkerlefton = false;
    digitalWrite(leftblinkerPin, LOW);
  }
  if (( gpio_1 == LOW ) && blinkerrighton == false) {
    blinkerrighton = true;
    hazardon = false;
    digitalWrite(rightblinkerPin, HIGH);
    digitalWrite(leftblinkerPin, LOW);
  }
  if ((gpio_1 == HIGH ) && blinkerrighton == true) {
    blinkerrighton = false;
    digitalWrite(rightblinkerPin, LOW);
  }
//blinker activated by screen buttons 
  if(gpio_3 == HIGH && gpio_1 == HIGH){
  
  //routine for automated left blinker set and reset   
    if (bl3s == HIGH && bl3son == false){ 
     bl3son = true;
     hazardon = false;
     digitalWrite(leftblinkerPin, HIGH);//switch on left blinker and
     digitalWrite(rightblinkerPin, LOW);// right blinker off
    } 
    if(bl3son == true && delta_deg < -10 && turned_left == false)//if steering turned to left more than 10°
    {
     turned_left = true;
    } 
    if(bl3son== true && delta_deg >= -10 && turned_left == true)//if steering returned back   to center
    {
     turned_from_left_to_center = true;
    }  
    if (bl3son == true && turned_from_left_to_center == true)
    {
      digitalWrite(leftblinkerPin, LOW);// switch off left blinker
      bt11_1.setValue(0);
      bl3son = false; 
      turned_left = false;
      turned_from_left_to_center = false;
     }
   //routine for automated right blinker set and reset     
   if (br3s == HIGH && br3son == false){ 
     br3son = true;
     hazardon = false;
     digitalWrite(rightblinkerPin, HIGH);//switch on left blinker and
     digitalWrite(leftblinkerPin, LOW);// right blinker off
    } 
    if(br3son == true && delta_deg > 10 && turned_right == false)//if steering turned to left more than 10°
    {
     turned_right = true;
    } 
    if(br3son== true && delta_deg <= 10 && turned_right == true)//if steering returned back   to center
    {
     turned_from_right_to_center = true;
    }  
    if (br3son == true && turned_from_right_to_center == true)
    {
      digitalWrite(rightblinkerPin, LOW);// switch off left blinker
      bt8_1.setValue(0);
      br3son = false; 
      turned_right = false;
      turned_from_right_to_center = false;
     }    
  }
}

explaining some details.
no complete sketch
no information if your problems are solved or not
just a short sentence

tips how to improve your posting style

Hi,
What are?

  leftb.getValue(&gpio_3);
  rightb.getValue(&gpio_1);
  bt11_1.getValue(&bl3s);
  bt8_1.getValue(&br3s);

Use pin variable names that describe the pin usage.
You do here;

    digitalWrite(leftblinkerPin, HIGH);
    digitalWrite(rightblinkerPin, LOW);

Please be consistent.
What is the "getValue()" function?

Did you actually write this code?

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

still ... the 2nd condition is always true if the 1st one is

Finally I changed the function blinker for being able to turn off the blinker if a blinker button was pressed on the display by mistake.
So let me describe the total function:
By pressing a dual state button which is available by Nextion software I will be able to switch on and off a blinker. If I switch on a blinker and I turn the steering axis to a certain degree the MCU realizes it and waits with turning off the blinker until the steering axis returns to center thus recognizes it by a steering angle entering below the prior mentioned threshold angle.
In addition to the dual state buttons I can use a mechanical switch as commonly used at a motorbike. The signals are sent to the Nextion display via gpio extension board and Nextion transfers the signals towards a MEGA 2560.
Here is the code

void blinker()
{
  leftb.getValue(&gpio_3);
  rightb.getValue(&gpio_1);
  bt11_1.getValue(&bl3s);
  bt8_1.getValue(&br3s);

  if ( gpio_3 == LOW  && blinkerlefton == false) { 
    blinkerlefton = true;
    hazardon = false;
    digitalWrite(leftblinkerPin, HIGH);
    digitalWrite(rightblinkerPin, LOW);
  }
  if (gpio_3 == HIGH  && blinkerlefton == true) { 
    blinkerlefton = false;
    digitalWrite(leftblinkerPin, LOW);
  }
  if (( gpio_1 == LOW ) && blinkerrighton == false) {
    blinkerrighton = true;
    hazardon = false;
    digitalWrite(rightblinkerPin, HIGH);
    digitalWrite(leftblinkerPin, LOW);
  }
  if ((gpio_1 == HIGH ) && blinkerrighton == true) {
    blinkerrighton = false;
    digitalWrite(rightblinkerPin, LOW);
  }
//blinker activated by screen buttons 
  if(gpio_3 == HIGH && gpio_1 == HIGH){
  //routine for automated left blinker set and reset   
    if (bl3s == HIGH && br3s == LOW && bl3son == false){ 
     bl3son = true;
     hazardon = false;
     digitalWrite(leftblinkerPin, HIGH);//switch on left blinker and
     digitalWrite(rightblinkerPin, LOW);// right blinker off
    } 
    if(br3s == LOW && bl3son == true && delta_deg < -10 && turned_left == false)//if steering turned to left more than 10°
    {
     turned_left = true;
    } 
    if(br3s == LOW && bl3son== true && delta_deg >= -10 && turned_left == true)//if steering returned back   to center
    {
     turned_from_left_to_center = true;
    }  
    if (((bl3s == LOW || br3s == HIGH) && bl3son == true)||( bl3son == true && turned_from_left_to_center == true))
    {
      digitalWrite(leftblinkerPin, LOW);// switch off left blinker
      bt11_1.setValue(0);
      bl3son = false; 
      turned_left = false;
      turned_from_left_to_center = false;
     }
   //routine for automated right blinker set and reset     
   if (br3s == HIGH && bl3s == LOW && br3son == false){ 
     br3son = true;
     hazardon = false;
     digitalWrite(rightblinkerPin, HIGH);//switch on left blinker and
     digitalWrite(leftblinkerPin, LOW);// right blinker off
    } 
    if(bl3s == LOW && br3son == true && delta_deg > 10 && turned_right == false)//if steering turned to left more than 10°
    {
     turned_right = true;
    } 
    if(bl3s == LOW && br3son== true && delta_deg <= 10 && turned_right == true)//if steering returned back   to center
    {
     turned_from_right_to_center = true;
    }  
    if (((br3s == LOW || bl3s == HIGH) && br3son == true)||( br3son == true && turned_from_right_to_center == true))
    {
      digitalWrite(rightblinkerPin, LOW);// switch off left blinker
      bt8_1.setValue(0);
      br3son = false; 
      turned_right = false;
      turned_from_right_to_center = false;
     }    
  }
}

still
no complete sketch
no variable declarations

So this code-snippet can be used for re-finding the logic that you have described.

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