 */
 
 #define MIN_EXPECTED_LEN 2 // +;
-#define MAX_EXPECTED_LEN 8 // v12.345;
+#define MAX_EXPECTED_LEN 9 // v12.3456;
 
 #define BUFF_LEN (MAX_EXPECTED_LEN + sizeof('\0'))
 char buffer[BUFF_LEN];
 char *buff_ptr;
 
+
 void setup()
 {
-  delay(1);
   serial.begin(9600);
-  serial.print("OK;");
-  serial.flush();
+
+  #ifdef HAS_BOOT_MESSAGE
+  {
+    delay(1);
+    serial.print("OK;");
+    serial.flush();
+  }
+  #endif
   
   // start up the SPI bus
   mySPI.begin();

  }
}

void printError(error_t error)
{
#ifdef HAS_ERROR_PRINTING
  serial.print("!e");
  serial.print(error);
  serial.print(";");
  serial.flush();
#endif
}

void printSuccess(command_t command)
{
#ifdef HAS_SUCCESS_PRINTING
  serial.print("ok");
  serial.print(command);
  serial.print(";");
  serial.flush();
#endif
}

bool DAC_would_overflow(uint8_t num_bits)
{
  return DAC_data == (1 << num_bits) - 1;
}

bool DAC_would_underflow()
{
  return DAC_data == 0;
}

void set_DAC_bits(uint8_t bits)
{
  bool use_2x_gain = true;
  voltageDAC.setVoltageOutputBits(bits, use_2x_gain);
}

#ifdef HAS_INCREMENT_COMMAND
error_t increment_output_voltage()
{
  if (DAC_would_overflow(DAC_num_bits))
  {
    return ERROR_INCREMENT_WOULD_CAUSE_OVERFLOW;
  }

  DAC_data++;
  set_DAC_bits(DAC_data);
  return OK_NO_ERROR;
}
#endif

#ifdef HAS_DECREMENT_COMMAND
error_t decrement_output_voltage()
{
  if (DAC_would_underflow())
  {
    return ERROR_DECREMENT_WOULD_CAUSE_UNDERFLOW;
  }

  DAC_data--;
  set_DAC_bits(DAC_data);
  return OK_NO_ERROR;
}
#endif

#ifdef HAS_VOLTS_COMMAND
error_t parse_and_run_voltage_command(char *buffer)
{
  float v = atof(buffer);
  
  // debug
  serial.println();
  serial.print("parsed volts: ");
  serial.println(v);
  serial.flush();
  
  DAC_data = voltageDAC.setVoltageOutput(v);
  return OK_NO_ERROR;
}
#endif

#ifdef HAS_HEX_COMMAND
error_t parse_and_run_hex_command(char *buffer)
{
  uint16_t bits = 0;
  int num_matches_found = sscanf(buffer, "%x", &bits);
  if (num_matches_found != 1)
  {
    return ERROR_PARSING_HEX_VALUE;
  }

  DAC_data = bits;
  set_DAC_bits(DAC_data);
  return OK_NO_ERROR;
}
#endif


  buff_ptr = buffer;
}


void loop()
{
  command_t command = read_command(&serial, buffer, BUFF_LEN);
  if (command >= END_OF_COMMANDS_SECTION)
  {
    #ifdef HAS_ERROR_PRINTING
    printError(command);
    #endif
    return;
  }

  error_t error;
  
  switch(command)
  {
    
    #ifdef HAS_INCREMENT_COMMAND
    case COMMAND_INCREMENT:
    {
      error = increment_output_voltage();
      break;
    }
    #endif
  
    #ifdef HAS_DECREMENT_COMMAND
    case COMMAND_DECREMENT:
    {
      error = decrement_output_voltage();
      break;
    }
    #endif
  
    #ifdef HAS_VOLTS_COMMAND
    case COMMAND_SET_VOLTS:
    {
      error = parse_and_run_voltage_command(buffer);
      break;
    }
    #endif
  
    #ifdef HAS_HEX_COMMAND
    case COMMAND_SET_HEX:
    {
      error = parse_and_run_hex_command(buffer);
      break;
    }
    #endif
  
    default:
    {
      error = ERROR_UNKNOWN_COMMAND;
      break;
    }
  }
  
  if (error != OK_NO_ERROR)
  {
    #ifdef HAS_ERROR_PRINTING
    printError(error);
    #endif
    return;
  }
  
  #ifdef HAS_SUCCESS_PRINTING
  printSuccess(command);
  #endif
}


command_t read_command(SoftwareSerial *serial, char *buffer, uint8_t buff_len)
{
