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!