An error...

Hi all, excuse the noobish post.
I've been working on a remote vehicle ignition for some time now, and have gotton over many hurdles thanks to members on this forum, and have learnt quite alot to something very new to me.

Currently, i'm at the programming stage.
I have had some coding help from a member here in the past, he wrote quite alot of the current code i am using. (i'm more of a designer rather than a programmer)

Here i have my current code, which is giving me a compile error of

arduino_remote_start_final.cpp: In function 'void HandleStoppedState()':
arduino_remote_start_final:150: error: a function-definition is not allowed here before '{' token
arduino_remote_start_final:160: error: expected `}' at end of input
arduino_remote_start_final:160: error: expected `}' at end of input
arduino_remote_start_final:160: error: expected `}' at end of input

My current code is:

//Remote Vehicle Ignition
//State Machine begin
#include <SoftwareSerial.h>

char inchar;

SoftwareSerial cell(2,3);

// system states 
#define STOPPED   0
#define STARTING  1
#define CRANKING  2
#define RUNNING   3

#define FUEL_PUMP_PRIME_TIME  5000
#define RUNNING_TIMEOUT 60000UL

const int ignitionPin = 12;
const int onPin = 11;
const int ledPin = 13;
const int onledPin = 9;
const int alternatorPin = 4;

int state = STOPPED;        // master variable for the state machine
unsigned long StartingTime; // fuel pump priming
unsigned long RunningTime;  //  ten minute timeout

void setup() 
{
pinMode(onPin, OUTPUT);
pinMode(onledPin, OUTPUT);
pinMode(ignitionPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(alternatorPin,INPUT);
Stop(); 
cell.begin(9600);

delay(30000);

cell.println("AT+CMGF=1");

delay(200);

cell.println("AT+CNMI=3,3,0,0");

delay(200);

}

void loop() 
{
switch(state)
  {
  case STOPPED:
    HandleStoppedState();
    break;
  case STARTING:
    HandleStartingState();
    break;
  case CRANKING: 
    HandleCrankingState();
   break;  
  case RUNNING:
    if(millis()-RunningTime > RUNNING_TIMEOUT)
      {
      Serial.println("Running Timeout");  
      Stop();  
      }
    break;  
  default:
    Serial.print("Unknown State: ");
    Serial.println(state);
    Stop(); 
    break;  
  }
}

void Stop()
{
Serial.println("TimeOut");  
digitalWrite(ignitionPin,LOW);
digitalWrite(onPin,LOW);
digitalWrite(onledPin,LOW);
state=STOPPED;
}

void HandleStartingState()
{
if(millis()-StartingTime > FUEL_PUMP_PRIME_TIME)
  {
  if(digitalRead(alternatorPin)==HIGH)
    {
    Serial.println("Abort cranking");  
    Stop(); 
    }
  else
    {  
    Serial.println("Starting Vehicle");  
    digitalWrite(onPin,HIGH);
    digitalWrite(ignitionPin,HIGH);
    state=CRANKING;
    }  
  }
}

void HandleStoppedState()
{

if(cell.available() >0)

 {
   
inchar=cell.read();

if (inchar=='#')

{
  delay(10);
  
inchar=cell.read();

if (inchar=='s')

{
  
delay(10);

inchar=cell.read();

if (inchar=='0')

{

digitalWrite(ignitionPin,LOW);
digitalWrite(onPin,LOW);
}

else if (inchar=='1')

{
  
  Serial.println("Priming Fuel Pump");  
  StartingTime=millis();
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,HIGH);
  state=STARTING;
  }      
}

void HandleCrankingState()
{
if(digitalRead(alternatorPin)==HIGH) 
  {    
  Serial.println("Vehicle Running");  
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,HIGH);
  digitalWrite(onledPin,HIGH);
  RunningTime=millis();
  state=RUNNING;
  }
}

I've tried a few work around's but cannot seem to get past this.

If anyone would have some idea's, that would be greatly appreciated.

Using an Arduino UNO, with a sparkfun eval board which uses the SM5100b cell chip

This is the code before i wrote in the cell components, for testing i was using serial input.

//Remote Vehicle Ignition
//State Machine begin

// system states 
#define STOPPED   0
#define STARTING  1
#define CRANKING  2
#define RUNNING   3

#define FUEL_PUMP_PRIME_TIME  5000
#define RUNNING_TIMEOUT 60000UL

const int ignitionPin = 12;
const int onPin = 11;
const int ledPin = 13;
const int onledPin = 9;
const int alternatorPin = 4;

int state = STOPPED;        // master variable for the state machine
unsigned long StartingTime; // fuel pump priming
unsigned long RunningTime;  // ten minute timeout

void setup() 
{
pinMode(onPin, OUTPUT);
pinMode(onledPin, OUTPUT);
pinMode(ignitionPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(alternatorPin,INPUT);
Stop(); // 
Serial.begin(9600);
}

void loop() 
{
switch(state)
  {
  case STOPPED:
    HandleStoppedState();
    break;
  case STARTING:
    HandleStartingState();
    break;
  case CRANKING: //
    HandleCrankingState();
   break;  
  case RUNNING:
    if(millis()-RunningTime > RUNNING_TIMEOUT)
      {
      Serial.println("Running Timeout");  
      Stop();  
      }
    break;  
  default:
    Serial.print("Unknown State: ");
    Serial.println(state);
    Stop(); // Should never get here
    break;  
  }
}

void Stop()
{
Serial.println("TimeOut");  
digitalWrite(ignitionPin,LOW);
digitalWrite(onPin,LOW);
digitalWrite(onledPin,LOW);
state=STOPPED;
}

void HandleStartingState()
{
if(millis()-StartingTime > FUEL_PUMP_PRIME_TIME)
  {
  if(digitalRead(alternatorPin)==HIGH)
    {
    Serial.println("Abort cranking");  
    Stop(); 
    }
  else
    {  
    Serial.println("Starting Vehicle");  
    digitalWrite(onPin,HIGH);
    digitalWrite(ignitionPin,HIGH);
    state=CRANKING;
    }  
  }
}

void HandleStoppedState()
{
if (Serial.available() > 0) 
  {
  Serial.read(); 
  Serial.println("Priming Fuel Pump");  
  StartingTime=millis();
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,HIGH);
  state=STARTING;
  }      
}

void HandleCrankingState()
{
if(digitalRead(alternatorPin)==HIGH) 
  {    
  Serial.println("Vehicle Running");  
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,HIGH);
  digitalWrite(onledPin,HIGH);
  RunningTime=millis();
  state=RUNNING;
  }
}

Basically, i need the HandleStoppedState to be initiated upon recieving '#s1'

If you use the Tools + Auto format menu item, your code would be a lot easier to read, and you might even see what your problem is.

You don't have matching { and } in the function HandleStoppedState(), so HandleCrankingState() is incorrectly placed.

Thanks for the tip, i shall try now.

Although, before i inputted all the cell code, it worked fine...

Got it to compile, although it wouldn't move to HandleCrankingState

Got it to compile, although it wouldn't move to HandleCrankingState

Probably not be whispering sweet nothings in the compiler's ear. Presumably, you changed some code. Now, that changed code doesn't do what you expect. As long as the changed code remains a mystery, so will the solution.

I added an } after HandleCrankingState.

Would it be possible at all Paul, to maybe take an actual look at the code and explain just what i'm doing wrong when entering the cell code?

Regards.

There was more than one closing brace missing. Can you post the current version?

Newbies make a lot of mysterious little coding errors. Perhaps you inadvertently deleted a brace?

Moving on, your code is pretty clear. The sketch should output "Starting Vehicle", before it goes to CRANKING state.

I'd get rid of the extra "//" that it probably does not matter:

  case CRANKING: //
    HandleCrankingState();
   break;

Add lots of print statements to HandleStartingState():

void HandleStartingState()
{
[color=red]Serial.println("In Starting Vehicle"); [/color] 
if(millis()-StartingTime > FUEL_PUMP_PRIME_TIME)
  {
[color=red]  Serial.println("Starting Vehicle, pump primed"); [/color] 
  if(digitalRead(alternatorPin)==HIGH)
    {
    Serial.println("Abort cranking");  
    Stop(); 
    }
  else
    {  
    Serial.println("Starting Vehicle");  
    digitalWrite(onPin,HIGH);
    digitalWrite(ignitionPin,HIGH);
    state=CRANKING;
    }  
  }
}

Try to pinpoint what is not right. Like once you establish that HandleStartingState() is called, you may want to stop printing "In Starting Vehicle" as it will be called repeatedly. Then you might check the alternator pin is correct, verify the alternator pin is setup right in code, verify it is correctly wired and put a volt meter on it to see if ever does go high.

So just pinpoint what is not as expected by printing diagnostics and checking hardware.

[color=red]Serial.println("In Starting Vehicle"); [/color]

Colour tags don't work in code boxes.

I see.
I have tested this code numerous times via serial whilst hooked upto the vehicle and it indeed works perfect, as soon as i changed the code from serial to cell, it got messy and keeps giving bracket errors.
I honestly cannot work out why it won't compile when all i've done is remove anything serial and add a few lines of code for the cell part of it.

I've litterally tried everything, i still keep getting compile error of:

void HandleCrankingState()
{  <<<COMPILE ERROR HIGHLIGHTS THIS
if(digitalRead(alternatorPin)==HIGH) 
  {     
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,HIGH);
  digitalWrite(onledPin,HIGH);
  RunningTime=millis();
  state=RUNNING;
  }
}

With the following:

arduino_remote_start_final.cpp: In function 'void HandleStoppedState()':
arduino_remote_start_final:146: error: a function-definition is not allowed here before '{' token
arduino_remote_start_final:155: error: expected `}' at end of input
arduino_remote_start_final:155: error: expected `}' at end of input
arduino_remote_start_final:155: error: expected `}' at end of input

Oh, I thought you got past the compile issue. What does it mean "replace serial with cell"?

When you get a brace error like you have look at the brace right there and the function definition, and then look at what came before. There may be an extra or missing brace before this method.

Can you make your edits one step at a time and compile after each edit? When I work, I generally save a version of a sketch every few hours at a good stop point like when it is all working. Then I add a new feature in the next version. I might have Ignition1.pde, Ignition2.pde, etc. If a bunch of edits don't work out, I can fall back on yesterday's save point.

The other thing you might try is, in a copy like IgnitionTest1.pde, delete all the subroutines on the bottom and comment out their calls in the main loop. See if it compiles. After you figure out what was wrong, just go back to the original code and fix it.

And try Paul's suggestion to Auto Format the code. These errors are often missing braces that are hard to see when the tabs are wrong.

Cleanup the formatting in HandleStoppedState(). You may have an extra end brace. Or you may have done something like (} instead of ().

arduino_remote_start_final:155: error: expected `}' at end of input
arduino_remote_start_final:155: error: expected `}' at end of input
arduino_remote_start_final:155: error: expected `}' at end of input

This is telling you that you have three missing closing braces.

The problem is, the auto format parser probably won't like the mismatched braces either :slight_smile:

This compiles:

//Remote Vehicle Ignition
//State Machine begin
#include <SoftwareSerial.h>

char inchar;

SoftwareSerial cell(2,3);

// system states 
#define STOPPED   0
#define STARTING  1
#define CRANKING  2
#define RUNNING   3

#define FUEL_PUMP_PRIME_TIME  5000
#define RUNNING_TIMEOUT 60000UL

const int ignitionPin = 12;
const int onPin = 11;
const int ledPin = 13;
const int onledPin = 9;
const int alternatorPin = 4;

int state = STOPPED;        // master variable for the state machine
unsigned long StartingTime; // fuel pump priming
unsigned long RunningTime;  //  ten minute timeout

void setup() 
{
  pinMode(onPin, OUTPUT);
  pinMode(onledPin, OUTPUT);
  pinMode(ignitionPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(alternatorPin,INPUT);
  Stop(); 
  cell.begin(9600);
  delay(30000);
  cell.println("AT+CMGF=1");
  delay(200);
  cell.println("AT+CNMI=3,3,0,0");
  delay(200);
}

void loop() 
{
  switch(state)
  {
  case STOPPED:
    HandleStoppedState();
    break;
  case STARTING:
    HandleStartingState();
    break;
  case CRANKING: 
    HandleCrankingState();
    break;  
  case RUNNING:
    if(millis()-RunningTime > RUNNING_TIMEOUT)
    {
      Serial.println("Running Timeout");  
      Stop();  
    }
    break;  
  default:
    Serial.print("Unknown State: ");
    Serial.println(state);
    Stop(); 
    break;  
  }
}

void Stop()
{
  Serial.println("TimeOut");  
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,LOW);
  digitalWrite(onledPin,LOW);
  state=STOPPED;
}

void HandleStartingState()
{
  if(millis()-StartingTime > FUEL_PUMP_PRIME_TIME)
  {
    if(digitalRead(alternatorPin)==HIGH)
    {
      Serial.println("Abort cranking");  
      Stop(); 
    }
    else
    {  
      Serial.println("Starting Vehicle");  
      digitalWrite(onPin,HIGH);
      digitalWrite(ignitionPin,HIGH);
      state=CRANKING;
    }  
  }
}

void HandleStoppedState()
{
  if(cell.available() >0)
  {
    inchar=cell.read();
    if (inchar=='#')
    {
      delay(10);
      inchar=cell.read();
      if (inchar=='s')
      {

        delay(10);
        inchar=cell.read();
        if (inchar=='0')
        {

          digitalWrite(ignitionPin,LOW);
          digitalWrite(onPin,LOW);
        }
        else if (inchar=='1')
        {
          Serial.println("Priming Fuel Pump");  
          StartingTime=millis();
          digitalWrite(ignitionPin,LOW);
          digitalWrite(onPin,HIGH);
          state=STARTING;
        }      
      }
    }
  }
}

void HandleCrankingState()
{
  if(digitalRead(alternatorPin)==HIGH) 
  {    
    Serial.println("Vehicle Running");  
    digitalWrite(ignitionPin,LOW);
    digitalWrite(onPin,HIGH);
    digitalWrite(onledPin,HIGH);
    RunningTime=millis();
    state=RUNNING;
  }
}

But I don't have your hardware, so I don't know if it works.

dxw00d:
This compiles:

//Remote Vehicle Ignition

//State Machine begin
#include <SoftwareSerial.h>

char inchar;

SoftwareSerial cell(2,3);

// system states
#define STOPPED   0
#define STARTING  1
#define CRANKING  2
#define RUNNING   3

#define FUEL_PUMP_PRIME_TIME  5000
#define RUNNING_TIMEOUT 60000UL

const int ignitionPin = 12;
const int onPin = 11;
const int ledPin = 13;
const int onledPin = 9;
const int alternatorPin = 4;

int state = STOPPED;        // master variable for the state machine
unsigned long StartingTime; // fuel pump priming
unsigned long RunningTime;  //  ten minute timeout

void setup()
{
  pinMode(onPin, OUTPUT);
  pinMode(onledPin, OUTPUT);
  pinMode(ignitionPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(alternatorPin,INPUT);
  Stop();
  cell.begin(9600);
  delay(30000);
  cell.println("AT+CMGF=1");
  delay(200);
  cell.println("AT+CNMI=3,3,0,0");
  delay(200);
}

void loop()
{
  switch(state)
  {
  case STOPPED:
    HandleStoppedState();
    break;
  case STARTING:
    HandleStartingState();
    break;
  case CRANKING:
    HandleCrankingState();
    break; 
  case RUNNING:
    if(millis()-RunningTime > RUNNING_TIMEOUT)
    {
      Serial.println("Running Timeout"); 
      Stop(); 
    }
    break; 
  default:
    Serial.print("Unknown State: ");
    Serial.println(state);
    Stop();
    break; 
  }
}

void Stop()
{
  Serial.println("TimeOut"); 
  digitalWrite(ignitionPin,LOW);
  digitalWrite(onPin,LOW);
  digitalWrite(onledPin,LOW);
  state=STOPPED;
}

void HandleStartingState()
{
  if(millis()-StartingTime > FUEL_PUMP_PRIME_TIME)
  {
    if(digitalRead(alternatorPin)==HIGH)
    {
      Serial.println("Abort cranking"); 
      Stop();
    }
    else
    { 
      Serial.println("Starting Vehicle"); 
      digitalWrite(onPin,HIGH);
      digitalWrite(ignitionPin,HIGH);
      state=CRANKING;
    } 
  }
}

void HandleStoppedState()
{
  if(cell.available() >0)
  {
    inchar=cell.read();
    if (inchar=='#')
    {
      delay(10);
      inchar=cell.read();
      if (inchar=='s')
      {

delay(10);
        inchar=cell.read();
        if (inchar=='0')
        {

digitalWrite(ignitionPin,LOW);
          digitalWrite(onPin,LOW);
        }
        else if (inchar=='1')
        {
          Serial.println("Priming Fuel Pump"); 
          StartingTime=millis();
          digitalWrite(ignitionPin,LOW);
          digitalWrite(onPin,HIGH);
          state=STARTING;
        }     
      }
    }
  }
}

void HandleCrankingState()
{
  if(digitalRead(alternatorPin)==HIGH)
  {   
    Serial.println("Vehicle Running"); 
    digitalWrite(ignitionPin,LOW);
    digitalWrite(onPin,HIGH);
    digitalWrite(onledPin,HIGH);
    RunningTime=millis();
    state=RUNNING;
  }
}




But I don't have your hardware, so I don't know if it works.

Thanks! shall test shortly.
But why are there so many braces at the end?

Yes, paying attention to indentation and matching braces as you go along will pay dividends.

As soon as i add this, it fails.

We're only going to tell you about 14 more times. You absolutely MUST have EXACTLY ONE { for every }. That last block of code has 9 curly braces - some open, some close. It must have an even number. Period. You can try anything you like but you can NOT get around that fact.

Thank you Paul for the sarcastic reply.
I'm fairly sure i now understand.

Regards.