O arduino, é uma plataforma de desenvolvimento muito simples para grandes aplicações de engenharia.
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 |
O sistema da figura 1 é composto por um divisor de tensão formado por um LDR e uma resistencia, alimentados no +5V (Figura 2). E como fonte de luz, um led com um resistor de limitação de corrente.
 |
Figura 2 - Divisor de tensão com o LDR |
Depois que instalei a biblioteca no meu arduino, começei a editar o exemplo e consegui executar o programa.
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 |
Na figuras 4a e 4b, o sensor está um ambiente iluminado, logo o pwm (curva amarela) é menor, tal como na figura 4b
 |
Figura 4a - Ambiente Iluminado |
 |
Figura 4b - Ambiente iluminado -> Brilho Baixo
|
A figura 5a mostra uma tentativa de simular uma condição de baixa luminosidade (tampei o sensor com o dedo), mas o sistema não está totalmente escuro.
 |
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);
}