Arduino is a great tool for rapid prototyping. It has a good Hardware and Software platform to quickly get started. But when it comes to Advanced Software concepts like Threads, Semaphores and Mutexes the Vanilla Arduino IDE doesn't have much to offer.
That is where ChibiOS comes in. ChibiOS is Real Time Operating System (RTOS) which is intended for Embedded system. Likely ChibiOS has a port for Arduino which can be used in Arduino IDE as a Library.
Using this allows Parallel code execution, Synchronized code excution and many more possible in Arduino. Previously I have done a small project to show Temperature and Humidity on 8x2 LCD Display.
This project has two parts, a Sensor Input Reading and LCD Output Writing both of which are done inside the void loop() section of the Arduino Sketch. But as we all know Input and Output are tasks can sometimes take longer than expected. For Ex:- During Network Input and Output.
So It is better to Parallelize the Input and Output. This can be achieved with ChibiOS-Arduino Library.
So I used the same setup from the aforementioned post with Threads this time to separate Read and Write. Plus Reading will take place every 200 Milliseconds but Writing will take place every 1000 Milliseconds (1 Second). And Read Thread and Write Thread communication is done via a Semaphore. Write Thread will wait on the Semaphore for data to be available and Read Thread will Signal on the Semaphore whenever data is available. So the Serial output for the Arduino Program will look like following, 1 Output Thread for 5 Input Threads
The full Arduino Sketch is following;
References
That is where ChibiOS comes in. ChibiOS is Real Time Operating System (RTOS) which is intended for Embedded system. Likely ChibiOS has a port for Arduino which can be used in Arduino IDE as a Library.
Using this allows Parallel code execution, Synchronized code excution and many more possible in Arduino. Previously I have done a small project to show Temperature and Humidity on 8x2 LCD Display.
This project has two parts, a Sensor Input Reading and LCD Output Writing both of which are done inside the void loop() section of the Arduino Sketch. But as we all know Input and Output are tasks can sometimes take longer than expected. For Ex:- During Network Input and Output.
So It is better to Parallelize the Input and Output. This can be achieved with ChibiOS-Arduino Library.
So I used the same setup from the aforementioned post with Threads this time to separate Read and Write. Plus Reading will take place every 200 Milliseconds but Writing will take place every 1000 Milliseconds (1 Second). And Read Thread and Write Thread communication is done via a Semaphore. Write Thread will wait on the Semaphore for data to be available and Read Thread will Signal on the Semaphore whenever data is available. So the Serial output for the Arduino Program will look like following, 1 Output Thread for 5 Input Threads
The full Arduino Sketch is following;
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example to demonstrate thread definition, semaphores, and thread sleep. | |
#include <ChibiOS_AVR.h> | |
#include <LiquidCrystal.h> | |
#include <dht.h> | |
#define DHT11_PIN 8 | |
int humidity = 0; | |
int temperature = 0; | |
dht DHT; | |
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); | |
// Declare a semaphore with an inital counter value of zero. | |
SEMAPHORE_DECL(sem, 0); | |
//------------------------------------------------------------------------------ | |
// Thread 1, Input Thread | |
// 64 byte stack beyond task switch and interrupt needs | |
static THD_WORKING_AREA(waThread1, 64); | |
static THD_FUNCTION(Thread1, arg) { | |
while (1) { | |
Serial.print("In Input Thread, \t"); | |
int chk = DHT.read11(DHT11_PIN); | |
switch (chk) | |
{ | |
case DHTLIB_OK: | |
Serial.print("OK\n"); | |
break; | |
case DHTLIB_ERROR_CHECKSUM: | |
Serial.print("Checksum error,\t"); | |
break; | |
case DHTLIB_ERROR_TIMEOUT: | |
Serial.print("Time out error,\t"); | |
break; | |
case DHTLIB_ERROR_CONNECT: | |
Serial.print("Connect error,\t"); | |
break; | |
case DHTLIB_ERROR_ACK_L: | |
Serial.print("Ack Low error,\t"); | |
break; | |
case DHTLIB_ERROR_ACK_H: | |
Serial.print("Ack High error,\t"); | |
break; | |
default: | |
Serial.print("Unknown error,\t"); | |
break; | |
} | |
temperature = (int) DHT.temperature; | |
humidity = (int) DHT.humidity; | |
chThdSleepMilliseconds(200); | |
chSemSignal(&sem); | |
} | |
} | |
//------------------------------------------------------------------------------ | |
// Thread 2, Output Thread | |
// 64 byte stack beyond task switch and interrupt needs | |
static THD_WORKING_AREA(waThread2, 64); | |
static THD_FUNCTION(Thread2, arg) { | |
while (!chThdShouldTerminateX()) { | |
// Wait for signal from thread 2. | |
chSemWait(&sem); | |
Serial.print("In Output Thread : "); | |
Serial.print(temperature); | |
Serial.print(", "); | |
Serial.print(humidity); | |
Serial.print("\n"); | |
lcd.clear(); | |
lcd.setCursor(0,0); | |
lcd.print("Tem:"); | |
lcd.print((int) temperature); | |
lcd.print("C"); | |
lcd.setCursor(0,1); | |
lcd.print("Hum:"); | |
lcd.print((int) humidity); | |
lcd.print("%"); | |
chThdSleepMilliseconds(1000); | |
chSemReset(&sem, 0); | |
} | |
} | |
//------------------------------------------------------------------------------ | |
void setup() { | |
chBegin(chSetup); | |
// chBegin never returns, main thread continues with mainThread() | |
while(1) { | |
} | |
} | |
//------------------------------------------------------------------------------ | |
// main thread runs at NORMALPRIO | |
void chSetup() { | |
Serial.begin(9600); | |
lcd.begin(8, 2); | |
lcd.clear(); | |
// Start Input Thread | |
chThdCreateStatic(waThread1, sizeof(waThread1), | |
NORMALPRIO + 2, Thread1, NULL); | |
// Start Output Thread | |
chThdCreateStatic(waThread2, sizeof(waThread2), | |
NORMALPRIO + 1, Thread2, NULL); | |
} | |
//------------------------------------------------------------------------------ | |
void loop() { | |
// not used | |
} |
References