2

I know this will sound absurdly simple. But I cannot think of, or adequately define to search for, how to have code in C to have a blinking LED going at a constant frequency while the rest of the program runs. Set and forget sort of thing. I have seen threading today, though it seemed a little to complicated for my basic understanding.

I am developing on Windows, and running on MikroC for a PIC18, but had the same thoughts when I was working on a different project on an Arduino.

VLL
  • 9,634
  • 1
  • 29
  • 54
Chris
  • 21
  • 1
  • Look into getting an integrated development environment (IDE). Perhaps Visual Studio would already have a feature which meets your need (and they have a free version too). – Tim Biegeleisen Apr 13 '16 at 05:05
  • Do you know multi-threading? – Mohit Jain Apr 13 '16 at 05:06
  • 1
    What OS are you running the program on? – user3386109 Apr 13 '16 at 05:08
  • Windows. Im coding on MikroC for a PIC18, but had the same thoughts when I was working on a different project on an Arduino. I have seen threading today, though it seemed a little to complicated for my basic understanding. Maybe I need to look into learning that. – Chris Apr 13 '16 at 05:21
  • 1
    The PIC18 is running Windows? I find that hard to believe. When you're running on bare hardware (with no operating system) the solution is [cooperative multitasking](https://en.wikipedia.org/wiki/Cooperative_multitasking). – user3386109 Apr 13 '16 at 05:33
  • 2
    I think you should post _some_ kind of code and indicate architecture. There are lots of ways to do this. On microcontrollers, it's common to have a service loop to update any timers in the system, or to use timed interrupts. On more complex processors / OSes that support threading, you might make a separate timer thread that wakes periodically to do its thing. Or you could use the other approaches and/or a combination of all. – paddy Apr 13 '16 at 05:37
  • Just because your cross-compiler executes in Windows, it doesn't make the PIC run Windows... You need some beginner-level learning material about embedded systems programming. Programming embedded systems is very different from programming Windows. – Lundin Apr 13 '16 at 07:50

4 Answers4

1

See the answers to Multithreading using C on PIC18

For standard C development, this would require multithreading, but this answer suggests using an event loop.

Community
  • 1
  • 1
Luke Pillar
  • 164
  • 1
  • 4
  • Multi-threading on 8 bit microcontrollers is nonsense. Neither multi-threading or event loops are needed for something so trivial and quick as toggling an I/O pin. – Lundin Apr 13 '16 at 07:41
1

Most microcontrollers have available hardware timers that can be used for such purposes. So your code in the timer will toggle the blinking, and the main software can set variables that tells the timer code if it should blink or not

int shouldblink = 0;
int ledstatus = 0;
void OnTimer(void) /* configure your microcontroller to call this on timer */
{
    if (ledstatus)
    {
        turnoffLED();
        ledstatus = 0;
    }
    else {
        if (shouldblink)
        {
            turnonLED();
            ledstatus = 1;
        }
    }
}

int main()
{
    configure_timer();
    shouldblink = 1;
    do_slow_work();
    shouldblink = 0;
}
machine_1
  • 4,266
  • 2
  • 21
  • 42
Stian Skjelstad
  • 2,277
  • 1
  • 9
  • 19
  • On a PIC, your `main` should better not simply run to an end, but rather stay in an endless loop. – tofro Apr 13 '16 at 11:16
1

Simply use the microcontroller hardware intended for such. Output compare timers, PWM hardware etc. If you don't have any such hardware, toggling the I/O port from an interrupt should be sufficiently accurate in most cases.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

On a PIC, you wouldn't necessarily jump directly from something as simple as busy-waiting loops to something as complicated as multithreading libraries, as proposed in some of the comments.

Let's assume you blink your LED every second in a loop - That gives code in that loop (or called from inside that loop) nearly 1 second to execute on something different. If you can slice those tasks into such small slices that they fit into the interval "when you need to be back" to blink the LED, that's a start.

Obviously, if you execute arbitrary code in the blinking loop, the frequency of your blinking will be affected by the time those other code parts use up and you can no longer use the CPU as a time base - You need something different to check whether blinking is due. Most MCUs have a timer that allows you to do that - Reading a free-running timer to check whether you "need to blink" would be the first simple step. See below pseudo-code:

while (1){
  if (((time = readTimer()) - oldTime) > INTERVAL){
     /* Timer run-around ignored for reasons of simplicity */
     oldTime = time;
     blink();
  }
  else
     doSomethingElse();
}

Note the somethingElse() must be finished in the least possible time as its run-time affects the precision of your blinking.

If you still want the blinking to be at exact intervals, you should be looking into interrupt service routines. Find out how you make the timer trigger an interrupt with the frequency of your blinking, and do the blinking in the interrupt service routine. That releases your main loop from doing that and you can do whatever long-running tasks you want there. The timer will trigger an interrupt at your wanted frequency, and the interrupt service routine will switch the lights.

tofro
  • 5,640
  • 14
  • 31
  • This will not give any real-time performance what-so-ever. Even if `doSomethingElse` is quicker than the blink duty cycle, you will get constant delays in the blinking frequency in the interval of 0 <= delay <= time to execute `doSomethingElse`. And he is using a 8 bit MCU with an ancient CPU core from the 1980s, he should definitely _not_ look into multi-threading libraries. – Lundin Apr 13 '16 at 07:44
  • I was trying to get the OP into experimenting and, using small steps, get to some acceptable solutions. Even if he *sees* the variations in blink frequency he would have learnt something (BTW he was not asking for real-time performance). Assuming it is not about controlling a mars robot, that looked like a feasible approach. – tofro Apr 13 '16 at 11:12
  • Depending on the length of the delay, the loop might cause flicker large enough for the human eye to notice. That being said, it is also a very bad idea to introduce _tight coupling_ in your programs. Your loop has a tight coupling between the LED code and something completely non-related. One day someone will change some TCP/IP socket code and then suddenly the LED "out of coffee" starts blinking rapidly. That's not how you design robust programs. – Lundin Apr 13 '16 at 11:16
  • You are perfectly right (and it was mentioned in my answer already), but again: That proposal was not aiming at mars robot performance. The OP realizing exactly what you described (jitter in the blinking), will make him look into the next level of exploration, namely timers. By pushing someone who has apparently just started doing something way up the learning curve onto the *ideal* solution, he'd loose the chance to actually learn something. – tofro Apr 13 '16 at 11:18
  • Or you could just teach him to do it right from the start. Timers are very fundamental in any embedded system development. Better to learn about them sooner than later. – Lundin Apr 13 '16 at 11:23