首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >arduino中浮动变量的精度

arduino中浮动变量的精度
EN

Stack Overflow用户
提问于 2016-02-23 18:31:04
回答 1查看 586关注 0票数 1

我从模拟输入的电压信号(A0引脚)和电流信号(以电压的形式)从模拟输入(A1引脚),将它转换成数字,然后处理它,以获得Vrms,Irms和相位数据。然后我将其存储在"dataString“中,并将其写入SD卡。

我面临的问题是,在功率因数的浮点计算中,我做了一些错误的事情,因为它的答案被“显示为”1.00,而在4.97 (度)的角度上,我应该得到cos(4.97) = 0.9962 (附图) Image1

虽然程序正在使用正确的值,即在进一步的计算中使用0.9962 (实数),但我希望它能够在十进制之后正确地显示功率因数4点。这是我的程序代码

代码语言:javascript
复制
#include <SPI.h>
#include <SD.h>

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;
#include "DHT.h"

#define DHTPIN 8 
#define DHTTYPE DHT21
DHT dht(DHTPIN, DHTTYPE);

#define count 100

const int analogInPin1 = A1;
const int analogInPin0 = A0;

const int chipSelect = 10;

void setup()
{
  Serial.begin(115200);
        Wire.begin();
        RTC.begin();

      if (! RTC.isrunning()) {
        Serial.println("#RTC is NOT running!");
        // following line sets the RTC to the date & time this sketch was compiled
        // uncomment it & upload to set the time, date and start run the RTC!
       // RTC.adjust(DateTime(__DATE__, __TIME__));
      }
  analogReference(DEFAULT);
  Serial.println("#DHTxx test!");

  dht.begin();


  Serial.print("#Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("#Card failed, or not present");
    // don't do anything more:
    return;
  }
  Serial.println("#card initialized.");
  Serial.println("#Date        Time           Vrms          Irms         Phase        Power_factor       Apparent_Power     Real_Power        Humidity         Temperature");


}

void loop()
{


  float sensorValue0[count];        
  float sumSensorValue0=0;
  float meanSensorValue0=0;
  float Vrms=0;
  sumSensorValue0=0;

  float sensorValue1[count];        
  float sumSensorValue1=0;
  float meanSensorValue1=0;
  float Irms=0;
  int i=0;
  sumSensorValue1=0;

  DateTime now = RTC.now();

  for(i=0;i<count;i++)
  {
    sensorValue1[i] = (analogRead(analogInPin1)*4.8)-3200; //4.8 mV (i.e. 0.0048 Volts)  per unit.. Vref/1024.. here Vref = 5 V ....//3.220 V = Offset
    sensorValue0[i] = (analogRead(analogInPin0)*4.8)-3200;

    sensorValue1[i] = sensorValue1[i]*sensorValue1[i];
    sensorValue0[i] = sensorValue0[i]*sensorValue0[i];
    sumSensorValue1+= sensorValue1[i];
    sumSensorValue0+= sensorValue0[i];
  }

  meanSensorValue1 = sumSensorValue1/count;
  meanSensorValue0 = sumSensorValue0/count;
  Irms = (sqrt(meanSensorValue1)*0.06); //60/1000 = 0.06 Calibrating 60 Ampere/1 Volt to give us the value for X amperes
  Vrms = (sqrt(meanSensorValue0)*0.3565); // Multiplying with 356.5(the product of ratios of 9V and 12 V transformer) gives the measured voltage in mV.. dividing by 1000 to bring it to Volts from mV
  float appPower;
  appPower = Vrms*Irms;

float Vsense=0;
float LastVsense=0;
float Isense=0;
float LastIsense=0;
float phase;
float mean_phase=0;
float counter=0;
unsigned long timer;

 for(int i=0;i<200;i++)
  {
  // put your main code here, to run repeatedly:
 Isense=analogRead(A1)*4.8-3200;
 Vsense=analogRead(A0)*4.8-3220;
 if(Vsense>= 0 && LastVsense<0  && Isense<0 )
   { 
  timer = micros();
  do{
    Isense=analogRead(A1)*4.8-3200;
  }while(!(Isense>=0));
    timer = micros()-timer;
    phase = (timer*360.0)/20000.0;
    mean_phase+=phase;
    counter+=1.0;
    }else;

    if(Isense >= 0 && LastIsense < 0  && Vsense < 0 )
   { 
  timer = micros();
  do{
    Vsense=analogRead(A0)*4.8-3200;
  }while(!(Vsense>=0));
    timer = micros()-timer;
    phase = (timer*360.0)/20000.0;
    mean_phase+=phase;
    counter+=1.0;
    }else;

LastIsense = Isense;
LastVsense = Vsense;

}
  mean_phase= mean_phase/counter;


  float realPower;
  float powerFactor;
  float phase_rad= mean_phase*PI/180.0;
  powerFactor =cos(phase_rad); //phase converted to radian for cosine function
  realPower = Vrms*Irms*powerFactor;

   String dataString = "";

  float h = dht.readHumidity();
  float t = dht.readTemperature();

   if (isnan(t) || isnan(h)) {
    Serial.println("#Failed to read from DHT");
  } else {
    dataString+=now.year(), DEC;
    dataString+="/";
    dataString+=now.month(), DEC;
    dataString+="/";
    dataString+=now.day(), DEC;
    dataString+=" ";
    dataString+=now.hour(), DEC;
    dataString+=":";
    dataString+=now.minute(), DEC;
    dataString+=":";
    dataString+=now.second(), DEC;
    dataString+="         ";
    dataString+=Vrms;
    dataString+="         ";
    dataString+=Irms;
    dataString+="         "; 
    dataString+=mean_phase;
    dataString+="         ";
    dataString+=powerFactor;
    dataString+="                 ";
    dataString+=appPower; 
    dataString+="                 ";
    dataString+=realPower;
    dataString+="         ";
    dataString+=h;
    dataString+="         ";
    dataString+=t;

  }
  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.dat", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }
  // if the file isn't open, pop up an error:
  else {
    Serial.println("#error opening datalog.dat");
    }

  delay(10000);
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-24 06:51:43

虽然程序在进一步的计算中使用了正确的值,即0.9962 .

这表明问题在您的打印代码中。

更具体地说,我怀疑这句话可能会引起麻烦:

代码语言:javascript
复制
dataString+=powerFactor;

您正在使用String类,因此WString.cpp是相关的文件。

如果我们检查它,我们会发现在第409行(至少在我的Arduino版本中,1.6.7IIRC中),+操作符是为浮点数声明的,它只是调用concat(float),这可以在第323行中找到:

代码语言:javascript
复制
unsigned char String::concat(float num)
{
    char buf[20];
    char* string = dtostrf(num, 4, 2, buf);
    return concat(string, strlen(string));
}

如果您阅读dtostrf文档,您将发现这是将一个双(浮点数被提升)转换为一个宽度为4位和2位精度的字符串。

解决这一问题的最简单方法是使用dtostrf将浮点数转换为具有所需精度的字符串,然后将该字符串附加到string实例中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35585385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档