0

I am using microC to program pic16f877a to operate motors and solenoids. I have some functions making motors move at different space times e.g. motor1 moves for 100ms, stops, moves again for 100ms etc. for 4 loops, motor2 for 200ms and so on. I want these functions to start at the same time.

Think about a robot when you want to move its right hand up and down every 200ms for a total 2 mins and its left hand up and down every 400ms for a total again 2 mins. This process should start at the same time.

So basically I want to start something like :

start:
solenoid1 runs functionQuarter(moves up-down every x time) total like 2 mins
solenoid2 runs functionHalf(moves up-down every 2x time) total like 2 mins
stop

Is it possible to do this with micro c for this pic and how can I call 2 or more functions to start at the same time?

GiorgosM
  • 11
  • 3

2 Answers2

1

Why do you think you need threads? You know exactly when an operation should occur, so perform that operation exactly at that time. All you need is an appropriate scheduling system that helps you keep track of the operations. Compared to threads, you don't have the problem of unexpected scheduling, probably lower latency, no need for inter-thread synchronization.

Consider this sketch:

// this task structure says at what time to set 
// an output to a certain value
struct task {
    time_type when;
    output_type output;
    value_type value;
};

struct task_queue {
    struct task** tasks;
    size_t count;
};
void task_queue_push(struct task_queue* q, struct task* t);
struct task* task_queue_front(struct task_queue* q);
struct task* task_queue_pop(struct task_queue* q);

Now, in a loop, you keep looking at the first element in the queue and just sleep() until the start of the next task. Of course, that means you need to keep those tasks sorted by their start time! If multiple tasks start at the same time, you need to run them both, the only limit to "at the same time" the the execution time of each task. If necessary, as part of handling one task, you can create one or more other tasks. As a variation, you can also use a callback instead of just the output and value infos that assume you want to set some digital outputs only.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
  • Please check my edit posting my functions and possibly help me what code to add at main to achieve that – GiorgosM Jul 19 '15 at 13:41
  • Just a few comments on your edit: Firstly, you undid some other edits that others made and which made your question much easier to read and understand. Then, that code you posted is barely readable, please format and document that. Lastly, your question now boils down to "please write some code for me", to which there is just one answer: No. – Ulrich Eckhardt Jul 19 '15 at 13:52
  • Ok i will try, but i didnt undid other edits of others . – GiorgosM Jul 19 '15 at 14:03
  • Well i am confused about what happened.I didnt even realize that others edited my post.I just wanted to add the code like its here not at the history.At the history the code appears different with the red marks. – GiorgosM Jul 19 '15 at 14:29
  • Yep, this is the right way to do it. You can have a table of events with times, if you want. You can have a table of things (like solenoids) with statuses. Your core bit of code basically figures out how long it is until the next thing it has to, and then waits for either that much time to pass or something to happen. If the time passes, it runs the event scheduled for that time and waits again. If something happens, it responds to that event (creating and destroying other events as needed), and then waits again. – David Schwartz Jul 24 '15 at 20:00
1

There isn't any solution for the pic16 series (it is far too small) but there is FreeRtos, made specifically for microcontrollers and there is a port for PIC18 (and a few others) check out the supported device list

Although freeRTOS is "free" to obtain and to use in personal projects I would recommend you purchase one of their books to help with implementation. There is free API on their site and demo code as well. It would be easier to understand it with the book (please note I am not tied to freeRTOS in anyway, I used it in projects with atmel controllers and found it very easy to use)

with freeRTOS you create a task (you define your solenoid control function) and then you set the priority, the delay then start the kernel. It's actually really straightforward.

Again, this won't work with your specific chip pic16, but if you can try another one, freeRTOS is a very well known and a pretty easy solution

andrew
  • 2,451
  • 1
  • 15
  • 22