/*********************************************************************
Mazda rotary engine compression test
Designed for single 200 PSI transducer application.
The program will work by sampling analog channel 2 (PB4) lookind for
maximum pressure value for each rotor face. The program will stop
updating display once six set of samples were obrained.
*********************************************************************/
#include <TinyWireM.h>
#include <Tiny4kOLED.h>
#include <TinyDebug.h>
#define TRANSDUCER_INPUT A2 // PB4 - analog channel 2
#define TRANSDUCER_MAX_PSI 200
// timer variables
unsigned long loop_t0_time = 0; // previous time reference
unsigned long loop_t1_time = 0; // current time reference
unsigned long display_t0_time = 0; // previous time reference
unsigned long display_t1_time = 0; // current time reference
unsigned long transducer_t0_time = 0; // previous time reference
unsigned long transducer_t1_time = 0; // current time reference
unsigned long transducer_times[3]; // time reference of recording maximum pressure samples
// measure variables
int transducer_min = 0; // minimum value measured before cranking
int transducer_t0_adc = 0; // previous sample
int transducer_t1_adc = 0; // current sample
int transducer_peaks[3]; // maximum recorded pressure samples
int peakCompressionCounter = 0; // counter for maximum pressure samples
int fallingCnt = 0; // counter for when pressure is dropping
int rotorRevolutionCounter = 0; // counter for number of full rotor revolution
// display variables
int display_state = 0; // 0 = loading, 1 = results
unsigned long t0 = 0; // time 0
unsigned long t1 = 0; // time 1
String loadingStr = ""; // loading dot string
int loadingCounter = 0; // dots counter
void updateDisplay() {
if (display_state == 0) {
updateDisplayV1();
} else {
updateDisplayV2();
}
}
void updateDisplayV1() {
if (loadingCounter > 26) {
oled.setCursor(0, 4);
oled.clearToEOL();
loadingCounter = 0;
loadingStr = "";
}
loadingCounter += 1;
loadingStr += ".";
oled.setCursor(24, 4);
oled.print(loadingStr);
}
int lineCounter = 0;
int columns[4] = { 0, 30, 60, 90 }; // column starting position
void updateDisplayV2() {
// Debug.print("Line ");
// Debug.print(lineCounter);
// Debug.print(" Peak ");
// Debug.print(peakCompressionCounter);
// Debug.print(" Rev ");
// Debug.println(rotorRevolutionCounter);
// fixed header takes first line (idx: 0)
if (lineCounter == 0) {
loadingStr = ""; // clear loading string so we can re-use it here
oled.setCursor(columns[0], 0);
oled.print("#1");
oled.setCursor(columns[1], 0);
oled.print("#2");
oled.setCursor(columns[2], 0);
oled.print("#3");
oled.setCursor(columns[3], 0);
oled.print("RPM");
lineCounter += 1; // do not forget to update line counter
}
// transducer results will cycle between second and seventh lines (idx: 1, 2, 3, 4, 5, 6)
oled.setCursor(columns[0], lineCounter);
oled.clearToEOL();
oled.setCursor(columns[0], lineCounter);
oled.print(String(transducer_peaks[0]));
// oled.print(String(map(transducer_peaks[0], 0, 1023, 0, TRANSDUCER_MAX_PSI)));
oled.setCursor(columns[1], lineCounter);
oled.print(String(transducer_peaks[1]));
// oled.print(String(map(transducer_peaks[1], 0, 1023, 0, TRANSDUCER_MAX_PSI)));
oled.setCursor(columns[2], lineCounter);
oled.print(String(transducer_peaks[2]));
// oled.print(String(map(transducer_peaks[2], 0, 1023, 0, TRANSDUCER_MAX_PSI)));
// From rotary engine overhaul 1979 booklet
// Crank engine for 5 seconds and count number of peaks.
// Peaks: 17 18 19 20 21 22 23 24 25
// RPM: 204 216 228 240 252 264 276 288 300
// 1 revolution of rotor = 3 rotation of eccentric shaft
// 5000 / 21 = 238 ms
// rpm = 180000 / 714 = 252 rpm
oled.setCursor(columns[3], lineCounter);
// int rpm[2] = {
// (int)(180000 / (transducer_times[1] - transducer_times[0])),
// (int)(180000 / (transducer_times[2] - transducer_times[1]))
// };
// oled.print(String((int)(rpm[0] + rpm[1]) / 2));
// Debug.print("t2 - t0 = ");
Debug.println(transducer_times[2] - transducer_times[0]);
int rpm = 180000 / (transducer_times[2] - transducer_times[0]);
oled.print(String((int)rpm));
// fixed footer takes last line (idx: 7)
if (lineCounter < 6) {
if (lineCounter % 3 == 0) {
oled.setCursor(columns[0], 7);
oled.clearToEOL();
loadingStr = "";
}
oled.setCursor(columns[0], 7);
oled.print("Keep cranking");
loadingStr += ".";
oled.print(loadingStr);
} else {
oled.setCursor(columns[0], 7);
oled.clearToEOL();
oled.setCursor(columns[0], 7);
oled.print("Stop cranking!!!");
}
lineCounter += 1;
}
void setup() {
Debug.begin();
pinMode(TRANSDUCER_INPUT, INPUT);
// compute average transducer output at zero pressure
// int samples[5];
// samples[0] = analogRead(TRANSDUCER_INPUT);
// samples[1] = analogRead(TRANSDUCER_INPUT);
// samples[2] = analogRead(TRANSDUCER_INPUT);
// samples[3] = analogRead(TRANSDUCER_INPUT);
// samples[4] = analogRead(TRANSDUCER_INPUT);
// transducer_min = (samples[0] + samples[1] + samples[2] + samples[3] + samples[4]) / 5;
transducer_min = 50;
oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br);
oled.enableChargePump(); // Most display require to display properly
oled.clear(); // Clear the memory before turning on the display
oled.on(); // Turn on the display
oled.setFont(FONT6X8P); // Two fonts are supplied with this library, FONT8X16 and FONT6X8
oled.setCursor(24, 2);
oled.print("Begin cranking");
}
void loop() {
// Debug.println(analogRead(TRANSDUCER_INPUT));
// Debug.print("Loop: ");
// loop_t1_time = micros();
// Debug.print(loop_t1_time - loop_t0_time);
// loop_t0_time = loop_t1_time;
// Debug.println("us");
// update display once every second
display_t1_time = millis();
if (display_t1_time - display_t0_time > 1000 && display_state == 0) {
// Debug.print("Display: ");
// Debug.print(display_t1_time - display_t0_time);
// Debug.println("ms");
display_t0_time = display_t1_time;
updateDisplay();
}
if (rotorRevolutionCounter < 6) {
// sampling
t1 = millis(); // slow down sampling rate
if (t1 - t0 > 10) {
t0 = t1;
transducer_t1_adc = analogRead(TRANSDUCER_INPUT);
// transducer_t1_time = micros();
transducer_t1_time = millis();
// Debug.print(transducer_t1_time);
// Debug.print(" : ");
// Debug.print(transducer_t1_adc);
// Debug.print(" - ");
// Debug.print(transducer_peaks[peakCompressionCounter]);
// Debug.print(" = ");
// Debug.println(transducer_t1_adc - transducer_peaks[peakCompressionCounter]);
if (transducer_t1_adc - transducer_peaks[peakCompressionCounter] > -3) {
fallingCnt = 0; // reset counter when pressure is rising
transducer_peaks[peakCompressionCounter] = transducer_t1_adc;
transducer_times[peakCompressionCounter] = transducer_t1_time;
} else {
fallingCnt += 1;
if (fallingCnt == 5) {
peakCompressionCounter += 1;
}
}
}
if (peakCompressionCounter == 3) {
display_state = 1;
if (rotorRevolutionCounter == 0) {
oled.clear(); // clear display on first state switch
}
peakCompressionCounter = 0;
rotorRevolutionCounter += 1;
updateDisplay();
}
}
}
Loading
ssd1306
ssd1306