What am I missing here

Im trying to make this code not repeat an action if it just done the action. Its lowering a carriage and I dont want it to go down again if its already been lowered if someone accidentally its the lower button again. The same on raising it.

int state;
int last_state = 9;
const int stepPin = 5; 
const int dirPin = 2; 

void setup() {
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}
void loop() {
  if (Serial.available() > 0) {
    if (Serial.peek() == 'c') {
      Serial.read();
      state = Serial.parseInt();
      if (state == 2) {
        if (last_state != 2) {
          raise_();
          delay(1000);
          last_state = state;
        }
        else {
          Serial.println("Already in raised state");
        }
      }
    }
  }
}
void raise_() {
  digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 3810; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
}

Did you mean to have a call to Serial.begin() somewhere in the code ?

You have a very complicated nest of IF statements. What is the point of the Serial.peek() - don't you need to remove the character from the buffer even if it is not a 'c'.

...R
Serial Input Basics - simple reliable ways to receive data.

Yes there is a serial begin in the code. I just took a sample of the code and posted it. The peek is in there because thats how i was shown to do it. Its a Tkinter gui that sends c0 , c1, etc depending on which button you press.

What happens if anything goes wrong and you get anything other than a 'c' ?

If a byte is available then read it and keep reading available bytes until you get a 'c' then deal with the subsequent character(s) Will the data following the 'c' only ever be 1 character ? If so then you don't need to use parseInt()

Don't rely on serial comms being bulletproof

Well Ill have to cross that bridge when i get there. In the mean time I ned to figure out how to make a software safety to keep the carraige from driving down or up twice in a row. I guess I could do it in the python script but would be nice just to figure out why the if else using the state/last_state comparative doesnt work.

What exactly (every byte) are you sending to the Arduino ?

Is there a carriage return or linefeed at the end of the string ?

I got it. It actually does work correctly. It was hanging up in one of the fill function waiting on the probe pin to gnd out before continuing. After manually grounding pin to simulate liquid detection works fine. Thanks for the input and sorry to waste your time.

int state;
int last_state = 9;
int val;
const int stepPin = 5; 
const int dirPin = 2; 
const int enPin = 8;
const int co2pin = 6;
const int liquid = 7;
const int level_probe = 9;

void setup() {
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  pinMode(co2pin, OUTPUT);
  pinMode(liquid,OUTPUT);
  pinMode(level_probe,INPUT_PULLUP);
  digitalWrite(enPin,LOW);  
  Serial.begin(115200);
}

void loop() {
  if (Serial.available() > 0) {
    if (Serial.peek() == 'c') {
      Serial.read();
      state = Serial.parseInt();
      if (state == 2){
        if (last_state != 2){
          raise_();
          delay(1000);
          last_state = state;
        }
        else{
          Serial.println("Already in raised state");         
        }
      }
      if (state == 1){
        if (last_state != 1){
          fill();
          delay(1000);
          last_state = state;
        }
        else{
          Serial.println("Already in fill state");
        }
      }
      if (state == 0){
        if (last_state != 0){
          lower();
          delay(1000);
          last_state = state;
        }
        else{
          Serial.println("Already in lowered state");       
        }
      }
    }
    while (Serial.available() > 0) {
      Serial.read();
    }
  }
}
void raise_() {
  digitalWrite(dirPin,HIGH); 
  for(int x = 0; x < 3810; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
}
void lower() {
  digitalWrite(dirPin,LOW); 
  for(int x = 0; x < 3810; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
}
void fill(){
  digitalWrite(co2pin,HIGH);
  delay(5000);
  digitalWrite(co2pin,LOW);
  //val = digitalRead(level_probe);
  //Serial.println(val);
  while(digitalRead(level_probe)==HIGH ) {
    digitalWrite(liquid,HIGH);
  }
  digitalWrite(liquid,LOW);
}

There's still (at least) one hole in your code:

Your state describes the last operation but does not remember that state of the carriage.

If you raised the carriage the state is remembered. However, if you then fill, the state of the carriage is forgotten. What if the next command is to raise the carriage?

Yep didnt think about that. What about something like this:

int state;
int last_state = 9;
int val;
bool lowered = false;
bool raised = true;
bool filled = false;
const int stepPin = 5; 
const int dirPin = 2; 
const int enPin = 8;
const int co2pin = 6;
const int liquid = 7;
const int level_probe = 9;

void setup() {
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  pinMode(co2pin, OUTPUT);
  pinMode(liquid,OUTPUT);
  pinMode(level_probe,INPUT_PULLUP);
  digitalWrite(enPin,LOW);  
  Serial.begin(115200);
}

void loop() {
  if (Serial.available() > 0) {
    if (Serial.peek() == 'c') {
      Serial.read();
      state = Serial.parseInt();
      if (state == 2){
        if (raised != true){
          raise_();
          delay(1000);
          raised = true;
          filled = false;
          lowered = false;
        }
        else{
          Serial.println("Already in raised state");         
        }
      }
      if (state == 1){
        if (filled != true){
          if (lowered == true){
            fill();
            delay(1000);
            filled = true;
            raised = false;
            lowered = false;
          }        
        }
        else{
          Serial.println("Already in fill state");
        }
      }
      if (state == 0){
        if (lowered != true){
          if (filled != true){
            lower();
            delay(1000);
            lowered = true;
            raised = false;
            filled = false;
          }        
        }
        else{
          Serial.println("Already in lowered state");       
        }
      }
    }
    while (Serial.available() > 0) {
      Serial.read();
    }
  }
}
void raise_() {
  digitalWrite(dirPin,HIGH); 
  for(int x = 0; x < 3810; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
}
void lower() {
  digitalWrite(dirPin,LOW); 
  for(int x = 0; x < 3810; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
}
void fill(){
  digitalWrite(co2pin,HIGH);
  delay(5000);
  digitalWrite(co2pin,LOW);
  //val = digitalRead(level_probe);
  //Serial.println(val);
  while(digitalRead(level_probe)==HIGH ) {
    digitalWrite(liquid,HIGH);
  }
  digitalWrite(liquid,LOW);
}

Or, just out of left field, an implementation like this:

byte
    state;
    
const int stepPin = 5; 
const int dirPin = 2; 
const int enPin = 8;
const int co2pin = 6;
const int liquid = 7;
const int level_probe = 9;

#define BUFF_SIZE       10
char
    RxBuff[BUFF_SIZE];

#define CLR_CF                  0b11111110
#define CARRIAGE_STATE_MASK     0x01
#define CARRIAGE_LOWERED        0x00    //bit 0 - 0 means carriage lowered
#define CARRIAGE_RAISED         0x01    //bit 0 - 1 means carriage now lowered
#define RAISE_CARRIAGE_DELAY    1000L
#define LOWER_CARRIAGE_DELAY    1000L
#define CO2_PURGE_TIME          5000L

#define TICK_TIME               500L

#define FILL_DELAY              2500L
#define FILL_TIMEOUT            20000L   //20 seconds to refill?

#define MAX_CMD                 4
unsigned long fill( void );
unsigned long noOperation( void );
unsigned long raiseCarriage( void );
unsigned long lowerCarriage( void );

unsigned long (*Functions[MAX_CMD])() = 
    {
        lowerCarriage,  //0
        fill,           //1
        raiseCarriage,  //2
        noOperation     //3
    };

void setup() 
{
    Serial.begin(9600);
    while(!Serial);   //optional wait for serial console
    
    pinMode(stepPin, OUTPUT);
    pinMode(dirPin, OUTPUT);
    pinMode(enPin,OUTPUT);
    pinMode(co2pin, OUTPUT);
    pinMode(liquid,OUTPUT);
    pinMode(level_probe,INPUT_PULLUP);
    //
    digitalWrite(enPin,LOW);  
    
    //home the carriage to set initial position and state
    state = CARRIAGE_RAISED;
    lowerCarriage();
    
}//setup

void loop() 
{
    static unsigned long
        timeDelay = 0;
    static unsigned long
        timeMessage = 0;
    unsigned long
        timeNow;
        
    timeNow = millis();    
    if( (timeNow - timeMessage) >= timeDelay )
    {
        timeDelay = MessageHandler();
        timeMessage = timeNow;
        
    }//if
        
}//loop

unsigned long MessageHandler( void )
{
    int
        numbytes;
        
    numbytes = CheckForMessage();
    if( numbytes )
    {
        //Serial.println("Got message!");
        return( ParseMessage() );
        
    }//if
    else
        return 0;
    
}//Message Handler

int CheckForMessage( void )
{
    bool
        done;
    int
        rcvdChar,
        idx;
        
    done = false;    
    idx = 0;
    
    if( Serial.available() == 0 )
        return idx;
    
    memset( RxBuff, 0, sizeof(RxBuff) );
    if( idx = Serial.available() )
    {
        Serial.readBytes( RxBuff, BUFF_SIZE );
               
    }//while
    
    return idx;
    
}//CheckForMessage

unsigned long ParseMessage( void  )
{
    int
        cmd;
        
    if( RxBuff[0] == 'c' || RxBuff[0] == 'C' )
    {
        cmd = RxBuff[1] - '0';
        if( (cmd < 0) || (cmd > (MAX_CMD-1)) )
        {
            Serial.print( "\n ERROR: Unrecognized command: "); Serial.println(cmd);
            return 0;
        }//if

        //act on the command
        return( Functions[cmd]() );               
        
    }//if
    else
        return 0;
        
}//ParseMessage

unsigned long noOperation( void )
{
    Serial.println("***NO OP***");
    return 0;    
    
}//noOperation

unsigned long raiseCarriage( void ) 
{
    unsigned long
        timeTick;
        
    if( (state & CARRIAGE_STATE_MASK) == CARRIAGE_RAISED )
    {
        Serial.println( "Carriage already in the raised state." );
        return 0;
    }//if
    Serial.println("CARRIAGE:");
    Serial.print(" ...Raising carriage");
    timeTick = millis();

    digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
    // Makes 200 pulses for making one full cycle rotation
    for(int x = 0; x < 3810; x++) 
    {
        if( millis() - timeTick >= TICK_TIME )
        {
            timeTick = millis();
            Serial.print(".");
        }            
        digitalWrite(stepPin,HIGH); 
        delayMicroseconds(500); 
        digitalWrite(stepPin,LOW); 
        delayMicroseconds(500); 
        
    }//for

    Serial.println("\n ...Raising complete");

    state = (state & CLR_CF) | CARRIAGE_RAISED;

    return( RAISE_CARRIAGE_DELAY );
    
}//raise_

unsigned long lowerCarriage( void )
{
    unsigned long
        timeTick;
        
    if( (state & CARRIAGE_STATE_MASK) == CARRIAGE_LOWERED )
    {
        Serial.println( "Already in the lowered state." );
        return 0;
    }//if
    Serial.println("CARRIAGE:");
    Serial.print(" ...Lowering carriage");
    timeTick = millis();
    digitalWrite(dirPin,LOW); // Enables the motor to move in a particular direction
    // Makes 200 pulses for making one full cycle rotation
    for(int x = 0; x < 3810; x++) 
    {
        if( millis() - timeTick >= TICK_TIME )
        {
            timeTick = millis();
            Serial.print(".");
        }            
            
        digitalWrite(stepPin,HIGH); 
        delayMicroseconds(500); 
        digitalWrite(stepPin,LOW); 
        delayMicroseconds(500); 
        
    }//for
    
    Serial.println("\n ...Lowering complete");
    
    state = (state & CLR_CF) | CARRIAGE_LOWERED;

    return( LOWER_CARRIAGE_DELAY );
    
}//lowerCarriage

unsigned long fill( void )
{
    unsigned long
        timeNow, timeTick;
        
    if( digitalRead(level_probe) == LOW )
    {
        Serial.println( "Already filled." );
        return 0;
    }//if

    Serial.println("FILL:");
    Serial.print(" ...CO2 Purge start");
    timeNow= millis();
    timeTick = timeNow;
    digitalWrite(co2pin,HIGH);
    do
    {
        if( millis() - timeTick >= TICK_TIME )
        {
            Serial.print(".");
            timeTick = millis();            
        }
    }while( millis() - timeNow < 5000 );
    digitalWrite(co2pin,LOW);
    Serial.println("\n ...CO2 Purge complete");
    
    timeNow = millis();
    timeTick = timeNow;
    Serial.print( " ...Filling" );
    digitalWrite(liquid,HIGH);
    do
    {
        if( millis() - timeTick >= TICK_TIME )
        {
            Serial.print(".");
            timeTick = millis();
            
        }//if

    }while( (digitalRead(level_probe)==HIGH) && (millis() - timeNow < FILL_TIMEOUT)  );
    digitalWrite( liquid, LOW );
    
    if( digitalRead(level_probe) == HIGH )
        Serial.println( "\n ...Fill failure -- TIMEOUT" );
    else
        Serial.println( "\n ...Fill complete" );

    return( FILL_DELAY );
    
}//fill