problema com um código (emissor IR)

Boa noite amigos,
eu não tenho muita experiencia com programação, então peço que tolerem minha ignorância!

#include <IRremote.h>

char rec;
int i = 0;
int total_canais;
bool cond_while = false;


IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() 
{
  rec = Serial.read();
   switch(rec)
   {
    case 'P':
      irsend.sendNEC(0x20DF10EF, 32); //Power TV
      Serial.println("Ligada/Desligada");
      break;

    case 'U': //Usuario entra com a quantidade de canais da tv que deseja subir
      Serial.println("digite a quantidade de canais:");
      total_canais = Serial.read();//lê a serial e denomina a variavel
              if( total_canais > 0)
              {
                cond_while = true;
              }
                 
              while(cond_while)
                {           
                  irsend.sendNEC(0x20DF00FF, 32); //Ch-UP
                  Serial.println("CH+");
                  delay(100);
                  i++;
                    if( i = total_canais )
                      {
                        cond_while = false;
                        i = 0;
                      }
                }
                break;
   }
  delay(100);
}

eu estou com um problema no case ‘U’: depois do serial.print ele não armazena na variável total_canais o valor digitado, alguém pode ajudar?

Obrigado!

Seria bom explicares o que pretendes... no entanto, acho que o teu problema está no facto que estás a enviar ASCII e o Arduino está a ler binário.

Se queres converter um número de ASCII para binário (apenas um caracter, note-se), faz assim:

total_canais = Serial.read() - '0';//lê a serial e denomina a variavel

Desculpe, acabei me esquecendo, mas o intuito é que apareça uma pergunta na serial e o usuario digita a quantidade de canais que ele deseja subir, dai ele pega esse numero e entra no loop while e repete o ciclo numa determinada quantidade de vezes, porem quando eu tento digitar U ele ja escreve CH+ na tela oque significa que ele nao esta esperando receber um dado pela serial

Claro que não está… tu não disseste para ele esperar por mais um dado.
Algumas coisas que estão em falta:

 if (Serial.available() > 0) { //isto indica que o arduino recebeu algo... 
   rec = Serial.read();
   switch(rec)
//depois metes todo o switch case dentro deste parêntesis...

No caso de escreveres U:

//antes crias esta variável fora de qulaquer função: 
unsigned long timeout = 0; 

//...
      Serial.println("digite a quantidade de canais:");
      timeout = millis();
      while (millis() - timeout < 100000) { // a partir daqui tens uma eternidade para inserir o canal...  
          if (Serial.available() > 0) break; //se algo foi recebido, sai deste loop... 
      } 
      total_canais = Serial.read() - '0' ;//lê a serial e denomina a variavel ajustada por causa do ASCII.
//....

Há algumas coisas a ter cuiaddo… por exemplo, se não receberes nenhum dado ao fim de 100 segundos o código vai executar na mesma. Isso não é ideal, mas deixo para tu pensares noutra forma de fazer.

Outra coisa que deves normalmente fazer é garantir que o valor em total_canais está entre 0 e 9… se alguém mandar um ‘a’ em vez de um número não sabes o que o programa vai fazer.

Experimenta e vê se funciona… eu não compilei nem testei o código mas deve funcionar…

parece que ele ainda pula a parte de esperar o numero, o código esta assim:

#include <IRremote.h>

char rec;
int i = 0;
int total_canais = 0;
bool cond_while = false;
unsigned long timeout = 0; 


IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() 
{
  if (Serial.available() > 0) //isto indica que o arduino recebeu algo... 
  {
  rec = Serial.read();
   switch(rec)
   {
    case 'P':
      Serial.println("Digitou P");
      irsend.sendNEC(0x20DF10EF, 32); //Power TV
      Serial.println("Ligada/Desligada");
      break;

    case 'U': //Usuario entra com a quantidade de canais da tv que deseja subir
    Serial.println("Digitou U");
      Serial.println("digite a quantidade de canais entre 0 e 9:");
      timeout = millis();
      while (millis() - timeout < 100000) // a partir daqui tens uma eternidade para inserir o canal... 
        {
          if (Serial.available() > 0) {break;} //se algo foi recebido, sai deste loop...
        }
        total_canais = Serial.read() - '0' ;//lê a serial e denomina a variavel ajustada por causa do ASCII.
        Serial.println(total_canais);
              if( 9 > total_canais > 0)
              {
                cond_while = true;
              }
                 
              while(cond_while)
                {           
                  irsend.sendNEC(0x20DF00FF, 32); //Ch-UP
                  Serial.println("CH+");
                  delay(100);
                    if( i = total_canais )
                      {
                        cond_while = false;
                        i = 0;
                       }
                   i++;
                }
    break;
   }
  }
  delay(100);
}

vou anexar uma imagem da resposta que ele retorna.
ao que parece ele não entra no while depois do timeout = millis();

Aquele while devia ser substituído por um for... não fica nada bonito a maneira como tens o código.

O teu problema está no setting da porta série... no fundo da porta série onde tens a definição da baud rate deves colocar "Sem Final de Linha" em vez de "Nova Linha".

O que acontece ao seleccionares qualquer uma das hipóteses sem ser a "Sem Final de Linha", é que a IDE envia um ou dois caracteres (\r e/ou \n) juntamente com o que escreveres.
Ao fazer isso, o teu código vê que foi recebido mais alguma coisa e prossegue em vez de esperar pelo caracter digitado.

Isto pode ser corrigido forçando o utilizador a enviar um caracter e se não ler algo entre 0 e 9 obrigar o utilizador a introduzir o caracter de novo.

obrigado, aquele erro foi corrigido, porem agora não consigo fazer ele entrar no for:

#include <IRremote.h>

char rec;
int i = 0;
byte total_canais;
bool cond_while = false;
unsigned long timeout = 0; 


IRsend irsend;

void setup()
{
  Serial.begin(9600);
}

void loop() 
{
  if (Serial.available() > 0) //isto indica que o arduino recebeu algo... 
  {
  rec = Serial.read();
   switch(rec)
   {
    case 'P':
      Serial.println("Digitou P");
      irsend.sendNEC(0x20DF10EF, 32); //Power TV
      Serial.println("Ligada/Desligada");
      break;

    case 'U': //Usuario entra com a quantidade de canais da tv que deseja subir
    Serial.println("Digitou U");
      Serial.println("digite a quantidade de canais entre 0 e 9:");
      timeout = millis();
      while (millis() - timeout < 100000) // a partir daqui tens uma eternidade para inserir o canal... 
        {
          if (Serial.available() > 0) {break;} //se algo foi recebido, sai deste loop...
        }
        total_canais = Serial.read() - '0' ;//lê a serial e denomina a variavel ajustada por causa do ASCII.
        Serial.println(total_canais);
              for( total_canais > 0; total_canais = i; i++)
                {           
                  irsend.sendNEC(0x20DF00FF, 32); //Ch-UP
                  Serial.println("CH+");
                  delay(100);
                }
    break;
   }
  }
  delay(100);
}

segue imagem da resposta que retorna no serial

O for não está escrito correctamente.

For (i=0; i < total_canais ; i++)

Muito obrigado bubulindo, funcionou perfeitamente!

Como eu faria para ele ler de 0 a 100 com o codigo ascii?

A maneira mais simples é através da definição dum protocolo.

Ou seja, uma definição do início e fim dum comando. No teu caso, já tens o início com o U (se bem que outras pessoas prefiram um adicional).
Agora de definires que por exemplo o caracter * é o fim do teu comando e entre o U e o * podem vir até 3 caracteres, podes programar o arduino para esperar por 4 (o numero mais o *) caracteres e quando os receber, processar.

No entanto, se fizeres assim terás de escrever 001 ou 020 porque o comando tem um formato fixo.
Se quiseres podes programar para o sistema estar à procura do * e quando o vir, pegar nos 3 últimos caracteres e converter para numero.
A função que faz essa conversão é a atoi().

ok mais dai o codigo que voce me ajudou a fazer que ele espera pela entrada de dados no serial será o mesmo né? so vou mudar esta parte?!

      total_canais = Serial.read() - '0' ;//lê a serial e denomina a variavel ajustada por causa do ASCII.
//....

Sim... vais ter de alterar consideravelmente essa parte.

Algures no meu blog há um post acerca de protocolos que pode ser interessante.
A questão ou problema mais comum aqui no fórum é precisamente este, como comunicar entre dois dispositivos onde não existe um protocolo definido.

Pode passar o link do seu blog???

Está na minha assinatura...

http://microsrus.blogspot.co.uk/