millis over delay!

Hello all

I’m currently in the process of creating a small ‘http gateway’ for my hvac system.

What I’ve done is that I’ve soldered myself (well the Arduino) onto the controlpad of the hvac system so
that I can mimic the up/down/left/right keys on the panel.

I’ve then set up a small HTTP server on the Arduino that accepts command from a home automation controller and I can then
control the fans/temp etc. by sending the correct key sequences.

My problem is that to mimic a key press on the control panel, I have to wait approx. 500mills between each press to let the control panel understand the press, or else the hvac system will loose that key press.

So to narrow in on my question…
As there is no ‘discrete’ commands for eg. going directly to eg. temp degree 23C or going to fan speed 2, I have to first send a lot of key presses to get to the ‘bottom’ of the ‘scale’ and then send the correct amount of key presses to reach the setting I really want.
This introduces a lot of 500ms delay inn between each digital.write(n,high/low); I use. It can go up to 6-7 seconds on the ‘worst’ commands, and thus strange things happens. The ethernet board stops answering pings, and sometimes the whole Arduino just hangs, and I have to reset it manually.

So I’m wondering if anyone has any ideas on how to use millis() in the code instead of delay()?

I’ve tried, but for me the whole mills() is not graspable.

If someone wants to take a look, I’ve attached most of my code below. I’ve taken out all the temperature up/down sequences as it is just a lot of repetitive stuff. Whats left is fan speed 1, 2 and 3.

#include <UIPEthernet.h>
//#include <UIPClient.h>
#include <UIPServer.h>
//#include <UIPUDP.h>

boolean reading = false;

////////////////////////////////////////////////////////////////////////
//CONFIGURE
////////////////////////////////////////////////////////////////////////
  byte ip[] = { 192, 168, 3, 177 };   //Manual setup only
  byte gateway[] = { 192, 168, 3, 1 }; //Manual setup only
  byte subnet[] = { 255, 255, 255, 0 }; //Manual setup only

  // if need to change the MAC address (Very Rare)
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

  EthernetServer server = EthernetServer(80); //port 80
////////////////////////////////////////////////////////////////////////

boolean done = false;


void setup(){
  Serial.begin(9600);

  //Pins 10,11,12 & 13 are used by the ethernet shield

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, INPUT);   //Temp Down
  pinMode(6, INPUT);   //Temp Up
  
  pinMode(7, INPUT);    //Fan Down
  pinMode(8, INPUT);    //Fan Up
  pinMode(9, OUTPUT);

  Ethernet.begin(mac);
  Ethernet.begin(mac, ip, gateway, subnet); //for manual setup

  server.begin();
  Serial.println(Ethernet.localIP());
  
}

void loop(){
  // listen for incoming clients, and process qequest.
    checkForClient();
  }

void checkForClient(){
 
  EthernetClient client = server.available();

  if (client) {

    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;

    while (client.connected()) {
      if (client.available()) {

        if(!sentHeader){
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          
          sentHeader = true;
        }

        char c = client.read();

        if(reading && c == ' ') reading = false;        
        if(c == '?') reading = true; //found the ?, begin reading the info

        if(reading){
          Serial.print(c);

           switch (c) {
            
             
//----------- 1           
// Klikker to ganger ned for å komme til nivå 1 
// Click twice down to reach fan level 2.
            case '1':
            pinMode (7,OUTPUT);
            delay(20);
            digitalWrite(7,LOW);
            delay(500);
            digitalWrite(7,HIGH);
            delay(500);

            digitalWrite(7,LOW);
            delay(500);
            digitalWrite(7,HIGH);
            delay(500);
            pinMode(7,INPUT);//Put Pin in TriState Mode
            client.print("Fan Level 1");
            break;
            
//----------- 2           
// Klikker to ganger ned og en gang opp for å komme til nivå 2. 
// Click twice down and the one up to reach fan level 2.            
            case '2':
            pinMode(7,OUTPUT); //

            delay(20);
            digitalWrite(7,LOW);
            delay(700);

            digitalWrite(7,HIGH);            
            delay(500);
            
            digitalWrite(7,LOW); 
            delay(700);

            digitalWrite(7,HIGH);            
            delay(500);
            pinMode(7,INPUT); //Put Pin in TriState Mode
     
            pinMode(8,OUTPUT); //
            delay(20);            
            digitalWrite(8,LOW); 
            delay(700);
            
            digitalWrite(8,HIGH); 
            delay(500);
            
            pinMode(8,INPUT); //Put Pin in TriState Mode
            client.print("Fan Level 2");
            break;
            
//----------- 3           
// Klikker to ganger upp for å komme til nivå 3.
// Click twice up to reach fan level 3.
            case '3':
            pinMode(8,OUTPUT); //
            delay(20);
            
            digitalWrite(8,LOW);
            delay(500);
            digitalWrite(8,HIGH);
            delay(500);
            
            digitalWrite(8,LOW); 
            delay(500);
            digitalWrite(8,HIGH);
            delay(500);
           
            pinMode(8,INPUT); //Put Pin in TriState Mode
            client.print("Fan Level 3");
            break;
         }

        }

        if (c == '\n' && currentLineIsBlank)  break;

        if (c == '\n') {
          currentLineIsBlank = true;
        }else if (c != '\r') {
          currentLineIsBlank = false;
        }

      }
    }

    delay(1); // give the web browser time to receive the data
    client.stop(); // close the connection:

  } 
}

You have put all those cretinous delays in your program, and you complain that it runs slowly ?

You need to understand how to code things without using delay. The "blink without delay" example sketch is a good place to start.

So I'm wondering if anyone has any ideas on how to use millis() in the code instead of delay()?

I've tried, but for me the whole mills() is not graspable.

Try looking at
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html

Hello

Thanks for a very good explanation in your link, even read the other ones you had there as well, nice reads. :slight_smile:

It's been a while, but I've been trying abit changing my code into using millis().

Can't say I've succeeded :slight_smile:

What I wonder is how to get back into the 'case' if I change delay() into millis()?

The thing is that even though delay() doesn't work properly on the longer button presses, millis() exits the case, and don't return into the 'case' on the next key. I then end up with one keypress to my HVAC instead on eg. 5.

Maybe I need to build the whole check in another way? The 'case' command was rather nice, but maybe it is limiting me now?

Any ideas are greatly appreciated.

Regards
Tommy

Post your code as it is now otherwise your question about cases makes no sense.

In general, when using a state machine the program returns to the same place in the switch/case each time through the loop() function. When the case is such that you are waiting for time to pass then you check each time the case is entered and update the state to a new one when the timing period is up, otherwise go and do something else like reading inputs.

Is that what your code is doing I wonder ?

If you want to see a complex example of a state machine that includes stages in the code as well as time passing in those stages then look at the code for this:-
http://www.thebox.myzen.co.uk/Hardware/Dice_Game.html

I wrote what I hope is a reasonably simple example of using millis() to manage several activities. See the first post in this Thread.

...R