Skip to content

Instantly share code, notes, and snippets.

@fjrg76-com
Last active June 6, 2022 04:13
Show Gist options
  • Save fjrg76-com/0a31618633cfcb2d72bd715372f23c31 to your computer and use it in GitHub Desktop.
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.
#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