Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 38

Thread: KISS problem setting Millis timed pulses during ON time

  1. #1
    Senior Member
    Join Date
    Sep 2016
    Posts
    174

    KISS problem setting Millis timed pulses during ON time

    I have one of those days that something is so simple,
    You can’t get your head around it.


    Simple Toggle

    Code:
    Void setup()
    {
    pinMode(13,OUTPUT);//led during On Time
    pinMode(0,OUTPUT);
    pinMode(1,OUTPUT);
    }
    
    
    Void loop()
    {
    // probably I’ll have to set the condition of the pin =0; because the compiler doesn’t know
    If(digitalRead(0)==HIGH)
    {
    digitalWrite (0,LOW);
    }
    else
    {
    digitalWrite(0,HIGH);
    }
    }
    
    
    
    }
    So this will toggle unlimited, I think.
    I would like use this inside a function to set the number of pulses during a period of time in mseconds or seconds.


    Code:
    Void setup()
    {
    pinMode(13,OUTPUT);//led during On Time
    pinMode(0,OUTPUT);
    pinMode(1,OUTPUT);
    }
    
    
    Void loop()
    {
    for(int i =0; i<5;i++)
    {
    If(digitalRead(0)==HIGH)
    {
    digitalWriteFast(0,LOW);
    }
    else
    {
    digitalWriteFast(0,HIGH);
    }
    }
    
    
    
    }
    It repeats 5 and should stop and jump out of the loop correct?


    The real question is
    How do I create a burst of pulses during an given amount of time and set the number of pulses over this Time. I have something like an interval, the Same as this example.
    HTML Code:
     https://www.baldengineer.com/millis-ind-on-off-times.html
    However this sets the pulses during the ON time but I don’t have control over the pulses and their respective time they are high or low.

    Can someone help me out?

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    That code will count to 5 for each continuous call of loop() - not noted which Teensy so it could be some 10K, or 100K or even some 1-10 Million per second calls to loop() each second.

    It seems that code is missing timing and counting options desired?

    For this purpose doing digitalToggle(uint8_t pin) or digitalToggleFast(uint8_t pin) { for a constant compile time pin# } would be faster than reading the current value and writing it back.
    > if the pin is always left HIGH as indicated { in second CODE piece, this could be done at the END of setup}
    > - then Toggle() will put that to LOW on the first call and then as implied Toggle that state on each call after that.

    To create a known specific pause/delay use { between each toggle }: delayMicroseconds()

    For time controlled entry use PJRC Variables of type: elapsedMicros or elapsedMillis

    That should give the tools needed to control the time between HIGH and LOW transitions, and also the time between those sets.

    Quick example types on the fly here:
    Code:
    elapsedMicros timeGroup = 435665; // A big number assuring it triggers the first time into loop
    
    // do pin setup()
    
    void loop() {
      if ( timeGroup > 1000 ) { // will trigger once per millisecond at 1,000 us
        for ( int ii=0; ii<5; ii++ ) {
          digitalToggleFast( 0 );
          delayMicroseconds( 100 ); leave in this state for 100 us
        }
        digitalWriteFast(0,HIGH);
        timeGroup=0;
      }
    
    }

  3. #3
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    Quote Originally Posted by defragster View Post
    That code will count to 5 for each continuous call of loop() - not noted which Teensy so it could be some 10K, or 100K or even some 1-10 Million per second calls to loop() each second.

    It seems that code is missing timing and counting options desired?

    For this purpose doing digitalToggle(uint8_t pin) or digitalToggleFast(uint8_t pin) { for a constant compile time pin# } would be faster than reading the current value and writing it back.
    > if the pin is always left HIGH as indicated { in second CODE piece, this could be done at the END of setup}
    > - then Toggle() will put that to LOW on the first call and then as implied Toggle that state on each call after that.

    To create a known specific pause/delay use { between each toggle }: delayMicroseconds()

    For time controlled entry use PJRC Variables of type: elapsedMicros or elapsedMillis

    That should give the tools needed to control the time between HIGH and LOW transitions, and also the time between those sets.

    Quick example types on the fly here:
    Code:
    elapsedMicros timeGroup = 435665; // A big number assuring it triggers the first time into loop
    
    // do pin setup()
    
    void loop() {
      if ( timeGroup > 1000 ) { // will trigger once per millisecond at 1,000 us
        for ( int ii=0; ii<5; ii++ ) {
          digitalToggleFast( 0 );
          delayMicroseconds( 100 ); leave in this state for 100 us
        }
        digitalWriteFast(0,HIGH);
        timeGroup=0;
      }
    
    }

    Didn稚 had any luck today running this kind of code inside an independent on off function
    Somehow I am misreading my signals from the teensy4.1.
    I値l try it first thing in the morning!

  4. #4
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    ... better luck in the morning

    The p#2 code could move the code after the "if ( timeGroup > 1000 )" to an independent function. Except probably the "timeGroup=0;" to leave that in control there, where it could be done before that function call if the next call was to be the same time apart from the last, or after as written that would be called about 500us later with each loop.

    As written it runs those enclosed instructions once per ms.

    Bumping those times up adding Zeroes would make it easy to see the LED blink rate - and even sent out Serial.print debug strings to see it working.

  5. #5
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    Good morning,

    So as to speak I’ll try this with elapsedmillis, I have more going on in my code. How do I check that the ONTime from the bald engineer link isn’t passed?
    Code:
    int setToggleTime=500;
    elapsedmillis=Timetoggle;
    Int OnTime=2000;// from previous function. Needs to check condition of the following if statement.
    
    //Something like:
    if(Timetoggle<=OnTime)
    {
    
    for ( int ii=0; ii<5; ii++ ) {
          digitalToggleFast( 0 );
          
        }
        digitalWriteFast(0,HIGH);
        Timetoggle=Timetoggle-setToggleTime;
      }
    
    Timetoggle=0;
    
    }
    Else
    {
    
    digitalWriteFast(0,LOW);
    
    }
    So it has to toggle in 500ms 5x and total 20x?
    Last edited by Bastiaan; 04-20-2021 at 06:26 AM. Reason: Something like this

  6. #6
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    Didn't follow the link - just provided a snippet in direction of the indicated desires to start and show function and the basic tools that can use Time to control I/O behavior.

    Once that is seen to work in reference to the post#1 the two time values in that sample can be adjusted to get the series of toggles desired at a given freq per second - which seemed to be the indicated desire - at least for a start.

  7. #7
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    Just seeing the code was modified - but not compiled or put into the IDE and using "Ctrl+T" to format the code for posting readability - doing that here it starts like - and has some issues so not sure of the intent:
    Code:
    loop() {
    	int setToggleTime = 500;
    	elapsedmillis = Timetoggle;
    	Int OnTime = 2000; // from previous function. Needs to check condition of the following if statement.
    
    //Something like:
    	if (Timetoggle <= OnTime)
    	{
    		for ( int ii = 0; ii < 5; ii++ ) {
    			digitalToggleFast( 0 );
    		}
    		digitalWriteFast(0, HIGH);
    		Timetoggle = Timetoggle - setToggleTime;
    	}
    
    	Timetoggle = 0;
    	else
    	{
    		digitalWriteFast(0, LOW);
    	}
    }
    Double check the usage of the elapsedMillis in use. An unsigned 32 bit integer once set to Zero ( or any value ) it is ever increasing ( until it exceeds the uint32 value it can hold) when it wraps to zero - in the case of Millis at the rate of 1,000 per second.

    To do this and then STOP? :: "to toggle in 500ms 5x and total 20x"
    Code:
    uint32_t setToggleTime = 500;
    elapsedmillis Timetoggle;  // this will start counting from 0 when the code is loaded and the variable in created before the code starts running
    // uint32_t OnTime = 2000; // from previous function. Needs to check condition of the following if statement.  // Not sure how this factors in? 2,000/500 is 4 not 5?
    uint32_t numRepeats = 20;
    uint32_t cntRepeats = 0;
    
    loop() {
    
    //Something like:
    	if ( cntRepeats < numRepeats && Timetoggle >= setToggleTime) // for 20 Toggle counts total this will enter once every 500ms==setTimeToggle, doing 5 each entry
    	{
    		for ( int ii = 0; ii < 5; ii++ ) {  // THIS will toggle the pin 0 as fast as possible - some few nano seconds without the delay in post #2
    			digitalToggleFast( 0 );   
    		        cntRepeats++;
    		}
    		digitalWriteFast(0, HIGH);
    		Timetoggle = 0;
    	}
    	else
    	{
    		digitalWriteFast(0, LOW);
    	}
    }
    This should do something reasonable to the definition provided ... hopefully ...

  8. #8
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    Code:
    #define ENCODER_OPTIMIZE_INTERRUPTS
    #include <SPI.h>
    #include <elapsedMillis.h>
    #include <ButtonEvents.h>
    #include <Encoder.h>
    
    // digital IO pins.
    #define C_BLACK      0x0000
    #define C_BLUE        0x001F
    #define C_RED         0xF800
    #define C_GREEN       0x07E0
    #define C_CYAN        0x07FF
    #define C_MAGENTA     0xF81F
    #define C_YELLOW      0xFFE0
    #define C_WHITE       0xFFFF
    
    #define TFT_CS     10
    #define TFT_RST    -1
    #define TFT_DC      9
    
    #define MAXMISO    39
    #define MAXCLK     27 //max31855 clk2 nothing else.
    
    #define MAX31855_1 29
    #define MAX31855_2 30
    #define MAX31855_3 31
    #define MAX31855_4 32
    
    
    //left side of the teensy4.1
    const int INB_AntiClockWise       = 0;
    const int INA_Clockwise             = 1;
    const int DIR_TEC_Cool            = 3;
    const int PWM_DRV_TEC1_2_3        = 5;
    const int PWM_DRV_PUMP            = 4;
    const int PWM_EMAGNET             = 5;
    const int ENCpin6                 = 6;
    const int ENCpin7                 = 7;
    const int FLOW_Sensor             = 24;  //switched with //PWM BACKLIGHT
    const byte buttonPin              = 28;
    
    byte ON_OFF_BIPOLAR = 0;
    unsigned long endmicros;  //speed check variables
    unsigned long currentmicros;
    elapsedMillis firstsecond;
    elapsedMillis TCmillis;
    elapsedMillis TFTmillis;
    elapsedMillis Delaymillis;
    
    byte menuCount = 1;
    byte HoldCount = 0;
    int icountreps = 0;
    //-------------------------------------------------Encoder Values Default
    long oldPosition  = -100;
    long newPosition;
    long Position;
    long oldPWMPosition = -100;
    long PWMPosition = 1;
    
    
    //-----------------------------------------------Default values for Sensors and PWM
    float TempValue               = 0;               //encoder value to double
    int PMPSpeed                  = 0;               //variable to be changed constrain and map
    float  PMP_Liter_Min_Display  = 0;               //display value from the PUMP ==corresponds with max L/min Datasheet VPP655
    int PMP_PWM                   = 0;               //Pump PWM
    float EMAGNET                 = 0;               //Screen Value current is max 16.7A.
    int EMAGNETPWM                = 0;               //PWM for Emagnet is 0.
    
    unsigned int Repitition_rate = 10;                 //goes infinite if Zero.
    
    int ON_VNH5019 = LOW;
    
    unsigned int ON_Time1 = 1000;                     // preliminary values at start up
    unsigned int OFFTime1 = 5000;
    unsigned int setToggleTime = 500;
    elapsedMillis TimeToggle;
    
    elapsedMillis ElapsedOFF;                         //used in the Background Calculations
    elapsedMillis ElapsedON;                          //Idem
    
    
    //default Configuration Current Direction Bipolar to Unipolar
    boolean Bipolar = true;
    boolean Unipolar = false;
    int ConfigMin = 2048;
    int ConfigMax = 4095;
    int EmagnetConfig;
    
    
    boolean LED13state = true;
    // Tracks the last time event fired
    unsigned long previousMillis = 0;
    byte LongPress = 0;
    
    // Interval is how long we wait
    int Interval = ON_Time1;
    ButtonEvents myButton;  // Instantiate a Bounce object
    Encoder enc(ENCpin6, ENCpin7); //instance Encoder Rotary
    
    
    
    
    void setup()
    {
      Serial.begin(9600);
      //SPI CS pins for the MAX31855 need to be set high!
      pinMode(buttonPin, INPUT);
      pinMode(INB_AntiClockWise, OUTPUT);
      pinMode(INA_Clockwise, OUTPUT);
      pinMode(DIR_TEC_Cool,OUTPUT);
      
      myButton.attach(buttonPin);
      myButton.activeHigh();
      myButton.debounceTime(5); //apply 15ms debounce
      myButton.doubleTapTime(250);//apply 250ms Double click detection
      myButton.holdTime(2000);
    
    
      //setting the default state of the VNH5019
      digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockWise, LOW);
    
    }
    
    void loop()
    {
      Serial.begin(9600);
      MENU_ON_OFF_HOLD(); //simple Hold buttonevent
      ON_OFFTIMER();// other function is called in the ON TIME of the ON_OFFTIMER.
    
    }
    
    int MENU_ON_OFF_HOLD()
    {
      if (myButton.update() == true)
      {
        switch (myButton.event())
        {
          // things to do if the button was held
          case (hold) :
            {
              HoldCount = HoldCount + 1;
              Serial.println("HOLD event detected");
              break;
            }
        }
      }
    
    
    
    
      if (HoldCount > 2)
      {
    
        HoldCount = 0;
    
    
      }
    
      if (HoldCount == 0)
      {
        ON_OFF_BIPOLAR = 0;
      }
    
      if (HoldCount == 1)
      {
        ON_OFF_BIPOLAR = 1;
    
      }
    }
    
    
    
    int ON_OFFTIMER()
    {
    
    
      /// blink during the menuCount check later on Countdown Zero or not Jump to MenuCount 1
      if ((ON_VNH5019 == HIGH) && (ElapsedOFF >= OFFTime1)) //OFFTime first
      {
        ON_VNH5019 = LOW;
        // ElapsedOFF=ElapsedOFF-OFFTime1;
        Serial.println(" OFF                  ");
        digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockWise, LOW);
        ElapsedOFF = 0; ElapsedON = 0;
    
      }
      else if ((ON_VNH5019 == LOW) && (ElapsedON >= ON_Time1)) //ONTime Second
      {
        ON_VNH5019 = HIGH;
        Repetition_Polarity_Change_Emag();
        //    delay(ON_Time1+minimumLT3760);
        ElapsedOFF = 0; ElapsedON = 0;
    
      }
    }
    
    
    
    
    
    int Repetition_Polarity_Change_Emag()
    {
      //Bipolar action check on HOLD Count
      if (ON_OFF_BIPOLAR == 1) //HOLD BUTTON press detected
      {
        Serial.print(" Bipolar ");
        if (TimeToggle > pulseDuration)
        {
          for (int i = 0; i < Repitition_rate; i++)
          {
    
    
            Serial.println("    Clockwise ");
            digitalToggleFast(INA_Clockwise);
            Serial.print(digitalRead(INA_Clockwise));
            Serial.print(" INA ");
            Serial.print(digitalRead(INB_AntiClockWise));
            Serial.println(" INB ");
            Serial.print("Counts ");
            Serial.println(i);
    
    
    
          }
    
         digitalWriteFast(INA_Clockwise, LOW); digitalToggleFast(INB_AntiClockWise);
         TimeToggle=0;
        }
         
    
        
      }
    
    
      else //UNIPOLAR if holdCount is something else as 1.
      {
        Serial.println("UNI ");
        if (TimeToggle > pulseDuration)
        {
          for (int i = 0; i < Repitition_rate; i++)
          {
    
            digitalToggleFast(INA_Clockwise);
            Serial.println("      Clockwise ");
            Serial.print(digitalRead(INA_Clockwise));
            Serial.print(" INA ");
            Serial.print(digitalRead(INB_AntiClockWise));
            Serial.println(" INB ");
    
    
          }
    
    
          digitalWriteFast(INA_Clockwise, LOW);digitalWriteFast(INB_AntiClockWise, LOW);
          Serial.println(" Break");
          Serial.print(digitalRead(INA_Clockwise));
          Serial.print(" INA ");
          Serial.print(digitalRead(INB_AntiClockWise));
          Serial.println(" INB ");
    
    
    
    
    
         TimeToggle=0;
         digitalWriteFast(INA_Clockwise, LOW);digitalWriteFast(INB_AntiClockWise, LOW);
          
        }
    
    
      }
    
    
    
    }
    almost there. i dont want to use delaymicroseconds but elapsedMillis();

  9. #9
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    Yes, always best to avoid delay() unless it is short and time critical as that stops other normal loop() code.

    Seems like that gives the needed tools now to work it out.

    It could be done other ways as well, perhaps an intervalTimer _isr() could be started in loop() as needed and it could stop itself after the needed cycles that would handle the I/O toggle ...

  10. #10
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    i thought combining the two independent millis into one would be proof much usefuller, why is it only reacting to the first If statement in the void loop?
    why cant i control the OnTimePulseClock and OffTimePulseClock?
    but somehow only the first If statement in the void loop is accessed but the other function with Micros is not accessed why?


    what i am trying to achieve is that during the independent ON Time the pins 0,1 are toggled and be controlled with variables to change the number of pulses and the pulsewidth,

    during the onTime=500 the pulses need to be 400useconds

    Code:
    int ledPin13 =  13;      // the number of the LED pin
    int ledState13 = LOW;             // ledState used to set the LED
    unsigned long previousMillis = 0;        // will store last time LED was updated
    long OnTime1 = 1000;           // milliseconds of on-time
    long OffTime1 = 500;          // milliseconds of off-time
    
    
     //first pulse from digitalPin 0
    int ledPin0 =  0;      // the number of the LED pin
    int ledPin1 =  1;
    int ledState1  =LOW;
    int ledState0 = LOW;             // ledState used to set the LED
    unsigned long previousMicros0 = 0;        // will store last time LED was updated
    long OnTimePulseClock_Pin_0 = 400;           // Microseconds of on-time
    long OffTimePulseClock_Pin_0 = 400;          // Microseconds of off-time
      unsigned long currentMicros=micros();
    
             // milliseconds of off-time
    
      
    
     
    void setup() 
    {
      // set the digital pin as output:
      pinMode(ledPin0, OUTPUT);
      pinMode(ledPin1, OUTPUT);      
      pinMode(ledPin13, OUTPUT);
    
      Serial.begin(9600);
    
           
    }
     
    void loop()
    {
      // check to see if it's time to change the state of the LED
    unsigned long currentMillis = millis();
     
      if((ledState13 == HIGH) && (currentMillis - previousMillis >= OnTime1)) ///on Time of the main loop
      {
        ledState13 = LOW;  // Turn it off
        previousMillis = currentMillis;  // Remember the time
        digitalWrite(ledPin13, ledState13);  // Update the actual LED
        
        Serial.println("ON ");
      }
      else if ((ledState13 == LOW) && (currentMillis - previousMillis >= OffTime1))
      {
        ledState13= HIGH;  // turn it on
        previousMillis = currentMillis;   // Remember the time
        digitalWriteFast(ledPin13, ledState13);    // Update the actual LED
    Function_Pulse_Control();
        Serial.println(" OFF ");
      }
      
      
    }
    
    int     Function_Pulse_Control()
    {
    
      if((ledState0 == HIGH) && (currentMicros - previousMicros0 >= OnTimePulseClock_Pin_0))
      {
        ledState0 = LOW;  // Turn it off
        previousMicros0 = currentMicros;  
        digitalToggleFast(ledPin0);  
        digitalWriteFast(ledPin1, LOW);
        Serial.println("  Clockwise  ");
      }
      else if ((ledState0 == LOW) && (currentMicros - previousMicros0 >= OffTimePulseClock_Pin_0))
      {
        ledState0 = HIGH;  // turn it on
        previousMicros0 = currentMicros;   
        digitalToggleFast(ledPin1);  
        digitalWriteFast(ledPin0, LOW);
        Serial.println("  AntiClockwise  ");
      }
    
    
      
    }
    Last edited by Bastiaan; 04-20-2021 at 11:28 AM.

  11. #11
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    of course i can tune them indepedent from each other

    but its a bit trickier, i have to set the On and OFF Time very low...

    any suggestions?

    Code:
    int ledPin13 =  13;      // the number of the LED pin
    int ledState13 = LOW;             // ledState used to set the LED
    unsigned long previousMillis = 0;        // will store last time LED was updated
            // will store last time LED was updated
    unsigned long OnTime1 = 1;          // milliseconds of on-time
    unsigned long OffTime1 = 10;          // milliseconds of off-time
    
    
    //first pulse from digitalPin 0
    int ledPin0 =  0;      // the number of the LED pin
    int ledPin1 =  1;
    int ledState1  = LOW;
    int ledState0 = LOW;             // ledState used to set the LED
    unsigned long previousMicros0 = 0;        // will store last time LED was updated
    unsigned long previousMicros1 = 0; 
    long OnTimePulseClock_Pin_0 = 100;           // Microseconds of on-time
    long OffTimePulseClock_Pin_0 = 100;         // Microseconds of off-time
    
    long setToggleTime = 10;
    elapsedMicros Timetoggle;  // this will start counting from 0 when the code is loaded and the variable in created before the code starts running
    // uint32_t OnTime = 2000; // from previous function. Needs to check condition of the following if statement.  // Not sure how this factors in? 2,000/500 is 4 not 5?
    uint32_t numRepeats = 100;
    uint32_t cntRepeats = 0;
    
    // milliseconds of off-time
    
    
    
    
    void setup()
    {
      // set the digital pin as output:
      pinMode(ledPin0, OUTPUT);
      pinMode(ledPin1, OUTPUT);
      pinMode(ledPin13, OUTPUT);
    
      Serial.begin(9600);
      digitalWriteFast(0, LOW); digitalWriteFast(1, LOW);
    
    }
    
    void loop()
    {
      // check to see if it's time to change the state of the LED
      unsigned long currentMillis = millis();
    
      if ((ledState13 == HIGH) && (currentMillis - previousMillis >= OnTime1)) ///on Time of the main loop
      {
        ledState13 = LOW;  // Turn it off
        previousMillis = currentMillis;  // Remember the time
    
        Function_Pulse_Control();
        Serial.println("ON ");
        digitalWrite(ledPin13, ledState13);  // Update the actual LED
      }
      else if ((ledState13 == LOW) && (currentMillis - previousMillis >= OffTime1))
      {
        ledState13 = HIGH; // turn it on
        previousMillis = currentMillis;   // Remember the time
        digitalWriteFast(ledPin13, ledState13);    // Update the actual LED
        digitalWriteFast(0, LOW); digitalWriteFast(1, LOW);
        Serial.println(" OFF ");
      }
    
    
    }
    
    int Function_Pulse_Control()
    {
    
      unsigned long currentMicros = micros();
      unsigned long currentMicros1 = micros();
    
      if ((ledState0 == LOW) && (currentMicros - previousMicros0 >= 200000)) //200ms//INA
      {
        
          ledState0 = HIGH;  // Turn it off
          previousMicros0 = currentMicros;
          
          digitalWriteFast(ledPin0, HIGH);
          Serial.println("  Clockwise  ");
         
        
        
      }
      else if ((ledState0 == HIGH) && (currentMicros - previousMicros0 >= 200000)) //200ms
      {
          ledState0 = LOW;  // turn it on
          previousMicros0 = currentMicros;
          digitalWriteFast(ledPin0, LOW);
        
          Serial.println("  AntiClockwise  ");
    
    
    
    
        
      }
      else
      {
        
        digitalWriteFast(ledPin0, LOW);
      }
    
    
      if ((ledState1 == LOW) && (currentMicros1 - previousMicros1 >= 500000))//500ms
      {
        
          ledState1 = HIGH;  // Turn it off
          previousMicros1 = currentMicros1;
          
          digitalWriteFast(ledPin1, LOW);
    
         
        
        
      }
      else if ((ledState1 == HIGH) && (currentMicros1 - previousMicros1 >= 100000))//100ms
      {
          ledState1 = LOW;  // turn it on
          previousMicros1 = currentMicros1;
          digitalWriteFast(ledPin1, HIGH);
       
          Serial.println("  AntiClockwise  ");
    
    
    
    
        
      }
      else
      {
        digitalWriteFast(ledPin1, LOW);
        
      }
    
    
    
    
    
      
    }

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    It can help to write out a statement of expected behavior in text. Without that even looking into the behavior of 'close' code won't help because what is wrong won't be obvious not knowing what it should be doing ... make sense?

    As noted one set of tools is understood now - the problem is not blocking with delay means the code has to act and leave and then know to return to do the 'next' toggle.

    If that Toggle behavior is STARTED (?) out - doing it with an interrupt driven intervalTimer _isr() it could be initiated and forgotten without working to get the loop() running to keep up with the needed toggles.
    Last edited by defragster; 04-20-2021 at 10:00 PM.

  13. #13
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    Hi Defragster,

    now its my turn, i didnt understand a thing you just told me, no offense.
    never worked with ISR, had it in my studies but never worked with it.
    no clue what speeling is.

    il elaborate

    ill go through the steps: the second assignment should only work during the ON Time of the first assignment.

    i have two cases for my VNH5019 Hbridge driver, (ill leave out the PWM because thats just an encoder value which i dont require to set now).

    First Assignment :

    i have a Millis with an independent ON OFF Timer that sets the duration when VNH5019 is going to be activated.
    The OFF time is relaxation, and the VNH5019 is OFF. this works with a led perfectly.
    ----------------------------------------------
    Second Assignment:

    First Case: Unipolar

    i have to switch one digitalPin INA HIGH or LOW to activate the motor turning Clockwise or Brake.
    the digitalPin INB is set low in this case.

    i would like to Control the duration of HIGH state of the INA. INB will be LOW=Brake. hence control the duration of the pulse.

    Second Case: Bipolar

    i switch both states INA and INB inverted to each other. they are not allowed to cross each others domain.
    and need to be seperated for security measures with 400us + same adjustable pulsewidth for both.

    INA==HIGH, INB==LOW, with 400us delay in between the pulses + pulsewidth.
    or Visa versa INA==LOW,INB==HIGH;

    -----------------------------------------------

    Third Assignment:

    i would like to check the size of the ON Time of the independent Timer.
    during this ON Time,
    if the Pulse width is set +400us in the unipolar or Bipolar state
    i would like to to create a variable adjustable pulse train toggling between INA and INB.
    (so INA == HIGH during 400us+Pulsewidth then INB==LOW during 400us+Pulsewidth) Current goes CLockwise
    (so INA == LOW during 400us+Pulsewidth then INB==HIGH during 400us+Pulsewidth) Current goes AntiClockwise

    setting the pulse train to a minimum of 400us+0 should be possible i think with a for loop?

    https://www.pololu.com/file/0J504/vnh5019.pdf page 12 Tdelay

    ok i hope i didnt tell anything completely Bahnhof. i splitted all the function apart. as you can see i have trouble with keeping the complexity out of it. i tried a bit of code and thought that implementing ON OFF timers inside an existing function should work. so the approach requires to be different.

    later i would like to implement this in a Encoder Menu to change the variables. using a HOLD action of the pushbutton to switch to unipolar to bipolar. and with an encoder menu set the repeat, pulsewidth (for unipolar or Bipolar) and on and off time.

    many thanks for reading your time and patience!

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,943
    Not sure what speeling is either of course ... seems like it may have been Starting the output with the _isr().

    For usage of that see PJRC.com for intervalTimer as noted.

    If the toggle is to be on a known time recurrence - the timer set for that rate will call the _isr() code where it could count the needed occurences passed - perform the toggle action - and on the last one .stop() the timer.

    If that fits the needed situation when the toggle string is needed - set the count and .start() the timer and then ignore it, it will repeat the call to the _isr() without further watching for the expiration time in loop().

    ... out of time now ... but looks like it was understood to make clear the desired behavior ... that is the first step given the tools at hand ... if they prove cumbersome or insufficient - there are other ways ...

  15. #15
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    would rather use this with millis.
    I値l stick with that, I have a few function calls with SPI, currentsense encoder and TFTScreen in the background.

    I think this is a better start. For the INA pin. I値l leave INB zero for now.
    Setting specific digital pulsewidth first with a 200us delay. And repeat it.

    Code:
    If((timer+rate_int)< Ontime) // if Millis is lower then the OnTime
    {
    For(int I=0;I<repeats;I++)
    {
    
    if (millis() >= (timer + rate_int))  // Checks the millis() time against the previous time + rate
     {
      timer = millis();                     // Set Timer to Millisecond Clock
       
      digitalWrite(INA_CLockwise, LOW);              // Sets the Output Low for the pulse
    
      pulse = micros();                   // Sets the Start Time for Pulse
     }
    
     if (micros() >= (pulse + pulseWidth))   // If the micros function is larger than the pulse width (200uS),
     {
      digitalWrite(INA_Clockwise, HIGH);         // Turn the output back to High
     }
    }
    }
    else
    {
    (timer +rate_int )=Ontime;  // if pulsewidth is bigger then the OnTime. Pulsewidth becomes Ontime
    }
    覧-
    Then use a for loop to set the repeats per pulse,
    I値l have to check that the OnTime isn稚 overwritten.( if statement)

    Bipolar set pulse for INA and INB

    Code:
    For(int I=I<repeats;I++)
    {
    if (millis() >= (timer + rate_int))  // Checks the millis() time against the previous time + rate
     {
      timer = millis();                     // Set Timer to Millisecond Clock
       DigitalWrite(INB_Clockwise,HIGH);
      digitalWrite(INA_CLockwise, LOW);              // Sets the Output Low for the pulse
    
      pulse = micros();                   // Sets the Start Time for Pulse
     }
    
     if (micros() >= (pulse + pulseWidth))   // If the micros function is larger than the pulse width (200uS),
     {
      DigitalWrite(INB_Clockwise,LOW);
      digitalWrite(INA_Clockwise, HIGH);         // Turn the output back to High
     }
    }
    Does something like this work?

  16. #16
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    so i am a bit further

    if i run this program, i can create pulsewidth and TimeStamp. during this time stamp the pulsewidth of INA will be high for x micros.
    INB will be shifted with 400us and is inverted.

    this works now.

    Code:
    //CODE 1
    const int INA_Clockwise = 2;
    const int INB_AntiClockwise = 3;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned long pulse;
    
    
    
    
    void setup()
    {
      pinMode(INA_Clockwise, OUTPUT); // put your setup code here, to run once:
      pinMode(INB_AntiClockwise, OUTPUT);
    }
    
    void loop()
    {
    
      if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
      {
        timer = millis();                     // Set Timer to Millisecond Clock
    
        digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
        digitalWrite(INB_AntiClockwise, LOW);
        pulse = micros();                   // Sets the Start Time for Pulse
      }
    
      if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
      {
        digitalWrite(INA_Clockwise, LOW);
        // Turn the output back to High
      }
        if (micros() >= (pulse + PulseWidth+2*timeDelaymin)) //create a shift between the INA and the INB
      {
        digitalWrite(INB_AntiClockwise, HIGH);
        // Turn the output back to High
      }
    }
    If I implement this code in the Duration of the ON en OFF

    Code:
    
    const int INB_AntiClockwise       = 0;
    const int INA_Clockwise             = 1;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned long pulse;
    
    unsigned int ON_Time1 = 1000;                     // preliminary values at start up
    unsigned int OFFTime1 = 5000;
    int VNH5019 = LOW;
    
    elapsedMillis ElapsedOFF;                         //used in the Background Calculations
    
    elapsedMillis ElapsedON;   
    
    void setup()
    {
    
    
    }
    
    void loop() 
    {
      
          if ((VNH5019==HIGH)&&(ElapsedOFF >= OFFTime1)) //OFFTime first  ///Positive Pulse
         {
             VNH5019=LOW;// put your main code here, to run repeatedly:
             digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockwise, LOW);  //doesnt matter high or low both need to be HIGH or LOW.
          ElapsedOFF=0;ElapsedON=0;
          }
          else if((VNH5019==LOW)&&(ElapsedON >= ON_Time1)) //ONTime Second
          {
            VNH5019=HIGH;
            Repetition_Polarity_Change_Emag(); //this functions sets the PulseWidth and Timestamp //here I call the function
            ElapsedOFF=0;ElapsedON=0;
    
    
          }
    
    }
    
    int  Repetition_Polarity_Change_Emag()
    {  
      if(HoldCount == 1)
      { //Bipolar
        if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
        {
          timer = millis();                     // Set Timer to Millisecond Clock
    
          digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
          digitalWrite(INB_AntiClockwise, LOW);
          pulse = micros();                   // Sets the Start Time for Pulse
        }
    
        if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
        {
          digitalWrite(INA_Clockwise, LOW);
          // Turn the output back to High
        }
        if (micros() >= (pulse + PulseWidth + 2 * timeDelaymin)) //create a shift between the INA and the INB
        {
          digitalWrite(INB_AntiClockwise, HIGH);
          // Turn the output back to High
        }
    
    
    
    
    
    
    
      }
      else  //Unipolar //it goes into unipolar because the HoldCount is not selected
      {
        if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
        {
          timer = millis();                     // Set Timer to Millisecond Clock
    
          digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
          digitalWrite(INB_AntiClockwise, LOW);
          pulse = micros();                   // Sets the Start Time for Pulse
        }
    
        if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
        {
          digitalWrite(INA_Clockwise, LOW);
          // Turn the output back to High
        }
    
      }
    }
    can someone explain why i dont get any pulses during the ON Time of the function?
    Last edited by Bastiaan; 04-21-2021 at 10:13 AM. Reason: changed the digital Output pins to 2,3.

  17. #17
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    so i am a bit further

    if i run this program, i can create pulsewidth and TimeStamp. during this time stamp the pulsewidth of INA will be high for x micros.
    INB will be shifted with 400us and is inverted.

    this works now.

    Code:
    //CODE 1
    const int INA_Clockwise = 0;
    const int INB_AntiClockwise = 1;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned long pulse;
    
    
    
    
    void setup()
    {
      pinMode(INA_Clockwise, OUTPUT); // put your setup code here, to run once:
      pinMode(INB_AntiClockwise, OUTPUT);
    }
    
    void loop()
    {
    
      if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
      {
        timer = millis();                     // Set Timer to Millisecond Clock
    
        digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
        digitalWrite(INB_AntiClockwise, LOW);
        pulse = micros();                   // Sets the Start Time for Pulse
      }
    
      if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
      {
        digitalWrite(INA_Clockwise, LOW);
        // Turn the output back to High
      }
        if (micros() >= (pulse + PulseWidth+2*timeDelaymin)) //create a shift between the INA and the INB
      {
        digitalWrite(INB_AntiClockwise, HIGH);
        // Turn the output back to High
      }
    }
    If I implement this code in the Duration of the ON en OFF

    Code:
    
    const int INB_AntiClockwise       = 0;
    const int INA_Clockwise             = 1;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned long pulse;
    
    unsigned int ON_Time1 = 1000;                     // preliminary values at start up
    unsigned int OFFTime1 = 5000;
    int VNH5019 = LOW;
    
    elapsedMillis ElapsedOFF;                         //used in the Background Calculations
    
    elapsedMillis ElapsedON;   
    
    void setup()
    {
    
    
    }
    
    void loop() 
    {
      
          if ((VNH5019==HIGH)&&(ElapsedOFF >= OFFTime1)) //OFFTime first  ///Positive Pulse
         {
             VNH5019=LOW;// put your main code here, to run repeatedly:
             digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockwise, LOW);  //doesnt matter high or low both need to be HIGH or LOW.
          ElapsedOFF=0;ElapsedON=0;
          }
          else if((VNH5019==LOW)&&(ElapsedON >= ON_Time1)) //ONTime Second
          {
            VNH5019=HIGH;
            Repetition_Polarity_Change_Emag(); //this functions sets the PulseWidth and Timestamp //here I call the function
            ElapsedOFF=0;ElapsedON=0;
    
    
          }
    
    }
    
    int  Repetition_Polarity_Change_Emag()
    {  
      if(HoldCount == 1)
      { //Bipolar
        if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
        {
          timer = millis();                     // Set Timer to Millisecond Clock
    
          digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
          digitalWrite(INB_AntiClockwise, LOW);
          pulse = micros();                   // Sets the Start Time for Pulse
        }
    
        if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
        {
          digitalWrite(INA_Clockwise, LOW);
          // Turn the output back to High
        }
        if (micros() >= (pulse + PulseWidth + 2 * timeDelaymin)) //create a shift between the INA and the INB
        {
          digitalWrite(INB_AntiClockwise, HIGH);
          // Turn the output back to High
        }
    
    
    
    
    
    
    
      }
      else  //Unipolar //it goes into unipolar because the HoldCount is not selected
      {
        if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
        {
          timer = millis();                     // Set Timer to Millisecond Clock
    
          digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
          digitalWrite(INB_AntiClockwise, LOW);
          pulse = micros();                   // Sets the Start Time for Pulse
        }
    
        if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
        {
          digitalWrite(INA_Clockwise, LOW);
          // Turn the output back to High
        }
    
      }
    }
    can someone explain why i dont get any pulses during the ON Time of the function?

    i also changed the digitalPins to pin 2,3.

    best regards

    Bastiaan

  18. #18
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,111
    Quote Originally Posted by Bastiaan View Post
    can someone explain why i dont get any pulses during the ON Time of the function?
    Very difficult to answer this sort of vague question.

    I'm sure you know what you mean by "during the ON Time of the function". But please try to read your question from the perspective of anyone on this forum who wants to help.

    First, you gave 2 programs. Probably the question is about the 2nd program? Even that isn't clear to me.

    Only the 1st program actually compiles if I copy the code into Arduino and click Verify. The 2nd program is missing the definition of HoldCount.

    In that 2nd program, I see 3 functions called "setup" (which is empty), "loop" and "Repetition_Polarity_Change_Emag". Both loop() and Repetition_Polarity_Change_Emag() use digitalWrite on 2 pins.

    Even if I know which function you are asking about, what exactly does "during the ON Time" mean? I don't understand what you mean by those words! (and I do not believe anyone who reads this thread could reliably understand your question)


    While I can not understand your question, I can offer some generic advice which might help.

    First, while using Arduino, click Tools > Auto Format. Or just type CTRL-T. This will automatically fix the indenting of your code. In many places your code has strange indenting which makes reading the if-else conditions difficult. Properly indented code is easier to view and understand. Even if you do not need this, it maybe the code easier for someone to read (without the extra step of copying into Arduino and pressing CTRL-T - which is what I did just now to try to make some sense of this code).

    Second, even with proper indenting, your code is overly complicated. While it is theoretically possible to make this sort of complicated design work, this style of programming usually does not end well. You really should use a simpler design.

    For example, in loop() you are using 2 different elapsedMillis variables called ElapsedON and ElapsedOFF. From the usage I can see, there is no need for 2, since you set both to zero and only use one or the other depending on the state of "VNH5019".

    Likewise, inside Repetition_Polarity_Change_Emag() the code is using 2 different variables named "timer" and "pulse" with 5 different cases which act upon the same 2 pins. I highly recommend you reduce this to only 1 timing variable. Using 2 timing variables and many cases is complex and difficult. Find a way to use only 1 timing variable.

    While a lesser issue, you will eventually have problems with numerical overflow on the conditional tests. The easiest solution is to use elapsedMicros or elapsedMillis, which do a similar calculation internally. Those are well tested and handle numerical overflow properly. They are also much simpler, and with your code having so many cases, simpler is better! But if you want to do the calculation yourself, the overflow problem is that eventually micros() and millis() will roll back to zero after the maximum unsigned integer is reached. Many websites and tutorials talk about the proper way to handle this using subtraction. The way you have written will eventually fail when numerical overflow happens.

    But the main issue is your program is using 4 different timing variables in redundant ways. That is an overly complex approach which is extremely difficult to make work properly. You really should simplify this code and use as few timing variables as possible. Especially inside Repetition_Polarity_Change_Emag(), use only 1 timing variable (and do yourself a favor by using elapsedMicros) and build the if-else cases to accomplish your goals with the same pins based on a single instance of timekeeping.

    Also, before your post your message, open a new Arduino window and copy the code back into Arduino and make sure it compiles and actually demonstrates the problem. When you post code which is incomplete, which doesn't even compile, you're only making everything much harder for everyone and reducing your changes of getting a useful answer.

  19. #19
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    thanks Paul, ill do that.
    ill remove the holdcount part

    ill start over and add some pictures.
    Click image for larger version. 

Name:	PulseWidth and TimeStamp.jpg 
Views:	3 
Size:	153.1 KB 
ID:	24509
    shows the following code:

    WORKS without Independent ON OFF
    Code:
    int VNH5019 = LOW;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned int ON_Time1 = 1000;                     // preliminary values at start up
    unsigned int OFFTime1 = 1000;
    elapsedMillis ElapsedTime;                         //used in the Background Calculations
    elapsedMicros pulse;
    
    
    void setup()
    {
    pinMode(INA_Clockwise,OUTPUT);digitalWrite(INA_Clockwise, LOW);
    pinMode(INB_AntiClockwise,OUTPUT);digitalWrite(INB_AntiClockwise, LOW);
    
    
    }
    
    
    void loop()
    {
    
      if (millis() >= (timer + Timestamp))  // Checks the millis() time against the previous time + rate
      {
        timer = millis();                     // Set Timer to Millisecond Clock
    
        digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
        digitalWrite(INB_AntiClockwise, LOW);
        pulse = micros();                   // Sets the Start Time for Pulse
      }
    
      if (micros() >= (pulse + PulseWidth + timeDelaymin)) // If the micros function is larger than the pulse width (200uS),
      {
        digitalWrite(INA_Clockwise, LOW);
        // Turn the output back to High
      }
        if (micros() >= (pulse + PulseWidth+2*timeDelaymin)) //create a shift between the INA and the INB
      {
        digitalWrite(INB_AntiClockwise, HIGH);
        // Turn the output back to High
      }
    }

    Questions:
    i have replaced all with elapsedMicros and elapsedTime
    and if I run this, over a long period of time i get a pulse which is really short and far spaced.
    where do I reset the pulse value?
    inside the if statements?
    you said something about else if how is this going to work? if statement is true (do something i understand)

    do I have to declare two different if(elapsedTime>=(timer+Timestamp) for each signal?


    could someone explain to me step by step,
    in red marker what and where i am doing wrong and how to correct this?
    i have been trying 3 days in a row.

    should I declare the ElapsedMicros as a global?

    Code:
     
    //are there variables declared wrong ? int long?
    int VNH5019 = LOW;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned int ON_Time1 = 1000;                     // preliminary values at start up
    unsigned int OFFTime1 = 1000;
    elapsedMillis ElapsedTime;                         //used in the Background Calculations
    elapsedMicros pulse;
    
    
    void setup()
    {
    pinMode(INA_Clockwise,OUTPUT);digitalWrite(INA_Clockwise, LOW);
    pinMode(INB_AntiClockwise,OUTPUT);digitalWrite(INB_AntiClockwise, LOW);
    
    
    }
    
    
    void loop()
    {
    ElapsedTime=0;
    if (ElapsedTime >= (timer + Timestamp))  // Checks the millis() time against the previous time + TimeStamp
      {
        timer = ElapsedTime;                     // Set Timer to Millisecond Clock
    
        digitalWrite(INA_Clockwise, HIGH);              // Sets the Output Low for the pulse
        digitalWrite(INB_AntiClockwise, LOW);
        pulse = elapsedMicros();          //is this correct?       
      }
    
      else if (pulse >= (pulse + PulseWidth + timeDelaymin)) //first Pulse for INA should be 400us+something given
      {
        digitalWrite(INA_Clockwise, LOW);
        // Turn the output back to High
       pulse=0;
      }
      else if (pulse >= (pulse + PulseWidth + 2 * timeDelaymin)) //create a shift between the INA and the INB
      {
        digitalWrite(INB_AntiClockwise, HIGH);
        // Turn the output back to High
       pulse=0;
    
      }
    }
    so i changed the parameters from millis to elapsedMillis and elapsedMicros. some of those elapsedmillis timings are need to be set in side the function, i think and are required to be set to 0. Please correct me if I am wrong.
    ------------------------------------------------------------------------------

    New Code Independent ON OFF

    Code:
    int VNH5019 = LOW;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned int ON_Time1 = 1000;                     // preliminary values at start up
    unsigned int OFFTime1 = 1000;
    elapsedMillis ElapsedTime;                         //used in the Background Calculations
    elapsedMicros pulse;
    
    
    void setup()
    {
    pinMode(INA_Clockwise,OUTPUT);digitalWrite(INA_Clockwise, LOW);
    pinMode(INB_AntiClockwise,OUTPUT);digitalWrite(INB_AntiClockwise, LOW);
    
    
    }
    
    
    //OFFTime1 and ON_Time1 are set to 1000ms this Program works. clearly the problem is in handling and creating pulses.
    
    void loop()
    {
    
      if ((VNH5019 == HIGH) && (ElapsedTime >= OFFTime1)) //OFFTime first  ///Positive Pulse
      {
        VNH5019 = LOW; // put your main code here, to run repeatedly:
        digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockwise, LOW);  //both digital Pins are set to LOW
        ElapsedTime = 0;
      }
      else if ((VNH5019 == LOW) && (ElapsedTime >= ON_Time1)) //ONTime Second
      {
        Serial.print("On Time");
        VNH5019 = HIGH;
       // Repetition_Polarity_Change_Emag(); //this functions sets the PulseWidth and Timestamp //here I call the function
    digitalWrite(INA_Clockwise, HIGH); digitalWrite(INB_AntiClockwise, HIGH);
        ElapsedTime = 0;
    
      }
    
    }

  20. #20
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,111
    Quote Originally Posted by Bastiaan View Post
    should I declare the ElapsedMicros as a global?
    Yes.


    Code:
        pulse = elapsedMicros();          //is this correct?
    No.

  21. #21
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    Quote Originally Posted by PaulStoffregen View Post
    Yes.


    Code:
        pulse = elapsedMicros();          //is this correct?
    No.


    Ok interesting. Ill try a bit with an easy example and a else if statement

    Or is better to use booleans to see if an if statement is run?

    And make a same check as the independent on off?

  22. #22
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    24,111
    I copied the 3 programs from msg #19 into Arduino. None of them compile. All 3 are missing definitions of some variables used in the code.

    Before we talk of what you should do with this code, you really need to do better at asking questions. Always compile and actually run the code before posting it here. That is an absolute bare minimum level of effort needed to ask for help here. We have the "Forum Rule" in red text at the top of every page on this forum for a reason. Please follow this rule. It saves everyone a lot of time and allows us to try to help you better.

    But you should do more than this absolute bare minimum. You've written many vague questions here, and to be frank, this thread is a confusing mess. You need to explain clearly what your program is actually trying to do. I know writing in English is difficult. Perhaps find a friend or co-worker and ask them to read your question (before posting) and ask them to explain in their own words what your program is meant to do. If they can't understand with you physically present, that is a sure sign your words are unclear. Nobody can help if they do not understand.

    And I do want to help. Other people here probably do too. I need you to understand these many messages as so unclear, so difficult to understand, and are filled with obvious wrong code you didn't even compile before posting, that it would take a pretty incredible miracle for anyone to answer your questions.

    Please, check your code before posting. Actually run it on your Teensy and make sure it really does demonstrate the problem. Clearly start what you meant for the code to do, and tell us what it is actually doing. I and others on this forum actually do copy your code into Arduino and sometimes I even run it here on a Teensy and connect my oscilloscope. But when you give wrong code, that is the end of my help. Rather than getting a useful answer, you get a reply like this... asking you to please follow the Forum Rule.

  23. #23
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    Quote Originally Posted by PaulStoffregen View Post
    I copied the 3 programs from msg #19 into Arduino. None of them compile. All 3 are missing definitions of some variables used in the code.

    Before we talk of what you should do with this code, you really need to do better at asking questions. Always compile and actually run the code before posting it here. That is an absolute bare minimum level of effort needed to ask for help here. We have the "Forum Rule" in red text at the top of every page on this forum for a reason. Please follow this rule. It saves everyone a lot of time and allows us to try to help you better.

    But you should do more than this absolute bare minimum. You've written many vague questions here, and to be frank, this thread is a confusing mess. You need to explain clearly what your program is actually trying to do. I know writing in English is difficult. Perhaps find a friend or co-worker and ask them to read your question (before posting) and ask them to explain in their own words what your program is meant to do. If they can't understand with you physically present, that is a sure sign your words are unclear. Nobody can help if they do not understand.

    And I do want to help. Other people here probably do too. I need you to understand these many messages as so unclear, so difficult to understand, and are filled with obvious wrong code you didn't even compile before posting, that it would take a pretty incredible miracle for anyone to answer your questions.

    Please, check your code before posting. Actually run it on your Teensy and make sure it really does demonstrate the problem. Clearly start what you meant for the code to do, and tell us what it is actually doing. I and others on this forum actually do copy your code into Arduino and sometimes I even run it here on a Teensy and connect my oscilloscope. But when you give wrong code, that is the end of my help. Rather than getting a useful answer, you get a reply like this... asking you to please follow the Forum Rule.
    many thanks for that Paul, and preseverance in helping me out.
    really appreciated.

  24. #24
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    ok so i have CODE1 that does the following.
    Attachment 24513

    creates a pulse of 400us
    within a total time of 10ms.

    the second pulse is 800us long and has the same Totaltime of 10ms
    over and over.


    for a Electromagnet project i would like to control the
    OFF Time
    ON Time
    Polarity change(i left this part out to prevent confusion; I use a long press action for a pushbutton)
    pulse,
    Totaltime


    -------------------------------------
    this is technically the bad code which works on the arduino 1.8.13 version. i use a teensy 4.1. i hope i am concise so far. and everybody understands.

    CODE1
    Code:
    //variables
    const int INA_Clockwise = 2;
    const int INB_AntiClockwise = 3;
    unsigned long Timestamp = 10; //10ms per division
    int PulseWidth = 2; //variable for setting the pulse
    int timeDelaymin = 400; //
    int repeats = 5;
    unsigned long timer;
    unsigned long pulse;
    
    void setup()
    {
      pinMode(INA_Clockwise, OUTPUT); 
      pinMode(INB_AntiClockwise, OUTPUT);
    }
    
    void loop()
    {
    
      if (millis() >= (timer + Timestamp))  //checks millis on total time 
      {
        timer = millis();                     // overwrite timer.
    
        digitalWrite(INA_Clockwise, HIGH);              // kind of toggle between INA and INB but shifted with 400us
        digitalWrite(INB_AntiClockwise, LOW);
        pulse = micros();                                       // Sets the Start Time for the Pulse
      }
    
      if (micros() >= (pulse + PulseWidth + timeDelaymin)) // check micros if the pulse is not larger
      {
        digitalWrite(INA_Clockwise, LOW);
      }
        if (micros() >= (pulse + PulseWidth+2*timeDelaymin))  // check micros if the pulse is not larger, create a shift in signal INA and INB
      {
        digitalWrite(INB_AntiClockwise, HIGH);
      }
    }

    CODE2
    elapsedMillis code doesnt work,
    probably i dont understand what i am doing or how to interact with global variables.
    I want the previous code to run the same as the elapsedMillis version.
    because this will ( i trust your opinion on elapsedMillis Paul) help me in the independent ON OFF time function.

    based on the CODE1, where do I place the pulse and elapsedmillis, this is a guess where do I set them to Zero? does it matter? is the approach right?

    Code:
    #define ENCODER_OPTIMIZE_INTERRUPTS
    #include <math.h>
    #include <stdio.h>
    #include <elapsedMillis.h>
    
    
    //Defining the pins
    
    const int INB_AntiClockwise       = 2;
    const int INA_Clockwise           = 3;
    
    unsigned long previousMillis = 0;
    unsigned long Timestamp = 10; //10ms per division                   //it does not matter setting this to int.
    unsigned long PulseWidth = 2; //variable for setting the pulse     // same for this variable
    unsigned long timeDelaymin = 400; //                                      //idem
    unsigned long timer;
    int VNH5019 = LOW;
    
    unsigned int ON_Time1 = 1000;                     //ON Time
    unsigned int OFFTime1 = 1000;                     //OFF Time
    
    elapsedMillis ElapsedTime;                         //used in the Background Calculations
    elapsedMicros pulse;
    void setup()
    {
       Serial.begin(9600); 
      
      pinMode(13, OUTPUT); digitalWrite(13, LOW);
      pinMode(INB_AntiClockwise, OUTPUT); pinMode(INB_AntiClockwise, LOW);
      pinMode(INA_Clockwise, OUTPUT); pinMode(INA_Clockwise, LOW);
    }
    
    
    void loop()
    {
    
    if (ElapsedTime >= (timer + Timestamp)) 
      {
        timer = ElapsedTime;                    
        Serial.println("TimeStamp");
        digitalWrite(INA_Clockwise, HIGH);              
        digitalWrite(INB_AntiClockwise, LOW);
                          
      }
    
      if (pulse > ( PulseWidth + timeDelaymin)) ,
      {
        digitalWrite(INA_Clockwise, LOW);
        // Turn the output back to High
    
      }
      if (pulse > (PulseWidth + 2 * timeDelaymin)) //create a shift between the INA and the INB
      {
        digitalWrite(INB_AntiClockwise, HIGH);
        // Turn the output back to High
      
    
      }
    
    }


    Third Code should put it all together: CODE2 is updated with ElapsedMillis in its function and it has been created as a global variable. CODE2 does react during the ON Time but does not give me pulses, which can be seen with the Serialmonitor if run.
    so i am guessing again that the CODE2 is faulty.

    but where and is the approach right?


    CODE3

    Code:
    #define ENCODER_OPTIMIZE_INTERRUPTS
    #include <math.h>
    #include <stdio.h>
    #include <elapsedMillis.h>
    
    
    //Defining the pins
    
    const int INB_AntiClockwise       = 2;
    const int INA_Clockwise           = 3;
    
    unsigned long previousMillis = 0;
    
    unsigned long Timestamp = 10; //10ms per division
    unsigned long PulseWidth = 2; //variable for setting the pulse
    unsigned long timeDelaymin = 400; //
    unsigned int timer;
    byte VNH5019 = LOW;   //it has not effect changing this from int to byte
    
    unsigned int ON_Time1 = 1000;                     //ON Time
    unsigned int OFFTime1 = 1000;                     //OFF Time
    
    elapsedMillis ElapsedTime;                         //ElapsedMillis
    elapsedMicros pulse;                               //ElapsedMicros
    
    void setup()
    {
      Serial.begin(9600); 
      
      pinMode(13, OUTPUT); digitalWrite(13, LOW);
      pinMode(INB_AntiClockwise, OUTPUT); pinMode(INB_AntiClockwise, LOW);
      pinMode(INA_Clockwise, OUTPUT); pinMode(INA_Clockwise, LOW);
     
    }
    
    void loop()
    {
      
    
    
      if ((VNH5019 == HIGH) && (ElapsedTime >= OFFTime1)) //OFFTime first 
      {
        VNH5019 = LOW; 
        digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockwise, LOW);  //doesnt matter high or low both need to be HIGH or LOW.
        ElapsedTime = 0;                                                  
      }
      else if ((VNH5019 == LOW) && (ElapsedTime >= ON_Time1)) //ONTime 1 second
      {
        //Serial.println("On Time");//so that i know i am in this part of the else if statement
        VNH5019 = HIGH;
        Repetition_Polarity_Change_Emag(); //this functions sets the PulseWidth and Timestamp //here I call the function
        ElapsedTime = 0;
    
      }
    
    }
    
    int  Repetition_Polarity_Change_Emag()
    {
    if (ElapsedTime >= (timer + Timestamp))  //it should be 10ms.... I changed it also to 10, it doesnt matter....:S,
      {
        timer = ElapsedTime;                   
        Serial.println("TimeStamp");
        digitalWrite(INA_Clockwise, HIGH);            
        digitalWrite(INB_AntiClockwise, LOW);
        //do I place the condition for the ElapsedTime =0; here?
                   
      }
    
      if (pulse > ( PulseWidth + timeDelaymin)) // If the pulse is larger than the pulse width (400us),
      {
        digitalWrite(INA_Clockwise, LOW);
        // Turn the output back to High
        Serial.println("Clockwise");
    pulse=0;    // do i place the pulse also here?  
      }
      if (pulse > (PulseWidth + 2 * timeDelaymin)) //create a shift between the INA and the INB
      {
        digitalWrite(INB_AntiClockwise, HIGH); //why does this pulse and why dont I get a pulse of 400us and a TimeStamp of 10ms?
        Serial.println("AntiClockwise");
           // do i place the pulse also here?  
      
      }
     //or do i place the pulse and elapsedTime here?
    }
    i tried playing with the if statements,
    changing them to else if with the same conditions, which didnt work, and got one pulse on the AntiClockwise Channel, and continious 1 second on off pulses on the Clockwise Channel

    Question1: where are the pulses as in the CODE 1?

    Question2:
    Do i have to set in the if statement something like this

    Code:
    if (digitalRead(INA_Clockwise)== LOW&&(pulse > ( PulseWidth + timeDelaymin)))
    ????

    Question3: where do i set the pulse =0; or the ElapsedTime=0;? i tried placing it everywhere in the code ( in the if statement) outside the if statement

    Question4: do I use the right variables? i just changed them all to unsigned long, because i am uncertain of this rollover thing.エ

    thanks for your patience.

    i really tried my best to make this as clear as possible.
    you can also call me. sometimes this is easier.

    I am Dutch, I do speak English and German and Dutch.
    Last edited by Bastiaan; 04-21-2021 at 08:18 PM.

  25. #25
    Senior Member
    Join Date
    Sep 2016
    Posts
    174
    good morning,

    i played a bit with the ElapsedMillis();

    so far i got two signals that are shifted please see pictures:
    Click image for larger version. 

Name:	IMG_4356.jpg 
Views:	12 
Size:	64.3 KB 
ID:	24520
    Click image for larger version. 

Name:	IMG_4355.jpg 
Views:	8 
Size:	65.9 KB 
ID:	24521
    Click image for larger version. 

Name:	IMG_4354.jpg 
Views:	5 
Size:	34.8 KB 
ID:	24522

    but the pulse train stops after a period of time of 1 second and doesnt repeat.



    i removed the functionRepetition_Polarity_Change_Emag()
    and used if else statements after the independent on off.

    Questions:

    Question1: could someone elaborate the ElapsedMillis why it doesnt work inside a nested if statement as in the CODE3?
    Question2:
    it just defies logic for me, but it has to do with the global variable i think of ElapsedTimeIndependent and is overwritten?

    this code works and creates a pulsetrain for 1 second with 12ms period. 2ms of this period is the pulse HIGH. but how come it doesnt repeat?

    Question3:

    Code:
    //Defining the pins
    
    const int INB_AntiClockwise       = 2;
    const int INA_Clockwise           = 3;
    
    unsigned long previousMillis = 0;
    
    unsigned long Timestamp = 10; //10ms per division
    unsigned long PulseWidth = 2; //variable for setting the pulse
    unsigned long timer;
    unsigned long timer2;
    bool VNH5019 = LOW;   //it has not effect changing this from int to byte
    
    unsigned int ON_Time1 = 1000;                     //ON Time
    unsigned int OFFTime1 = 1000;                     //OFF Time
    
    elapsedMillis ElapsedTime;                         //ElapsedMillis for pulses and period
    elapsedMillis ElapsedTimeIndependent;
    elapsedMillis pulse;                               //ElapsedMicros
    
    void setup()
    {
      Serial.begin(9600);
    
      pinMode(13, OUTPUT); digitalWrite(13, LOW);
      pinMode(INB_AntiClockwise, OUTPUT); pinMode(INB_AntiClockwise, LOW);
      pinMode(INA_Clockwise, OUTPUT); pinMode(INA_Clockwise, LOW);
    
    }
    
    void loop()
    {
    
    
    
      if ((VNH5019 == HIGH) && (ElapsedTimeIndependent >= OFFTime1)) //OFFTime first
      {
        VNH5019 = LOW;
        digitalWrite(INA_Clockwise, LOW); digitalWrite(INB_AntiClockwise, LOW);  //doesnt matter high or low both need to be HIGH or LOW.
        ElapsedTimeIndependent = 0;//this resets the elapsedTime
      }
      else if ((VNH5019 == LOW) && (ElapsedTimeIndependent >= ON_Time1)) //ONTime 1 second
      {
        //Serial.println("On Time");//so that i know i am in this part of the else if statement
        VNH5019 = HIGH;
        //   Repetition_Polarity_Change_Emag();  //this functions sets the PulseWidth and the Period //here I call the function
    
      }
      else if (ElapsedTimeIndependent >= (timer + Timestamp)) 
      {
        digitalWrite(INA_Clockwise, HIGH);
        digitalWrite(INB_AntiClockwise, LOW);
        timer = ElapsedTime + 2; //pulse is shifted with 2ms
        timer2 = ElapsedTime;
        //duration of the Pulse is set here.
        Serial.println("TimeStamp");
      }              // Sets the Output Low for the pulse
      else if ((pulse) > (timer + Timestamp)) 
      {
        digitalWrite(INA_Clockwise, HIGH);
        // Turn the output back to High
    
      }
      else if ((pulse) > (timer2 + Timestamp)) //create a shift between the INA and the INB
      {
    
        digitalWrite(INB_AntiClockwise, HIGH);
        // Turn the output back to High
    
    
      }
          
    
    }
    Last edited by Bastiaan; 04-22-2021 at 11:15 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •