我從模擬輸入(A0引腳)和模擬輸入(A1引腳)的電流信號(電壓形式)中取出電壓信號,將其轉換爲數字形式,然後對其進行處理以獲得Vrms ,Irms和相位數據。然後,我將它存儲在「dataString」中,並將其寫入SD卡。arduino中浮點變量的精度
我面臨的問題是,在功率因數的浮點計算的某個地方,我做了一些錯誤,因爲答案被「顯示爲」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);
}