#include <Arduino_FreeRTOS.h> // include LCD library function
#include <queue.h> // include Queue library
#include<LiquidCrystal.h> // include LCD library function
LiquidCrystal lcd (7,6,5,4,3,2); //RS, E, D4, D5, D6, D7
QueueHandle_t xQueue; //Queue handle
// Define Tasks
void SensorTask( void *pvParameters );
void LcdTask ( void *pvParameters );
void alarmTask ( void *pvParameters );
//define pins so compiler will replace any mention to the pin names with it value specified at compile time.
#define alarmPin A0
#define trigPin 10
#define EchoPin 9
// Define Global variables
char line;
void setup()
{
Serial.begin(9600); // open serial port with boud rate 9600.
pinMode(EchoPin, INPUT); // set the digital pin as Input.
pinMode(trigPin, OUTPUT); // set the digital pin as Output.
pinMode(alarmPin, OUTPUT); // set the digital pin as Output.
lcd.begin(16,2); // set up the LCD 16x2.
xQueue = xQueueCreate( 5, sizeof( int ) ); // create the Queue
if( xQueue != NULL )
{
// set up three tasks to run independently.
xTaskCreate( SensorTask, "Sensor", 128, NULL, 1, NULL );
xTaskCreate( LcdTask, "LCD" , 128, NULL, 2, NULL );
xTaskCreate( alarmTask, "Alarm" , 128, NULL, 2, NULL );
vTaskStartScheduler();
}
else { /* The queue could not be created. */ }
}
void loop() { /*empty loop*/ }
void SensorTask( void * pvParameters ) //This is a task with a void pointer parameter. Task 1 .
{
(void) pvParameters ; // to supress compiler warning when parameter unused.
for( ;; ) // A task shall never return or exit.
{
//define local variables
long duration, distance;
// the sensor is triggered by a High pulse of 10 microseonds.
// But give a short LOW pulse before so to ensure get a clean High pulse.
digitalWrite(trigPin, LOW); //set the digital pin OFF.
delayMicroseconds(2); //pauses for 2 microseconds.
digitalWrite(trigPin, HIGH);//set the digital pin ON.
delayMicroseconds(10); //pauses for 10 microseconds.
digitalWrite(trigPin, LOW); //set the digital pin OFF.
//Read signal from the sensor : a High pulse whose
duration = pulseIn(EchoPin, HIGH); // duration is the time from sending in microSeconds of the ping to the reception of its echo off of an object.
distance = (duration/2 ) /29.1 ; //convert duration into a distance in cm.
xQueueSend( xQueue, &distance, portMAX_DELAY ); // send data to the queue
//print on the Serial monitor
Serial.println("--------------------------ReadSensor------------------------");
Serial.println("Task ReadSensor is working");
Serial.print("Distance= ");
Serial.print(distance);
Serial.println("cm");
vTaskDelay(500 / portTICK_PERIOD_MS); // delay (block) a function for a specified number of ticks.
}
}
void LcdTask( void *pvParameters ) //This is a task with a void pointer parameter. Task 2 .
{
int ReceivedValue = 0;
(void) pvParameters ; // to supress compiler warning when parameter unused.
for( ;; ) // A task shall never return or exit.
{
if (xQueueReceive( xQueue, &ReceivedValue, portMAX_DELAY ) ) //Read data from the queue
{
//print on the Serial monitor
Serial.println("--------------------------LCD------------------------");
Serial.println("Task LCD is working");
Serial.print( "Distance = ");
Serial.println(ReceivedValue);
//print on the LCD
lcd.clear(); //clears the LCD and position cursor in the upper-left corner.
lcd.setCursor(0, 0); //Set cursor to colum 0 , line 0 ( lin 0 = first row )
lcd.print("Distance= "); //print string
lcd.setCursor(10, 0); //Set cursor to colum 10 , line 0 ( lin 0 = first row )
lcd.print(ReceivedValue); //print variable value
lcd.setCursor(14, 0); //Set cursor to colum 14 , line 0 ( lin 0 = first row )
lcd.print("cm"); //print string
lcd.setCursor(0, 1); //Set cursor to colum 0 , line 1 ( lin 1 = second row )
line =255;
if (ReceivedValue >=141){ lcd.print(line); }
if(ReceivedValue >= 101 && ReceivedValue < 140 ) { for (int i =0 ; i<3 ; i++) { lcd.print(line); } }
if(ReceivedValue >= 21 && ReceivedValue <= 100 ) { for (int i =0 ; i<8 ; i++) { lcd.print(line); } }
if(ReceivedValue >= 0 &&ReceivedValue <= 20 ) { for (int i =0 ; i<15 ; i++){ lcd.print(line); } }
lcd.setCursor(15, 1); //Set cursor to colum 15 , line 1 ( lin 1 = second row )
lcd.print('X'); //print character
}
taskYIELD(); // request context switch.
}
}
void alarmTask( void * pvParameters ) //This is a task with a void pointer parameter. Task 3 .
{
int ReceivedValue = 0;
(void) pvParameters ; // to supress compiler warning when parameter unused.
for( ;; ) // A task shall never return or exit.
{
if (xQueueReceive( xQueue, &ReceivedValue, portMAX_DELAY ) ) //Read data from the queue
{
if(ReceivedValue >=141 ){ noTone(alarmPin); /*Stop generating the tone*/ }
if(ReceivedValue >= 121 && ReceivedValue <= 140) { tone(alarmPin, 1); /* Plays 1 Hz tone */}
if(ReceivedValue >= 101 && ReceivedValue <= 120) { tone(alarmPin, 10); /* Plays 10 Hz tone */}
if(ReceivedValue >= 81 && ReceivedValue <= 100 ) { tone(alarmPin, 100); /* Plays 100 Hz tone */}
if(ReceivedValue >= 61 && ReceivedValue <= 80 ) { tone(alarmPin, 200); /* Plays 200 Hz tone */}
if(ReceivedValue >= 41 && ReceivedValue <= 60 ) { tone(alarmPin, 300); /* Plays 300 Hz tone */}
if(ReceivedValue >= 21 && ReceivedValue <= 40 ) { tone(alarmPin, 500); /* Plays 500 Hz tone */}
if(ReceivedValue >= 11 && ReceivedValue <= 20 ) { tone(alarmPin, 700); /* Plays 700 Hz tone */}
if(ReceivedValue >= 0 && ReceivedValue <= 10 ) { tone(alarmPin, 1000); /*Plays 1000 Hz tone*/}
//print on the Serial monitor
Serial.println("--------------------------Buzzer------------------------");
Serial.println("Task Buzzer is working");
Serial.print( "Distance = ");
Serial.println(ReceivedValue);
}
taskYIELD(); // request context switch.
}
}