//baseado no site
//https://www.manualdomaker.com/article/sensor-de-gestos-apds9960/
//Biblioteca do Arduino
#include <Arduino.h>
//Bibliotecas FreeRTOS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include"freertos/queue.h"
#include <SparkFun_APDS9960.h>
// Pins
#define APDS9960_INT GPIO_NUM_27
bool is_isr = false;
SparkFun_APDS9960 apds = SparkFun_APDS9960();
//pino do botao da interrupção
#define BT 12
#define LED_CIMA 4
#define LED_BAIXO 5
#define LED_DIREITA 16
#define LED_ESQUERDA 2
// Variáveis para armazenamento do handle das tasks
TaskHandle_t taks1Handle = NULL; //tarefa leitura sensor humidade/temp.
//protítipos das Tasks
void vTask1(void *pvParameters);
void handleGesture();
//declaração da ISR
void IRAM_ATTR exec_isr(void *arg){
if (!is_isr){
gpio_intr_disable(APDS9960_INT);
is_isr = true;
}
}
//função para ISR
void handleGesture(){
if (apds.isGestureAvailable()){
switch (apds.readGesture()){
case DIR_UP:
Serial.println("UP");
break;
case DIR_DOWN:
Serial.println("DOWN");
break;
case DIR_LEFT:
Serial.println("LEFT");
gpio_set_level(GPIO_NUM_2, HIGH);
break;
case DIR_RIGHT:
Serial.println("RIGHT");
gpio_set_level(GPIO_NUM_2, LOW);
break;
case DIR_NEAR:
Serial.println("NEAR");
break;
case DIR_FAR:
Serial.println("FAR");
break;
default:
Serial.println("NONE");
}
}
}
void setup() {
Serial.begin(115200);
pinMode(LED_CIMA, OUTPUT);
pinMode(LED_BAIXO, OUTPUT);
pinMode(LED_DIREITA, OUTPUT);
pinMode(LED_ESQUERDA, OUTPUT);
pinMode(BT,INPUT_PULLUP);
//criação das tasks
xTaskCreate(vTask1,"TASK1",configMINIMAL_STACK_SIZE+1024,NULL,3,&taks1Handle);
pinMode(2, OUTPUT);
digitalWrite(2,HIGH);
//configurando o LED onboard para responder a ligamento e desligamento
//gpio_set_direction(, OUTPUT);
gpio_set_level(GPIO_NUM_2, LOW);
Serial.println("Ativando interrupções");
gpio_set_direction(APDS9960_INT, GPIO_MODE_INPUT);
gpio_set_pull_mode(APDS9960_INT, GPIO_PULLUP_ONLY);
gpio_install_isr_service(0);
gpio_set_intr_type(APDS9960_INT, GPIO_INTR_NEGEDGE);
gpio_intr_enable(APDS9960_INT);
gpio_isr_handler_add(APDS9960_INT, exec_isr, NULL);
if (apds.init()){
Serial.println(F("APDS9960 inicializado"));
}
else{
Serial.println(F("APDS9960 não inicializado"));
}
if ( apds.enableGestureSensor(true) ) {
Serial.println(F("Sensor de gestos em execução"));
} else {
Serial.println(F("..."));
}
}
//função loop (vazia)
void loop() {
//coloquei no loop mas provavel vou ter que migrar para um task
if (is_isr){
is_isr = false;
handleGesture();
gpio_intr_enable(APDS9960_INT);
}
}
//vTask1 - leitura do sensor de humidade/temperatura
void vTask1(void *pvParameters){
while (1){
Serial.println("cima ");
digitalWrite(LED_CIMA, HIGH);
digitalWrite(LED_BAIXO, LOW);
digitalWrite(LED_DIREITA, LOW);
digitalWrite(LED_ESQUERDA, LOW);
vTaskDelay(pdMS_TO_TICKS(300));
Serial.println("baixo ");
digitalWrite(LED_CIMA, LOW);
digitalWrite(LED_BAIXO, HIGH);
digitalWrite(LED_DIREITA, LOW);
digitalWrite(LED_ESQUERDA, LOW);
vTaskDelay(pdMS_TO_TICKS(300));
Serial.println("direita ");
digitalWrite(LED_CIMA, LOW);
digitalWrite(LED_BAIXO, LOW);
digitalWrite(LED_DIREITA, HIGH);
digitalWrite(LED_ESQUERDA, LOW);
vTaskDelay(pdMS_TO_TICKS(300));
Serial.println("esquerda ");
digitalWrite(LED_CIMA, LOW);
digitalWrite(LED_BAIXO, LOW);
digitalWrite(LED_DIREITA, LOW);
digitalWrite(LED_ESQUERDA, HIGH);
vTaskDelay(pdMS_TO_TICKS(300));
}
}
/*
//Biblioteca do Arduino
#include <Arduino.h>
//Bibliotecas FreeRTOS
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include"freertos/queue.h"
//do sensor de humidade/temperatura
#include <DHT.h>
#define DHT_SENSOR_PIN 32 // ESP32 pin GPIO21 conectado no sensor DHT22
#define DHT_SENSOR_TYPE DHT22
//pino do botao da interrupção
#define BT 12
//led que sinaliza acionamento do CONTROLE de Aquecimento
#define LED_CONTROL_AQUECIMENTO 2
//led que sinaliza acionamento do CONTROLE de Arrefecimento
#define LED_CONTROL_ARREFECIMENTO 16
//led que sinaliza acionamento da INTERRUPÇÃO
#define LED_INTER 4
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#define I2C_ADDR 0x27
#define LCD_COLUMNS 16
#define LCD_LINES 2
// Definindo o tamanho máximo da fila
#define MAX_QUEUE_SIZE 10
#define TEMP_LIMITE_SUPERIOR 39 // limite superior do controle de temperatura
#define TEMP_LIMITE_INFERIOR 35 // limite inferior do controle de temperatura
// semaforos utilizados
SemaphoreHandle_t xSerial_semaphore;
//definindo uma estrutura para receber os dados de temperatura e umidade
struct SensorData {
float temperature;
float humidity;
};
// Variáveis para armazenamento do handle das tasks
TaskHandle_t taks1Handle = NULL; //tarefa leitura sensor humidade/temp.
TaskHandle_t taks2Handle = NULL; //tarefa de CONTROLE (acende led e escreve na serial)
TaskHandle_t taks3Handle = NULL; //tarefa que escreve no display
QueueHandle_t dataQueue;
//protítipos das Tasks
void vTask1(void *pvParameters);
void vTask2(void *pvParameters);
void vTask3(void *pvParameters);
DHT dht_sensor(DHT_SENSOR_PIN, DHT_SENSOR_TYPE);
#define TEMPO_DEBOUNCE 10 //ms
unsigned long timestamp_ultimo_acionamento = 0;
//funcao da interrupção
void IRAM_ATTR trataISR_BT(){
// Conta acionamentos do botão considerando debounce
if ( (millis() - timestamp_ultimo_acionamento) >= TEMPO_DEBOUNCE )
{
digitalWrite(LED_INTER, !digitalRead(LED_INTER));
timestamp_ultimo_acionamento = millis();
}
}
void setup() {
Serial.begin(115200);
dht_sensor.begin(); // initializa o DHT22 sensor
// criacao da fila que irá transportar os dados de temperatura e umidade
dataQueue = xQueueCreate(MAX_QUEUE_SIZE, sizeof(SensorData));
//configura pino do botao da interrupção como entrada e com resistor de pull-up
pinMode(BT,INPUT_PULLUP);
//configura a interrupçao associada ao botao e ligada a funcao trataISR. aciona na trasicao de alto para baixo (falling)
attachInterrupt(digitalPinToInterrupt(BT),trataISR_BT,CHANGE);
//configurando pino do led do CONTROLE de Aquecimento como saída
pinMode(LED_CONTROL_AQUECIMENTO, OUTPUT);
//configurando pino do led do CONTROLE de Arrefecimento como saída
pinMode(LED_CONTROL_ARREFECIMENTO, OUTPUT);
//configurando pino do led sinalizador da INTERRUPÇÃO como saida
pinMode(LED_INTER, OUTPUT);
//configurando o lcd
Wire.begin(18, 19);
lcd.init();
lcd.backlight();
// Criação dos semaforos
xSerial_semaphore = xSemaphoreCreateMutex();
//criação das tasks
xTaskCreate(vTask1,"TASK1",configMINIMAL_STACK_SIZE+1024,NULL,3,&taks1Handle);
xTaskCreate(vTask2,"TASK2",configMINIMAL_STACK_SIZE+1024,NULL,2,&taks2Handle);
xTaskCreate(vTask3,"TASK3",configMINIMAL_STACK_SIZE+1024,NULL,2,&taks3Handle);
}
//função loop (vazia)
void loop() {
}
//variaveis globais para o sensor de humidade/temperatura
float humi, tempC;
//vTask1 - leitura do sensor de humidade/temperatura
void vTask1(void *pvParameters){
SensorData data;
while (1)
{
xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
//gravando a temperatura na estrutura
data.temperature = dht_sensor.readTemperature();
//gravando a umidade na estrutura
data.humidity = dht_sensor.readHumidity();
xSemaphoreGive(xSerial_semaphore);
//se a leitura dos dados de temperatura e umidade ocorreu bem entao eles sao enviados para fila
if (!isnan(data.temperature) && !isnan(data.humidity)) {
// Enviando dados para a fila
xQueueSend(dataQueue, &data, portMAX_DELAY);
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
//vTask2 - tarefa de CONTROLE (acende LED de aquecimento e arrefecimento e escreve na serial)
void vTask2(void *pvParameters){
SensorData data;
while (1)
{
// Verificando se há dados na fila
if (xQueueReceive(dataQueue, &data, portMAX_DELAY)) {
// Escrevendo os dados na porta serial
Serial.print("Temperatura: ");
Serial.print(data.temperature);
Serial.print(" °C, Umidade: ");
Serial.print(data.humidity);
Serial.println("%");
}
else{
Serial.println("erro ao verificar os dados na fila (task2)");
}
//se a temperatura for maior ou igual a 39 graus é acionado o led de aquecimento(vermelho) e desligado o led e arrefacimentp (amarelo)
//se a temperatura for menor ou igual a 35 graus é acionado o led de arrefecimento (amarelo) e desligado o led e aquecimento (vermelho)
//se a temperatura for maior que 35 e menor que 39 os leds de aquecimento e arrefecimento ficam desligados
if (data.temperature >= TEMP_LIMITE_SUPERIOR){
digitalWrite(LED_CONTROL_AQUECIMENTO, LOW); // desliga LED aquecimento
digitalWrite(LED_CONTROL_ARREFECIMENTO, HIGH); // liga LED arrefecimento
}
if (data.temperature <= TEMP_LIMITE_INFERIOR){
digitalWrite(LED_CONTROL_AQUECIMENTO, HIGH); // liga LED aquecimento
digitalWrite(LED_CONTROL_ARREFECIMENTO, LOW); // desliga LED arrefecimento
}
if (data.temperature > TEMP_LIMITE_INFERIOR && data.temperature < TEMP_LIMITE_SUPERIOR){
digitalWrite(LED_CONTROL_AQUECIMENTO, LOW); // desliga LED aquecimento
digitalWrite(LED_CONTROL_ARREFECIMENTO, LOW); // desliga LED arrefecimento
}
//digitalWrite(LED_INTER, !digitalRead(LED_INTER));
vTaskDelay(pdMS_TO_TICKS(300));
}
}
//vTask3 - escreve no Display
void vTask3(void *pvParameters){
SensorData data;
while (1)
{
// Verificando se há dados na fila
if (xQueueReceive(dataQueue, &data, portMAX_DELAY)) {
xSemaphoreTake(xSerial_semaphore, portMAX_DELAY );
// Escrevendo os dados na porta serial
lcd.clear();
if (digitalRead(LED_INTER)==1){
lcd.setCursor(0, 0);
lcd.print("PORTA ABERTA");
} else {
lcd.setCursor(0, 0);
lcd.print(data.temperature);
lcd.print(" o C");
lcd.setCursor(0, 1);
lcd.print(data.humidity);
lcd.print(" %");
}
xSemaphoreGive(xSerial_semaphore);
}
else{
Serial.println("erro ao verificar os dados na fila (task3)");
}
vTaskDelay(pdMS_TO_TICKS(300));
}
}
*/