quarta-feira, 10 de dezembro de 2014

INDUSCON 2014, Blog 2015


   Olá a todos. Quanto tempo que não posto nada. Desde setembro, se não me engano. Enfim, esse é a parte ruim de fazer engenharia em paralelo com mais um monte de outras coisas. Mas, agora, no fim do ano, resolvi fazer um post para falar sobre coisas gerais.

IEEE INDUSCON 2014 - XI International Conference on Industry Applications

   A primeira delas é que estou na INDUSCON. Como já falei aqui, eu fiz pesquisa no ano passado. Então, com o resultado do trabalho submetemos um artigo que foi aceito e agora está sendo representado na INDUSCON. O nome do congresso é um acrônimo para International Conference on Industry Applications e está na sua 11ª edição, que está sendo realizada em Juíz de Fora, MG. A INDUSCON é uma conferência ligada a IEEE (Institute of Eletrical and Electronics Engineers), a maior associação profissional do mundo em número de inscritos, com aproximadamente 500 mil profissionais cadastrados como membros. Essa oportunidade de estar aqui é muito legal, já que o máximo que tinha saído do meu estado (RS) desde sempre foi para Chapecó (SC). Só que Chapecó é praticamente divisa com RS. Então, de certa forma, é como se eu nunca tivesse saído do estado.

   Dessa vez foi diferente, peguei um ônibus à Porto Alegre, depois um avião à São Paulo onde fiz conexão para o Rio de Janeiro para viajar 3 horas de ônibus para Minas Gerais. Me hospedei no hotel e estou aproveitando a conferência. É realmente um ambiente muito diferente. Eu sou técnico em eletrônica e graduando em engenharia de controle e automação, mas posso assegurar tranquilamente que tenho a menor escolaridade da conferência. Serão 3 dias completos de palestras e apresentação de pôsteres com mestres e doutores em engenharia de todo o Brasil. Com destaque especial para o sempre fortíssimo pessoal do GEPOC (Grupo de Eletrônica de Potência e Controle) de Santa Maria. Grupo do qual já conhecia um integrante e passei a conhecer alguns outros na conferência. Realmente o trabalho que eles executam na UFSM é muito bom e eles merecem a fama que conquistaram.

   Já apresentei meu pôster, consegui minha dose de elogios, mas a maior vitória é estar em um lugar onde só se tem a aprender. Também conheci muita gente legal, e reencontrei algumas pessoas também. Agora resta aguardar a publicação do artigo!


FUTURO DO BLOG PARA 2015

   Pois bem! O ano de 2014 está quase acabando e, por consequência, 2015 está quase começando. Eu não vou prometer constância nas publicações desse blog, devido aos inúmeros compromissos que assumi. Pensei inclusive em encerrar as atividades do blog. Porém me decidi pelo contrário, devido ao fato de já haver muito conteúdo bom publicado aqui.

   Quando o blog começou em... fevereiro de 2012 eu estava iniciando o curso técnico. E adorava este blog. Nessa época eu cursava o terceiro ano do ensino médio no turno da manhã e acordava um pouco antes para publicar neste blog três vezes por semana. De lá pra cá acabei o ensino médio, comecei a graduação, comecei a trabalhar, terminei o curso técnico, comecei a fazer pesquisa e isso tudo contribuiu para que o blog ficasse negligenciado. C'est la vie.

   Não vou deletar o blog até por um motivo sentimental. Ele me acompanha durante um longo tempo e quero, daqui muito mais tempo, poder olhar pra trás e ver o quanto eu evolui. E o blog é um registro escrito do quanto evolui e um registro que me permite ajudar outras pessoas a evoluir também.

   Embora o blog esteja confirmado para 2015, a frequência de postagem provavelmente será baixa. Quero terminar a série de posts dobre programação na linguagem C e começar alguma coisa sobre microcontroladores. Também estarei disponível para sanar dúvidas pelos comentários e, se alguém tiver uma sugestão de post, posso escrevê-lo também (já que ter um feedback serve de motivação para o processo criativo).

   Tendo dito isso, encerro esse post. Abraço a todos. Bom fim de ano. Boas festas e um próspero ano novo à todos.

sábado, 13 de setembro de 2014

Algoritmo e Programação - Funções (Exemplo de Aplicação)

   Olá. Semana passada não pude postar nada, devido a indisponibilidade de tempo. Então vamos retomar esta semana, continuando do tema do último post: funções na linguagem C. Hoje eu vou mostrar como criar uma função simples em um programa. Caso você não saiba nada de funções na linguagem C ainda, por favor, dê uma olhada no último post (clique neste link).

   Primeiramente, crie um novo programa, inclua as bibliotecas que sempre utilizamos e escreva o seguinte código:

float nota_1 = 0, nota_2 = 0, nota_3 = 0, media = 0;
float calculo_media (float n1, float n2, float n3)
{
    float media_aritmetica;
    media_aritmetica = (n1+n2+n3)/3;
    return media_aritmetica;
}
main()
{
    printf("Digite nota 1: ");
    scanf("%f",&nota_1);
    printf("Digite nota 2: ");
    scanf("%f",&nota_2);
    printf("Digite nota 3: ");
    scanf("%f",&nota_3);
    media = calculo_media(nota_1, nota_2, nota_3);
    printf("A media calculada foi de: %f.\n",media);
    if(media < 6)
        printf("Aluno reprovado!\n\n");
    else
    {
        if( media < 7 )
            printf("Aluno aprovado por pouco!\n\n");
        else
        {
            if( media < 8 )
                printf("Aprovado!\n\n");
            else
            {
                if( media < 9 )
                    printf("Aprovado! Parabens!\n\n");
                else
                {
                    if( media <= 10 )
                        printf("Aprovado com louvor!\n\n");
                }
            }
        }
    }
    system("pause");
}
 
   Esse exemplo já foi dado na série de algoritmos e programação, mas até então não sabíamos nada sobre funções ainda. Agora que um pouco dos conceitos das funções foram explicados, vale a pena voltar e dar outra olhada para esse programa.
 
   Como podem lembrar (ou perceber), esse programa calcula a média aritmética de três notas digitadas pelo usuário do programa. Antes do main() perceba que existe o seguinte trecho de código:
 
float calculo_media (float n1, float n2, float n3)
{
    float media_aritmetica;
    media_aritmetica = (n1+n2+n3)/3;
    return media_aritmetica;
}
 
   Bem. Isso é uma função. A primeira palavra é "float". Essa primeira palavra representa o tipo de valor retornado pela função. Mas o que é valor retornado? Basicamente todas funções operam sobre alguns dados. Nesse caso específico, a função calcula a média aritmética baseado em três notas. Algumas funções, após operar com os dados podem fornecer algum resultado. Neste caso, a função fornecerá o resultado calculado da média. A primeira palavra "float" indica que o resultado a ser devolvido é do tipo ponto fluante, ou seja, um número decimal (com virgula). Outros tipos possíveis é int (em geral, números inteiros de 16 bits), char (números inteiros de 8 bits) e void. O void é utilizado quando a função não retornará nenhum valor. Isso significa que ela operará com os dados fornecidos mas não devolverá nenhuma resposta.

   Após a primeira palavra, que determina o tipo de retorno da função, está escrito calculo_media. Esse é o nome da função, e é arbitrário. Porém algumas regras devem ser seguidas. A linguagem C não aceita nomes que comecem com números. Também não são permitidos nomes com espaço (isso justifica o uso do underline no nome). Nomes iguais a palavras reservadas da linguagem, tais como if, else, while, também não são permitidos. É importante lembrar que a linguagem C é case sensitive. Isso significa que ela diferencia letras maiúsculas de minúsculas. Portanto, se eu criei a função "calcula_media" e, dentro do programa, tentar chamar a função "Calcula_Media", o compilador dirá que a função chamada não existe.

   Após o nome, entre parênteses, existe uma lista de argumentos. Essa lista contém o tipo e o nome de todas as variáveis utilizadas nas funções. Vamos começar entendendo o tipo dessas variáveis. Ali percebe-se novamente o uso da palavra float. Isso indica que as variáveis que vão entrar na função são do tipo ponto flutuante, ou seja, admitem valores decimais que não sejam inteiros. O que faz todo sentido nesse exemplo de cálculo de notas, já que as notas podem ser números com vírgula.

   Quanto aos nomes das variáveis, são completamente arbitrários, desde que sejam seguidas as mesmas regras explicadas para nomear funções. Uma coisa importante é que o nome das variáveis da lista de argumentos da função não precisa ser igual ao nome das variáveis passadas para função. Complicada essa explicação? Ok, permita-me exemplificar: perceba que no programa de exemplo a função possui, em sua lista de argumentos, três variáveis. Todas elas são do tipo float e estão nomeadas como n1, n2, n3. Note também que dentro do main() é solicitado ao usuário digitar três valores para notas, que são atribuídas a três variáveis distintas, nomeadas como nota_1, nota_2 e nota_3. Quando eu chamo a função dentro do programa com a seguinte linha de comando "media = calculo_media(nota_1, nota_2, nota_3);" eu passo para dentro da função as variáveis nota_1, nota_2 e nota_3. Perceba que o nome das variáveis que eu passei é diferente do nome das variáveis na lista de argumentos. E isso não constitui problema algum. O que irá acontecer é que a função vai atribuir a primeira variável de sua lista de argumentos (nesse caso, n1) o valor da primeira variável passada como argumento na chamada da função (nesse caso, nota_1). Isso se repetirá com todas as variáveis envolvidas. Ao final desse processo, a função terá uma variável n1 com o valor da variável nota_1, a variável n2 com o valor da variável nota_2 e a variável n3 com o valor da variável nota_3.

   Uma vez que a função tem todas as variáveis, ela pode começar a executar as linhas de instruções no seu corpo, ou seja, dentro de suas chaves. E, no nosso exemplo, a primeira coisa que a função faz é criar uma variável chamada media_aritmetica. Essa variável é local, como todas variáveis criadas dentro de funções. Se você não sabe o que é uma variável local, permita-me, em um novo parágrafo, lhe explicar.

   As variáveis de um programa podem ser divididas em variáveis locais e globais. Uma variável global é aquela cujo escopo é todo o programa. Isso significa que ela pode ser "vista" de todo o programa. As variáveis globais são aquelas criadas fora de qualquer função. Nosso programa contém quatro variáveis globais, que são nota_1, nota_2, nota_3 e media. Perceba que, como eu disse, essas variáveis estão fora das funções do programa (que são o main( ) e media_aritmetica( )). Portanto, por ser global, essa variável pode ser utilizada dentro do main() (como está sendo feito no exemplo) e, se eu quisesse, eu poderia utilizá-las dentro da função media_aritmetica(). Já a variável media_aritmetica foi criada dentro de uma função (a saber: calcula_media( )). Isso significa que ela é uma variável local e seu escopo abrange somente a função onde foi criada. Isso significa que ela não pode ser vista de nenhum outro lugar que não seja dentro da função calcula_media(). Se eu, por exemplo, tentar utilizar a variável media_aritmetica dentro da função main() o compilador gerará uma mensagem de erro, informando que essa variável não está definida dentro da função main().

   Retomando a explicação, uma vez criada a variável calcula_media, ela recebe a soma das notas n1, n2 e n3 dividida por três, pois essa é a forma de calcular a média aritmética de três notas. Após o cálculo, a última instrução da função é "return media_aritmética". Essa instrução diz para a função encerrar, devolvendo o valor da variável media_aritmetica para o local onde a função foi chamada. Se você olhar dentro do programa, a função foi chamada da seguinte forma "media = calculo_media(nota_1, nota_2, nota_3);". Portanto, a variável que irá receber o valor devolvido pela função é "media". Então, atingimos nosso objetivo, pois fizemos com que a variável "media" recebesse a média aritmética das três notas digitadas.

   Após isso o programa segue normalmente, conforme o que já estudamos anteriormente. Espero que tenham gostado, que eu tenha sido claro e que tenham aprendido tudo. Devido ao apuro de tempo, não pude revisar apropriadamente o texto. Então qualquer dúvida ou correção, mandem um comentário. Sugestões e críticas também são bem vindas. Obrigado a todos e até a próxima.

sábado, 30 de agosto de 2014

Algoritmo e Programação - Funções (Conceitos Fundamentais)

   Olá a todos. Hoje eu vou falar genericamente de funções na linguagem C: o que são, para que servem e seus prós e contras. A ideia desse post é que alguém com conhecimento nulo sobre funções (mas com algum conhecimento em linguagem C) possa entender todos os conceitos fundamentais de funções. Em um próximo post trabalharemos exclusivamente com a implementação de funções em um programa simples. Primeiramente vou falar para que servem as funções.

Contextualização

   Imagine que você é um professor de 3 turmas de 60 alunos cada e costuma aplicar três provas durante o semestre para cada turma. Então você terá a maçante tarefa de efetuar o cálculo da média (vamos considerar nesse exemplo a média aritmética) das três notas 180 vezes (uma para cada aluno). Você com certeza não irá escrever no seu código 180 vezes o cálculo da média, que consistiria em (N1+N2+N3)/3. Então você decide usar os laços de repetição apresentados nos últimos posts, dessa forma o programa poderá executar as 180 repetições do cálculo da média de que precisamos.

   Mas você não quer somente calcular a média naquela tela preta de console que vimos nos compiladores usados. Então você estuda um pouco mais e cria uma interface gráfica, com alguns botões e mensagens interativas. Acrescenta algumas funcionalidades extras no seu programa. No final, você acaba com um programa cujo código contém aproximadamente 1000 linhas.

   Então, por uma mudança da instituição onde você trabalha a média deixa de ser aritmética para se tornar harmônica. E, nesse caso, você precisa alterar o código de seu programa. Isso significa que você precisa encontrar e alterar uma expressão específica dentro de 1000 linhas de texto já escrito. Você pode me responder que utilizando um CTRL+F você encontraria rapidamente o trecho procurado. Mas suponha que, por qualquer motivo você precisou escrever a expressão da média aritmética em 10 lugares diferentes de seu código. Nesse caso você deve encontrar todos os locais onde a expressão foi escrita e alterar todos. Mas se você escreveu seu código meses, ou até anos atrás, você se lembrará de quantas vezes diferentes você escreveu a expressão da média?

O que são funções

   Justamente para sanar o problema apresentado anteriormente usa-se as funções da linguagem C. Basicamente uma função nada mais é do que um trecho de código que executa determinadas instruções. Em nosso exemplo inicialmente criaríamos uma função que calculasse a média aritmética. Depois, se precisássemos calcular a média em 10 lugares diferentes do código, simplesmente utilizaríamos a função criada. Quando se utiliza uma função dentro do código nós dizemos que a função foi "chamada". Uma chamada de função nada mais é do que sua utilização dentro do código do programa.

   Assim as funções são trechos de códigos escritos que serão repetidos em diversos lugares do programa que está sendo desenvolvido.

Vantagem das Funções

   Quando fosse necessário efetuar alterações do cálculo da média no programa, simplesmente alteraríamos um único lugar: a função. Uma vez que a função foi alterada (e o projeto compilado novamente), todos os lugares que a utilizavam, sejam 10, 20 ou 100 lugares diferentes do código, passarão a utilizar a nova função. A facilidade em dar manutenção, ou seja, a possibilidade de alterar rapidamente o código é uma das vantagens de utilizar funções.

   Outra vantagem é a facilidade de utilizar trabalho feito em um projeto em outro. Ou seja, imagine que você vá criar outro programa que também necessite efetuar cálculos de médias. Você poderia ir no programa inicial, encontrar os trechos onde foi escrito o cálculo da média e dar um CTRL+C e CTRL+V, copiando-os para o código que está sendo escrito. Mas, se você utilizou funções no primeiro programa, você poderia simplesmente importar a função para o segundo programa ou, no pior caso, dar um CTRL+C e CTRL+V na função, copiando-a para o segundo programa.

   Uma terceira vantagem do uso de função, embora um pouco mais técnica, é a economia de espaço de programa. Não digo apenas da economia de linhas conseguida, já que ao escrever uma função não é necessário escrever 10 vezes a mesma coisa dentro do programa. Refiro-me a economia no espaço de memória ocupado pelo programa. Mas, por que há economia de espaço em memória? Muito simples. Se você repetir 10 vezes o mesmo trecho de código dentro do programa e compilar, o compilador irá gerar instruções todas as vezes que você escreveu determinado trecho de código. Já se, por outro lado, você utilizou funções, o compilador irá gerar instruções apenas uma vez e, toda vez que o programa precisar utilizar essas instruções ele irá "saltar" para o local da memória onde as instruções foram compiladas.

   Embora essa explicação seja um pouco mais técnica e exija alguns conhecimentos sobre organização da memória, resumidamente é isso que acontece. Talvez algum dia (mas não vou prometer nada) exista alguns posts básicos sobre funcionamento de computadores: arquitetura de processadores e organização de memória.

Desvantagem das Funções

   Uma desvantagem das funções, embora relativamente imperceptível com a capacidade atual dos computadores, é a velocidade de execução das funções. Toda vez que o programa acha uma função ele precisa saltar para o trecho da memória que contém as instruções. Esse salto gasta tempo, pois envolve a mudança de valores que estão armazenados nos registradores do processador. Portanto saltar para uma função é mais demorado do que se as instruções tivessem sido repetidas 10 vezes. Porém, como dito, essa demora extra é imperceptível devido à velocidade alta dos computadores modernos.

Quando criar funções?

   Ao escrever o código devemos avaliar quais tarefas são importantes e serão repetidas em nosso programa. Isso serve para não cometermos nem excessos e nem faltas. Não devemos nos exceder e criar funções para tudo dentro do programa, incluindo tarefas que realizamos apenas uma vez no programa. Por outro lado não devemos pecar por falta e não criar nenhuma função dentro de um programa, a menos que ele seja de extrema simplicidade.

   Portanto devemos criar funções para todas as tarefas que:
* Acreditamos que serão utilizadas extensamente dentro de nosso programa;
* Acreditamos que possam ser úteis no futuro para criação de outros programas;

   Esses são os meus critérios para decidir quando criar uma função.

   E por hoje era isto. Nesse post expliquei apenas os conceitos e ideias do uso de funções. No próximo post sobre o assunto falaremos sobre a implementação real de uma função em um exemplo simples. Falaremos sobre a sintaxe da criação de uma função, sobre os parâmetros, sobre o valor de retorno e sobre tudo que for necessário para criação de uma função simples em C. Mais adiante seguiremos com ponteiros e como passar endereços de variáveis para funções. Enfim, temos ainda muito pano para manga e bastante coisa legal para vermos. Sobre este post deixem sugestões e críticas nos comentários. Não hesite em se expressar caso tenha achado algum trecho da explicação confuso. Obrigado a todos e até a próxima!

quinta-feira, 28 de agosto de 2014

200000 Visualizações. lol

O blog chegou a 200k visualizações. Fico feliz com isso! Infelizmente meu computador estragou recentemente, mas assim que eu superar esse contra tempo voltaremos com o ritmo usual de postagem, voltando com a série de programação. Temos ainda algumas coisas para ver sobre esse tema, e depois teremos um novo leque de possibilidades para explorar.

Abraço a todos que leem e, principalmente, que seguem esse blog. Muito obrigado.
Rumo a 300k visualizações!
*-*

sábado, 16 de agosto de 2014

Algoritmo e Programação - While

     Olá a todos. Hoje, para dar sequência aos posts sobre programação eu vou falar de um outro laço de repetição, que se chama while. While é uma palavra inglesa que significa "enquanto", e esse nome é muito bom pois descreve exatamente o que esse laço faz: executa um trecho do programa enquanto uma determinada condição for verdadeira. Para entender melhor, vamos discutir um exemplo:


int main()

{
     unsigned char i = 0;
     while( i < 5)
     {
          printf("O valor de i: %d.\n",i);

          i++;
     }
}


     Bom, o que este exemplo faz? Exatamente a mesma coisa que o exemplo principal do post sobre o laço "for" fazia, que é  escrever o valor de "i" que irá variar de 0 até 4. Então vamos analisar a sintaxe do comando while.

     Primeiro, existe a palavra do comando (while) e entre parênteses a condição que, nesse caso, é i < 5. Dessa forma, enquanto o valor de "i" for menor que 5 o laço continuará repetindo os comandos que estiverem dentro das chaves do comando.

     Basicamente o que podemos falar do laço while é isso. O while é uma instrução mais simples que o for e, em geral, menos poderoso. Para quem já conhece o laço for (quem não conhecer pode buscar o post nesse link) será interessante comparar a estrutura dos dois laços.

     Primeiramente, o laço while não tem inicialização. Enquanto no laço for podíamos inicializar o valor de uma ou mais variáveis que seriam utilizadas no laço dentro da sintaxe do comando, no while não temos essa possibilidade. É por isso que no exemplo dado nesse post a variável "i" recebeu seu valor antes de entrar no laço.

     Outra diferença entre o while e o for é que o while não altera automaticamente a variável testada. Por isso que nesse exemplo a variável "i" está sendo alterada dentro do laço. No laço for não há a necessidade disso pois o próprio laço, após uma iteração, altera os valores das variáveis determinadas pelo programador.

     Uma utilização comum do while é criar laços infinitos. Embora eu tenha comentado no post sobre o for que laços infinitos são perigosos (e realmente são, quando criados de forma não intencional), eles algumas vezes são necessários. Um exemplo disso é em programas de microcontroladores, que geralmente possuem dentro da função main um laço infinito. A função desse laço é repetir continuamente a execução do programa. Caso esse laço não fosse utilizado, o microcontrolador iria executar todo o programa uma única vez e, depois disso, ficaria sem fazer nada. Isso é ruim. Imagine que seu trabalho seja programar um sensor de temperatura. Você quer um sensor que leia a temperatura 1 única vez? Que para fazer outra medição você tenha que religar o equipamento? Provavelmente não. Mais comum é um programa que a cada intervalo de tempo faça uma leitura de temperatura e mostre o valor em um display. Nesse caso usa-se  um laço while com alguma função que controle o tempo para executar a leitura no intervalo de tempo necessário. A estrutura genérica e simplificada de um programa para microcontrolador é:

#includes e qualquer tipo de definição inicial de hardware
void main()
{
   inicialização de registradores e periféricos;
   while(1)
   {
      comandos do programa;
   }
}

     Nesse esqueleto de programa temos os includes e definições de hardware. Os includes tem a mesma utilidade dos que utilizamos para computador. Eles permitem que usemos funções prontas desenvolvidas pelos fabricantes  do microcontrolador ou outras pessoas. As definições de hardware dependem do compilador e hardware utilizado, que em geral não seguem um padrão. Em microcontroladores geralmente deve-se definir o tipo e a velocidade do oscilador utilizado (os osciladores de microcontroladores geralmente estão na casa de MHz) e, algumas vezes, os tipos de interrupções que serão habilitadas.

     Dentro do main temos um trecho sobre inicialização de registradores e periféricos, que se encontra antes do laço while. Um microcontrolador pode ter diversos registradores que controlam, por exemplo, se um pino será entrada ou saída, ou se será uma entrada digital ou analógica. Para informarmos ao microcontrolador a função específica de cada pino utilizamos registradores. Esse é apenas um exemplo dos  usos de registradores, que estudaremos mais detalhadamente no futuro. O microcontrolador pode também ter diversos periféricos, que são circuitos  internos ao microcontrolador que executam tarefas específicas, como medir tensões analógicas ou se comunicar via protocolo RS-232 (padrão das seriais de computador). Ter um periféricos específico para uma tarefa  facilita muito a execução da mesma.

     Após isso temos um laço while(1). Perceba que no lugar da condição do laço temos apenas um número constante de valor 1. Para entender a razão disso devemos entender que na linguagem C o valor 0 representa algo falso e qualquer valor diferente de zero representa algo verdadeiro. Se tomarmos uma variável "i" com valor 4 e fizermos a comparação (i == 5), a linguagem C entende essa sentença como 0, pois é uma sentença falsa. Por outro lado, a sentença (i == 4) seria interpretada como 1, pois é verdadeira. Mas não somente o 1 representa verdadeiro, como qualquer outro número diferente de 0.

     Como visto o número 1 equivale a uma sentença verdadeira. Como o laço for executa comandos enquanto a condição for verdadeira, e o número 1 será sempre uma sentença verdadeira, isso significa que o programa jamais encerrará o laço while. Após entrar nele o programa só sairá se ocorrer o desligamento ou alguma interrupção (trataremos disso no futuro). Portanto, esse laço garantirá a repetição indefinida do nosso programa, como desejávamos.

     Conforme o que foi dito nos parágrafos anteriores, também seria um laço infinito escrever while(2), por exemplo. Porém, a prática mais comum é utilizar o valor 1 para representar sentenças verdadeiras.

     Por hoje era isso. Espero ter explicado claramente o laço while e sua funcionalidade. Espero também ter sido claro na minha breve introdução sobre programação de microcontroladores, que será descrita neste blog em um futuro não tão distante. Qualquer dúvida, crítica, sugestão ou comentário, por favor, use o campo dos comentários. Abraço e até a próxima!

domingo, 10 de agosto de 2014

Teoria vs Prática

   Olá a todos. Hoje vou falar e dar minha opinião sobre uma discussão sem fim que é: será que os currículos dos cursos de graduação são muito teóricos? E para começar eu quero abordar uma outra pergunta que está relacionada: o que é mais importante: a teoria ou a prática?

   Arrisco dizer que o que vale mais seja sempre os resultado práticos. E essas são palavras saídas dos dedos de um teórico irremediável que sou. Mas independente de se trabalhar em empresa, pesquisa ou até mesmo como professor, o que importa é o resultado prático. Se você trabalha em empresa, o resultado será um projeto bem feito, robusto e com qualidade. Para quem trabalha na pesquisa o resultado pode ser uma ideia diferente e a redação de um bom artigo sobre ela. Caso você seja professor seu resultado é fazer com que seus alunos compreendam a disciplina e saiam dela com um conhecimento maior.

   O resultado prático, além de ser o que importa, é também o que é visto. Quando alguém nos mostra algo, a primeira coisa que vemos é o que está feito. Não vemos o caminho trilhado para aquilo ser feito. No caso do projetista não vemos se ele fez contas ou não para implementar aquele projeto, ou se o pesquisador estudou ou não para chegar na ideia apresentada, ou se o professor preparou ou não as aulas para serem claras.

   Uma vez que o que importa e o que vemos são resultados práticos, do que importa a teoria? Por que não cortar carga teórica dos cursos de graduação e aumentar o enfoque na prática? Pois  bem, para argumentar sobre isso vou me basear no meu curso de graduação em engenharia. Não sei o quanto esse problema impacta  outros cursos de graduação.

   O currículo contém disciplinas teóricas como matemática e física pois aquilo é esperado de um engenheiro. É pré requisito para o título de engenheiro um conhecimento nessas áreas, mesmo que ele não trabalhe com isso no dia a dia. E o conhecimento teórico é fundamental quando se projeta algo que nunca foi feito. Quando você está fazendo algo que já foi feito e com bases bem conhecidas, é comum utilizar o senso comum e trabalhar por tentativa e erro. Nesse caso talvez essa técnica apresente um melhor custo-benefício do que sentar, calcular e depois implementar. Um exemplo bem básico disso é ligar um LED em uma bateria de 12V. Enquanto alguém sentar para calcular a queda de tensão do LED e a corrente necessária para acendê-lo eu já coloquei um resistor de 1K e o LED já está brilhando. Nesse caso ligar um LED é algo conhecido que não necessita cálculo.

   Porém, quanto mais um projeto sai do senso comum maior será a relevância da teoria. Quando alguém precisa fazer algo que nunca foi feito, não há nada anterior no que se basear. E nesse caso se recorre a teoria. E existem exemplos disso. Quando os EUA precisaram construir a primeira bomba nuclear, eles reuniram um grupo de excelentes físicos e pesquisadores. Pessoas que estavam na fronteira da teoria nuclear. Hoje em dia, após a criação das bombas nucleares, diversos países relativamente pequenos as possuem (coisa realmente preocupante). Dizem até que bomba nuclear possui uma fabricação quase "caseira" nos dias de hoje (outro fato preocupante). Mas se construí-la é algo "simples", por que os Estados Unidos recrutaram seus melhores cientistas para fazê-la? Por que até aquele momento isso nunca tinha sido feito.

   Se você procurar qualquer coisa grandiosa já feita, ela contou com o apoio de cientistas que dominavam a teoria. Você acha que a NASA envia sondas espaciais para o espaço sem levar em conta modelos teóricos e matemáticos? Conforme a complexidade de um projeto aumenta, seu custo aumenta e seu nível de "novidade" aumenta, a técnica de tentativa e erro se torna inviável e, nesse caso, a teoria adquire um espaço importante.

   Mas nesse momento alguém poderia dizer: "mas eu não vou construir bombas e nem trabalhar na NASA. Por que preciso de tanta teoria?". A resposta é: a faculdade ou universidade não sabe o que você vai fazer. No ensino médio eu estudei geografia, algo que nunca usei na minha vida profissional. Porém no ensino médio a escola não sabia o que cada aluno faria, e pode ser que algum dos meus colegas esteja utilizando esse conhecimento em seu trabalho. O mesmo se aplica para a universidade. Eles não sabem quais de seus alunos trabalharão na indústria, quais serão professores e quais se direcionarão à pesquisa. Eles não sabem quais vão trabalhar na Fórmula 1 ou se algum deles será contratado pela NASA.  Então eles buscaram construir um currículo que atendesse ao maior número de possíveis necessidades futuras.

   Por fim, digo que concordo que os cursos devem  levar em conta a prática. Eles devem adequar seus currículos para incluir visitas a empresas ou locais cotidianos da profissão, devem realizar palestras com projetistas de  empresas do setor em questão. Agora a pessoa que diz que deveria ter menos teoria (e em geral atacam as disciplinas de cálculo e física) por que ela  não consegue entendê-la ou passar em uma disciplina teórica, na minha opinião, não tem o necessário para ser formado em um curso de nível superior.

   Por hoje era isso. Se concorda, discorda ou tem algo a dizer sobre isso, use os comentários. Abraço a todos e que continuemos estudando.

domingo, 3 de agosto de 2014

Algoritmo e Programação - For

  Olá a todos. Vamos dar sequência a nossa série de programação estudando um novo comando: o for.

  O comando for é um dos comandos de laço existentes na linguagem C. A função de um comando de laço é repetir múltiplas vezes o mesmo trecho de código, até que uma certa condição seja atendida. Esse comando é extremamente flexível e, por isso, estudaremos ele inicialmente. Como exemplo, vamos analisar o seguinte trecho de código.

int main()
{
     unsigned char i;
     for(i = 0; i < 5; i++)
     {
          printf("O valor de i: %d.\n",i);
     }
}


  O que esse trecho de código fará? Primeiramente criará uma variável do tipo char com o nome "i". Perceba que essa variável é local (sua existência se limita ao interior da função main()) e foi criada sem a definição de um valor inicial. Enquanto as variáveis globais são criadas com valor igual a 0, as variáveis locais não são necessariamente criadas com algum valor inicial, podendo conter qualquer valor de "lixo". É necessário tomar cuidado com essas regras pois elas podem variar conforme o compilador usado (problema especialmente verificado em compiladores para microcontroladores, que nem sempre seguem à risca as regras de C ANSI).

  Após criada a variável "i", cujo valor, à priori, não sabemos, há o comando for. O comando for recebe três argumentos (e aqui argumentos é somente uma forma de falar, pois o comando for não é uma função) separados por ponto e vírgula. Primeiramente colocamos as condições de inicialização. Essas condições atribuem valores as variáveis antes que o laço de repetição comece a ser executado. Neste caso foi atribuído a variável i o valor 0. Também tenha em mente que é possível inicializar o valor de múltiplas variáveis, como, por exemplo:

for(i = 0, j = 3; i < 5; i++)
{
     //Qualquer coisa aqui dentro!
}

  Neste trecho de código foi atribuído a variável i o valor 0 e a variável j o valor 3 na mesma inicialização do for. Atente para o fato de que as variáveis i e j devem ser declaradas antes do comando for.

  Após a inicialização vem a condição, que é uma expressão que determinará quando o laço deve ser encerrado. No nosso exemplo temos a condição (i < 5). Isso significa que o laço se repetirá enquanto o valor da variável i for menor que 5. Se ao final de uma iteração (onde uma iteração é a execução de todos os comandos internos a um laço de repetição) o valor de i for igual ou maior que 5, o laço for não será executado mais e o programa seguirá executando os comandos posteriores ao for.

  Na condição devemos ter apenas um teste, mas esse teste pode envolver mais de uma variável. Vejamos os seguintes exemplos:

for(i = 0, j = 2; i+j<10 i="" p="">{
     //Qualquer coisa aqui.
}

for(i = 0, j = 0; (i<2 amp="" i="" j="" p="">{
     //Qualquer coisa aqui.
}

  No primeiro exemplo estamos testando a soma da variável i e da variável j. Enquanto o resultado dessa soma for menor que 10 o laço continuará a ser repetido. No segundo exemplo estamos testando se o valor da variável i é menor que 2 e se, ao mesmo tempo, o valor da variável j é menor que 1. Enquanto ambas condições forem verdadeiras simultaneamente, o laço de repetição continuará a ser executado.

  Vamos voltar ao nosso exemplo inicial. Após o segundo ponto e vírgula temos o incremento. No incremento vamos determinar quais variáveis terão seu valor alterado. No nosso exemplo inicial temos a expressão mais comum, que é i++. Essa expressão, como já sabemos, incrementam em 1 o valor atual da variável i. Mas nem sempre temos que incrementar em 1 o valor da variável. Vejamos outro exemplo:

for(i = 100; i > 40; i-=5)
{
     //Qualquer coisa aqui.
}

  Nesse último exemplo a variável i é decrementada por um valor de 5. Ou seja, ao final dos comandos contidos pelo laço for a variável i tem seu valor diminuído por 5.

  Também é possível alterar o valor de mais de uma variável. Vejamos o próximo exemplo.

for(i = 100, j = 50; i+j > 40; i-=5, j-=10)
{
     //Qualquer coisa aqui.
}

  Neste último exemplo estamos alterando o valor de duas variáveis, que são i e j. A variável i tem seu valor decrementado por 5, enquanto a variável j tem seu valor decrementado por 10.

  No nosso exemplo inicial, o laço é executado 5 vezes, e o valor de i é incrementado 1 unidade, passando pelos valores 0, 1, 2, 3 e 4. Quando o valor de i é igual a 5, o laço for é encerrado, e os comandos não são executados com i igual a 5. O programa então mostra as seguintes mensagens na tela:

O valor de i: 0.
O valor de i: 1.
O valor de i: 2.
O valor de i: 3.
O valor de i: 4.

  Devemos porém prestar atenção nas possíveis armadilhas que existem quando utilizamos laços de repetição. A mais famosa (e mais perigosa) é o laço infito. Esse problema ocorre quando criamos um laço sem condição de encerramento, ou cuja condição nunca possa ser alcançada. Vamos a um exemplo.

for(i = 0; i != 3; i +=2)
{
     //Qualquer comandos aqui, desde que não alterem o valor de i;
}

  A implementação acima consiste de um laço infinito. Analisando esse trecho, percebe-se que o valor de i foi inicializado com 0, e que o laço será executado enquanto o valor de i for diferente de 3. Porém, no incremento, definimos que o valor de i é sempre incrementado por um valor de 2. Se temos um número par, e sempre incrementamos por um número par, nunca teremos um número ímpar como 3. Dessa forma, a condição de encerramento do laço nunca poderá ser atingida e, portanto, o laço executará para sempre. Hoje em dia isso causa "apenas" o travamento completo de seu programa. Porém, antigamente, o sistema operacional (SO) não conseguia tomar o controle da máquina. Então cabia aos programas terem comandos que devolviam ao sistema operacional o controle do processador. Em um sistema assim (chamado de processamento cooperativo) se o programa entrava em um laço infinito e não conseguia devolver ao SO o controle da máquina, todo o computador ficava travado e precisava ser reiniciado. Não havia Ctrl+Alt+Del para finalizar a tarefa. Então perceba o quanto um laço infinito é perigoso para um sistema. E, levando em conta que a maioria das aplicações microcontroladas não possui SO, os laços infinitos continuam travando completamente esse tipo de sistema. Portanto, esteja sempre atento!

  E por hoje era isso. Seguindo nosso ritual tradicional de final de post, digo que qualquer dúvida, sugestão ou crítica deixem comentários. Cumprido os procedimentos protocolados, um abraço a todos e continuem estudando.

sábado, 26 de julho de 2014

Algoritmo e Programação - Switch Case

   Olá a todos. Já que retornamos, vamos dar continuidade a série sobre algoritmo e programação. Hoje vamos falar de um novo comando, que é o switch case (também conhecido como switch).

   Imagine que temos uma variável inteira que em nosso programa vai assumir valores de 0 até 9. Para cada valor, devemos escrever uma mensagem diferente na tela com o comando printf. Uma das maneiras de fazer isso é criar 10 comandos ifs, um para cada situação, da seguinte forma:

unsigned char variavel = 2;

int main()
{
if(variavel == 0)
{
printf("Valor zero.\n");
}
if(variavel == 1)
{
printf("Valor um.\n");
}
if(variavel == 2)
{
printf("Valor dois.\n");
}
if(variavel == 3)
{
printf("Valor três.\n");
}
if(variavel == 4)
{
printf("Valor quatro.\n");
}
if(variavel == 5)
{
printf("Valor cinco.\n");
}
if(variavel == 6)
{
printf("Valor seis.\n");
}
if(variavel == 7)
{
printf("Valor sete.\n");
}
if(variavel == 8)
{
printf("Valor oito.\n");
}
if(variavel == 9)
{
printf("Valor nove.\n");
}
system("pause");
}

   Este é um jeito de fazer. Um jeito meio longo (ocupou 49 linhas, embora alguém pudesse dizer que isso se deve pela forma que eu costumo escrever o código) mas funciona.

   O comando switch serve para quando queremos comparar o valor inteiro de uma variável com diversos outros valores. Vamos aplicá-lo ao exemplo dado anteriormente para observarmos sua sintaxe.

unsigned char variavel = 7;

int main()
{
switch (variavel)
{
case 0:
printf("Valor zero.\n");
break;
case 1:
printf("Valor um.\n");
break;
case 2:
printf("Valor dois.\n");
break;
case 3:
printf("Valor três.\n");
break;
case 4:
printf("Valor quatro.\n");
break;
case 5:
printf("Valor cinco.\n");
break;
case 6:
printf("Valor seis.\n");
break;
case 7:
printf("Valor sete.\n");
break;
case 8:
printf("Valor oito.\n");
break;
case 9:
printf("Valor nove.\n");
break;
default:
printf("Valor estranho encontrado!\n");
break;
}
system("pause");
}

   Então vamos prestar atenção na sintaxe do comando switch. Após o comando switch escreve-se, dentro de parênteses, a variável que será testada. Nesse caso eu nomeei a variável como "variavel" (que criativo que eu sou). Após isso abre-se um bloco de chaves.

   Dentro do bloco colocamos case, o valor a ser testado e dois pontos. Depois disso escrevemos todos os comandos que devem ser executados se a variável for igual ao valor testado. Depois dos comandos que queremos que sejam executados finalizamos com comando break.

   Para que serve o comando break? Quando nosso programa encontra o comando break, ele sai fora do laço que está sendo executado. Neste caso, ele sai fora do comando switch. Vamos supor que nos esqueçamos de colocar break no comando switch, e a variável tenha valor zero. Nesse caso ela é comparada com o case 0, será igual e mostrará na tela a mensagem "Valor zero.". Mas, como o programa não encontrou um break, ele vai mostrar na tela a mensagem "Valor um." que está dentro do case 1, mesmo que o valor da variável seja diferente de 1, e continuará mostrando todas as mensagens seguintes. Se esquecermos de todos os breaks, o programa vai mostrar todas as mensagens e executar todos os comandos após o case que corresponder ao valor da variável. Por isso, sempre que seu case executar os comandos de mais de um caso, verifique se você não esqueceu de colocar o comando break em algum dos cases.

   Por fim temos o default. O programa vai executar os comandos dentro de default sempre que a variável testada não se encaixar em nenhum dos cases. Por isso que o nome desse caso é default (um pouco auto explicativo). Após os comandos do default devemos lembrar de fechar o bloco de chaves do switch.

   Perceba que, nesse caso, não ganhamos muita economia de linhas (gastei 45 linhas para fazer esse código). O maior ganho foi em organização. Ao ver um comando switch o programador já sabe que terá múltiplas comparações de valores inteiros e isso facilita a compreensão do código.

   Note que o comando switch compara apenas igualdade. Não é possível comparar se um valor é maior que ou menor que outro utilizando esse comando. Também só é possível comparar valores do tipo inteiro, e nunca valores do tipo float (decimais, números com vírgula). Em todos os casos onde o switch não se aplica, é aconselhado o uso do comando if. O comando switch suporta números negativos desde de que a variável testada comporte esses números (seja do tipo signed).

   Caso você queira testar esses exemplos no seu compilador, lembre-se de inclui os arquivos stdio.h e stdlib.h. Caso se esqueça, o compilador gerará erro dizendo que o comando system("pause") não está definido dentro do escopo do programa.

   Por hoje era isso. Qualquer dúvida me avisem pelos comentários. Sugestões? Comentários! Críticas? Comentários! Para entrar em contato, utilize os comentários. Espero que tenham gostado e entendido. Vamos continuar estudando! Um abraço e até a próxima.

sexta-feira, 25 de julho de 2014

Retorno Triunfal!

Nossa, quanto tempo faz que não escrevo aqui. Deixe-me ver, faz desde março desse ano!

Primeiro, permitam-me explicar o motivo de minha ausência aqui. Este último ano estive envolvido com pesquisa tecnológica na Universidade de Caxias do Sul. Estava trabalhando em um projeto sobre identificação de parâmetros de baterias chumbo ácidas reguladas por válvula (VRLA ou também conhecida como bateria de carro!).

Devido a pesquisa estive mais dedicado a funções dentro da universidade, como monitorias e até mesmo minhas próprias aulas. Mas este ano estou deixando o projeto, então creio que vou ter mais tempo e disposição para escrever aqui.

Então vamos lá. O que temos pendente para fazer? Temos a série sobre programação C, que nunca foi terminada =/.

Depois disso vamos começar uma série sobre microcontroladores (por que não?). Estou trabalhando em um programa para Arduíno (sim, eu comprei um ^^) para comunicar com um controle de PS2. Estou terminando isso e, após finalizar, quero expandir para outros microcontroladores que conheço (PIC e ARM).

Também quero incluir algumas coisas sobre física (amor de minha vida) e química (apenas uma paixão momentânea). Por que não? O blog é meu mesmo!!!

Como sempre estou aceitando comentários, sugestões e críticas para continuar melhorando o blog. Conto com a ajuda de todos os leitores.

Então vamos lá, que 2014 não terminou e temos muito trabalho a recuperar.

Abraço a todos e de volta aos estudos!!!

sábado, 1 de março de 2014

Não Jogue Fora: Conserte!

Não jogue fora, conserte. Essa era a frase estampada na capa da revista Galileu, de fevereiro de 2014. Fazia chamada para um excelente artigo falando sobre a cultura do conserto, de grupos de pessoas que se opõem à obsolescência programada e clamam pelo direito de seus equipamentos serem facilmente consertáveis. Assim, no meio da matéria, descobri o site iFixit, que reúne diversos guias e manuais de reparos de diversos produtos diferentes, como celulares e consoles, e tudo gratuito!

Ainda não explorei completamento o site, mas com certeza é muito útil saber que ele existe. E, por isso, compartilhei esta descoberta aqui no blog. Aproveito para recomendar a revista Galileu, que me pareceu ser uma ótima revista, com diversas matérias interessantes.

Enfim, é isso. Espero que essa informação seja útil para alguém. Obrigado pela atenção e até a próxima! E lembrem-se: continuem estudando, que eu também continuarei! Abraço!

Resumo da Série de Eletrônica Digital

     Olá a todos. A algum tempo me empenhei em escrever uma série de posts sobre eletrônica digital e que, com o último post sobre memórias, eu dei como concluída (muito embora, no futuro, possam ser acrescentados mais posts a ela!). Com isso acho conveniente escrever um resumo, que mais serve como um índice da série, com os links de cada post, assim como fiz com a série de conversores chaveados.
     Caso seja necessário acrescentar outro post nessa série, esse índice será atualizado. Como saberei se outro post é necessário? Com a ajuda de vocês, leitores! Assim, qualquer sugestão tipo "ei, faltou um post sobre tal assunto" será útil para indicar o que faltou na série.
     A ideia principal é, após o fechamento de outra série em andamento, sobre linguagem C, iniciar uma série sobre microcontroladores PIC.
     Então, sem mais delongas, vamos ao índice, que busquei organizar no sentido de pré-requisitos, ou seja, para ler um post qualquer é necessário do conhecimento dos anteriores:


     Aí está o sumário dessa série, que espero que possa ajudar todos que precisarem e, por favor, eu, como estudante de engenharia de controle, me importo muito com o feedback. Sugiram nos comentários, se vocês acham que falta algo. O post sobre o circuito para senha de cofre, por exemplo, surgiu como sugestão de um leitor.

   Obrigado pela atenção. Abraço e bom início de semestre a todos. Lembrem-se: continuem estudando, que eu também vou! Fui.

Atualizado pela última vez em: 01/03/2014.

quinta-feira, 13 de fevereiro de 2014

Aniversário do Blog!

     Fevereiro é o mês de aniversário do blog. O blog completou 3 anos de existência e embora o ritmo de postagens não seja mais o mesmo (eu estou ficando devagar, muito trabalho, estudo e namoro) a qualidade dos posts e do auxílio que eu busco prestar a quem me procura aumentou! Isso por que quando eu comecei em 2011 eu não tinha nem experiência prática e nem formação teórica em eletrônica.

     Hoje, três anos depois, eu me formei técnico em eletrônica, iniciei o curso de engenharia de controle e automação, trabalho há 1 ano e meio na indústria, faço pesquisa acadêmica há 6 meses, fui monitor de sistemas digitais e, nesse semestre, serei de microprocessadores I.

     Ou seja, estou me esforçando. E todo o conhecimento que acumulei nesse início da minha trajetória profissional me mostrou o quão pouco eu sei. Interagir com pessoas que estão em um nível muito acima do meu me fez perceber que tenho muito a aprender.

     Mas, por sorte (essa última que, por mais que não goste de admitir, tem um papel muito importante na minha vida), essas pessoas de alto nível estão sempre disponíveis para me ensinar e me ajudar a buscar o meu próprio conhecimento.

     E elas tem não somente aumentado meu nível de conhecimento técnico, mas tem me mostrado a importância de pessoas disposta a compartilhar o conhecimento. É para isso que o blog existe desde o começo, e para isso que continuará existindo pelo máximo de tempo que eu puder mantê-lo. E mesmo com um baixo ritmo de postagem, ainda me alegra de ver que todo dia pelo menos 100 pessoas visualizam esse blog. Espero que essas pessoas estejam encontrando o que procuram aqui e que saibam que, se precisarem, podem deixar um comentário que eu com certeza responderei (dentro de um prazo de dois dias úteis :).

     Obrigado a todos os leitores e seguidores do blog. Um feliz aniversário para nós. Que esse ano seja de muito esforço e muitas conquistas. Vamos continuar estudando.

quinta-feira, 2 de janeiro de 2014

Problema em Conversor Chaveado: Indutor e Validação de Projeto!

     Olá. Alguns meses atrás eu fiz um post contando um caso sobre problemas em circuitos eletrônicos devido ao excesso de fluxo de solda na placa. Hoje eu volto para, novamente, contar um caso que acompanhei na empresa na qual trabalho, em um circuito de sensor de inclinação. Como no momento estou trabalhando na parte de qualidade de produto, terei muitas histórias técnicas para contar, então pode ser que esse modelo de "estudo de caso" se torne mais comum no blog.

     Basicamente ocorreu o seguinte. Foi feita uma alteração na placa desse sensor de inclinação. O circuito em si não foi alterado. A alteração se limitou ao lay-out dos componentes, para a placa ficar menor e melhor organizada. Como o circuito era o mesmo, a nova versão de placa não foi testada pelo setor de projetos e passou direto para a produção. Então dois colegas meus, muito observadores, perceberam que o sensor ficou um pouco menos estável. Enquanto na versão antiga o ângulo possuía uma variação de 0,2° na versão nova a variação chegava a 0,7°, porém o problema parecia um pouco intermitente.

     Então teve um período de discussão se aquilo era um problema ou se era algo da nossa cabeça, foram feitas algumas comparações entre versões de placa, diversos testes. Enfim, passado esse período, determinamos que era um problema e passamos a buscar a causa. Minha ideia era desconectar o conversor chaveado e ligar uma fonte linear no lugar, para ver se a variação diminuía (suspeitava de ruido eletromagnético). Mas como não estou mais presente na empresa em tempo integral, um colega meu (um dos que observou o problema em primeiro lugar) teve a seguinte ideia: dessoldou o indutor do conversor chaveado, soldou dois fios nele e o reconectou eletricamente no circuito, porém fisicamente longe do resto dos componentes. O resultado foi uma diminuição da variação para valores iguais a versão anterior da placa.

Conclusões

     Não é novidade que conversores e fontes chaveadas geram ruído eletromagnético e o indutor é um componente onde esse fenômeno está mais concentrado. Desse caso tiramos a lição que CIs sensíveis, e nessa categoria incluo principalmente circuitos de instrumentação e medição, podem ser afetados por ruído tanto elétrico (que pode entrar pela alimentação) quanto eletromagnético. Nesses projetos o lay-out faz a diferença. A organização da placa deixa de ser uma questão puramente estética ou de economia de espaço e se torna uma questão de funcionalidade do produto, o que não ocorre com tanta ênfase em circuitos com fontes lineares, por exemplo.

     Outra lição é adotar a política de validação de projeto e alterações antes de passá-los para a produção. Mesmo nas alterações que parecem ser irrelevantes. Se a alteração foi significante a ponto de ser feita, deve ser significante a ponto de ser validada. Isso evita uma situação onde um projeto é passado para a produção, são montadas muitas vezes centenas de peças e depois percebe-se uma não conformidade. Por isso bato na tecla da validação de projeto!

     Então as dicas que eu deixo são essas: cuidado com o lay-out em fontes ou conversores chaveados. O lay-out importa muito nesses casos. Validação de projeto é uma política importante que faz a diferença.

     Espero que este estudo de caso sirva de ajuda para alguém passando por problemas semelhantes. Qualquer dúvida, sugestão, crítica ou contribuição com alguma história que presenciou, usem os comentários, que serão respondidos o mais breve possível. Um abraço, até a próxima e continuem estudando para resolvermos problemas como esse cada vez com mais facilidade!