How to wait outside the loop without delay()?
You could split Request() into two separate functions: You call sendRequest(), then go do other stuff, then, some time later, you call getResponse(). If you get RESPONSE_NOT_READY, then you know you have to call it later:



#define REQ_WAIT_DELAY     250  // Wait for 250 ms
#define RESPONSE_NOT_READY ((uint16_t) -1)

uint32_t time_request_sent;

void COZIR::sendRequest(char* s)
{
  Command(s);
  time_request_sent = millis();
}

uint16_t COZIR::getResponse()
{
  if (millis() - time_request_sent &lt; REQ_WAIT_DELAY)
      return RESPONSE_NOT_READY;
  buffer[0] = '\0';  // empty buffer
  int idx = 0;
  // From here, same as original COZIR::Request()
}


This assumes that RESPONSE_NOT_READY (0xffff) is not an otherwise valid response. If all 2^16 values of an uint16_t may be valid, then you need another way for the library to signal that the response is not ready. Also, make sure you never compare timestamps, because of the millis() rollover problem. Taking the difference between two timestamps and comparing this with a specified delay (as in the example above) is rollover-safe.

Update: Here is an example of how this could be used:

COZIR cozir(some_serial_connection);

void loop()
{
    static bool waiting_for_a_cozir_response = false;

    if (time_to_get_another_cozir_reading()) {
        if (waiting_for_a_cozir_response) {
            report_something_is_wrong("This COZIR is too slow!");
        }
        else {
            cozir.sendRequest("Hi Cozir! Pliz send me another reading.");
            waiting_for_a_cozir_response = true;
            /* We won't get the response on this iteration. *
             * We will ask next time.                       */
        }
    }
    else if (waiting_for_a_cozir_response) {
        uint16_t response = cozir.getResponse();
        if (response == RESPONSE_NOT_READY) {
            /* Nothing to do now, really. We will just try again *
             * at the next loop() iteration.                     */
        }
        else {
            waiting_for_a_cozir_response = false;
            do_something_with_the_cozir_response(response);
        }
    }
    do_whatever_else_has_to_be_done_in_the_loop();
}