我从模拟输入的电压信号(A0引脚)和电流信号(以电压的形式)从模拟输入(A1引脚),将它转换成数字,然后处理它,以获得Vrms,Irms和相位数据。然后我将其存储在"dataString“中,并将其写入SD卡。
我面临的问题是,在功率因数的浮点计算中,我做了一些错误的事情,因为它的答案被“显示为”1.00,而在4.97 (度)的角度上,我应该得到cos(4.97) = 0.9962 (附图) Image1。
虽然程序正在使用正确的值,即在进一步的计算中使用0.9962 (实数),但我希望它能够在十进制之后正确地显示功率因数4点。这是我的程序代码
#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);
}发布于 2016-02-24 06:51:43
虽然程序在进一步的计算中使用了正确的值,即0.9962 .
这表明问题在您的打印代码中。
更具体地说,我怀疑这句话可能会引起麻烦:
dataString+=powerFactor;您正在使用String类,因此WString.cpp是相关的文件。
如果我们检查它,我们会发现在第409行(至少在我的Arduino版本中,1.6.7IIRC中),+操作符是为浮点数声明的,它只是调用concat(float),这可以在第323行中找到:
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实例中。
https://stackoverflow.com/questions/35585385
复制相似问题