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");
}