Thanks for explaining everything. I am still working my way through it. Very Impressive.
"This also has the test pulse code enabled." - I didn't get it at first - that you had to create your own test pulses. But that explains some of the code which confused me. So, if I uncomment the "define TESTPULSES", most of the code is not used?
I have another question for you.
My intention is to use the anemometer with a watt meter and a time/date stamp to record data from my wind turbine on a SD Card.
The watt meter, SD card, and time/date all run in the loop. Since the fWindSpeed reading occurs outside the loop, I get an error that it is not defined when I merge your sketch with mine.
Is there a way to send the fWindSpeed reading into the loop so that I can write to the SD card?
Here is the whole code
this is link to pzem library: GitHub - olehs/PZEM004T: Arduino communication library for Peacefair PZEM-004T Energy monitor
#include <Wire.h>
#include <LiquidCrystal.h>
#include <SD.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <PZEM004T.h>
#include <DS3231.h>
LiquidCrystal lcd(8,7,3,4,5,6);
PZEM004T pzem(10,11); // TX,RX connections for watt meter
IPAddress ip(192,168,1,1);
DS3231 rtc(SDA, SCL); // connections for time and date stamp
File myFile;
int pinCS = 53; //assign pin for sd card reader
int maxspeed = 0;
// insert Blackfin code
//#define TESTPULSES 1 //uncomment to use test pulses on pin 7 (jumper to pin 2)
const byte pinAnamometer = 2; //anamometer signal input
#ifdef TESTPULSES
const byte pinTestOutput = 7; //if TESTPULSES is defined, this is a test pin the produces
//a test pulse that can be fed into pin 2 to simulate an anamometer
#endif
#define UPDATE_PERIOD 500 //send serial messages to the monitor every 500mS
#define PULSE_TOUT 1000ul //time between pulses where we say wind speed is basically 0.0mph
void ISR_anamomPulse( void ); //prototype of the function used for the anamometer pin rising-edge interrupt
unsigned long
Period, //holds the time between rising edges in microseconds
pulseTimeout; //holds the time of the last pulse (mS) use to determine if there's little/no wind
bool
bFirstPulse, //indicates to ISR that this is the first pulse
bGotPulse; //indication from ISR that a valid Period reading is ready
void setup()
{
// insert Blackfin setup code
Serial.begin( 9600 );
pinMode( pinAnamometer, INPUT_PULLUP );
#ifdef TESTPULSES
pinMode( pinTestOutput, OUTPUT );
#endif
//set up to interrupt on rising edges of pin 2 (anamometer input) and to call function ISR_anamomPulse
//on each interrupt
attachInterrupt( digitalPinToInterrupt(pinAnamometer), ISR_anamomPulse, RISING );
//ready the ISR to receive its first pulse and indicate no period is ready yet
bFirstPulse = true;
bGotPulse = false;
//end Blackfin setup
pinMode(pinCS, OUTPUT);
pzem.setAddress(ip);
rtc.begin(); // Initialize the rtc object
lcd.begin(16, 4);
lcd.print("Initializing");
delay(1000);
lcd.clear();
if (SD.begin())
{
Serial.println("SD card is ready to use.");
} else
{
Serial.println("SD card initialization failed");
return;
}
}
void loop()
{
//Send Day-of-Week
Serial.print(rtc.getDOWStr());
Serial.print(" ");
// Send date
Serial.print(rtc.getDateStr());
Serial.print(" -- ");
// Send time
Serial.println(rtc.getTimeStr());
// insert Blackfin Loop
//if defined, this sets up and times the test pulses produced on pin 7
#ifdef TESTPULSES
static bool
bTestState = false;
static unsigned long
testPulse = 0;
unsigned long
timeNow;
//change the value (e.g. 10) to lengthen the pulses
timeNow = millis();
if( (timeNow - testPulse) > 10 )
{
//when the time has passed, set the current time as the last time
testPulse = timeNow;
//toggle the internal flag representing the pin state (high or low, true or false, 1 or 0 etc)
bTestState ^= true;
//then set the pin to that state
/ digitalWrite( pinTestOutput, (bTestState)?HIGH:LOW );
}//if
#endif
//check to see if too much time has elapsed since the last anamometer rising edge
CheckPulseTimeout();
//see if it's time to send a windspeed message
CheckSpeed();
// end Blackfin loop
if (fWindSpeed > maxspeed) maxspeed = fWindSpeed; //track highest windspeed
float v = pzem.voltage(ip);
if (v < 0.0) v = 0.0;
Serial.print(v);Serial.print("V; ");
float i = pzem.current(ip);
if(i >= 0.0){ Serial.print(i);Serial.print("A; "); }
float p = pzem.power(ip); // power = watts
if(p >= 0){ Serial.print(p);Serial.print("W; "); }
float e = pzem.energy(ip); // energy = watt hours
if(e >= 0.0){ Serial.print(e);Serial.print("Wh; "); }
//num = num + 1; // start a counter which will reset every 30 cycles
// Serial.print(num);
// Serial.println();
//if (num > 30) //print to sd card every 30th count if producing energy
//{
if (p > 10) // only write to sd card if turbine is making more than 10 watts
{
myFile = SD.open("test.txt", FILE_WRITE); // print to sd card: date, time, windspeed and watts
if (myFile) {
myFile.print(rtc.getDateStr());
myFile.print(", ");
myFile.print(rtc.getTimeStr());
myFile.print(", ");
myFile.print(fWindSpeed);
myFile.print(" mph =");
myFile.print(p);
myFile.println(" watts, ");
myFile.close(); // close the file
}
else {
Serial.println("error opening test.txt");
}
}
// num = 0; // reset counter to 0
//}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(fWindSpeed);
lcd.setCursor(6,0);
lcd.print("MPH");
lcd.setCursor(13,0);
lcd.print(maxspeed);
lcd.setCursor(17,0);
lcd.print("MAX");
lcd.setCursor(0,1);
lcd.print(p);
lcd.setCursor(6,1);
lcd.print("Watts");
lcd.setCursor(4,2);
lcd.print(e);
lcd.setCursor(10,2);
lcd.print("Watt hours");
lcd.setCursor(4,3);
lcd.print(i);
lcd.setCursor(10,3);
lcd.print("Amps");
}
//insert remaining Blackfin code
void CheckSpeed( void )
{
char
szSpd[20];
// I had to remove the rest of the code to get under the 9000 character limit for this post.