Hello guys, me and my friend need to do a project but we dont understand much of programming.
The project uses ESP32, DHT11 temperature sensor, display oled, one led and a fan, and the purpose is to simulate the temperature of an engine. The fan will turn on when the temperature is above 90ºC and turning off when its lower than that.
We try to gather information to do the code but its not working very well.
If someone could help it would be great.
Thank you all!
CODE:
/*-LIBRARIES-----------------------------------------------------------------------------------------------------------------------*/
#include "Arduino.h"
//Sensor Temperatura e LCD
#include <SPI.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
//INTERRUPT
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_task_wdt.h"
/*-DEFINES------------------------------------------------------------------------------------------------------------------------*/
//LCD
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
//Sensor Temperatura - DHT11
#define DHTPIN 33 // Digital pin connected to the DHT sensor
#define DHTTYPE DHT11 // Sensor DHT 11
//LED
#define LED_PIN_Red 5 //PIN 5 - Led VERMELHO
//ADC
#define THERMISOR_PIN 33 //PIN 33 - Sensor Analógico de Temperatura
//INTERRUPT PIN
const uint8_t interruptPin = 32; //PIN 32 para butão de interrupção
/*-FUNCTIONS---------------------------------------------------------------------------------------------------------------------*/
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
/*-TASK FUNCTIONS----------------------------------------------------------------------------------------------------------------*/
void vTaskBrain(void*pvParameters); //Função Tarefa Brain
void vTask_T_LCD (void*pvParameters); //Função Tarefa que lê temperatura e mostra no LCD
void vTaskFAN (void*pvParameters); //Função Tarefa aciona o Buzzer
void vTaskLED (void*pvParameters); //Função Tarefa que controla os LED
void vTaskADC (void*pvParameters); //Função Tarefa Sensor Temp. Analógico
TaskHandle_t xHandleLED;
TaskHandle_t xHandleADC;
static void vHandlerTask( void *pvParameters );
/*-INTERRUPTS--------------------------------------------------------------------------------------------------------------------*/
//static void vInterruptHandler( void );
void IRAM_ATTR vInterruptHandler();
/*-SEMAPHORES--------------------------------------------------------------------------------------------------------------------*/
SemaphoreHandle_t xBinarySemaphore;
/*-QUEUES------------------------------------------------------------------------------------------------------------------------*/
QueueHandle_t xQueueTemp, xQueueTempBRAIN, xQueueInterruptBRAIN;
/*-MUTEX-------------------------------------------------------------------------------------------------------------------------*/
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
SemaphoreHandle_t xMutex;
/*-VOID SETUP--------------------------------------------------------------------------------------------------------------------*/
void setup()
{
Serial.begin(115200);
//Criar QUEUE's
xQueueTempBRAIN = xQueueCreate(1, sizeof(float));
xQueueTemp = xQueueCreate(1, sizeof(float));
xQueueInterruptBRAIN = xQueueCreate(1, sizeof(float));
//Criar Semáforo Binário
vSemaphoreCreateBinary( xBinarySemaphore );
xMutex = xSemaphoreCreateMutex();
//Criar Tarefa Brain
xTaskCreatePinnedToCore( vTaskBRAIN, "Brain", 10000, NULL, 3, NULL, 1);
//Criar Tarefa p/ Mostrar Temperatura no LCD
xTaskCreatePinnedToCore( vTask_T_LCD, "TempinLCD", 10000, NULL, 4, NULL, 0);
xTaskCreatePinnedToCore( vTaskLED, "LED", 10000, NULL, 1, &xHandleLED, 1);
//Criar Tarefa p/ ADC
xTaskCreatePinnedToCore( vTaskADC, "ADC", 10000, NULL, 1, &xHandleADC, 1);
pinMode(interruptPin, INPUT_PULLUP); //Definir PIN da interrupção com pullup interna
attachInterrupt(digitalPinToInterrupt(interruptPin), vInterruptHandler, FALLING);
interrupts();
/* Check the semaphore was created successfully. */
if( xBinarySemaphore != NULL ){
xTaskCreatePinnedToCore( vHandlerTask, "Handler", 1000, NULL, 3, NULL, 0); //Criar HandlerTask no Core
}
}
/*-VOID vTASK------------------------------------------------------------------------------------------------------------------*/
void vTaskBRAIN (void*pvParameters){ //Inicio da Tarefa Brain
TickType_t xLastWakeTime; //Variavel para determinar nº de ticks
xLastWakeTime = xTaskGetTickCount();
float temperature, TempBrain;
int Emergencia;
for(;;){
xQueueReceive(xQueueTemp, &temperature, 0); //Receber Temperatura do DHT11
xQueueReceive(xQueueInterruptBRAIN, &Emergencia, 0); //Receber estado do botão de emergencia
TempBrain = (temperature * 7.66666666)-100; //Converter Temperatura Ambiente em Temp. aproximada do Motor
if(TempBrain>=90){
//Criar Tarefa p/ Fan
xTaskCreatePinnedToCore( vTaskFAN, "Fan", 10000, NULL, 1, NULL, 0);//Criar tarefa Buzzer no Core 0 apenas
//com temp>90
}
Serial.print("Emergencia:"); //Verificar estado do botão em porta série
Serial.println(Emergencia);
if (Emergencia == 1 && TempBrain > 90) { //Ativar Emergência apenas quando a TempBrain>115
//Criar Tarefa p/ Fan
xTaskCreatePinnedToCore( vTaskFAN, "FAN", 10000, NULL, 1, NULL, 0);//Criar tarefa Buzzer no Core 0 apenas
//com temp>90
int ledChannel_Red = 5;
int resolution = 8;
int dutyCycle_Red = 100;
//Led Red
ledcWrite(ledChannel_Red, dutyCycle_Red); //Acender Led Vermelho com dutycycle = 100
}
xQueueSendToBack(xQueueTempBRAIN, &TempBrain, 0); //Enviar Temp. aproximada do Motor
vTaskDelayUntil( &xLastWakeTime, ( 250 / portTICK_PERIOD_MS ) ); //Tarefa ocorre durante 250ms
}
} //Fim da Tarefa Brain
static void vHandlerTask( void *pvParameters ){ //Inicio Handler Task
int Emergencia = 0;
xSemaphoreTake( xBinarySemaphore, 0); //Dar sinal verde à tarefa
for( ;; )
{
xSemaphoreTake( xBinarySemaphore, portMAX_DELAY ); //Dar sinal verde à tarefa
if(Emergencia == 0){ //Alterar estado do botão
Emergencia = 1;
}
else
Emergencia = 0;
vTaskDelay(200 / portTICK_PERIOD_MS); //Tarefa ocorre durante 200ms
xSemaphoreTake( xBinarySemaphore, portMAX_DELAY );//Redundancia
xQueueSendToBack(xQueueInterruptBRAIN, &Emergencia, 0); //Enviar estado do botão para a brain
}
} //Fim da Handler Task
void vInterruptHandler(){ //Inicio Interrupção
static signed portBASE_TYPE xHigherPriorityTaskWoken;
/* 'Give' o semáforo para desbloquear a Task */
Serial.println("Interrupcao gerada");
xSemaphoreGiveFromISR( xBinarySemaphore, (signed portBASE_TYPE*)&xHigherPriorityTaskWoken );
} //Fim Interrupção
void vTask_T_LCD (void*pvParameters){ //Inicio Tarefa TempInLCD
TickType_t xLastWakeTime; //Variavel para determinar nº de ticks
xLastWakeTime = xTaskGetTickCount();
float oldtemp=0;
//Função Sensor Temperatura
DHT dht(DHTPIN, DHTTYPE); //Definir Sensor de Temperatura
dht.begin();
xSemaphoreTake(xMutex, portMAX_DELAY); //Mutex para proteger comunicação I2C
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { //Detetar se está a ocorrer comunicação
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
vTaskDelay(1000 / portTICK_PERIOD_MS); //Ocupar processador durante 1000ms
display.clearDisplay(); //Limpar Display
display.setTextColor(WHITE); //Selecionar cor do texto
for(;;){
vTaskDelay(2500 / portTICK_PERIOD_MS); //Ocupar processador durante 2500ms
//Ler Temperatura
float temp = dht.readTemperature(); //Receber e ler temperatura do sensor DHT11
//Erro na leitura da temperatura
if (isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");
temp=oldtemp;
}
else{
oldtemp = temp;
}
// clear display
display.clearDisplay();
//Lê Temperatura corretamente
// display temperature
display.setTextSize(1); //Selecionar tamanho do texto
display.setCursor(0,0); //Selecionar onde imprime o texto no display
display.print("Temperature: ");
display.setTextSize(2.5); //Selecionar tamanho do texto
display.setCursor(0,10); //Selecionar onde imprime o texto no display
display.print((temp * 7.66666666)-100); //Mostrar Temperatura no display
display.print(" ");
display.setTextSize(1);
display.cp437(true); //Desenhar "º" no display
display.write(167);
display.setTextSize(2);
display.print("C");
if( (temp * 7.66666666)-100 > 90){
display.setTextSize(3); //Selecionar tamanho do texto
display.setCursor(0,45); //Selecionar onde imprime o texto no display
display.print("WARNING");
}
xSemaphoreGive(xMutex); //Mutex
xQueueSendToBack(xQueueTemp, &temp, 0); //Enviar valor temp para a Brain
//Testar Tarefa
Serial.print(F("Temperature: "));
Serial.println(temp);
Serial.println(F("Temperature: OK"));
display.display();
vTaskDelayUntil( &xLastWakeTime, ( 250 / portTICK_PERIOD_MS ) ); //Tarefa ocorre durante 250ms
}
} //Inicio Tarefa TempInLCD
void vTaskFAN (void*pvParameters){ //Inicio Tarefa BUZER
//Porta Definida para o Buzzer c/ ESP32
int INA = 35; //for ESP32
int INB = 13; //for ESP32
pinMode (INA, OUTPUT); //Definir pin do Fan
pinMode (INB, OUTPUT); //Definir pin do Fan
for(;;){
digitalWrite (INA, HIGH); //turn Fan on
digitalWrite (INB, LOW); //turn Fan on
vTaskDelay(100 / portTICK_PERIOD_MS);
digitalWrite (INA, LOW); //turn Fan off
digitalWrite (INB, LOW); //turn Fan off
vTaskDelay(1000 / portTICK_PERIOD_MS);
//Testar Tarefa
Serial.println(F("FAN: OK"));
vTaskDelete(NULL); //Eliminar tarefa Fan
}
} //FIM Tarefa FAN
void vTaskLED (void*pvParameters){ //Inicio Tarefa LED
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
float TempBrain;
int freq = 100000; //Frequencia LED
int ledChannel_Red = 5; //PIN LED Vermelho
int resolution = 8;
ledcSetup(ledChannel_Red, freq, resolution);
ledcAttachPin(LED_PIN_Red, ledChannel_Red);
for(;;){
xQueueReceive(xQueueTempBRAIN, &TempBrain, 0); //Receber valor de TempBRAIN
if( 90 <= TempBrain){
//LED RED
for (int dutyCycle_Red = 50; dutyCycle_Red <= pow(2,resolution); dutyCycle_Red++) { //Piscar LED Vermelho
ledcWrite(ledChannel_Red, dutyCycle_Red);
vTaskDelay((1024/pow(2,resolution)) / portTICK_PERIOD_MS );
}
for (int dutyCycle_Red = pow(2,resolution); dutyCycle_Red >= 0; dutyCycle_Red--) {
ledcWrite(ledChannel_Red, dutyCycle_Red);
vTaskDelay((1024/pow(2,resolution)) / portTICK_PERIOD_MS );
}
}
//Testar Tarefa
Serial.println(F("LED's: OK"));
vTaskDelayUntil( &xLastWakeTime, ( 150 / portTICK_PERIOD_MS ) ); //Tarefa ocorre durante 150ms
}
} //Fim Tarefa LED
void vTaskADC (void*pvParameters){ //Inicio Tarefa Sensor Analógico
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
uint16_t Vo;
float R1 = 10000;
float logR2, R2, T, Tc, Tf;
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
for(;;){
Vo = analogRead(THERMISOR_PIN); //Equação de Conversão Analog-Digital
R2 = R1 * (1023.0 / (float)Vo - 1.97640000032);
logR2 = log(R2);
T = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2)); // temperature in Kelvin
Tc = T - 273.15; // Temperature in Celsius
Serial.print("Temperatura Ambiente: ");
Serial.print(Tc);
Serial.println("ºC");
vTaskDelay(1000 / portTICK_PERIOD_MS);
//Testar Tarefa
Serial.println(F("ADC: OK"));
vTaskDelayUntil( &xLastWakeTime, ( 150 / portTICK_PERIOD_MS ) ); //Tarefa ocorre durante 150ms
}
} //Fim da Tarefa ADC
// The loop function is called in an endless loop
void loop()
{
vTaskDelete( NULL);
}