timer/counter/millis

Hi all, I am looking for some help for a sequence.
I would like some help for the following…

When a switchstate is high and a variable is > 0 the following should happen,

stepper motor should turn, when the motor stops a timer should start, when the timer reaches a set value, the sequence should then loop to the start reset the timer and check switchstate and variable >0.

This should continue until either the switch is low or the variable reaches 0. And each time the timer is reset as it goes through the loop

This is what I have so far,

{   

  if (ModeState != lastModeState) {                    // Compare the Switch state to its previous state
  if (ModeState == LOW){                               // If the unit is in Run mode (HIGH), the quantity and length values can be changed by the user display panel 
                                                       // If the unit is in  mode (LOW), the quantity and length buttons are disabled and the motor loop is enabled
  Serial.println("RUN mode");
  
    
 
 if(QtyPushCounter > 1);                                                      // If the QtyPushCounter is greater than 1 print the value to the serial monitor
 Serial.println(QtyPushCounter);
  }
  unsigned long currentMillis = millis();
  
    if(currentMillis - previousMillis >= interval && QtyPushCounter > 0) // Time since the arduino started
    {    previousMillis = currentMillis;
     int i;

  digitalWrite(DirectionPullThrough, LOW);             // Set the Direction of Pull-through motor (LOW = Anti-clockwise/HIGH = Clockwise)
 QtyPushCounter --;
   for (i = 0; i<3200; i++)                                // Turn the stepper the value of the ButtonPushLength * 2 ( in this case 1600 steps)
  {
    digitalWrite(SleepPullThrough, HIGH);              // ENABLE the PullThroughMotor
    digitalWrite(StepPullThrough, HIGH);               // Step set to HIGH
    digitalWrite(StepPullThrough, LOW);                // Step set to LOW
    delayMicroseconds(1000);                             // Motor Speed (fast = < slow = >)
   
    
  }
  } 
   else {                                               
      
      digitalWrite(SleepPullThrough, LOW);             // Set the PullThroughMotor to SLEEP mode
  } 
  lastModeState = ModeState;                            // Save the Mode State for next time round the loop
  {
    Serial.println("Time:");                                 // Print the currentMillis value to the serial monitor
    currentMillis = millis();
    Serial.println(currentMillis);
    delay(1000);
  }

My problem is, I dont think the millis function is what im after, does anyone have any examples. Or be good enough to put me out of my misery?

Thanks in advance

if(QtyPushCounter > 1);You need to get out of the habit of putting semicolons after everything.

A good habit to get into would be to use the IDE's auto-format tool before posting code

Apologies, will repost with auto format, however that semi-colon isn't affecting the timer issue. Can you shed any light on how I can achieve the timing sequence?

scarney1986: Can you shed any light on how I can achieve the timing sequence?

When you post all your code, maybe, but I'm watching Jools Holland right now, then going to bed.

no internet connection to the desktop at the moment the hub keeps going down on my street so can't post the full code, everything else is working fine, only code relevant to this section is;

unsigned long previousMillis =0; long interval =10000;

void setup()

//stuff

Void loop()

The code in post #1

Note: the motor turns, the switch states are working, the variables and if else statements are okay it's just the timers I need help with.

scarney1986: My problem is, I dont think the millis function is what im after, does anyone have any examples.

Unless you need to do sub-millisecond timing you should be able to time any sort of process with millis()

But we need to see the complete program.

...R

Full program attached,

qty_length_lcd_all_comments.ino (32.1 KB)

You seem to be a college student so I reckon you should already know to use functions to make a program manageable. At the moment all the code is in loop() which means it would take me a long time to figure it out (and I am lazy).

Have a look at Planning and Implementing a Program and re-organize your code. In doing so I suspect you will find the solution to the problem.

...R

I am a student, but not of programming/microcontrollers or any coding language of any sort.

This is my first dip into the waters of programming, and i’m still finding my feet, im finishing an EE course in the next month, I am happy for any help/advice but the trouble is I have no prior knowledge and i’m picking things up as I go, so if my approach may seem haphazard in my execution then that’s the reason.

In my defence, considering most other issues on here from new starters, I’ve at least made some semblance of effort before asking for help. It would be nice if people could oblige, I will take a look at the implementation and planning sheet you attached Robin, however I am reluctant to perform an overhaul of code where 95% is functioning as I’d expect it to and making a bigger task then is necessary, this timer to start the motor loop whilst in run mode is literally the final piece of the puzzle then the projects done.

I am not being marked on the efficiency of the code in any way shape or form, the tutors won’t even look at it, it is the electronic circuitry/pcb’s/wiring and specifications they are interested in. The programming just makes it perform the operation.

Thanks for any help you can provide AWOL/Robin2 or anyone else for that matter, I really do wish to learn and any help is much appreciated.

Sean

scarney1986:
In my defence, considering most other issues on here from new starters, I’ve at least made some semblance of effort before asking for help. It would be nice if people could oblige

I understand that. But you must remember that you are very familiar with your program and I am not. Where should I start looking for the part that is causing the problem?

Maybe if you point out the line-numbers where you think the problem arises it would help. But oftentimes the problem is not where it is first thought to be. To my mind you have been unusually lucky to get so far with such a large program before running into a problem.

…R
PS. I am not impressed by a college that expects students to produce that size of program without giving any tuition in programming.

I can fully appreciate that Robin and I'm chuffed that you and others are even attempting to help, I'm currently going through your guide now to restructure it, as advice given is advice worth listening to in my experience.

The code is recording the states of two sets of spst buttons, 3 for quantity counter circuit 3 for length counter circuit 1 switch determining run/setup mode

The spst buttons correspond to up/down/reset to some sn74ls192n logic ids which drive sn74ls47n bcd encoders to 7seg displays. The idea is the code records the state of the buttons then when a button changes state it changes the logic of the counter if on the pin it relates to, so up=pin5 down =pin 4, reset =14. So the user has the 7segments 0-999 counters to select quantity of wires to cut, and length which it cuts them.

The quantity variable determines how many times the motor sequence loops, and the length variable determines how many steps the pull through motor takes to pull the wire off a spool.

All the counting, writing to LCD display, to serial monitor, variables are working and in good order, the point I'm at now is the motor sequence right at the bottom.

//MOTOR SEQUENCE

The motor is driven by dir and step pins from an easydriver4.4pcb, I can get the step and direction working fine, so the wiring is not an issue, my problem is.

The motor sequence should start when it ModeState goes LOW, and then the loop should check for the following,

QtyPushCounter >0 (meaning there is 1 or more wires required to be cut) LengthPushCounter > 10 (meaning the user has specified a length of more than 10mm) ModeState == LOW

Once these checks have been made I'd like the motor to turn for the steps, I can do that fine then pause using interval =10000 as part of the Millis()function then QtyPushCounter --; to decrease the quantity variable by 1. Then loop until either the QtyPushCounter variable reaches 0 OR the ModeState changes.

Like I said I am heeding your advice and I'm restructuring the code but it's just this millis() loop at the end that I'm struggling with. Thanks again Robin I know you must be despairing of me by now.

I was browsing your program again and it has a huge amount of repetition. For example the code starting at line 263 is almost identical to the code that starts at line 287 and a lot of it is also repeated at line 330 and probably elsewhere. Those repetitive chunks should be in a function so you only need to write them once and call them whenever you need them. Writing the same thing over an over just introduces opportunities for typing errors and if you change something you have to remember to do it in several places - which is easy to forget.

I conceived this before reading your Reply #10, which I will do now.

...R

I have had a look at your MOTOR SEQUENCE section and I have re-formatted it a bit to make it easier to see the relationships between IF and ELSE. I have also removed some superfluous pairs of {} and moved some long comments to their own lines so t is easier to read the code without my eye alighting on them.

There seems to be a superfluous } on line 526 or 527 and there is an erroneous ; at the end of line 507.

The collection of }}} on line 540 is a recipe for confusion. Put each one on its own line properly indented. Use the auto-format tool in the Arduino IDE.

I prefer to do my indentation using the tab key but they don’t reproduce properly here so I have converted each tab to 4 spaces.

Maybe you can have a look over this version and then explain again what is actually happening and what you want to happen.

    // MOTOR SEQUENCE
    
ModeState = digitalRead(ModeSwitch);        // Read the Mode Switch input Pin 36   
 
if (ModeState != lastModeState) {           // Compare the Mode Switch state to its previous state
    if (ModeState == LOW){                               
            // If the unit is in Run mode (HIGH), the quantity and length values can be changed by the user display panel 
            // If the unit is in Setup mode (LOW), the quantity and length buttons are disabled and the motor loop is enabled
        Serial.println("Run Mode");         // Print Run Mode to the Serial monitor

        if(QtyPushCounter > 0) {            // If Quantity Push counter is greater than 0
            Serial.println(QtyPushCounter);                  
                // Print the value of Quantity Push Counter to the serial monitor
        }
    }
    unsigned long currentMillis = millis();
 
 
    if(currentMillis - previousMillis >= interval && QtyPushCounter > 0) {    
            // If the Time since the Pull-through Motor turned is greater than the interval time, and the qtyPushCounter is greater than 0
        previousMillis = currentMillis;                                           
            // Save currentMillis value as variable PreviousMllis value for next time through the loop

        int i;

        digitalWrite(DirectionPullThrough, LOW);             
            // Set the Direction of Pull-through motor (LOW = Anti-clockwise/HIGH = Clockwise)

        for (i = 0; i<3200; i++)   {                         
            // Turn the stepper the value of the ButtonPushLength * 2 ( in this case 1600 steps)

            digitalWrite(SleepPullThrough, HIGH);       // ENABLE the PullThroughMotor
            digitalWrite(StepPullThrough, HIGH);        // Step set to HIGH
            digitalWrite(StepPullThrough, LOW);         // Step set to LOW
            delayMicroseconds(1000);                    // Motor Speed (fast = < slow = >)
        }

    } 
    else {                                               
        
        digitalWrite(SleepPullThrough, LOW);            // Set the PullThroughMotor to SLEEP mode
    } 
    lastModeState = ModeState;                           
        // Save current Mode state for next time through the loop

    Serial.println("Time:");            // Print Time: to the Serial Monitor
    currentMillis = millis();           // Check current value of millis()
    Serial.println(currentMillis);                       
        // Print current value of millis() to the Serial Monitor
    delay(1000);                                         
        // Delay by 1000 ms to make the Serial Monitor feed readable

}

…R

Robin first off, can I thank you so much for your help and patience especially.
I have restructured as per your guide and I now think I understand the functions and how to layout the code properly.

I have attached my new code, hope it does your guide justice, it still needs each of the lines of code commenting on whats going on, and I have to finish of the lcd and cutting motor functions but theyre easily in hand now that I have the rest sorted.

Thanks once again, and if you could see anywhere I may still need further improvement please feel free to make comments.

Thanks Sean

AutomaticWireCutter.ino (16.7 KB)