Mas, a verdadeira beleza das coisas está na simplicidade.
E apesar de inicialmente parecer uma coisa bastante complexa, a lógica fuzzy é bastante simples de implementar utilizando o arduino.
A principal referência está endereço: http://www.zerokol.com/2012/09/arduinofuzzy-uma-biblioteca-fuzzy-para.html. É um excelente tutorial sobre uma biblioteca de lógica fuzzy para qualquer microcontrolador. Para os curiosos, no link acima, tem uma breve explicação sobre fuzzy, um tutorial explicando como instalar a biblioteca, e também algumas explicações e dicas.
Acabei de desenvolver um sistema de controle de luminosidade utilizando lógica fuzzy.
É bem simples!!
![]() |
Figura 1 - Sistema Iluminação Automática com Fuzzy |
![]() |
Figura 2 - Divisor de tensão com o LDR |
Gostaria de compartilhar aqui as regras de entrada.
No Fuzzy, a programação é assim, por exemplo: Se Escuro Então BrilhoLED Elevado.
Primeiro, criei 3 situações para a Iluminação : Escuro, Normal e Iluminado. Lembrando que Iluminação é a saída do sensor LDR. E é portanto a variável de entrada do sistema.
E depois criei 3 condições de saída, ou seja, para o brilho do led: Baixo, Medio, Elevado.
E por fim, criei as regras:
"SE iluminacao = escuro ENTAO Brilho do LED = elevado"
"SE iluminacao = normal ENTAO Brilho do LED = medio"
"SE iluminacao = Iluminado ENTAO Brilho do LED = baixo"
Bem, Definidas as minhas regras, aí os próximos passos, vou apenas citar, mas prometo que num próximo tutorial explico tudo, mas adianto que no link que citei no anterior do artigo tem algumas explicações. Em fim, os passos são:
Fuzzyficar, Inferir, Defuzzificar.
No arduino, os comandos utilizados foram:
float iluminacao_medida = (analogRead(LDR))*0.09765; //0.09765 = 100/1024
fuzzy->setInput(1,iluminacao_medida ); // iluminação medida é a variável de entrada
fuzzy->fuzzify();
int output = fuzzy->defuzzify(1);
analogWrite(9,output); // onde output é a saída PWM e varia de 0-255
//***********
Resultados Obtidos
Na figura 3a e 3b, o sistema encontra - se no escuro, logo o Brilho é Elevado.
Figura 3a - Sensor no Escuro - Brilho Elevado |
Na figura 3b, a forma de onda amarela é o sinal de saída do PWM que aciona o LED. E a forma de onda azul é o sinal de tensão divisor de tensão, tal como mostrado na figura 2.
Figura 3b - Formas de onda - Escuro |
Figura 4a - Ambiente Iluminado |
Figura 4b - Ambiente iluminado -> Brilho Baixo |
Figura 5a - Condição de Baixa luminosidade |
E por fim, as formas de onda. A tensão no sensor caiu e o pwm aumentou, aumentando assim o briho do led.
Figura 5b - Aumento do brilho do LED |
***********************************************************************************
Finalizo deixando aqui o código para que você tenha acesso à informação assim como eu tive. Perdoe-me por erros indevidos, e também por algumas coisas que não consegui deixar claro, principalmente em relação ao processo fuzzy. Apesar disso, estou à disposição para tirar dúvidas por email.Um abraço
**********
#include <FuzzyRule.h>
#include <FuzzyComposition.h>
#include <Fuzzy.h>
#include <FuzzyRuleConsequent.h>
#include <FuzzyOutput.h>
#include <FuzzyInput.h>
#include <FuzzyIO.h>
#include <FuzzySet.h>
#include <FuzzyRuleAntecedent.h>
int iluminacao_saida = 0;
int LDR = 5;// Sensor de iluminacao
int initPin = 13;
unsigned long pulseTime = 0;
// Instanciando um objeto da biblioteca
Fuzzy* fuzzy = new Fuzzy();
void setup(){
Serial.begin(9600);
// set init pin as output
pinMode(initPin, OUTPUT);
// set sensor lm35 como entrada
// create array loop to iterate over every item in the array
for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
readings[thisReading] = 0;
}
// Criando o FuzzyInput iluminacao
FuzzyInput* iluminacao = new FuzzyInput(1);
// Criando os FuzzySet que compoem o FuzzyInput iluminacao
FuzzySet* escuro = new FuzzySet(0, 40, 40, 65); // iluminacao escuro 15° 35°
iluminacao->addFuzzySet(escuro); // Adicionando o FuzzySet escuro em iluminacao
FuzzySet* normal = new FuzzySet(30, 50, 50, 70); // iluminacao normal
iluminacao->addFuzzySet(normal); // Adicionando o FuzzySet normal em iluminacao
FuzzySet* Iluminado = new FuzzySet(60, 80, 80, 100); // iluminacao muito normal
iluminacao->addFuzzySet(Iluminado); // Adicionando o FuzzySet Iluminado em iluminacao
fuzzy->addFuzzyInput(iluminacao); // Adicionando o FuzzyInput no objeto Fuzzy
// Criando o FuzzyOutput Brilho da LED
FuzzyOutput* brilho = new FuzzyOutput(1);
// Criando os FuzzySet que compoem o FuzzyOutput Brilho do LED
FuzzySet* baixo = new FuzzySet(0, 80, 80, 130); // Brilho do LED baixo
brilho->addFuzzySet(baixo); // Adicionando o FuzzySet baixo em brilho
FuzzySet* medio = new FuzzySet(70, 150, 150, 200); // Brilho do LED normal
brilho->addFuzzySet(medio); // Adicionando o FuzzySet medio em brilho
FuzzySet* elevado = new FuzzySet(150, 190, 255, 255); // Brilho do LED elevado
brilho->addFuzzySet(elevado); // Adicionando o FuzzySet elevado em brilho
fuzzy->addFuzzyOutput(brilho); // Adicionando o FuzzyOutput no objeto Fuzzy
//-------------------- Montando as regras Fuzzy
// FuzzyRule "SE iluminacao = escuro ENTAO Brilho do LED = Elevado"
FuzzyRuleAntecedent* ifiluminacaoescuro = new FuzzyRuleAntecedent(); // Instanciando um Antecedente para a expresso
ifiluminacaoescuro->joinSingle(escuro); // Adicionando o FuzzySet correspondente ao objeto Antecedente
FuzzyRuleConsequent* thenbrilhoelevado = new FuzzyRuleConsequent(); // Instancinado um Consenormal para a expressao
thenbrilhoelevado->addOutput(elevado);// Adicionando o FuzzySet correspondente ao objeto Consenormal
// Instanciando um objeto FuzzyRule
FuzzyRule* fuzzyRule01 = new FuzzyRule(1, ifiluminacaoescuro, thenbrilhoelevado); // Passando o Antecedente e o Consenormal da expressao
fuzzy->addFuzzyRule(fuzzyRule01); // Adicionando o FuzzyRule ao objeto Fuzzy
// FuzzyRule "SE iluminacao = normal ENTAO Brilho do LED = medio"
FuzzyRuleAntecedent* ifiluminacaonormal = new FuzzyRuleAntecedent(); // Instanciando um Antecedente para a expresso
ifiluminacaonormal->joinSingle(normal); // Adicionando o FuzzySet correspondente ao objeto Antecedente
FuzzyRuleConsequent* thenbrilhomedio = new FuzzyRuleConsequent(); // Instancinado um Consenormal para a expressao
thenbrilhomedio->addOutput(medio);// Adicionando o FuzzySet correspondente ao objeto Consenormal
// Instanciando um objeto FuzzyRule
FuzzyRule* fuzzyRule02 = new FuzzyRule(2, ifiluminacaonormal, thenbrilhomedio); // Passando o Antecedente e o Consenormal da expressao
fuzzy->addFuzzyRule(fuzzyRule02); // Adicionando o FuzzyRule ao objeto Fuzzy
// FuzzyRule "SE iluminacao = Iluminado ENTAO Brilho do LED = baixo"
FuzzyRuleAntecedent* ifiluminacaoIluminado = new FuzzyRuleAntecedent(); // Instanciando um Antecedente para a expresso
ifiluminacaoIluminado->joinSingle(Iluminado); // Adicionando o FuzzySet correspondente ao objeto Antecedente
FuzzyRuleConsequent* thenbrilhobaixo = new FuzzyRuleConsequent(); // Instancinado um Consenormal para a expressao
thenbrilhobaixo->addOutput(baixo);// Adicionando o FuzzySet correspondente ao objeto Consenormal
// Instanciando um objeto FuzzyRule
FuzzyRule* fuzzyRule03 = new FuzzyRule(3, ifiluminacaoIluminado, thenbrilhobaixo); // Passando o Antecedente e o Consenormal da expressao
fuzzy->addFuzzyRule(fuzzyRule03); // Adicionando o FuzzyRule ao objeto Fuzzy
}
void loop(){
// send 10 microsecond pulse
digitalWrite(initPin, HIGH);
// wait 10 microseconds before turning off
delayMicroseconds(10);
// stop sending the pulse
digitalWrite(initPin, LOW);
float iluminacao_medida = (analogRead(LDR))*0.09765;
fuzzy->setInput(1,iluminacao_medida );
fuzzy->fuzzify();
int output = fuzzy->defuzzify(1);
analogWrite(9,output);
Serial.print(" iluminacao: ");
Serial.print(iluminacao_medida);
Serial.print(" Brilho do LED: ");
Serial.println(output*0.39215);
Serial.print(" % ");
// wait 100 milli seconds before looping again
delay(100);
}
Bom dia Thiago, não entendi muito bem quando "FuzzySet(0, 40, 40, 65); // iluminacao escuro 15° 35°"
ResponderExcluirO que seria 0, 40, 40, 65?
Ha como calibrar? Me explique um pouco sobre.
Att. Camilo Jr.
Dentro da teoria de conjuntos Fuzzy, existem as funções de pertinência. Esses números são os valores que definem esta função.
Excluirbom dia Thiago não entendi como você criou as bibliotecas para o fuzzy.
ResponderExcluirBom dia Thiago, eu tentei compilar o seu código e outros do site zerokol, só que ambos estão dando erro na mesma linha:
ResponderExcluirFuzzy* fuzzy = new Fuzzy();
você poderia me ajudar com isso???
Parabéns, são poucos brasileiros que sabem o valor da lógica fuzzy e como isso poderia simplificar a vida de muita gente largando mão de loops PID insintonizáveis.
ResponderExcluircuando compilo el código me dicta un error en la siguiente línea:
ResponderExcluirfor (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
como lo resuelvo
gracias
mi e-mail es: medina@ib.upchiapas.edu.mx
Me perdoe minha ignorância, mas não seria mais fácil usar um switch-case? Sério mesmo, fique na dúvida, pois esse código pesa muito mais na ROM do Arduino....
ResponderExcluirSim Angelo, claro você está completamente correto. Este codigo não está optimizado para rodar em Arduino. Concordo com seu ponto de vista e ainda mais em termos de programação sempre existe mais de um jeito de se atingir a sua meta. Poderia ser com If, case, ou qualquer outro sistema de tomada de decisão.
ResponderExcluirQuando repliquei e apliquei este codigo, achei muito interessante o fato de ser com Fuzzy. Talvez isso não esteja muito claro na minha explicação, mas o ponto principal era validar as tabelas de fuzificação e aplicar esta bela teoria em uma coisa simples e prática.
Estou à disposição caso queria conversar mais sobre este assunto!
Obrigado por seu comentário!
Um abraço
Mas eu gostei muito mesmo. Bem legal. Acredito que a lógica fuzzy com arduino seria melhor aplicada quando comessássemos a trabalhar com teoria de conjuntos, do tipo, 3 LDRs em pontos distintos de um mesmo aposento, por exemplo. Ainda, diversos sensores de temperatura poderia controlar a velocidade e a direção do ar-condicionado.
ExcluirDo tipo, seria extremamente útil para aplicações de domótica, por exemplo.
O que você acha?
Este comentário foi removido por um administrador do blog.
ResponderExcluirThiago,
ResponderExcluirPrecisamos fazer um controle de velocidade de abertura do servo motor utiliando um sensor ultrassonico.
Ex:
Quanto maior a velocidade, mais rapida é a abertura do servo(cancela), se carro estiver lento, cancela abre gradualmente
Esse código não compila
ResponderExcluirQual erro voce está tendo? Voce seguiu o exemplo da pagina original?
Excluirhttps://blog.zerokol.com/2012/09/arduinofuzzy-uma-biblioteca-fuzzy-para.html