Nano works fine over USB but locks up on external power

Ive written a sketch which as far as I can tell works fine. The arduino picks up values from an RC receiver and controls throttle and steering relays for a big electric toy truck.

I power it from USB on my laptop and monitor the serial output for a 'long' period of time. I mean like, 20minutes. Ultimately it needs to be powered from a battery (car/motorbike type 12v). Im using an LM317 to drop the voltage down to ~8v on the Vin pin, and this gives me a solid +5v on the arduino 5v pin which Im then using to power a few relays and an RC receiver.
When I use the battery as a power source after some time, maybe 5-10 minutes, the relays all switch on and the Tx light stops blinking which suggests to me the arduino has locked up.

I dont know where to look for the issue. Should I remove all serial outputs when theyre not in use? Otherwise the only difference is power. Is 8v cooking the arduino and causing it to stop functioning? The only change is that I remove the USB and use the Vin pin. The relays and receiver are still powered by the 5v pin.

Sketch below but I dont know if its of any use?

Thanks

#include <EnableInterrupt.h>

#define SERIAL_PORT_SPEED 57600
#define RC_NUM_CHANNELS  2

#define RC_CH1  0
#define RC_CH2  1

#define RC_CH1_INPUT  A0
#define RC_CH2_INPUT  A1

#define THROTTLE_OUTPUT_1    2
#define THROTTLE_OUTPUT_2    3
#define STEERING_OUTPUT_1    4
#define STEERING_OUTPUT_2    5
#define STEERING_DIRECTION_1 6
#define STEERING_DIRECTION_2 7

//throttle input 900-2036
//steering input 950-2050

#define THROTTLE_LEVEL     1750
#define THROTTLE_DEADBAND  100

#define STEERING_START     975   //left
#define STEERING_STOP      2025  //right
#define STEERING_DRIVETIME 7000
#define STEERING_DEADBAND  7
int     STEERING_RANGE     = STEERING_STOP - STEERING_START;
int     STEERING_CALC_POS  = STEERING_STOP - (STEERING_RANGE / 2);
float   STEERING_DELAY     = STEERING_DRIVETIME / STEERING_RANGE;

uint16_t rc_values[RC_NUM_CHANNELS];
uint32_t rc_start[RC_NUM_CHANNELS];
volatile uint16_t rc_shared[RC_NUM_CHANNELS];

int refresh = 200;
int prevRefresh = 0;

void rc_read_values() {
  noInterrupts();
  memcpy(rc_values, (const void *)rc_shared, sizeof(rc_shared));
  interrupts();
}

void calc_input(uint8_t channel, uint8_t input_pin) {
  if (digitalRead(input_pin) == HIGH) {
    rc_start[channel] = micros();
  } else {
    uint16_t rc_compare = (uint16_t)(micros() - rc_start[channel]);
    rc_shared[channel] = rc_compare;
  }
}

void calc_ch1() {
  calc_input(RC_CH1, RC_CH1_INPUT);
}
void calc_ch2() {
  calc_input(RC_CH2, RC_CH2_INPUT);
}

void setup() {
  Serial.begin(SERIAL_PORT_SPEED);

  pinMode(RC_CH1_INPUT, INPUT);
  pinMode(RC_CH2_INPUT, INPUT);
  pinMode(THROTTLE_OUTPUT_1, OUTPUT);
  pinMode(THROTTLE_OUTPUT_2, OUTPUT);
  pinMode(STEERING_OUTPUT_1, OUTPUT);
  pinMode(STEERING_OUTPUT_2, OUTPUT);
  pinMode(STEERING_DIRECTION_1, OUTPUT);
  pinMode(STEERING_DIRECTION_2, OUTPUT);

  enableInterrupt(RC_CH1_INPUT, calc_ch1, CHANGE);
  enableInterrupt(RC_CH2_INPUT, calc_ch2, CHANGE);
}

void loop() {
  rc_read_values();
  checkThrottle();
  checkSteering();

  int now = millis();
  if (prevRefresh <= now - refresh) {
    prevRefresh = now;
    printData();
  }
}

void checkThrottle() {
  int throttleSignal = rc_values[RC_CH2];
  if (throttleSignal > (THROTTLE_LEVEL + (THROTTLE_DEADBAND / 2))) {
    writeThrottle(true);
  } else if (throttleSignal < (THROTTLE_LEVEL - (THROTTLE_DEADBAND / 2))) {
    writeThrottle(false);
  }
}

void writeThrottle(bool v) {
  if (v) {
    digitalWrite(THROTTLE_OUTPUT_1, LOW);
    digitalWrite(THROTTLE_OUTPUT_2, LOW);
  } else {
    digitalWrite(THROTTLE_OUTPUT_1, HIGH);
    digitalWrite(THROTTLE_OUTPUT_2, HIGH);
  }
}

void checkSteering() {
  int steeringSignal = rc_values[RC_CH1];
  //  int error = STEERING_CALC_POS - steeringSignal;

  //to be determined
  //if left, enable steering, if right enable direction + steering
  //steer right > value goes up, steer left < value goes down
  if (steeringSignal < (STEERING_CALC_POS - STEERING_DEADBAND) && STEERING_CALC_POS >= STEERING_START) {
    digitalWrite(STEERING_DIRECTION_1, LOW);
    digitalWrite(STEERING_DIRECTION_2, LOW);
    digitalWrite(STEERING_OUTPUT_1, LOW);
    digitalWrite(STEERING_OUTPUT_2, LOW);
    delay(STEERING_DELAY);
    STEERING_CALC_POS -= 1;
  } else if (steeringSignal > (STEERING_CALC_POS + STEERING_DEADBAND) && STEERING_CALC_POS <= STEERING_STOP) {
    digitalWrite(STEERING_DIRECTION_1, HIGH);
    digitalWrite(STEERING_DIRECTION_2, HIGH);
    digitalWrite(STEERING_OUTPUT_1, LOW);
    digitalWrite(STEERING_OUTPUT_2, LOW);
    delay(STEERING_DELAY);
    STEERING_CALC_POS += 1;
  }
  digitalWrite(STEERING_OUTPUT_1, HIGH);
  digitalWrite(STEERING_OUTPUT_2, HIGH);
}

void printData() {
  Serial.print("Throttle signal   - ");
  Serial.print(rc_values[RC_CH2]);
  Serial.print("\t");

  Serial.print("Steering signal   - ");
  Serial.print(rc_values[RC_CH1]);
  Serial.print("\t");

  Serial.print("Steering position - ");
  Serial.print(STEERING_CALC_POS);
  Serial.println("\t");

}

I doubt you can power a few relays from a Nano's 5V pin when feeding it with an external supply. Measure the voltage on the 5V pin when all relays are active.

fair point, but is it different when plugged into USB? because they all switch on and off without any issue from either power source. until some time when it stops working from the battery supply.

The clear blunder is not comprehending what the "Vin" or "RAW" terminal is. The regulator on the Arduino UNO/ Nano/ Pro Mini/ Mega2560/ Leonardo/ Pro Micro has very little heatsink, so will not pass very much current (depending on the input voltage and thus, how much voltage it has to drop) before it overheats and (hopefully reversibly) shuts down. It is essentially a novelty provided in the very beginning of the Arduino project when "9V" power packs were common and this was a practical way to power a lone Arduino board for initial demonstration purposes. And even then it was limited because an unloaded 9 V transformer-rectifier-capacitor supply would generally provide over 12 V which the regulator could barely handle.

Nowadays, 5 V regulated switchmode packs are arguably the most readily available in the form of "Phone chargers" and switchmode "buck" regulators are cheap on eBay so these can be fed into the USB connector or (more appropriately) 5 V pin to provide adequate power for most applications. Unfortunately, many tutorials or "instructables" are seriously outdated or misleading and have not been updated to reflect the contemporary situation.

I only checked the reference on the arduino page which says the input can be 7-12v.

So the best option then will be to use a 5v supply or USB charger and cut a usb cable to provide it via the USB socket.

Thats easy enough then. I was going to use a 5v voltage regulator anyway to power the relays externally based on the previous post and that may solve the problem, but it wont be any more hassle to do this at the same time.

I had read however that the 5v pin can power the board but is unregulated so this is not advised compared to using the USB socket.

You don't need to cut any cables. Just parallel up all the 5V lines and feed them all from one good power source at 5V.

steven_191:
I had read however that the 5v pin can power the board but is unregulated so this is not advised compared to using the USB socket.

And that is of course, the most absurd nonsense imaginable. :roll_eyes:

Obviously, that is a source of information so dangerously corrupt as to be avoided "like the plague". Can you tell us where you found it?

Or did you misinterpret something? :astonished:

I think you can power the Nano direct from 12V through the RAW pin provided that you keep the current drawn from the 5V pin to no more than ~100mA. Replace your 5V relays with 12V relays so they won't need any current at 5V. Or even better, use logic-level MOSFETs if possible.

Alternatively use a 12V to 5V DC-DC converter with at least 1A capacity and use that to power the 5V relays and the Nano (via 5V pin).

What else draws power from the Nano at 5V?

Paul__B:
And that is of course, the most absurd nonsense imaginable. :roll_eyes:

Obviously, that is a source of information so dangerously corrupt as to be avoided "like the plague". Can you tell us where you found it?

Or did you misinterpret something? :astonished:

Im not sure. I had a google to find out about external power for the nano and it came up somewhere.
But if thats totally absurd, then whats the difference using the Vin pin which you would assume should be the first place to put a power input? Its not clearly detailed on the nano reference page other than 'input voltage 7-12v', and you would make the assumption that the 5v pin wouldnt be the place to put 12v right? That and the fact the nano schematic show the 5v as an output voltage, not input. But the Vin shows as voltage in.

But even still, like I said previously, all the relays power on with no problem for a longer period of time on USB. So the problem is the nano managing the higher voltage? if I use a regulated 5v either over the usb socket or the 5v pin then the problem should go away? I tried 5v on the Vin pin and the 5v pin then only had ~4v.

The point is this:

You have an ATmega328 microprocessor chip.

It is intended to run on 5 V. That is the design voltage, at least to use a 16 MHz clock which is what the Nano has. To use USB, it also has a USB interface chip which is - generally - designed to run on the USB voltage which is 5 V. That is 5 V OK? :astonished:

I repeat my "stock" explanation to this question every time as in #3. The "Vin" - or "Barrel jack" on a UNO - is a legacy "novelty" from the times ten or twenty years ago when 5 V switchmode power supplies were not common as they now are. It allowed you to use unregulated 9 V "plug packs" (US: "Wall warts") which were the common supply for computer "phone" modems and ADSL boxes which contained heat-sinked 7805 regulators. But the regulator on a tiny Nano or even the UNO board has minimal heat-sinking and is only suitable for simple demonstrations of the basic board and a few LEDs.

For protection, there is a diode between the USB connector and the 5 V supply line (which is also the "5V" pin) in the Nano, so plugging 5 V power into the USB jack loses a significant part of a Volt before it gets to the 5 V line. According to the original circuit, this would be a SS1P3L with only 350 mV drop and capable of passing one Amp, but depending on what clone you have, this may be quite different.

So you can simply forget the on-board regulator and "Vin" and when you have a nice regulated supply of 5 V - generally from a switchmode "buck" regulator - you want to convey it to where it is actually required - the "5V" pin and your relay module. :grinning:

Paul__B:
So you can simply forget the on-board regulator and "Vin" and when you have a nice regulated supply of 5 V - generally from a switchmode "buck" regulator - you want to convey it to where it is actually required - the "5V" pin and your relay module. :grinning:

I hadnt seen that indicated anywhere when I looked for info other than the post recommending not to use the 5v pin.

Thanks for the input.