• Stars
    star
    948
  • Rank 48,215 (Top 1.0 %)
  • Language
    C++
  • License
    MIT License
  • Created over 11 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

⏳ A simple way to run Threads on Arduino

ArduinoThread Logo

ArduinoThreads Motivation

Arduino does not support isolated parallel tasks (Threads), but we can make the main loop switch function execution conditionally and thus simulate threading with Protothread mechanism. This library implements it and helps you to:

  • schedule, manage and simplify parallel, periodic tasks
  • define fixed or variable time between runs
  • organize the code in any type of project
    • put all sensor readings in a thread
    • keep the main loop clean
  • hide the complexity of thread management
  • run "pseudo-background" tasks using Timer interrupts

Blinking an LED is often the very first thing an Arduino user learns. And this demonstrates that periodically performing one single task, like toggling the LED state, is really easy. However, one may quickly discover that managing multiple periodic tasks is not so simple if the tasks have different schedule.

The user defines a Thread object for each of those tasks, then lets the library manage their scheduled execution.

It should be noted that these are not “threads” in the real computer-science meaning of the term: tasks are implemented as functions that are run periodically. On the one hand, this means that the only way a task can yield the CPU is by returning to the caller, and it is thus inadvisable to delay() or do long waits inside any task. On the other hand, this makes ArduinoThreads memory friendly, as no stack need to be allocated per task.

Installation

  1. Download the Master branch from gitHub.
  2. Unzip and modify the Folder name to "ArduinoThread" (Remove the '-master' suffix)
  3. Paste the modified folder on your Library folder (On your Libraries folder inside Sketchbooks or Arduino software).
  4. Restart the Arduino IDE

If you are here just because another library requires a class from ArduinoThread, then you are done now .

Getting Started

There are many examples showing many ways to use it. We will explain Class itself, what it does and how it does.

There are three main classes included in the library: Thread, ThreadController and StaticThreadController (both controllers inherit from Thread).

  • Thread: Basic class, witch contains methods to set and run callbacks, check if the Thread should be run, and also creates a unique ThreadID on the instantiation.

  • ThreadController: Responsible for managing multiple Threads. Can also be thought of as "a group of Threads", and is used to perform run in every Thread ONLY when needed.

  • StaticThreadController: Slightly faster and smaller version of the ThreadController. It works similar to ThreadController, but once constructed it can't add or remove threads to run.

Create Thread instance:

Thread myThread = Thread();
// or, if initializing a pointer
Thread* myThread = new Thread();

Setup thread behaviour

You can configure many things:

myThread.enabled = true; // Default enabled value is true
myThread.setInterval(10); // Setts the wanted interval to be 10ms
/*
	This is useful for debugging
	(Thread Name is disabled by default, to use less memory)
	(Enable it by definint USE_THREAD_NAMES on 'Thread.h')
*/
myThread.ThreadName = "myThread tag";
// This will set the callback of the Thread: "What should I run"?
myThread.onRun(callback_function); // callback_function is the name of the function

Running threads manually

Ok, creating threads isn't too hard, but what do we do with them?

// First check if our Thread should be run
if(myThread.shouldRun()){
  // Yes, the Thread should run, let's run it
  myThread.run();
}

Running threads via a controller

If you had 3, 5 or 100 threads, managing them manually could become tedious. That's when ThreadController or StaticThreadController comes into play and saves you the repetitive thread management parts of code.

// Instantiate new ThreadController
ThreadController controller = ThreadController();
// Now, put bunch of Threads inside it, FEED it!
controller.add(&myThread); // Notice the '&' sign before the thread, IF it's not instantied as a pointer.
controller.add(&hisThread);
controller.add(&sensorReadings);
...

or

// Instantiate a new StaticThreadController with the number of threads to be supplied as template parameter
StaticThreadController<3> controller (&myThread, &hisThread, &sensorReadings);
// You don't need to do anything else, controller now contains all the threads.
...

You have created, configured, grouped it. What is missing? Yes, whe should RUN it! The following will run all the threads that NEED to run.

// call run on a Thread, a ThreadController or a StaticThreadController to run it
controller.run();

Congratulations, you have learned the basics of the ArduinoThread library. If you want to learn more, see bellow.

Tips and Warnings

  • ThreadController is not of a dynamic size (like a LinkedList). The maximum number of threads that it can manage is defined in ThreadController.h (default is 15)

  • When extending the Thread class and overriding the run() function, remember to always call runned(); at the end, otherwise the thread will hang forever.

  • It's a good idea, to create a Timer interrupt and call a ThreadController.run() there. That way, you don't need to worry about reading sensors and doing time-sensitive stuff in your main code (loop). Check ControllerWithTimer example.

  • Inheriting from Thread or even ThreadController is always a good idea. For example, I always create base classes of sensors that extends Thread, so that I can "register" the sensors inside a ThreadController, and forget about reading sensors, just having the values available in my main code. Check the SensorThread example.

  • Remember that ThreadController is in fact, a Thread itself. If you want to group threads and manage them together (enable or disable), think about putting all of them inside a ThreadController, and adding this ThreadController to another ThreadController (YES! One inside another). Check ControllerInController example.

  • StaticThreadController is optimal when you know the exact number of threads to run. You cannot add or remove threads at runtime, but it doesn't require additional memory to keep all the treads together, doesn't limit the number of thread (except for available memory) and the code may be slightly better optimized because all the threads always exist and no need to do any runtime checks.

  • Check the full example CustomTimedThread for a cool application of threads that run for a period, after a button is pressed.

  • Running tasks on the Timer interrupts must be thought though REALLY carefully

    • You mustn't use sleep() inside an interrupt, because it would cause an infinite loop.

    • Things execute quickly. Waiting too loooong on a interrupt, means waiting too loooong on the main code (loop)

    • Things might get "scrambled". Since Timers interrupts actually "BREAK" your code in half and start running the interrupt, you might want to call noInterrupts and interrupts on places where cannot be interrupted:

noInterrupts();
// Put the code that CANNOT be interrupted...
interrupts(); // This will enable the interrupts egain. DO NOT FORGET!

Library Reference

Configuration options

Thread

  • bool Thread::enabled - Enables or disables the thread. (doesn't prevent it from running, but will return false when shouldRun() is called)
  • void Thread::setInterval() - Schedules the thread run interval in milliseconds
  • bool Thread::shouldRun() - Returns true, if the thread should be run. (Basically,the logic is: (reached time AND is enabled?).
  • void Thread::onRun(<function>) - The target callback function to be called.
  • void Thread::run() - Runs the thread (executes the callback function).
  • int Thread::ThreadID - Theoretically, it's the memory address. It's unique, and can be used to compare if two threads are identical.
  • int Thread::ThreadName - A human-readable thread name. Default is "Thread ThreadID", eg.: "Thread 141515". Note that to enable this attribute, you must uncomment the line that disables it on Thread.h
  • protected: void Thread::runned() - Used to reset internal timer of the thread. This is automatically called AFTER a call to run().

ThreadController

  • void ThreadController::run() - Runs the all threads grouped by the controller, but only if needed (if shouldRun() returns true);
  • bool ThreadController::add(Thread* _thread) - Adds a the thread to the controller, and returns true if succeeded (returns false if the array is full).
  • void ThreadController::remove(Thread* _thread) - Removes the thread from the controller
  • void ThreadController::remove(int index) - Removes the thread at the index position
  • void ThreadController::clear() - Removes ALL threads from the controller
  • int ThreadController::size(bool cached = true) - Returns number of threads allocated in the ThreadController. Re-calculates thread count if cached is false
  • Thread* ThreadController::get(int index) - Returns the thread at the index position

StaticThreadController

  • void StaticThreadController::run() - Runs all the threads within the controller, but only if needed (if shouldRun() returns true);
  • int StaticThreadController::size() - Returns how many Threads are allocated inside the controller.
  • Thread* ThreadController::get(int index) - Returns the thread at the index position - or nullptr if index is out of bounds.

More Repositories

1

IAMDinosaur

🦄 An Artificial Inteligence to teach Google's Dinosaur to jump cactus
JavaScript
2,800
star
2

Is-Now-Illegal

🚫 A NERD protest against Trump's Immigration ban
JavaScript
1,372
star
3

node-draftlog

📜 Create mutable log lines into the terminal, and give life to your logs!
JavaScript
1,244
star
4

LinkedList

🔗 A fully implemented LinkedList made to work with general Microcontrollers and Arduino projects
C++
346
star
5

DueTimer

⏳ Timer Library fully implemented for Arduino DUE
C++
211
star
6

unicute

💙 Cute Unicode symbols. Make the terminal GREAT AGAIN
57
star
7

ArduinoSensors

A Library of Libraries of Sensors. Infrared, Ultrasonic, Compass and many others, ready to work with ArduinoThread and fully object oriented
C++
54
star
8

Gaussian

Library that makes Gaussian work easy to use with C++ and Arduino
C++
52
star
9

BigBang-js

Recreate the BigBang with JavaScript
JavaScript
48
star
10

Robot-Soccer-Simulator

⚽️ An Open-Source Soccer simulator for virtual robots tournaments
Java
34
star
11

EasyFly

A simple and just another Drone Firmware
C++
25
star
12

3DLiveView-ABB

Application using QT and native OpenGL, with a three based rendering engine to show a 3D ABB robot in sync with an arduino
C++
20
star
13

node-require-smart

The smart way of requiring multiple files in NodeJS
JavaScript
18
star
14

ABBNator

ABB Robots, playing TicTacToe with NodeJS in it's free time
JavaScript
16
star
15

Robot-Rescue-2013

RoboCup Junior Rescue B Robot sharing (CAD, Software, Electronics, materials and all stuff)
C
15
star
16

ArdUI

A generic, simple, easy to use User Interface for Arduino
C++
14
star
17

Robot-Soccer-2013

RoboCup Junior Soccer Robot sharing (CAD, Software, Electronics, materials and all stuff)
C
14
star
18

UTFT

A generic LCD Library for Arduino
C
11
star
19

Nao-Taokei

🚫Um app NERD para gerar gifs Huehue BR
JavaScript
6
star
20

NodePlate

Node boilerplate for servers
JavaScript
6
star
21

Robot-Rescue-2012

RoboCup Junior Rescue B Robot sharing (CAD, Software, Electronics, materials and all stuff)
Java
6
star
22

pcb-libraries

Place to keep and share special Altium, Eagle and Proteus components that we create and share with others.
6
star
23

oscilodrawer

Osciloscope Image drawer with Arduino and Nodejs MQTT
C++
5
star
24

Primo

Primo version using Stepper Motors and custom Software
C++
5
star
25

docker-node-python-opencv

A Dockerfile that installs Node.js, Python and OpenCV
4
star
26

tournamenter-obr

Extensão para o Tournamenter que permite pontuar pelo tablet em competições da OBR
JavaScript
4
star
27

easy-admin

Simple Admin UI with CRUD for Node.js
JavaScript
3
star
28

geddy-rest

REST Api made easy for Geddy
JavaScript
3
star
29

Robot-VerySmall-2015

Very Small Robot for 2015 CBR competition
Python
2
star
30

projetohangar

HTML
2
star
31

i23

An innovative way of connecting and communicating sensors with microcontrollers
2
star
32

node-ssl-vision

RoboCup SSL Vision Client library for Node.JS
JavaScript
2
star
33

Robot-Rescue-2011

Emerotecos Team's robot of Rescue A (OBR) 2011
HTML
1
star
34

Phyto-Gear

A simple Arduino robot that communicates with Facebook to notify that it's happy, sad, with or without light...
Arduino
1
star
35

TemPeixeNoRU

App de leitura de cardápio do RU da UFABC
1
star
36

Chenn

An real time graph as learning object for schools
JavaScript
1
star
37

rifa-generator

Projeto antigo de um Gerador de PDF's de Rifas
JavaScript
1
star
38

tournamenter-wro

Tournamenter Plugin for WRO - World Robotics Olympiad
JavaScript
1
star
39

robocup2014

Robocup 2014 Administration panel for leagues
JavaScript
1
star
40

NoFlow

A (really-simple) flow based programming framework
JavaScript
1
star