initial
This commit is contained in:
141
ferrarismonitor/FerrarisMonitor/FerrarisMonitor.ino
Normal file
141
ferrarismonitor/FerrarisMonitor/FerrarisMonitor.ino
Normal file
@@ -0,0 +1,141 @@
|
||||
int portLeft = 4;
|
||||
int portRight = 3;
|
||||
|
||||
long sampleMetro = 10;
|
||||
long printMetro = 100;
|
||||
|
||||
int16_t stateLeft = 0;
|
||||
int16_t stateRight = 0;
|
||||
|
||||
int16_t minLeft = 1024;
|
||||
int16_t maxLeft = 0;
|
||||
int16_t nextMinLeft = 1024;
|
||||
int16_t nextMaxLeft = 0;
|
||||
int16_t minRight = 1024;
|
||||
int16_t maxRight = 0;
|
||||
int16_t nextMinRight = 1024;
|
||||
int16_t nextMaxRight = 0;
|
||||
|
||||
int16_t margin = 5;
|
||||
int16_t rotation = 1; // right = 1, normal, -1 is reverse
|
||||
|
||||
int16_t lightLeft = 0; // latest reading
|
||||
int16_t lightRight = 0;
|
||||
|
||||
double prevMs = 0; // timestamp of last peak
|
||||
long previousSample = 0;
|
||||
long previousPrint = 0;
|
||||
double len = 0; // delay between the last two peaks
|
||||
|
||||
void setup() {
|
||||
Serial.begin(57600);
|
||||
Serial.println("\n[Monitoring a Ferraris Meter]");
|
||||
|
||||
//portLeft.mode(INPUT);
|
||||
//portRight.mode(INPUT);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
unsigned long currentMillis = millis();
|
||||
// take a reading from both sensors
|
||||
if(currentMillis - previousSample > sampleMetro) {
|
||||
previousSample = currentMillis;
|
||||
// read sensors
|
||||
lightLeft = analogRead(portLeft);
|
||||
lightRight = analogRead(portRight);
|
||||
|
||||
// to take into account changing peak sizes, we follow the peak size continuously
|
||||
// the found peak size serves as the target (minus a small margin) for the next peak detection
|
||||
// update minimum and maximum for the left sensor
|
||||
if ( lightLeft > nextMaxLeft ) {
|
||||
nextMaxLeft = lightLeft;
|
||||
}
|
||||
// we also do this for the valley
|
||||
if ( lightLeft < nextMinLeft ) {
|
||||
nextMinLeft = lightLeft;
|
||||
}
|
||||
|
||||
// and the same for the right sensor
|
||||
// update minimum and maximum for the right sensor
|
||||
if ( lightRight > nextMaxRight ) {
|
||||
nextMaxRight = lightRight;
|
||||
}
|
||||
if ( lightRight < nextMinRight ) {
|
||||
nextMinRight = lightRight;
|
||||
}
|
||||
|
||||
if (( stateLeft == 0 ) && (lightLeft > maxLeft - margin )) {
|
||||
// make state = 1 when light above threshold and state == 0
|
||||
stateLeft = 1;
|
||||
|
||||
// we are now going to a minimum, reset the minimum value of the left sensor
|
||||
minLeft = nextMinLeft;
|
||||
nextMinLeft = 1024;
|
||||
|
||||
// calculate rotation direction
|
||||
if (( stateRight == 0 ) && (rotation < 1)) {
|
||||
rotation++;
|
||||
} else if ((stateRight == 1 ) && (rotation > -1)) {
|
||||
rotation--;
|
||||
}
|
||||
|
||||
// calculate delay between the last two peaks, now and prevMs
|
||||
double ms = millis();
|
||||
len = ms - prevMs;
|
||||
prevMs = ms;
|
||||
|
||||
} else if ((stateLeft == 1 ) && (lightLeft < minLeft + margin)) {
|
||||
// make state = 0 when light below threshold and state == 1
|
||||
stateLeft = 0;
|
||||
|
||||
// we are now going to a maximum, reset the maximum value of the left sensor
|
||||
maxLeft = nextMaxLeft;
|
||||
nextMaxLeft = 0;
|
||||
|
||||
}
|
||||
|
||||
if (( stateRight == 0 ) && (lightRight > maxRight - margin )) {
|
||||
// make state = 1 when light above threshold and state == 0
|
||||
stateRight = 1;
|
||||
|
||||
// we are now going to a minimum, reset the minimum value of the right sensor
|
||||
minRight = nextMinRight;
|
||||
nextMinRight = 1024;
|
||||
|
||||
} else if ((stateRight == 1 ) && (lightRight < minRight + margin)) {
|
||||
// make state = 0 when light below threshold and state == 1
|
||||
stateRight = 0;
|
||||
|
||||
// we are now going to a maximum, reset the maximum value of the right sensor
|
||||
maxRight = nextMaxRight;
|
||||
nextMaxRight = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// print current status
|
||||
if(currentMillis - previousPrint > printMetro) {
|
||||
previousPrint = currentMillis;
|
||||
// calculate new delay between now and the previous peak (prevMs)
|
||||
double ms = millis();
|
||||
double tempDelay = ms - prevMs;
|
||||
|
||||
// if 'tempDelay' is larger than the delay between the last two peaks 'len' it means that the disc is spinning slower and power usage is decreasing
|
||||
// so max power consumption at this moment is not len, but tempDelay.
|
||||
if ( len > tempDelay ) {
|
||||
tempDelay = len;
|
||||
}
|
||||
|
||||
int watt = rotation * 4800000 / tempDelay; // my kwh meter says 600 rotations per kwh
|
||||
|
||||
Serial.print(watt);
|
||||
Serial.print(" | ");
|
||||
Serial.print(rotation);
|
||||
Serial.print(" | ");
|
||||
Serial.print(lightLeft);
|
||||
Serial.print(" | ");
|
||||
Serial.println(lightRight);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user