Last active
June 6, 2022 04:13
-
-
Save fjrg76-com/0a31618633cfcb2d72bd715372f23c31 to your computer and use it in GitHub Desktop.
Monitors using FreeRTOS mutex'es. The monitor example protects the Arduino's ADC.
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
#include <stdint.h> | |
#include <FreeRTOS.h> | |
#include <task.h> | |
#include <semphr.h> | |
class AdcMonitor | |
{ | |
private: | |
SemaphoreHandle_t mutex{ NULL }; | |
public: | |
AdcMonitor() | |
{ | |
this->mutex = xSemaphoreCreateMutex(); | |
} | |
int16_t read( uint8_t channel, uint16_t timeout ) | |
{ | |
int16_t ret_val = -1; | |
if( xSemaphoreTake( this->mutex, timeout ) != pdFALSE ) | |
{ | |
ret_val = analogRead( channel ); | |
xSemaphoreGive( this->mutex ); | |
} | |
return ret_val; | |
} | |
}; | |
//---------------------------------------------------------------------- | |
// Monitor instance: | |
//---------------------------------------------------------------------- | |
AdcMonitor adc_monitor; | |
#define LM35_ADC_CHANNEL 0 | |
#define LM35_TIMEOUT 50 | |
#define LM35_PERIOD 500 | |
void task_lm35( void* pvParameters ) | |
{ | |
(void) pvParameters; | |
TickType_t last_wake_time = xTaskGetTickCount(); | |
while( 1 ) | |
{ | |
vTaskDelayUntil( &last_wake_time, pdMS_TO_TICKS( LM35_PERIOD ) ); | |
int16_t ret_val = adc_monitor.read( LM35_ADC_CHANNEL, pdMS_TO_TICKS( LM35_TIMEOUT ) ); | |
Serial.print( "LM35: " ); | |
if( ret_val >= 0 ) | |
{ | |
float temp_lm35 = ( ret_val * 5.0 * 100.0 ) / 1024.0; | |
Serial.println( temp_lm35 ); | |
} | |
else | |
{ | |
Serial.println( "TIMEOUT" ); | |
} | |
} | |
} | |
#define MCP9700_ADC_CHANNEL 1 | |
#define MCP9700_TIMEOUT 50 | |
#define MCP9700_PERIOD 500 | |
void task_mcp9700( void* pvParameters ) | |
{ | |
(void) pvParameters; | |
TickType_t last_wake_time = xTaskGetTickCount(); | |
while( 1 ) | |
{ | |
vTaskDelayUntil( &last_wake_time, pdMS_TO_TICKS( MCP9700_PERIOD ) ); | |
int16_t ret_val = adc_monitor.read( MCP9700_ADC_CHANNEL, pdMS_TO_TICKS( MCP9700_TIMEOUT ) ); | |
Serial.print( "9700: " ); | |
if( ret_val >= 0 ) | |
{ | |
float temp_9700 = ( 500.0*ret_val - 51200.0 ) / 1024.0; | |
Serial.println( temp_9700 ); | |
} | |
else | |
{ | |
Serial.println( "TIMEOUT" ); | |
} | |
} | |
} | |
#define PERIOD_HIGH 20 | |
#define PERIOD_LOW 980 | |
void heart_beat( void* pvParameters ) | |
{ | |
(void) pvParameters; | |
pinMode( 13, OUTPUT ); | |
bool led = false; | |
while( 1 ) | |
{ | |
vTaskDelay( pdMS_TO_TICKS( !led ? PERIOD_LOW : PERIOD_HIGH ) ); | |
digitalWrite( 13, ( led = !led ) ); | |
} | |
} | |
void setup() | |
{ | |
xTaskCreate( task_lm35, "LM35", 128, NULL, tskIDLE_PRIORITY + 1, NULL ); | |
xTaskCreate( task_mcp9700, "9700", 128, NULL, tskIDLE_PRIORITY, NULL ); | |
xTaskCreate( heart_beat, "HBT", 128, NULL, tskIDLE_PRIORITY, NULL ); | |
Serial.begin( 115200 ); | |
Serial.println( "\nmonitor_ADC.ino\n" ); | |
vTaskStartScheduler(); | |
} | |
void loop() | |
{ | |
// nothing in here when using a kernel! | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment