Getting startup output blips, seems code related

Hello all. I've been working on a motorcycle controller for some time and have it mostly worked out except for some blips I'm getting on startup. I've routed out a board that uses MOSFET's to control outputs and switches to ground for input. I've been reading a bit about startup blips on outputs and it's often suggested that it is because of the tristate pins floating high on turn on before they are assigned as outputs. This, however, does not seem to be the case because if I remove the 'if' statement for this output from the main code it no longer blips at startup, suggesting that the if statement itself is causing the problem. The only outputs I've noticed this on are 'horn' and 'starter,' though it could be happening on other outputs I'm not aware of.

The board is a Sainsmart Nano. I can post the schematic if anyone likes, but it is somewhat complicated and I adjusted it a little on the actual board.

Dose anyone have any insight into how to code the 'if' statement(s) to avoid it popping on during startup?

Specifically, here is the 'if' statement for the starter that I have been trying to work out (mainly because the starter blipping on is really not cool!):

//Starter Relay

//Energize starter relay

if ((digitalRead(StartSwitch)) == LOW)

digitalWrite( StarterRelay , HIGH );

else

digitalWrite( StarterRelay , LOW );

Bike_Program.abp.ino (9.21 KB)

At the beginning of setup() you have this line, before declaring any inputs or outputs.

digitalWrite(StarterRelay, HIGH);

when declaring inputs why is D3 declared as an output? Also it is best to avoid using pins 0 & 1 if possible because they are used for Serial communication it could effect your ability to upload sketches to your board.

// set input and pullup on D0-D3
 
   pinMode(0, INPUT);
     digitalWrite(0, HIGH);
   pinMode(1, INPUT);
     digitalWrite(1, HIGH);
   pinMode(2, INPUT);
     digitalWrite(2, HIGH);
   pinMode( 3 , OUTPUT);  //<<<<<<< ????????
     digitalWrite(3, HIGH);  //<<<<<<< ????????

It is clearer to use the INPUT_PULLUP command to set pullups. And you made those nice variable names for your pins why not use them?

pinMode(NeutralKick, INPUT_PULLUP); // Like This

it's not in your sketch but
if ((digitalRead(StartSwitch)) == LOW) has an extra ) after StartSwitch and no { or } either.

  if ((digitalRead(StartSwitch) == LOW)
{
     
      digitalWrite( StarterRelay , HIGH );

    else

      digitalWrite( StarterRelay , LOW );
}

The blips are indeed probably because of the I/O floating on startup. Use a pull up or pull down (depending on which state you want as a default). It can be that the compiler compiles the sketch really different when the if is in it or not. Maybe setting up the I/O happens quicker etc. So a pull up / down resistor is a really good idea to have on a MOSFET.

Btw:

digitalWrite( StarterRelay , !digitalRead(StartSwitch) );

Does the same as the hole if else :smiley:

Thanks so much for the replies. The code was a little sloppy from me trying to work this problem before (e.g. the digitalwrite before the output was declared was something someone had suggested to try). I've cleaned up and reposted the most recent version here.

Although it probably would make the most sense to try a pulldown resistor at the outputs, it is far from easy to do at this point. The board the arduino lives on was routed onto copper clad, and the layout was super tight. The custom made aluminum enclosure just barely fits under the gas tank (took me about 6 versions to get that right even), and the copper clad just barely fits in it. So putting pull down resistors in would require new layout, new board, new enclosure, etc etc. I tried to work out all the bugs on breadboards before I did final layout and what not, but it looks like I missed this one. So, thats the long story of why I'm trying to work this out in code rather than just putting a resistor on the output pins.

I am, however, slightly skeptical that it's outputs floating as inputs initially because the problem goes away when I remove the StarterRelay code in the loop (which I changed based on the last reply). Specifically, all other things being the same if I have this in the loop:

//Starter Relay
  
    //Energize starter relay 

  digitalWrite( StarterRelay , !digitalRead(StartSwitch) );

the starter blips on when the arduino starts. However, if I just remove the line:

digitalWrite( StarterRelay , !digitalRead(StartSwitch) );

the starter no longer blips at startup, and the starter switch no longer works of course :(.

How could this be if it's a problem of inputs floating at startup? Would they not float the same with or without that statement in the loop? Septillion, you suggested that maybe it compiles more quickly without the if statement. Is there, perhaps, a way of speeding up this code to achieve the same effect? For example, I've read about using port manipulation to move faster than digitalWrite/Read's, but I don't know much about it.

Bike_Program.abp.ino (8.97 KB)

excellrec:
How could this be if it's a problem of inputs floating at startup?

Because like I said, the compiler might change the startup bit because of the change in code. It might detect the output is now steady in one state (because you removed the loop part) and changes the setup because of that. Only way to tell is to disassamble the hex and look at the assembly. Google to find out how.

But I personally would not want to rely on the micro being fast enough the don't float when it's something as critical as the starter relay. Certainly when there is a bootloader on the board that can hold program execution... Then just build a version 7/8/9 to get it right, how annoying that might be (or bodge the circuit if it's a one of).

Thank you for your assistance Septillion. I tried as you suggested and temporarily attached pull down resistors from 1-10k on the output pin for starter relay. Unfortunately, the starter keeps blipping on when the arduino is powered up. I suppose, at this point it could be due to something with the arduino interacting with the circuit on power up, but I can't really fathom how. I am investigating changes in Hex code following inclusion and exclusion of the starter relay 'if' statement. Probing a little difficult to decipher all that hex but I'm working on it :confused:. If anyone has any other suggestions it would be greatly appreciated!

I've attached a photo of my schematic. It's actually not as complicated as I remember, just the same little circuit for each of the inputs and outputs then some power stuff to go from 12v to 5v at the arduino, yet retaining 12v switching at the mosfets using a voltage divider via the two resistors.

I took a look at the whole code. For starter, press ctrl+t for fun. The code indentation can use some help.

Second, making nice const variables to name the pins is great. But then not using them when you set up the I/O not so much. Makes it hard to look for it. When I want to know what happens with the starter relay, I now have to look at StarterRelay AND I have to look for 10 :confused:

And it might be a good idea to start making functions. It's now just one big pile of code. And please stop using

a

freaking

blank

line

every

time.... It's just like paragraphs, use them when making a block of code makes sens.

Okay, back to the problem. Something I notice, at line 60 you do digitalWrite(StarterRelay, HIGH), on line 107 you do digitalWrite(10, LOW) (see what I mean by looking for two things...). So what is it!? Does the output needs to be HIGH or LOW to be off?

If it needs to be LOW => use a pull down resistor and do

pinMode(StarterRelay, OUTPUT);
//digitalWrite(StarterRelay, LOW); //not needed, default is LOW

If it needs to be HIGH on start up => use a pull up resistor and do

digitalWrite(StarterRelay, HIGH); //doing this first ensures the pin is HIGH when it becomes a output
pinMode(StarterRelay, OUTPUT);

Hmm, it's bizarre that the digitalWrite(10, LOW) is in the code uploaded, I could have sworn I did that after I uploaded that file. Anyways. It does need to stay low until it goes high. That was just another thing I was using to troubleshoot the problem to see what the heck is going on, it's not something that would be a part of the running code. I've tried pulling this pin up, down... the results are as expected, you pull it up and the starter runs all the time (as it should), pull it down and the starter blips on during boot-up then behaves properly. Sigh.

I feel like I've got to figure out why it doesn't do it with the if statement removed, that verifies that certain code can work, it's just a matter of figuring out what it is...

Yeah, investigation is needed. Because it should not happen. I would start by tiding up the code.

  • Remove all useless blank lines
  • Fix indentation (ctrl+t in the IDE)
  • Don't use pin numbers anywhere in the code except when you name a pin.
  • Check all comments. A comment should explain what happens, not just tell what you do. So not "if (BrakeState == LOW) //See if the brake state is high", yeah, you don't do that... So tell us you want to check if it's pressed, not if it's high or low, we can see that from the statement alone. And "//Right turn signal (A2)" You give it a name so you don't have to deal with the pin, don't mention it then.
  • Break the code up into smaller pieces and put the smaller pieces into functions. This also saves code for things you do twice like the turn signals...

When you did that it's a whole lot easier to debug :slight_smile: