1

I am currently working on making some test equipment for µUSB cables. The code is supposed to recoqnise when an error in the cable occurs. Most of it works as expected, but I have some trouble understanding the use of millis() timers. I, therefore want to ask, in the code below, how can I make my program pick up on an missing connection in the cable and make sure it turns on the LED always? And secondly, how can I make it stay on for 2 seconds, even if the cable has "fixed" itself again (i.e. the connection has returned)?

Update It seems that I have misunderstood the assignment. The program should turn on a LED, when an error is present and keeps this on while the error is present (already fixed this in the code). When the connection has been regained a timer should start, which turns off the LED after two seconds. (Here's the trouble I'm having, I can't seem to pinpoint where and how this timer should start)

case microUSB:
  if (Vcc_Ext_val > 50)
  {
    digitalWrite(ActivateLoad, HIGH);
    LoadActivated = true;

  }
  else if (Vcc_Ext_val < 30)
  {
    digitalWrite(ActivateLoad, LOW);
    LoadActivated = false;
  }
  if ((Vcc_Ext_val < 50) || (USB_DP_VAL < 10)|| (USB_DM_VAL < 10))
  {
    PulseCurrentMillis = millis();
    if (FirstPulse == true)
    {
    digitalWrite(RedIntLED, StateLEDON); 
    FirstPulse = false;
    }
    if (PulseCurrentMillis - PulseLastMillis >= PulseInterval)
    {
      PulseLastMillis = PulseCurrentMillis;
      if (LEDState == StateLEDON)
      {
        LEDState = StateLEDOFF;
      }
      else
      {
        LEDState = StateLEDON;
      }
    }
    digitalWrite(GreenIntLED, StateLEDOFF);
    digitalWrite(RedIntLED, LEDState);
  } 
  else
  {
    digitalWrite(GreenIntLED, StateLEDON);
  }
  break;

3 Answers 3

0

When you turn on the led, record the time.

After that, turn off the led if

  1. The led is on and

  2. Sufficient time has passed.

edit: this is what I would do.

//detect if sufficient time has passed
//1. turn on the led on button high -> low transition
//2. turn off the led after certain time (LED_DLY)
uint8_t led_ctrl(void) {
    static uint32_t led_timeoff=0;                              //time to turn the led off
    uint32_t time_now = millis();                               //take time now

    //if sufficient delay has passed, turn the led off
    if (isLED_ON() && (time_now >= led_timeoff)) {              //if led is already on
        LED_OFF();                                              //turn off the led
    }

    //if the button has experienced a the falling edge, turn on the led and set up the time to turn the led off
    if (btn_pressed()) {
        LED_ON();                                               //turn on the led
        led_timeoff = time_now + LED_DLY;                       //set up the time to turn off the led
    }

}

it is almost a literal implementation of what I wrote above.

here is the code in action, responding to button's falling edge with a 150ms delay turn off for the led: the button is on D12 and the led on D8.

enter image description here

fairly straight forward, isn't it?

3
  • It would seem that this is what I should accomplish, but I have some trouble understanding how to do this. Mar 25, 2017 at 17:31
  • You have trouble implementing it or understanding it? Potential solutions for the first and no solution for the latter.
    – dannyf
    Mar 25, 2017 at 18:13
  • I have trouble understanding how to implement this in a way so that the program recognizes that the connection has been reestablished and then turn off the LED after 2s Mar 25, 2017 at 18:20
1

I have made it work now.

The working code is as following, if anyone else gets the same issue.

case microUSB:
  if ((Vcc_Ext_val > 50) && (USB_DP_VAL > 10) && (USB_DM_VAL > 10) && (digitalRead(RedIntLED) == StateLEDON))
  {
    if (FirstStart == true)
    {
      StartMillis = millis();
      FirstStart = false;
    }
    PulseCurrentMillis = millis();
    if ((PulseCurrentMillis - StartMillis >= PulseInterval) && (digitalRead(RedIntLED) == StateLEDON))
      {
        PulseLastMillis = PulseCurrentMillis;
        digitalWrite(RedIntLED, StateLEDOFF);
      }
  }
  if (Vcc_Ext_val > 50)
  {
    digitalWrite(ActivateLoad, HIGH);
    LoadActivated = true;

  }
  else if (Vcc_Ext_val < 30)
  {
    digitalWrite(ActivateLoad, LOW);
    LoadActivated = false;
  }
   if ((Vcc_Ext_val < 50) || (USB_DP_VAL < 10) || (USB_DM_VAL < 10))
    { 
      FirstStart = true;
      digitalWrite(GreenIntLED, StateLEDOFF);
      digitalWrite(RedIntLED, StateLEDON);        
    } 
    else
    {
      digitalWrite(GreenIntLED, StateLEDON);
    }
  break;
0

Look at one of the timer libraries such as SimpleTimer. It handles the timing for you and calls a routine you specify at the appropriate time. Your code just has to call its run() function frequently - once in every loop() iteration is typical.

Update:

Either library should work for you; neither should disturb the hardware timers or millis(), which depends on them. Try one of the timer example programs, blinking two leds at different rates for example, and expand or adapt from there.

1
  • I initially used the timer.h library, but since I have a timer elsewhere in the code that uses the millis() function (Couldn't find an appropriate function for this in the library), the behavior of the digital pins became quite odd (They started to oscillate at a very low voltage, causing the LED's to blink, when they should be turned off) Mar 23, 2017 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.