Ir ao conteúdo

Posts recomendados

Postado

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);
  }
}
}

 

  • Membro VIP
Postado

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...

Postado
  Em 07/12/2017 às 11:12, 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...

Expandir  

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. 

  • Membro VIP
Postado

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.

Postado
  Em 07/12/2017 às 15:52, jbiribi disse:

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

Expandir  

 

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
  Em 07/12/2017 às 15:52, 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. 

Expandir  

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
		{
		}
	}

 

  • Membro VIP
Postado
  Em 07/12/2017 às 11:12, Isadora Ferraz disse:

fazer algum tipo de conversão

Expandir  

 

  Em 07/12/2017 às 17:48, Carlos Zanon disse:

você precisa tratar antes...

Expandir  

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
Postado
  Em 07/12/2017 às 18:27, Isadora Ferraz disse:

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

Expandir  

 

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
  • Membro VIP
Postado

 

  Em 07/12/2017 às 18:52, aphawk disse:

dá para usar float tranquilamente

Expandir  

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

 

 

Postado
  Em 07/12/2017 às 22:42, 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

Expandir  

 

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 !

 

  Em 07/12/2017 às 22:58, _xyko_ disse:


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

 

Expandir  

 

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

 

Paulo

Postado

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á?

  • Membro VIP
Postado

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

  Em 07/12/2017 às 18:52, aphawk disse:

questão de velocidade mais lenta

Expandir  

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
Postado

 

  Em 08/12/2017 às 06:32, jbiribi disse:

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

Expandir  

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
  Em 08/12/2017 às 10:31, 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).

 

Expandir  

É... 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.

Postado
  Em 08/12/2017 às 11:18, 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.

Expandir  

 

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?

Postado

@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...

  • Membro VIP
Postado

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
Postado
  Em 08/12/2017 às 16:42, Carlos Zanon disse:

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

Expandir  

 

É 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. 

 

 

Postado
  Em 08/12/2017 às 18:02, 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

 

Expandir  

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
  Em 08/12/2017 às 18:42, 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??

Expandir  

 

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

 

 

Postado
  Em 08/12/2017 às 18:51, 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/

 

 

Expandir  

 

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;
}

 

  • Membro VIP
Postado
  Em 08/12/2017 às 18:26, _xyko_ disse:

o que seria o erro?

Expandir  

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:

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

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

Mostrar 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

Mostrar mais  
×
×
  • Criar novo...