Hi Arduino Gurus!
I've recently inherited a code to measure the performance of a model (3 straight bladed) Vertical Axis Wind Turbine which I have been trying to expand and build upon (with varying success).
Original set up included an Adafruit BMP280 to measure the Temperature and barometric pressure of the test section prior to any incoming flow, a MPXV5004DP to measure incoming flow velocity, and an OPB704 Reflectance object sensor to measure the rotational velocity of the turbine.
I have since incorporated another diffpx (MPXV5004DP) sensor to connect to a second pitot tube in order to measure the wakeflow velocity. The issue I've been having is that I can't successfully set up the wakeflow pitot to take more than one measurement per turbine rotation. I really need to do this since Vwakeflow changes depending where in the rotation the turbine is in.
Rotational velocity (omega) is set up on a 'while' loop where while it registers the turbine spinning, it will measure and serial print: data line number, omega, time taken for rotation, Front velocity (m/s), Back (wakeflow) Velocity (m/s).
Different attempts to fix so far:
- set wakeflow velocity (back pitot) to take measurements every 5 milliseconds, either by:
--outside 'while' statement (lots of dead data before running the wind tunnel and difficult to determine when the turbine makes one rotation).
-- inside 'while' statement (to get rid of dead data but only prints one Vback measurement per rotation) - set up a matrix to take x Vback data points per rotation
-- number of data points required at low rotational velocities is not the same at high rotational velocities
Goal is to measure wakeflow (Velb) every five milliseconds (arbitrary time stamp) and then when turbine is registered as spinning, measure omega, time taken for the rotation, then incoming flow (VelF) once per rotation
Current code is below, any suggestions or guidance would be really appreciated:
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#define BMP_SCK 13
#define BMP_MISO 12
#define BMP_MOSI 11
#define BMP_CS 10
Adafruit_BMP280 bmp(BMP_CS); // hardware SPI
// ******* End temp & barometric pressure setup *******
volatile byte FLAG;
unsigned int data;
float omega, time, temp, baro, rho, velocity_front, velocity_back, Vout1,Vout2, diffPx1, diffPx2;
int ledPin = 7; // Status LED
long currenttime = 0.0;
long currenttime_data = 0;
long prevtime = 0;
unsigned long interval = 5; //interval between diff px 2 readings (wake velocity)
unsigned long previousMillis = 0; //millis() returns an unsigned long
float prevomega = 0;
const float TPi = 6.283185307L;
void setup()
{
Serial.begin(115200); // Initiates serial monitor (communication between board and computer)
attachInterrupt(digitalPinToInterrupt(2), angVel, FALLING);
Activate temp and baro sensor: *******
Serial.println(F("BMP280 test"));
if (!bmp.begin()) {
Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
while (1);
}
// ******* End activation of temp and baro sensor *******
temp = bmp.readTemperature()+273.15; // Temperature output in Kelvin
baro = bmp.readPressure(); // Barometric pressure in Pa
rho = baro/(287*temp); // Calculated density
data = 0; // Counts every revolution (to ensure no output data is missing)
FLAG = false;
time = 0;
pinMode(ledPin, OUTPUT);
Serial.print(F("Temperature (*C)= ")); Serial.print("\t");
Serial.println(bmp.readTemperature());
Serial.print(F("Temperature (K)= ")); Serial.print("\t");
Serial.println(temp);
Serial.print(F("Barometric Pressure (Pa) = ")); Serial.print("\t");
Serial.println(bmp.readPressure());
Serial.print(F("Density (kg/m^3)= ")); Serial.print("\t");
Serial.println(rho,4);
Serial.print( "Data" ) ; Serial.print("\t");
Serial.print( "Omega" ) ; Serial.print("\t");
Serial.print( "time" ); Serial.print("\t");
Serial.print( "VelF" ) ; Serial.print("\t"); //Incoming flow velocity
Serial.print( "VelB" ) ; Serial.print("\t"); Serial.print("\n"); //wakeflow velocity
}
void loop()
{
time = (currenttime - prevtime) * .001;
omega = TPi / time; // Calculates the angular velocity omega
//****** Front Velocity Readings***//
int average = 0; // takes 10 samples of diff px1 and prints the average
for (int i=0; i < 10; i++) {
average = average + analogRead(A0);
delay(1); // delay for stability
}
Vout1 = ((average/10)); // Reads output voltage from differential pressure sensor
diffPx1 = 5*((Vout1 / 1023.0)-0.2); // Rearranged diffPx formula
velocity_front = sqrt((2*diffPx1*1000)/rho); // Bernoullis equatio - convert kPa to Pa
prevtime = currenttime;
prevomega = omega;
//*** Back (wakeflow) Velocity Readings***//
unsigned long currentMillis = millis(); // grab current time
if ((unsigned long)(currentMillis-previousMillis) >= interval){
Vout2 = (analogRead(A1)); // Output voltage form diff px2
previousMillis = millis();
}
diffPx2 = 5*((Vout2 / 1023.0)-0.2);
velocity_back = sqrt((2*diffPx2*1000)/rho);
while(FLAG == true) // When interrupt is activated flag goes true causing the while loop to run
{
currenttime = millis();
//***Data prints to serial Monitor***//
Serial.print( data ) ; Serial.print("\t");
Serial.print( omega ); Serial.print("\t");
Serial.print( time,4 ); Serial.print("\t"); //,4 = print to 4 decimal places
Serial.print( velocity_front,3 ); Serial.print("\t");
Serial.print( velocity_back,3 ); Serial.print("\t"); Serial.print("\n");
FLAG = false;
}
}
void angVel() // Interupt that is triggered on a rising signal
{
data++; // Adds one to data count each time interupt is triggered
FLAG = true; // Makes flag 'true' to activate the while loop above
long currenttime = millis();
}