Got a new little problem. I am trying to do a serial read and a bunch of other stuff and it causes the arduino to reset. There is no command in there for a software reset (and to my knowledge there is no such thing anyway) any ideas on what might cause this behavior? vector overflow? something having to do with memory usage? i searched the forum and was unable to find anyone with a similar issue.
Most causes of unexpected resets are power related. However software errors could cause the sketch to jump into the tall weeds and case rabbits. Posting your code and maybe a drawing of your wiring might help someone figure it out for you.
Thanks for the reply, the code is big so hold on...
//LIBRARY DECLARATIONS
//FOR PID CONTROL
#include <PID_v1.h> //PID Libarary
//FOR PID CONTROL
//For Motor Control
#include <ServoTimer2.h> // the servo library
//For Motor Control
//LIBRARY DECLARATIONS
int dan1=0;
//ULTRASONIC RANGEFINDER VARIABLES
int rangepin=7;
//ULTRASONIC RANGEFINDER VARIABLES
//EXPERIMENTAL Low Level Flight Control Var
int desiredalt=24; //Desired altitude in inches
int altthrottlebias=0;
//EXPERIMENTAL Low Level Flight Control Var
//Global Variable Declarations
//GUIDANCE CONTROL TEST VARIABLES
// double pitchval;
double PitchBias;
// double rollval;
double RollBias;
//GUIDANCE CONTROL TEST VARIABLES
//FOR MOTOR CONTROL
// define the pins for the servos
#define rollPin 5
#define pitchPin 4
#define yawPin 3
#define danPin 2
ServoTimer2 servoRoll; // declare variables for up to eight servos
ServoTimer2 servoPitch;
ServoTimer2 servoYaw;
ServoTimer2 servoDan;
int spd1; //Motor control numbers go Counter clock wise from nose
int spd2;
int spd3;
int spd4;
//FOR MOTOR CONTROL
//FOR PID CONTROL
double Setpoint, Input, Output;
double Setpointalt,Inputalt,Outputalt;
PID myPID(&Input, &Output, &Setpoint,2,5,1,DIRECT);
PID AltPID(&Inputalt, &Outputalt, &Setpointalt,2,5,1,DIRECT);
//FOR PID CONTROL
//AHRS GLOBAL VARIABLE DECLARATIONS
char incoming=-1;
int counta=0;
int count=0;
float rollval;
float pitchval;
float yawval;
char checker=-1;
int searchcount=0;
int chrrecord;
int chrcheck;
char commacheck=0;
char rollstring[8]="";
char pitchstring[8]="";
char yawstring[8]="";
int invaliddata=0;
int mastercountercheck=0;
int incomingcheck=0;
//AHRS GLOBAL VARIABLE DECLARATIONS
void setup()
{
Serial.begin(57600); //DATA OUTPUT STREAM
Serial1.begin(57600); //AHRS DATA INPUT STREAM
Serial3.begin(4800); //GPS DATA INPUT STREAM
Serial.println("Arduino Reset");
//FOR PID CONTROL
myPID.SetMode(AUTOMATIC); //Activates the PID Subroutine
AltPID.SetMode(AUTOMATIC); //Activates the low level Altitude control PID Subroutine
myPID.SetOutputLimits(-25,25); //Sets a Throttle Bias of +-25% as maximum (values converted to percentage later in prog)
AltPID.SetOutputLimits(-50,50); //Sets a Throttle Bias of +-50% as maximum (values converted to percentage later in prog)
//FOR PID CONTROL
//FOR MOTOR CONTROLLER
servoRoll.attach(rollPin); // attach a pin to the servos and they will start pulsing
servoPitch.attach(pitchPin);
servoYaw.attach(yawPin);
servoDan.attach(danPin);
delay(5000);
servoRoll.write(1000); //Sends Activation Signal to ESC's
servoPitch.write(1000); //Sends Activation Signal to ESC's
servoYaw.write(1000); //Sends Activation Signal to ESC's
servoDan.write(1000); //Sends Activation Signal to ESC's
delay(3000); //Delay to make sure that all ESC's have recieved signal
servoRoll.write(1350); //Sends Activation Signal to ESC's
servoPitch.write(1350); //Sends Activation Signal to ESC's
servoYaw.write(1350); //Sends Activation Signal to ESC's
servoDan.write(1350); //Sends Activation Signal to ESC's
delay(5000); //Waits for people to clear before idling motors (5s)
//FOR MOTOR CONTROLLER
}
void loop()
{
gpsgo=0;
//while(dan1==0)
//{
//AHRS DATA READ CODE
mastercountercheck=0;
for (int mastercounter=0;mastercounter<=50;mastercounter++) //provides a ratio of AHRS reads/corrects to altitude and GPS reads/corrects
{
rollval=0; //Cleans roll data
pitchval=0; //Cleans pitch data
yawval=0; //Cleans yaw data
char dataset[35]=""; //initiallizes the AHRS data storage string
count=0; //Zeros out the counter for reading in the AHRS data
incoming=-1; //Sets the incoming byte to a null value
while (incoming!='X' && count<=30) //Ends the Serialread function if an X is detected (end of data) or an overflow is imminent
{
incomingcheck++;
Serial.println(incomingcheck);
if (Serial1.available()>0)
{
incoming=Serial1.read(); // Read a byte of the serial port
dataset[count]=incoming; //add the incoming byte into dataset
count++;
}
else
{
Serial.println("Serial Unavailable");
}
}
incomingcheck=0;
chrcheck=5; //Starts looking for data after the header
commacheck=0; //Zeros out the comma found trigger
invaliddata=0; //moves invalid data to the null position (data valid)
if (dataset[0]=='!') //looks for initial part of header
{
if (dataset[4]==':') //Looks for trailing part of header
{
chrrecord=0; //Sets the begining of the recieving string
while(commacheck==0) //runs until first commma is found
{
rollstring[chrrecord]=dataset[chrcheck]; //copies the data from dataset into rollstring
chrcheck++;
chrrecord++;
if(dataset[chrcheck]==',') //Check to see if a comma was found
{
commacheck=1; //comma found
chrcheck++;
chrrecord=0;
}
if (chrrecord>12) //if a comma cannot be found by this point then the data is invalid (THIS CONDITION ONLY WORKS FOR THE FIRST COMMA)
{
commacheck=1; //uses the already existing trigger to exit the loop
invaliddata=1; //Activates the invalid data trigger
}
}
commacheck=0;
while(commacheck==0) //runs until first commma is found
{
pitchstring[chrrecord]= dataset[chrcheck];
chrcheck++;
chrrecord++;
if(dataset[chrcheck]==',')
{
commacheck=1;
chrcheck++;
chrrecord=0;
}
if (chrrecord>20) //if a comma cannot be found by this point then the data is invalid (THIS CONDITION ONLY WORKS FOR THE SECOND COMMA)
{
commacheck=1; //uses the already existing trigger to exit the loop
invaliddata=1; //Activates the invalid data trigger
}
}
commacheck=0;
while(commacheck==0)
{
yawstring[chrrecord]=dataset[chrcheck];
chrcheck++;
chrrecord++;
if(dataset[chrcheck]=='X')
{
commacheck=1;
}
if (chrrecord>28) //if the X cannot be found by this point then the data is invalid (THIS CONDITION ONLY WORKS FOR THE END)
{
commacheck=1; //uses the already existing trigger to exit the loop
invaliddata=1; //Activates the invalid data trigger
}
}
}
else
{
invaliddata=1;
}
}
else
{
invaliddata=1;
}
rollval=atof(rollstring);
yawval=atof(yawstring);
pitchval=atof(pitchstring);
Serial.println(dataset);
Serial.print("Roll: ");
Serial.println(rollval);
Serial.print("Yaw: ");
Serial.println(yawval);
Serial.print("Pitch: ");
Serial.println(pitchval);
Serial.println(mastercounter);
if (invaliddata==1)
{
Serial.println("Invalid Data");
}
//Serial.println(memavail);
//Serial.println(rollstring);
Serial.println("---------------------------------");
//AHRS DATA READ CODE
if (invaliddata==0) //Only runs the PID routine if the AHRS data is valid
{
//PID CONTROL ALGORITHITHM (PITCH CONTROL)
Input=pitchval; //Input Value for Pitch
Setpoint=0; //Desired Pitch Angle
myPID.Compute(); //Executes PID command
PitchBias=Output; //Transfers PID solution into the PITCH bias value
PitchBias=PitchBias/100; //Converts the bias to decimal value
spd1=spd1+(spd1*PitchBias); //Sets motor1 Speed to include Bias
spd3=spd3-(spd3*PitchBias); //Sets motor3 Speed to include Bias
//PID CONTROL ALGORITHITHM>
//PID Control (Allows Re-use of PID) zeros all values to get a clean PID run
Input=0;
Setpoint=0;
Output=0;
//PID Control (Allows Re-use of PID) zeros all values to get a clean PID run
//PID CONTROL ALGORITHITHM (ROLL CONTROL)
Input=rollval; //Input Value for Roll
Setpoint=0; //Desired Bank Angle
myPID.Compute(); //Executes PID command
RollBias=Output; //Transfers PID solution into the ROLL bias value
RollBias=RollBias/100; //Converts the bias to decimal value
spd2=spd2+(spd2*RollBias); //Sets motor2 Speed to include Bias
spd4=spd4+(spd4*RollBias); //Sets motor4 Speed to include Bias
//PID CONTROL ALGORITHM
//Update roll, pitch, yaw values to the motors
servoRoll.write(spd1);
servoPitch.write(spd2);
servoYaw.write(spd3);
servoDan.write(spd4);
//Update roll, pitch, yaw values to the motors
}
Serial.println("Loop Completed");
mastercountercheck++;
} //End "MasterCounter" loop
Serial.println("Loop Exit");
the part that seems to trip it up is the part in the mastercounter for loop... it will read successfully from the AHRS like 6 times and then reset....
Ok so I did some checking and this definitely does not appear to be a hardware issue. Something in software having to do with reading serial data is causing this. if the AHRS chip does not transmit the arduino will not reset. it will just transmit serial unavailable until told to stop so it definitely seems that something having to do with reading in data is causing this... does anybody know what could do that?
There is likely a buffer overflow occurring. Not that I think this is the issue, but rollstring is 8 bytes long and your check chrrecord>12 permits you to write past its end if a comma is missing or corrupted in the input. If you could refactor the parsing of each the three strings into a function, it might make it clearer what is happening. As is, you're relying fairly heavily on the string appearing exactly as you expect.
Your parsing code needs a serious overhaul. There is a perfectly good function, strtok() that can be used to find tokens. It's been thoroughly tested under all kinds of conditions for more than 30 years. I'm pretty sure all of the bugs have been worked out of it. Can you say the same for your code?
You need to create functions for perform some of the task that you are now performing in loop(). In a program of any complexity, and this code certainly qualifies, loop() should be doing little more than calling a handful of functions.
Tools + Auto Format... would make it much easier to read your code.
Sorry about the formatting I didnt even know about the auto format. As for the chrrecord issue, the if statement should have been for chrcheck, because if it couldnt find a comma by the 12th character it was a garbage signal... I corrected that but the problem is still persisting I am trying to narrow where the problem occurs as paul mentioned it is most likely in the parsing section. But i was curious if when it opens the serial comm to talk back to my PC can that cause the reset that arduino does before an upload?
I'm betting it's the servos that are the cause. They love to do crazy things like suck all the power they can get. Not sure how you are powering this, but trying to run 4 servos at once from the Arduino directly probably won't work. When your setup code runs the servos start up in series with delays between, which shouldn't be an issue since only 1 is probably on at a time. When you get into the mastercontrol loop however you are trying to update them immediately without delay, which will result in them being all "on" at the same time. Depending on position and how far they have to move etc... could be the defining factor of how many loops you make it through before it dies.
Do a quick test and comment out the servo update statements:
//Update roll, pitch, yaw values to the motors
servoRoll.write(spd1);
servoPitch.write(spd2);
servoYaw.write(spd3);
servoDan.write(spd4);
//Update roll, pitch, yaw values to the motors
Or even just try running the code without the servo connected to the Arduino.
But i was curious if when it opens the serial comm to talk back to my PC can that cause the reset that arduino does before an upload?
When the Arduino opens the serial port, it does not reset. How could it? If it reset when it did the Serial.begin(), it would start setup() again, and call Serial.begin() again, which would cause a reset and start the process over again.
When the PC opens the serial connection, that DOES trigger a reset of the Arduino.
Well here was the deal. Paul pretty much called it, parsing=junk. I tracked the error to the data parsing section of my code, I read up on strtok() and rewrote it from scratch. That fixed the issue. Im not sure what was causing the restart in that area but it doesnt matter because the new code is quicker and more reliable thanks for the help everyone.