Getting data from a DS18B20 temp sensor

Hi everyone,

I’m trying to integrate tabs into my code and I want to read a few waterproof temp sensors. I want to show the temperature as a sliding scale bar and I think I’m close, I have a DS18B20 in Pin 2 on my Arduino uno. When I run my sketch the box that I want shows up, however I’m not getting temperature. I ran an Arduino code that verifies the thermometer is working, so I’m assuming the error in my code has to do with getting the data from the sensor. I’m still learning so I’m not entirely sure what I need to add to get a connection to the sensor. Thanks!

Here is my sketch:

import processing.serial.*;

import cc.arduino.*;
import org.firmata.*;

Serial myPort;
PFont font; 

Temp temp1;
Temp temp2;

Arduino arduino;

float temp = 0;

public void setup() {
  size(800,400);
  
  arduino = new Arduino(this, "COM3", 57600);
  
  arduino.pinMode(2, Arduino.OUTPUT);
  arduino.pinMode(7, Arduino.OUTPUT);
  
  font = createFont("font", 16);
  textFont(font);
 
  temp1 = new Temp(200, 0, 100, 100, "Temp C");
  temp2 = new Temp(200, 0, 100, 100, "Temp C");
}

public void draw() {
  background(#310FF7);
 
  temp1.displayTemp();
  temp1.setSensorValue(temp);
  
  temp2.displayTemp();
  temp2.setSensorValue(temp);
}

public void serialEvent(Serial myPort) {
  String myString = myPort.readStringUntil('\n');
  if(myString != null){
    myString = trim(myString);
    int sensorData[] = int(split(myString, ','));
    temp = sensorData[0];
  }
}
 

and this is my class for temp:

class Temp {
  
  float sensorValue;
  float threshold; 
  String text; 
  int x;
  int y;
  int d;
  
  Temp(int x, int y, int d, float threshold, String text) {
    this.x = x;
    this.y = y;
    this.d = d;
    this.threshold = threshold; 
    this.text = text;
  }
  void setSensorValue(float sensorValue) {
    this.sensorValue = sensorValue;
  }
  
  void displayTemp() {
    noStroke();
    fill(255, 255, 255);
    rect(this.x, this.y, this.d, 100);
    
    float mappedSensorValue = map(sensorValue, -20, threshold, 0, 100); 
    
    //noStroke();
    
      rect(this.x, 200-mappedSensorValue, this.d, 100);
      
      if(this.sensorValue >= 0 && this.sensorValue < (this.threshold * 0.25)) {
        fill(#11F5C9);
      } else if(this.sensorValue >= (this.threshold * 0.25) && this.sensorValue < (0.50 * this.threshold)) {
        fill(#23F511);
      } else if(this.sensorValue >= (this.threshold * 0.50) && this.sensorValue < (0.75 * this.threshold)) {
        fill(#F1FF36);
      } else { 
        fill(#F51130);
      }
      
      textSize(35);
      text(int(sensorValue), 305, 200);
      textSize(25);
      text(char(176) + text, 365, 200);
  }
}
      
      

When things don’t go as planned one approach is to temporarily forget about the project and write very simple code that sends and receives data. When I get that working then I incorporate it into the project.

For example, can you get this to work:

Processing code:

import processing.serial.*;

Serial myPort;    // The serial port
String inStr;    // Input string from serial port
int lf = 10;    // ASCII linefeed
float x, y;

void setup() {
  surface.setVisible(false); // Output is in console at bottom of editor
  // List all the available serial ports:
  printArray(Serial.list());
  // Enter device number for your system
  myPort = new Serial(this, Serial.list()[4], 9600);
  myPort.bufferUntil(lf);
}

void draw() {
}

void serialEvent( Serial myPort) {
  //'\n' (line feed) is delimiter indicating end of packet
  inStr = myPort.readStringUntil('\n');
  //make sure our data isn't empty before continuing
  if (inStr != null) {
    //trim whitespace and formatting characters (like carriage return and/or line feed)
    inStr = trim(inStr);  //Data is sent as a string
    println("inStr = ", inStr);
    String[] myData = split(inStr, ','); // String is split into array at comma
  //  printArray(myData);
    x = Float.valueOf(myData[0]); // Array elements are converted back to floats
    println("x = ", x);
    y = Float.valueOf(myData[1]);
    println("y = ", y);
  }
}

Arduino code:

int randNumber[2];

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

void loop() {
  // print a random number from 0 to 299
  randNumber[0] = random(300);
  Serial.print(randNumber[0]);
  Serial.print(','); // Comma separated values
  // print a random number from 10 to 19
  randNumber[1] = random(10, 20);
  Serial.println(randNumber[1]); // line feed terminated
  delay(50);
}

Hi @bkeith. I have several DS18B20 on the side of my hot-water tank and connected to an Arduino Nano. There are lots of tutorials e.g. Arduino and DS18b20. Maybe you’ve done that already “I ran an Arduino code that verifies the thermometer is working”. This is the usual way using a driver that knows the protocol for DS18B10.

Firmata is a general purpose way of controlling the Ard’s i.o. and knows nothing about the DS18B20 protocol. (Last time I looked, which was a few years ago.) If you were up for a challenge you might be able to create a special Firmata with calls to DS18B20 code. Then add an object for it in a modified Processing Ard library. (See how the servo is constructed in both.) I don’t know how to do all that.

Much easier to you use your working Ard+DS18B20 sketch. Make it Serial.print the temperature(s). Then use @svan’s code to read the print and interpret it back to numeric data.