Ir ao conteúdo
  • Comunicados

    • Gabriel Torres

      Seja um moderador do Clube do Hardware!   12-02-2016

      Prezados membros do Clube do Hardware, Está aberto o processo de seleção de novos moderadores para diversos setores ou áreas do Clube do Hardware. Os requisitos são:   Pelo menos 500 posts e um ano de cadastro; Boa frequência de participação; Ser respeitoso, cordial e educado com os demais membros; Ter bom nível de português; Ter razoável conhecimento da área em que pretende atuar; Saber trabalhar em equipe (com os moderadores, coordenadores e administradores).   Os interessados deverão enviar uma mensagem privada para o usuário @Equipe Clube do Hardware com o título "Candidato a moderador". A mensagem deverá conter respostas às perguntas abaixo:   Qual o seu nome completo? Qual sua data de nascimento? Qual sua formação/profissão? Já atuou como moderador em algo outro fórum, se sim, qual? De forma sucinta, explique o porquê de querer ser moderador do fórum e conte-nos um pouco sobre você.   OBS: Não se trata de função remunerada. Todos que fazem parte do staff são voluntários.
    • DiF

      Poste seus códigos corretamente!   21-05-2016

      Prezados membros do Fórum do Clube do Hardware, O Fórum oferece um recurso chamado CODE, onde o ícone no painel do editor é  <>     O uso deste recurso é  imprescindível para uma melhor leitura, manter a organização, diferenciar de texto comum e principalmente evitar que os compiladores e IDEs acusem erro ao colar um código copiado daqui. Portanto convido-lhes para ler as instruções de como usar este recurso CODE neste tópico:  
jbiribi

Arduino LM35 para ligar um LED através do Arduino

Recommended Posts

Estou tentando fazer com que um LED ligue caso o valor que eu colocar na serial for maior que a temperatura que ele está medindo. O problema é que está ligando sempre. Caso eu tire o if(Serial.available() > 0) liga sempre também mas desliga depois de um tempo. Alguém poderia me ajudar? 

 

const int LM35 = A0; 
float temperatura;

void setup() {
  
Serial.begin(9600);
pinMode(13, OUTPUT);
  
}

void loop() {
 
temperatura = (float(analogRead(LM35))*5/(1023))/0.01;

Serial.print("Temperatura: ");  
Serial.println(temperatura);
delay(2000);


if(Serial.available() > 0){
    
  if(temperatura <= Serial.read()){
    digitalWrite(13, HIGH);
  }
  else if(temperatura > Serial.read()){
    digitalWrite(13, LOW);
  }
}
}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

O programa é de tua autoria ou estás a ctrl-c ctrl-v? ok.. isso faz pouca diferença...(mas faz)  Pra que serve a função Serial.available()? Avaliar se serial presente?.. parece.

 

temperatura= float. ok. Mas que tipo de dado sai da função Serial.read()? Talvez tenhas que fazer algum tipo de conversão. Aguarde algum arduineiro...

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • Autor do tópico
  • 4 horas atrás, Isadora Ferraz disse:

    O programa é de tua autoria ou estás a ctrl-c ctrl-v? ok.. isso faz pouca diferença...(mas faz)  Pra que serve a função Serial.available()? Avaliar se serial presente?.. parece.

     

    temperatura= float. ok. Mas que tipo de dado sai da função Serial.read()? Talvez tenhas que fazer algum tipo de conversão. Aguarde algum arduineiro...

    Serial.available() é para verificar se a porta está disponível.

     

    A única parte que não foi eu que escrevi foi a parte do LM35 --> https://portal.vidadesilicio.com.br/lm35-medindo-temperatura-com-arduino/

     

    Quanto ao tipo de dado da porta serial eu não achei nada na internet, mas pelo que lembre já vi ser comparado com float. 

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Faz sentido o que a Isadora diz, mas o monitor serial serve pra isto.
    Apesar de estar engatinhando em C++, poderia fazer o seguinte pra monitorar valores:

     

    int SerDisp = Serial.available();
    if(!SerDisp)
    {
     Serial.println(SerDisp);

    // Imprimir o que quiser aqui

    //

    //

     digitalWrite(13, HIGH);
    }

     

    Desta forma pode comparar valores e saber o por que do "ligar sempre".

     

    @Isadora Ferraz Estou errado? Aceito críticas.

    Editado por _xyko_

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    1 hora atrás, jbiribi disse:

    Serial.available() é para verificar se a porta está disponível.

     

    Não é bem isso o que este método faz. Veja a documentação: https://www.arduino.cc/reference/en/language/functions/communication/serial/available/

    Get the number of bytes (characters) available for reading from the serial port. This is data that's already arrived and stored in the serial receive buffer (which holds 64 bytes). available() inherits from the Stream utility class.

    "Obtém o número de bytes (caracteres) disponíveis para leitura através da porta serial."

    Seu programa só vai ascender o LED quando e enquanto houver dados na porta serial. 

    adicionado 2 minutos depois
    1 hora atrás, jbiribi disse:

    Quanto ao tipo de dado da porta serial eu não achei nada na internet, mas pelo que lembre já vi ser comparado com float. 

    Acho que você não leu a documentação =)

    adicionado 15 minutos depois

    O Serial.read() retorna o primeiro byte (int) recebido pela comunicação Serial...

    Se você for ler tudo, você pode usar o Serial.readBytes()

    	// Existem dados a serem lidos...
    	int tamanhoDados = Serial.available();
    	char[] dados;
    	if(tamanhoDados > 0 && Serial.readBytes(dados, tamanhoDados) == tamanhoDados)
    	{
    		// Tratar informações recebidas em dados
    	}

     

    Pra fazer isso ai que você quer, você precisa tratar antes...

    Por exemplo:

    	// Existem dados a serem lidos...
    	if(Serial.available() > 0)
    	{
    		float valorInserido = Serial.parseFloat();
    		
    		if(temperatura > valorInserido)
    		{
    		}
    		else
    		{
    		}
    	}
    

     

    Editado por Carlos Zanon

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    7 horas atrás, Isadora Ferraz disse:

    fazer algum tipo de conversão

     

    33 minutos atrás, Carlos Zanon disse:

    você precisa tratar antes...

    suspeitei desde o princípio.

     

    Querido Chicão @_xyko_

    tá vivo e bem? 

    Ou tá no infinito?

    e além?

    kk poesia macabra...

    Não tenho contato com arduínos & CIA. Como float e mc de 8 bits não se dão muito bem, assim somos eu e arduíno. Só intuição mesmo que uso.

    abç

    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    22 minutos atrás, Isadora Ferraz disse:

    Como float e mc de 8 bits não se dão muito bem, assim somos eu e arduíno

     

    Bom ... Da mesma forma que dá para usar float tranquilamente até em microcontroladores de 4 bits ( perguntem prá Texas Instruments ou para a HP ... na década de 70 era assim....  ) a @Isadora Ferraz pode também mexer com os Arduínos.... apenas uma questão de velocidade mais lenta kkkk !

     

    Paulo

    • Curtir 1
    • Haha 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

     

    3 horas atrás, aphawk disse:

    dá para usar float tranquilamente

    Acho nos anos 70 falavam o mesmo do eniac kk. bem talvez nem tão tranquilo...

     

    float e mc 8 bits é para os fracos e reconheço que facilita a vida dos iniciantes. Já usei e recentemente kk.

    Passado sempre presente (de novo?) me fez lembrar ... Certa feita quando estudava matrizes havia um cálculo trilôco pra fazer. E era a mão (e mente). Pra conferir, o professor alimentou os dados -eram muitos , tive que ditar pra ele - numa calculadora HP top da época (que emprestou do Paulão kk) e deixou na mesa esperando muitos e muitos minutos pra ela dar o resultado. Achei sinistro

     

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Oi...cheguei...@Isadora Ferraz
    O sinal é porque sempre volto, não importa quanto tempo...

    @aphawk
    Posso, sem vergonha de falar em C, C#, C++.  enfim, reciclagem, mas BASCOM,  kkk é bom

     

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    32 minutos atrás, Isadora Ferraz disse:

    Pra conferir, o professor alimentou os dados -eram muitos , tive que ditar pra ele - numa calculadora HP top da época (que emprestou do Paulão kk) e deixou na mesa esperando muitos e muitos minutos pra ela dar o resultado. Achei sinistro

     

    kkkk mas a calculadora fazia certinho !!!

    Na minha faculdade, no quarto ano tinhamos de fazer um trabalho de PERT, e tinhamos de alimentar o computador grande da faculdade com os dados via cartão perfurado. Entre entregarmos os dados e o resultado sair, demoravam 2 dias ! Eu tinha uma HP-41Cv e a impressora dela,  e resolvi fazer o programa nela. Após algumas horas, o programa saiu e deu certo, mas demorava pouco mais de uma hora para processar tudo e finalmente imprimir os resultados...

    No dia seguinte levei na faculdade, e no mesmo dia vários colegas copiaram o programa  para as calculadoras deles, e toda a classe conseguiu fazer o trabalho nesse unico dia, com um total de 7 calculadoras rodando durante umas 9 horas ....

     

    Como você disse, os cálculos podem ser bem lentos em sistemas de 4 e 8 bits, mas é bem mais rápido do que fazermos nós mesmos esses cálculos !

     

    26 minutos atrás, _xyko_ disse:


    Posso, sem vergonha de falar em C, C#, C++.  enfim, reciclagem, mas BASCOM,  kkk é bom

     

     

    Heheheh bem vindo, velho companheiro de Bascom !!! Agora já não me sinto sózinho em extinção, somos dois extintos agora kkkk !

     

    Paulo

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Eu nunca te abandoei...meu amigo. Mas as vezes fico nas sombras.
    Aprendi um pouco (ou +) de C#, C++, e algo mais. Demonstro segundo o que precisarem..

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • Utilizei o Serial.parseFloat como o  Carlos Zanon falou e funcionou. Pelo que li o Serial.parseFloat lê um float ao invés do ASCII.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • O problema agora é que o programa em C que estou fazendo para mandar estes valores não parece estar comunicando corretamente.

     

    #include <stdio.h>
    #include <windows.h>
    #include <conio.h>
    
    HANDLE hSerial;
    wchar_t port[6] = {L"COM3"};
    
    int main() {
    	
    	hSerial = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    	
    	DCB dcbSerialParams = {0};
    	dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    	GetCommState(hSerial, &dcbSerialParams);
    	dcbSerialParams.BaudRate = CBR_9600;
    	dcbSerialParams.ByteSize = 8;
    	dcbSerialParams.StopBits = ONESTOPBIT;
    	dcbSerialParams.Parity = NOPARITY;
    	SetCommState(hSerial, &dcbSerialParams);
    	
    	COMMTIMEOUTS timeouts = {0};
    	timeouts.ReadIntervalTimeout = 50;
    	timeouts.ReadTotalTimeoutConstant = 50;
    	timeouts.ReadTotalTimeoutMultiplier = 10;
    	timeouts.WriteTotalTimeoutConstant = 50;
    	timeouts.WriteTotalTimeoutMultiplier = 10;
    	SetCommTimeouts(hSerial, &timeouts);   
    
    	float comando, temperatura;
    	int menu;
    	
    	while (menu != 27){
    		
    		printf("\n\nQual temperatura você deseja?\n");
    		scanf("%f", &comando);
    		
    		float TxBuff [1];
    		unsigned int TotalBytesaEnviar = 12;
    		unsigned long BytesEnviados;  
    		
    		TxBuff [0] = comando;
    		WriteFile(hSerial, &TxBuff, TotalBytesaEnviar, &BytesEnviados, NULL);
    		
    		float RxBuff [1];
    		unsigned int TotalBytesaReceber = 1;
    		unsigned long BytesRecebidos;
    		
    		ReadFile(hSerial, &RxBuff, TotalBytesaReceber, &BytesRecebidos, NULL);
    		
    		temperatura = RxBuff[0];
    		
    		printf("\n\nTemperatura atual: %f\n", temperatura);
    		
    		printf("\n\nTecle ESC para sair. Outra tecla para reiniciar");
    		menu = getch ();
    	}
    	
    	
    	CloseHandle (hSerial);
    	return 0;
    }

     

    Mesmo enviando valores não acontece nada. E a temperatura recebida está errada. Isso é algum problema com o Serial.parseFloat será?

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Se eu fosse você trabalharia tudo em asc-ii mesmo. A serial se dá bem com asc-ii  e o mc com 8 bits. Além do + geralmente o conversor ad do mc é de 10bits o que nos leva a considerar a trabalhar com no máximo variáveis tipo int (16 bits).

    Do lado do mc, dá uma olhadela como trabalhar direto com os registros do hw dele. Ou se tiver tempo e não se importar com a

    15 horas atrás, aphawk disse:

    questão de velocidade mais lenta

    e quiser ficar só "na" sw aguarde alguma iluminação.

    Ok concordo que a "moleza" do sw pode deixar mais rápida a solução de problemas mas atrofia os músculos mentais

    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

     

    4 horas atrás, jbiribi disse:

    O problema agora é que o programa em C que estou fazendo para mandar estes valores não parece estar comunicando corretamente.

    Eu tinha um programa meu em C# perdido aqui no meu micro com .net 4 que abre porta serial e envia... usava pra fazer esses testes ai... acabei de subir ele no github... veja se te ajuda... qualquer coisa avisa :P https://github.com/carloshenrq/serialport

    adicionado 8 minutos depois
    47 minutos atrás, Isadora Ferraz disse:

    Se eu fosse você trabalharia tudo em asc-ii mesmo. A serial se dá bem com asc-ii  e o mc com 8 bits. Além do + geralmente o conversor ad do mc é de 10bits o que nos leva a considerar a trabalhar com no máximo variáveis tipo int (16 bits).

     

    É... pouco tempo atrás eu fiz da seguinte forma: fazia todo o processo com int mesmo... fixava um numero de casas... tipo pra 3 casas decimais eu usava formato '999999' por exemplo dai já sabia que os 3 últimos são as casas decimais... trabalhava com o valor e depois retornava da mesma forma pela serial... era só tratar... dividir por 1000  quando chegava no programa do PC no caso... e funciona que é uma beleza...

     

    Tenho uma rotina de arredondamento com 10 casas decimais que faço dessa forma ai também (por causa da ABNT NBR 5891:2014) e achei mais simples implementar usando inteiros.

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • 5 horas atrás, Carlos Zanon disse:

     

    Eu tinha um programa meu em C# perdido aqui no meu micro com .net 4 que abre porta serial e envia... usava pra fazer esses testes ai... acabei de subir ele no github... veja se te ajuda... qualquer coisa avisa :P https://github.com/carloshenrq/serialport

    adicionado 8 minutos depois

    É... pouco tempo atrás eu fiz da seguinte forma: fazia todo o processo com int mesmo... fixava um numero de casas... tipo pra 3 casas decimais eu usava formato '999999' por exemplo dai já sabia que os 3 últimos são as casas decimais... trabalhava com o valor e depois retornava da mesma forma pela serial... era só tratar... dividir por 1000  quando chegava no programa do PC no caso... e funciona que é uma beleza...

     

    Tenho uma rotina de arredondamento com 10 casas decimais que faço dessa forma ai também (por causa da ABNT NBR 5891:2014) e achei mais simples implementar usando inteiros.

     

    Estou engatinhando em C ainda, ou seja, não entendi muita coisa do C#. Mesmo assim obrigado pela ajuda hehe.

     

    Tentarei ir pro lado do ASCII como vocês falaram. Só tenho que aprender como converter, porque não sei se entendi bem o que você falou, sobre fixar casas e tal. É possível usar casas decimais no int?

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    @jbiribi Não é possível trabalhar com casas decimais em int. Você pode programar da seguinte forma:

    O Número 999.999 equivale a 999999 em int ou até mesmo 10.00 equivale a 1000... tire as casas decimais e trabalhe com ela em int... Come menos ram e espaço :P

    adicionado 2 minutos depois

    Eu uso algo parecido com isso aqui:

    int converterInt(float fValor, int iCasas)
    {
    	return floor(fValor * (pow(10, iCasas)));
    }

    O Programa em C# que postei é só pra compilar... compila e usa ele pra enviar e receber os dados...

    adicionado 5 minutos depois

    Dai usando a função ai..

    converterInt(10.99, 2) // vai retornar 1099

     

    Dependendo do teu uso, pode resolver o problema... só tome cuidado com valores muito altos, nesse caso ai vai dar overflow de limite se for valor acima de 2147483647 (ou 32767? não me recordo agora) se não me engano :P

    adicionado 9 minutos depois

    Se precisar de valores maiores, você pode apelar pra usar 2 variaveis...

    Tem um post meu aqui

    Que eu faço uso em algumas coisas pra não estourar alguns limites e poder usar os valores normalmente...

    Editado por Carlos Zanon

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Permita-me...

    Em c só a simples presença do . já vai subtender que existe um float e qualquer operação que fizer ( p.ex. converterInt(10.99, 2) ou i*=12.45) já vai comer um baita recurso.

    No antigo c, nativamente um unsigned int só pode ir até 65535

     

    Digamos que você queria transmitir um resultado do conversor ad 1234 pro terminal e nele quer que apareça 12,34 veja o que eu (eu) faria algo como...

    i=1234;
    putc((i%10)+0x30);//converte pra asc-ii "4"
    i/=10;
    putc((i%10)+0x30); //"3"
    putc(',');//","
    i/=10;
    putc((i%10)+0x30);//"2"
    i/=10;
    putc((i%10)+0x30);//"1"

    É só um conceito pra perceberes as alternativas pra trabalhar com inteiros e asc-ii. De fato nem sei se dá certo. Faça 1 teste e retorne, se achar que deve...

    • Curtir 1

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Minha amiga, o que seria o erro?

     

     

    Só quero aprender.

    puyt.jpg

    Editado por _xyko_

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • 1 hora atrás, Carlos Zanon disse:

    O Programa em C# que postei é só pra compilar... compila e usa ele pra enviar e receber os dados...

     

    É que esse projeto tem que ser em C, senão usaria o C# sem problemas.

     

    Consegui entender agora sobre as casas decimais e trabalhar elas como número inteiro. A dúvida agora é: como fazer o arduino receber esse número sem que ele veja o ASCII separado de cada um deles?? 

    Dei uma lida e vi que subtraindo 0 ele converte esse ASCII pra número real no arduino, mas continua vendo tudo separado. Em alguns lugares falava para colocar em uma string e depois converter pra um número. 

     

     

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    52 minutos atrás, Isadora Ferraz disse:

    Permita-me...

    Em c só a simples presença do . já vai subtender que existe um float e qualquer operação que fizer ( p.ex. converterInt(10.99, 2) ou i*=12.45) já vai comer um baita recurso.

    No antigo c, nativamente um unsigned int só pode ir até 65535

     

    Eu faço isso antes de enviar :P Só um exemplo algoritmo se não ia consumir muito do mcu

    Eu já envio os 1099 faço os calculos e vamos dizer que ele retorne 3000 depois da conta, eu só retorno os 3000 pela serial... faço tudo via int... depois que o programa no PC le os 3000, ele mesmo faz a conversão pra 30.00

     

    adicionado 1 minuto depois
    11 minutos atrás, jbiribi disse:

    A dúvida agora é: como fazer o arduino receber esse número sem que ele veja o ASCII separado de cada um deles??

     

    https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/

     

     

    Editado por Carlos Zanon

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
  • Autor do tópico
  • 27 minutos atrás, Carlos Zanon disse:

    Eu faço isso antes de enviar :P Só um exemplo algoritmo se não ia consumir muito do mcu

    Eu já envio os 1099 faço os calculos e vamos dizer que ele retorne 3000 depois da conta, eu só retorno os 3000 pela serial... faço tudo via int... depois que o programa no PC le os 3000, ele mesmo faz a conversão pra 30.00

     

    adicionado 1 minuto depois

     

    https://www.arduino.cc/reference/en/language/functions/communication/serial/parseint/

     

     

     

    Com Serial.parseInt() no arduino funciona perfeitamente, mas pelo programa em C nada acontece.

     

    #include <stdio.h>
    #include <windows.h>
    #include <conio.h>
    #include <stdlib.h>
    
    HANDLE hSerial;
    wchar_t port[6] = {L"COM3"};
    
    int main() {
    	
    	hSerial = CreateFile("COM3", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    	
    	DCB dcbSerialParams = {0};
    	dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    	GetCommState(hSerial, &dcbSerialParams);
    	dcbSerialParams.BaudRate = CBR_9600;
    	dcbSerialParams.ByteSize = 8;
    	dcbSerialParams.StopBits = ONESTOPBIT;
    	dcbSerialParams.Parity = NOPARITY;
    	SetCommState(hSerial, &dcbSerialParams);
    	
    	COMMTIMEOUTS timeouts = {0};
    	timeouts.ReadIntervalTimeout = 50;
    	timeouts.ReadTotalTimeoutConstant = 50;
    	timeouts.ReadTotalTimeoutMultiplier = 10;
    	timeouts.WriteTotalTimeoutConstant = 50;
    	timeouts.WriteTotalTimeoutMultiplier = 10;
    	SetCommTimeouts(hSerial, &timeouts);   
    
    	
    	int comando;
    	int menu;
    	
    	while (menu != 27){
    		
    		printf("\n\nQual temperatura você deseja?\n");
    		scanf("%i", &comando);
    		printf("%i", comando);
    		
    		int TxBuff [1];
    		unsigned int TotalBytesaEnviar = 12;
    		unsigned long BytesEnviados;  
    		
    		TxBuff [0] = comando;
    		WriteFile(hSerial, &TxBuff, TotalBytesaEnviar, &BytesEnviados, NULL);
    		
    		printf("\n\nTecle ESC para sair. Outra tecla para reiniciar");
    		menu = getch ();
    	}
    	
    	
    	CloseHandle (hSerial);
    	return 0;
    }

     

    Editado por jbiribi

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites
    4 horas atrás, _xyko_ disse:

    o que seria o erro?

    puts... putc é pra escrever em arquivo. O erro seria que era pra especificar o byte e o arquivo destino.

    Tente putchar. Este deve enviar byte pra serial.

    Mals:oops:

    Compartilhar este post


    Link para o post
    Compartilhar em outros sites

    Crie uma conta ou entre para comentar

    Você precisar ser um membro para fazer um comentário






    Sobre o Clube do Hardware

    No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

    Direitos autorais

    Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

    ×