Janela Processing -Valores do Arduino

Olá a todos.

Estou a ter um problema para mostrar os valores da Temperatura numa janela no Processing

No Arduino tenho como um exemplo, neste caso, o seguinte código:

    if(tempC <= 22.0)
    {
      Serial.print(tempC, 1);
      Serial.print("\t");
      Serial.print(tempK, 1);
      Serial.print("\t");
      Serial.print(tempF, 1);
      Serial.print("\t");
      Serial.println("Alarme!" );
    }

No software Processing estou a conseguir gravar para um bloco de notas neste formato:

    2013/8/28    16:31:52    25.6    298.7    78.1
    2013/8/28    16:31:53    25.9    299.1    78.7
    2013/8/28    16:31:54    25.9    299.1    78.6

Mas quando mostro a string sensorReading numa janela, aparece desta forma:
25.9299.178.6

Está a mostrar a Temperatura em ºC, Kelvin e ºF coladas uma à outra.

No Processing estou a utilizar o seguinte código:

import processing.serial.*;
    Serial myPort;
    String sensorReading="";
    PFont font;
    PrintWriter output;

    void setup()
    {
      size(600, 300);
      myPort = new Serial(this, "COM4", 9600);
      myPort.bufferUntil('\n');
      font = createFont(PFont.list()[4], 36);
      textFont(font);
      output = createWriter( "C:/Users/alunosdefi/Desktop/data.txt" );
    }


    void draw()
      {
      } 

    void serialEvent (Serial myPort)
    {
     sensorReading= myPort.readStringUntil('\n');
     
      if(sensorReading != null) 
      { 
       sensorReading=trim(sensorReading);
      }

      output.println(year() + "/" + month() + "/" + day() + "\t" + hour() + ":" + minute() + ":" + second() + "\t" + sensorReading);
      output.flush();
     
     writeText("Temperatura:  " + sensorReading + " ºC");
    }
     
    void writeText(String textToWrite)
     {
      background(180);  
      fill(127,0,0);
      text(textToWrite, width/20, height/2);  
     }

Alguém me sabe dizer como consigo mostrar apenas a temperatura em ºC na janela?

Penso que o código chave é este:

 sensorReading= myPort.readStringUntil('\n');
     
      if(sensorReading != null) 
      { 
       sensorReading=trim(sensorReading);
      }

e depois vou buscar a variável a ser imprimida aqui:

 writeText("Temperatura:  " + sensorReading + " ºC");

Um dos métodos que fiz e deu foi criar no ínicio a variavel:

String imprimir="";

e antes de imprimir o código chave anterior coloquei o seguinte código:

imprimir =myPort.readStringUntil('\t');
   if(imprimir != null) 
  {  
   imprimir=trim(imprimir); 
   writeText("Temperatura:  " + imprimir + " ºC");
  }

A questão aqui é que tenho de imprimir duas vezes a temperatura em ºC no código do Arduino, visto que a lê apenas até o primeiro tab - "/t", porque senão a temperatura em ºC não aparecia no bloco de notas.
Mas o problema maior é tbm que depois na janela não aparece a String "ALARME!" sempre que a TempC < 22 ºC...

Alguma sugestão??

Cumprimentos,

Pedro

Porque nao apenas uma flag para marcares que tens alarme em vez de passares a string ALARME!
Tambem nao necessitas de passar o valor da temperatura em celcius e em kelvin podes apenas passar a temperatura em celsius e depois converter no processing para kelvin com uma simples conta.

{
Serial.print(tempC, 1);
Serial.print("\t");
Serial.print(tempK, 1);
Serial.print("\t");
Serial.print(tempF, 1);
Serial.print("\t");
Serial.println("Alarme!" );
}

Isto sao demasiados bytes a passar para dizer o mesmo, valor da temperatura ...

Depois na Base de dados terei a tabela com 6 colunas:

    DATA   |    HORA  |    Temperatura ºC    |    Temperatura K   |   Temperatura ºF    |   Estado    |
2013/8/28  | 16:31:52 |         25.6         |         298.7      |          78.1       |             |
2013/8/28  | 16:31:53 |         33.0         |         306.1      |          82.7       |   Alarme!   |
2013/8/28  | 16:31:54 |         25.9         |         299.1      |          78.6       |             |

Pelo que podia fazer então no Arduino era só imprimir a temperatura em ºC e a palavra Alarme!

Ficando depois desta forma na tabela:

    DATA   |    HORA  |    Temperatura ºC    |    Estado  |
2013/8/28  | 16:31:52 |         25.6         |            |
2013/8/28  | 16:31:53 |         33.0         |    Alarme! |
2013/8/28  | 16:31:54 |         25.9         |            |

Poderia então depois converter a string lida até o "/t" para float, e ficava com o valor por exemplo o ultimo lido, os 25.9.

Depois passava a string com o valor 25.9 para float.
Depois sim poderia converter esse float que estaria em ºC para K e ºF.
e imprimia depois esses valores no bloco de notas tbm!
Concordam com a ideia?

Assim de repente acho k para ler a string, que pelo exemplo que iniciei o tópico e sem as conversões, mas numa situação de alarme

(Serial.print(tempC, 1);
Serial.print("\t");
Serial.println("Alarme!" );

viria desta forma:
29.2Alarme!

Ou seja, acho que se fizesse:

sensorReading= myPort.readString(); //Lia o que estava a imprimir no serial monitor do Arduino
sensorReadingT= myPort.readStringUntil(´\t´)  //Iria ler até o "\t" imprimido, ou seja a string 29.2)
sensorReadingT=float(sensorReadingT); // converte a string 29.2 para float

float tempK=sensorReadingT + 273.15;
...

depois acho k se imprimisse:

output.println(year() + "/" + month() + "/" + day() + "\t" + hour() + ":" + minute() + ":" + second() + "\t" + sensorReading + "\t" + tempK + "\t" + tempF);

Iria ter a tabela que pretendia a gravar

Pesquisei tbm que na propria string que imprimi quando iniciei o tópico que poderia usar a função split() para retirar a string até o valor que pretendia, algo como este exemplo:

String mystring = myPort.readString();
String parts[] = mystring.split("[\t]");
println(parts);

Consideram que quantos menos bytes ler pela porta série melhor será? (menos imprimir no serialmonitor do Arduino?

*PS: a Temperatura será medida de 15 em 15 minutos

A mim parece-me que o '\t' não está a ser processado...

Sim, quanto menos bytes mandares pela porta série melhor para o Arduino e para o teu computador.

eu modifiquei o código que tinha.
Neste momento defini no inicio as variáveis:

String sensorReading="";
String imprimir="";

float tempK=0;
float tempF=0;

Este foi o código que eu alterei:

void serialEvent (Serial myPort)
{ 

imprimir =myPort.readStringUntil('\t'); because i do Serial.print(tempC) and after ("\t)
   if(imprimir != null) 
  {  
   imprimir=trim(imprimir); //imprimir is the value of temperature in ºC
 }
  
 tempK= Float.parseFloat(imprimir) + 275.15; //Converter to Kelvin

tempF= 1.8 * Float.parseFloat(imprimir) + 32; // Converter to ºF

String tempF1= nfc(tempF, 1); // i find this code in Processing Forum to print with only one decimal

String tempK1= String.format("%.1f", tempK); // i find this code too in other site
  
sensorReading= myPort.readStringUntil('\n'); //Read the ºC, "/t" and the word Alarme! (if temp>X or temp<Y)
 if(sensorReading != null)
  {  
   sensorReading=trim(sensorReading);
  }

No Arduino eu só estou a fazer o Serial.print de temperatura em º C, e no Processing estou a converter a mesma para Kelvin e Fahrenheit.
Estou a imprimir para o bloco de notas desta forma:

( imprimir + "\t" + sensorReading + "\t" + tempK1 + "\t" + tempF1)

Há apenas um problema

Está a imprimir a separação das casas decimais da temperatura K e ºF com virgula em vez de ponto.
exemplo:

2013/8/29	18:39:30	25.7		300,9	78,3
2013/8/29	18:39:31	25.6		300,8	78,1
2013/8/29	18:39:32	25.6		300,8	78,1
2013/8/29	18:39:33	25.6		300,8	78,1
2013/8/29	18:39:34	25.6		300,8	78,1
2013/8/29	18:39:35	25.6		300,8	78,1

Com os dois códigos que encontrei, vi que ambos imprimem o valor de K e temperatura F º a virgula de separação decimal ..
alguma sugestão?

Obrigado!!!

Normalmente ler a documentação das funções que usas ajuda imenso...

Ajuda ainda mais ver que a conversão de temperatura está errada (300 Fahrenheit são 150 celsius) e perceber porquê. Ordem errada...

Já pensaste em mudar as settings do teu computador? Quando vais ao Excel, podes usar pontos como sinal decimal? Ou só virgulas?

No excel para construir gráficos por exemplo, tenho de utilizar ponto (.)!

No caso prático em questão irá construir o gráfico com a coluna 3, com a Temperatura em ºC, na qual já tenho o ponto (.) a separar a unidade da casa decimal, pelo que a temperatura em K e ºF não seria relevante neste caso, mas em termos de apresentação, gostaria que tivessem todas as temperaturas no mesmo formato!!

Contudo acho estranho esta situação.
Sem utilizar essas funções aparecem-me os números com o ponto (.), mas com mais casas decimais.
Pesquisei funçoes para limitar as casas decimais, pois só pretendia uma, daí ter recorrido a essas funções! ambas apresentam realmente só com uma casa decimal, mas trocaram o ponto pela virgula.

Se mais alguem tiver alguma sugestão agradeço.

Obrigado!

Resultou com este código:

tempK= Float.parseFloat(imprimir) + 273.15; // Conversão para Kelvin
 tempF= 1.8 * Float.parseFloat(imprimir) + 32; // Conversão para ºFahrenheit
  
  DecimalFormat decimal = new DecimalFormat("0.0");  

    String tempK1 = decimal.format(tempK);
    tempK1 = tempK1.replaceAll(",", "."); // Troca da , por .


    String tempF1= decimal.format(tempF); //Passagem do valor para String
    tempF1 = tempF1.replaceAll(",", "."); // Troca da , por .

Tendo como resultado:

2013/8/30	15:9:53	17.0	Alarme!	290.1	62.6
2013/8/30	15:9:54	17.1	Alarme!	290.2	62.8
2013/8/30	15:9:55	17.1	Alarme!	290.2	62.8
2013/8/30	15:9:56	17.1	Alarme!	290.2	62.8
2013/8/30	15:9:57	17.1	Alarme!	290.2	62.8
2013/8/30	15:9:58	17.1	Alarme!	290.2	62.8
2013/8/30	15:9:59	17.1	Alarme!	290.2	62.8

Mesmo tendo definido o formato como 0.0 ele não grava com o ponto, mas com a virgula, sendo necessário efetuar a troca da , por . na função replaceAll()

Cumprimentos e obrigado pelas dicas!!