Singletact reading data (arduino)


#1

Hey guys,

i need help again :wink:

How can i convert the Sensor Data Readings like (256) to 0,5V automatic or to Force with Arduino ???

in datasheet of this Sensor says that from 256 to 511 ist = from 0,5 to 1,5 V (look pic)

then i want to convert the Sensor Data Readings to Pressure but im getting 0,0 why ??

this ist the code

#include "DHT.h"
#include <SD.h>
#include <SPI.h>
#define DHTTYPE DHT22
const int DHTPin = 2;     // what digital pin we're connected to
DHT dht(DHTPin, DHTTYPE);
float Pressure;
#include <Wire.h> //For I2C/SMBus
File myFile;

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
  //TWBR = 12; //Increase i2c speed if you have Arduino MEGA2560, not suitable for Arduino UNO
  Serial.begin(9600);  // start serial for output
  Serial.flush();
   Serial.println("CLEARSHEET");
  Serial.println("LABEL,Date,Time,,Humidity [%],Temperatur [*C],,, Sensor_Data, Pressure [mmHg]");

  // SD Card Initialization
  if (SD.begin(10))
  {
    Serial.println("SD card is ready to use.");
  } else
  {
    Serial.println("SD card initialization failed");
    return;
  }

  //Write myFile Header
  File myFile = SD.open("st.txt", O_CREAT | O_TRUNC | O_WRITE);
  if (myFile)
  {
    String header = "Humidity [%],Temperatur [°C],,, Sensor_Data, Pressure [mmHg]";
    myFile.println(header);
    myFile.close();
    Serial.println(header);
  } else {
    Serial.println("error opening st.txt");
  }
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("PPS UK: SingleTact sensor value in PSI. \n(resembles PC executable display)");
  Serial.println("Refer manual for any other calculation.");
  Serial.println("----------------------------------------");  
  dht.begin();
}

void loop()
{
  ////////////   Reading temperature or humidity  //////////////
  float h = dht.readHumidity();
  float t = dht.readTemperature();

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  Serial.print("Humidity [%]: ");
  Serial.print(h);
  Serial.print("Temperatur [°C]:");
  Serial.print(t);
  Serial.println("");

//ST//
    byte i2cAddress = 0x04; // Slave address (SingleTact), default 0x04
    short data = readDataFromSensor(i2cAddress);
    Serial.print("Sensor_Data:");
    Serial.println(data);    

    //S8 A= 50.265mm^2 // S8 A= 176.715mm^2
    // Pressure = (data/512) * 1/A = N/mm2 = (N/mm^2)*7500.63755 = mmHg
    Pressure = ((data/512)/176.715)*7500.63755;
    Serial.print("Pressure in mmHg: ");
    Serial.println(Pressure);
    
    
    File myFile = SD.open("st.txt", FILE_WRITE);
 
  if (myFile) {

    myFile.print(h);
    myFile.print(",");
    myFile.print(t);
    myFile.print(",");
    myFile.print(",");
    myFile.print(",");
    myFile.print(data);
    myFile.print(",");
    myFile.println(Pressure);
    myFile.close();

  } else {
    Serial.println("error opening st.txt");
  }
  
  Serial.print("DATA,DATE,TIME," + String() + "," + String(h) + "," + String(t) + "," + +"," +  + "," + String(data) + "," + String(Pressure));
  Serial.println();
  Serial.println("--------------------");
  delay(1000); // Change this if you are getting values too quickly 
}


short readDataFromSensor(short address)
{
  byte i2cPacketLength = 6;//i2c packet length. Just need 6 bytes from each slave
  byte outgoingI2CBuffer[3];//outgoing array buffer
  byte incomingI2CBuffer[6];//incoming array buffer

  outgoingI2CBuffer[0] = 0x01;//I2c read command
  outgoingI2CBuffer[1] = 128;//Slave data offset
  outgoingI2CBuffer[2] = i2cPacketLength;//require 6 bytes

  Wire.beginTransmission(address); // transmit to device 
  Wire.write(outgoingI2CBuffer, 3);// send out command
  byte error = Wire.endTransmission(); // stop transmitting and check slave status
  if (error != 0) return -1; //if slave not exists or has error, return -1
  Wire.requestFrom(address, i2cPacketLength);//require 6 bytes from slave

  byte incomeCount = 0;
  while (incomeCount < i2cPacketLength)    // slave may send less than requested
  {
    if (Wire.available())
    {
      incomingI2CBuffer[incomeCount] = Wire.read(); // receive a byte as character
      incomeCount++;
    }
    else
    {
      delayMicroseconds(10); //Wait 10us 
    }
  }

  short rawData = (incomingI2CBuffer[4] << 8) + incomingI2CBuffer[5]; //get the raw data

  return rawData;
}

thanks


#2

@Aiman This is a community forum for Particle not Arduino!

then i want to convert the Sensor Data Readings to Pressure but im getting 0,0 why ??

IMHO the problem is here Pressure = ((data/512)/176.715)*7500.63755; If data is < 512 then data/512 will return 0 (using integer maths?). Try Pressure = (((float) data/512)/176.715)*7500.63755; or Pressure = ((data/512.0)/176.715)*7500.63755; Better still resolve out the constants to Pressure = (float) data * 0.08290005;


#3

You asked me the exactly same thing in a PM and there you got the answer a few hours before the answer here.
It is not appreciated to post the same question in multiple places (including PMs) since it ties down resources of multiple people for no extra benefit.

Since there were some other points addressed in the PM thread, I’ll make it public below.


#4

https://community.particle.io/t/fsr-code-with-excel-plx-daq/44795/26

Hey guys,

i need help again :wink:

How can i convert the Sensor Data Readings like (256) to 0,5V automatic or to Force with Arduino ???

in datasheet of this Sensor says that from 256 to 511 ist = from 0,5 to 1,5 V (look pic)

then i want to convert the Sensor Data Readings to Pressure but im getting 0,0 why ??

this ist the code

#include “DHT.h”
#include <SD.h>
#include <SPI.h>
#define DHTTYPE DHT22
const int DHTPin = 2; // what digital pin we’re connected to
DHT dht(DHTPin, DHTTYPE);
float Pressure;
#include <Wire.h> //For I2C/SMBus
File myFile;

void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
//TWBR = 12; //Increase i2c speed if you have Arduino MEGA2560, not suitable for Arduino UNO
Serial.begin(9600); // start serial for output
Serial.flush();
Serial.println(“CLEARSHEET”);
Serial.println(“LABEL,Date,Time,Humidity [%],Temperatur [*C], Sensor_Data, Pressure [mmHg]”);

// SD Card Initialization
if (SD.begin(10))
{
Serial.println(“SD card is ready to use.”);
} else
{
Serial.println(“SD card initialization failed”);
return;
}

//Write myFile Header
File myFile = SD.open(“st.txt”, O_CREAT | O_TRUNC | O_WRITE);
if (myFile)
{
String header = “Humidity [%],Temperatur [°C], Sensor_Data, Pressure [mmHg]”;
myFile.println(header);
myFile.close();
Serial.println(header);
} else {
Serial.println(“error opening st.txt”);
}

while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.println(“PPS UK: SingleTact sensor value in PSI. \n(resembles PC executable display)”);
Serial.println(“Refer manual for any other calculation.”);
Serial.println("----------------------------------------");
dht.begin();
}

void loop()
{
//////////// Reading temperature or humidity //////////////
float h = dht.readHumidity();
float t = dht.readTemperature();

if (isnan(h) || isnan(t)) {
Serial.println(“Failed to read from DHT sensor!”);
return;
}

Serial.print(“Humidity [%]: “);
Serial.print(h);
Serial.print(“Temperatur [°C]:”);
Serial.print(t);
Serial.println(””);

//ST//
byte i2cAddress = 0x04; // Slave address (SingleTact), default 0x04
short data = readDataFromSensor(i2cAddress);
Serial.print(“Sensor_Data:”);
Serial.println(data);

//S8 A= 50.265mm^2 // S8 A= 176.715mm^2
// Pressure = (data/512) * 1/A = N/mm2 = (N/mm^2)*7500.63755 = mmHg
Pressure = ((data/512)/176.715)*7500.63755;
Serial.print("Pressure in mmHg: ");
Serial.println(Pressure);


File myFile = SD.open("st.txt", FILE_WRITE);
if (myFile) {

myFile.print(h);
myFile.print(",");
myFile.print(t);
myFile.print(",");
myFile.print(",");
myFile.print(",");
myFile.print(data);
myFile.print(",");
myFile.println(Pressure);
myFile.close();
} else {
Serial.println(“error opening st.txt”);
}

Serial.print(“DATA,DATE,TIME,” + String() + “,” + String(h) + “,” + String(t) + “,” + +"," + + “,” + String(data) + “,” + String(Pressure));
Serial.println();
Serial.println("--------------------");
delay(1000); // Change this if you are getting values too quickly
}

short readDataFromSensor(short address)
{
byte i2cPacketLength = 6;//i2c packet length. Just need 6 bytes from each slave
byte outgoingI2CBuffer[3];//outgoing array buffer
byte incomingI2CBuffer[6];//incoming array buffer

outgoingI2CBuffer[0] = 0x01;//I2c read command
outgoingI2CBuffer[1] = 128;//Slave data offset
outgoingI2CBuffer[2] = i2cPacketLength;//require 6 bytes

Wire.beginTransmission(address); // transmit to device
Wire.write(outgoingI2CBuffer, 3);// send out command
byte error = Wire.endTransmission(); // stop transmitting and check slave status
if (error != 0) return -1; //if slave not exists or has error, return -1
Wire.requestFrom(address, i2cPacketLength);//require 6 bytes from slave

byte incomeCount = 0;
while (incomeCount < i2cPacketLength) // slave may send less than requested
{
if (Wire.available())
{
incomingI2CBuffer[incomeCount] = Wire.read(); // receive a byte as character
incomeCount++;
}
else
{
delayMicroseconds(10); //Wait 10us
}
}

short rawData = (incomingI2CBuffer[4] << 8) + incomingI2CBuffer[5]; //get the raw data

return rawData;
}

senor%20data


#5

That’s a lot of code I’d need to plough through to find the place you are refering to and due to the missing indetation following that code is also harder than need be.

Also which sensor are you refering to?
The DHT library already provides you with the correct units.

However, when you get a raw reading of one scale and need to translate to another direct proportional scale that’d be Highschool grade maths linear interpolation.

If you were running that code on a Particle device you could use

  value = map((double)rawData, 256.0, 511.0, 0.5, 1.5);

I think Arduino only supports integer map() so you’d have to write your own floating point version like this

double map(double value, double fromStart, double fromEnd, double toStart, double toEnd)
{
    if (fromEnd == fromStart) {
        return value;
    }
    return (value - fromStart) * (toEnd - toStart) / (fromEnd - fromStart) + toStart;
}

(this is linear interpolation)


#6

Hey thanks for our replay,

i use the Singletact Sensor, hier ist the info about code and like that https://github.com/SingleTact

i thing i dow a calibrate curve is better like code

oki i have still a quetion:

why i gott 0,0 from this code:

// Pressure = (data/512) * 1/A = N/mm2 = (N/mm^2)*7500.63755 = mmHg
    float Pressure = ((data/512)/176.715)*7500.63755;
    Serial.print("Pressure in mmHg: ");
    Serial.println(Pressure);

thanks


#7

Since data and 512 are both integers, the parenthesis will be calculated via integer division and given the chance that data is almost always less than 512 the division will always render 0.

To solve that, you should write 512.0 to make one of the operands a floating point number and hence force a floating point division but for the sake of precision you should rearrange your formula in a way to first perform all multiplications and only as a last step the division since divisions always cause loss of information due to the way how floating point numbers are digitally stored.