#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
/* defines - LCD */
#define LCD_16X2_CLEAN_LINE " "
#define LCD_16X2_I2C_ADDRESS 0x27
#define LCD_16X2_COLS 16
#define LCD_16X2_ROWS 2
/* defines - LED */
#define LED_PIN 5
// #define LED_PIN_LDR 3
// #define LDR_PIN A1
//int VALUE_LDR=0;
#define LED_THRESHOLD 4.0 /* V */
// #define LDR_THRESHOLD 400 /* V */
#define LED_THRESHOLD_MEDIUM 2.0 /* V */
/* defines - ADC */
#define ADC_MAX 1023.0
#define MAX_VOLTAGE_ADC 5.0
/* tasks */
void task_breathing_light( void *pvParameters );
void task_serial( void *pvParameters );
void task_lcd( void *pvParameters );
void task_sensor( void *pvParameters );
void task_led( void *pvParameters );
void task_led_yellow( void *pvParameters );
void task_led_green( void *pvParameters );
/* Variaveis relacionadas ao LCD */
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
/* filas (queues) */
QueueHandle_t xQueue_SENSOR, xQueue_LED, xQueue_LDR;
/* semaforos utilizados */
SemaphoreHandle_t xSerial_semaphore;
void setup()
{
/* Inicializa serial (baudrate 9600) */
Serial.begin(9600);
/* Inicializa o LCD, liga o backlight e limpa o LCD */
lcd.init();
lcd.backlight();
lcd.clear();
/* Inicializa e configura GPIO do LED */
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
// pinMode(LED_PIN_LDR, OUTPUT);
// digitalWrite(LED_PIN_LDR, LOW);
// pinMode(LDR_PIN, INPUT);//Define ldr (pino analógico A0) como saída
while (!Serial) {
; /* Somente vai em frente quando a serial estiver pronta para funcionar */
}
/* Criação da fila (queue) */
xQueue_SENSOR = xQueueCreate( 1, sizeof( float ) );
//xQueue_LED = xQueueCreate( 1, sizeof( float ) );
//xQueue_LDR = xQueueCreate( 1, sizeof( float ) );
/* Criação dos semaforos */
xSerial_semaphore = xSemaphoreCreateMutex();
if (xSerial_semaphore == NULL)
{
Serial.println("Erro: nao e possivel criar o semaforo");
while(1); /* Sem semaforo o funcionamento esta comprometido. Nada mais deve ser feito. */
}
/* Criação das tarefas */
// xTaskCreate( task_ldr /* Funcao a qual esta implementado o que a tarefa deve fazer */
// ,"sensor_ldr" /* Nome (para fins de debug, se necessário) */
// , 32 /* Tamanho da stack (em words) reservada para essa tarefa */
// , NULL /* Parametros passados (nesse caso, não há) */
// , 6 /* Prioridade */
// , NULL ); /* Handle da tarefa, opcional (nesse caso, não há) */
// xTaskCreate( task_led_ldr /* Funcao a qual esta implementado o que a tarefa deve fazer */
// ,"led_ldr" /* Nome (para fins de debug, se necessário) */
// , 32 /* Tamanho da stack (em words) reservada para essa tarefa */
// , NULL /* Parametros passados (nesse caso, não há) */
// , 5 /* Prioridade */
// , NULL ); /* Handle da tarefa, opcional (nesse caso, não há) */
// xTaskCreate( task_sensor /* Funcao a qual esta implementado o que a tarefa deve fazer */
// ,"sensor" /* Nome (para fins de debug, se necessário) */
// , 2000 /* Tamanho da stack (em words) reservada para essa tarefa */
// , NULL /* Parametros passados (nesse caso, não há) */
// , 4 /* Prioridade */
// , NULL ); /* Handle da tarefa, opcional (nesse caso, não há) */
xTaskCreatePinnedToCore(task_sensor,
"sensor",
2048,
NULL,
4,
NULL,
APP_CPU_NUM);
// xTaskCreate(task_lcd
// ,"LCD"
// , 2000
// , NULL
// , 3
// , NULL );
xTaskCreatePinnedToCore(task_lcd,
"LCD",
1024,
NULL,
3,
NULL,
APP_CPU_NUM);
// xTaskCreate(task_led
// , "LED"
// , 2000
// , NULL
// , 2
// , NULL );
xTaskCreatePinnedToCore(task_led,
"LED",
1024,
NULL,
2,
NULL,
APP_CPU_NUM);
}
void loop()
{
/* Tudo é executado nas tarefas. Há nada a ser feito aqui. */
}
/* --------------------------------------------------*/
/* ---------------------- Tarefas -------------------*/
/* --------------------------------------------------*/
void task_sensor( void *pvParameters )
{
(void) pvParameters;
int adc_read=0;
UBaseType_t uxHighWaterMark;
float voltage = 0.0;
while(1)
{
adc_read = analogRead(0);
voltage = ((float)adc_read/ADC_MAX)*MAX_VOLTAGE_ADC;
/* Envia tensão lida em A0 para as tarefas a partir de filas */
xQueueOverwrite(xQueue_SENSOR, (void *)&voltage);
//xQueueOverwrite(xQueue_LED, (void *)&voltage);
/* Espera um segundo */
vTaskDelay( 1000 / portTICK_PERIOD_MS );
/* Para fins de teste de ocupação de stack, printa na serial o high water mark */
xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
Serial.print("task_sensor high water mark (words): ");
Serial.println(uxHighWaterMark);
Serial.println("---");
xSemaphoreGive(xSerial_semaphore);
}
}
void task_lcd( void *pvParameters )
{
(void) pvParameters;
float voltage_rcv = 0.0;
UBaseType_t uxHighWaterMark;
while(1)
{
/* Espera até algo ser recebido na queue */
xQueueReceive(xQueue_SENSOR, (void *)&voltage_rcv, portMAX_DELAY);
/* Uma vez recebida a informação na queue, a escreve no display LCD */
lcd.setCursor(0,0);
lcd.print("Tensao ADC:");
lcd.setCursor(0,1);
lcd.print(LCD_16X2_CLEAN_LINE);
lcd.setCursor(0,1);
lcd.print(voltage_rcv);
lcd.setCursor(15,1);
lcd.print("V");
/* Para fins de teste de ocupação de stack, printa na serial o high water mark */
xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
Serial.print("task_lcd high water mark (words): ");
Serial.println(uxHighWaterMark);
Serial.println("---");
xSemaphoreGive(xSerial_semaphore);
vTaskDelay(100);
}
}
void task_led( void *pvParameters )
{
(void) pvParameters;
float voltage_rcv = 0.0;
UBaseType_t uxHighWaterMark;
while(1)
{
/* ATENÇÃO: NUNCA USE A FUNÇÃO delay() QUANDO ESTIVER USANDO FREERTOS!
em seu lugar, use a função vTaskDelay( tempo / portTICK_PERIOD_MS );, substituindo "tempo" pelo tempo de delay
(em ms) desejado.
*/
xQueueReceive(xQueue_SENSOR, (void *)&voltage_rcv, portMAX_DELAY);
if(voltage_rcv >= LED_THRESHOLD)
digitalWrite(LED_PIN, HIGH);
else
digitalWrite(LED_PIN,LOW);
/* Para fins de teste de ocupação de stack, printa na serial o high water mark */
xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
Serial.print("task_led high water mark (words): ");
Serial.println(uxHighWaterMark);
Serial.println("---");
xSemaphoreGive(xSerial_semaphore);
}
}
// void task_ldr( void *pvParameters )
// {
// (void) pvParameters;
// UBaseType_t uxHighWaterMark;
// float value_ldr;
// while(1)
// {
// /* ATENÇÃO: NUNCA USE A FUNÇÃO delay() QUANDO ESTIVER USANDO FREERTOS!
// em seu lugar, use a função vTaskDelay( tempo / portTICK_PERIOD_MS );, substituindo "tempo" pelo tempo de delay
// (em ms) desejado.
// */
// value_ldr=analogRead(LDR_PIN);//Lê o valor do sensor ldr e armazena na variável valorldr
// xQueueOverwrite(xQueue_LDR, (void *)&value_ldr);
// /* Espera um segundo */
// vTaskDelay( 1000 / portTICK_PERIOD_MS );
// /* Para fins de teste de ocupação de stack, printa na serial o high water mark */
// xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
// uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
// Serial.print("task_ldr high water mark (words): ");
// Serial.println(uxHighWaterMark);
// Serial.println("---");
// Serial.print("Valor lido pelo LDR = ");//Imprime na serial a mensagem Valor lido pelo LDR
// Serial.println(value_ldr);//Imprime na serial os dados de valorldr
// xSemaphoreGive(xSerial_semaphore);
// }
// }
// void task_led_ldr( void *pvParameters )
// {
// (void) pvParameters;
// float value_ldr_rcv = 0;
// UBaseType_t uxHighWaterMark;
// while(1)
// {
// /* ATENÇÃO: NUNCA USE A FUNÇÃO delay() QUANDO ESTIVER USANDO FREERTOS!
// em seu lugar, use a função vTaskDelay( tempo / portTICK_PERIOD_MS );, substituindo "tempo" pelo tempo de delay
// (em ms) desejado.
// */
// xQueueReceive(xQueue_LDR, (void *)&value_ldr_rcv, portMAX_DELAY);
// if(value_ldr_rcv <= LDR_THRESHOLD){
// Serial.println("to aqui porra");
// digitalWrite(LED_PIN_LDR, HIGH);}
// else
// digitalWrite(LED_PIN_LDR,LOW);
// /* Para fins de teste de ocupação de stack, printa na serial o high water mark */
// xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
// uxHighWaterMark = uxTaskGetStackHighWaterMark( NULL );
// Serial.print("task_led_ldr high water mark (words): ");
// Serial.println(uxHighWaterMark);
// Serial.println("---");
// xSemaphoreGive(xSerial_semaphore);
// }
// }