First init.
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
/* Latest DinoFan 19.06.2024-001
|
||||
Added watchdog timer, 4 seconds.
|
||||
Removed SoftSerial since it interferred with Wire.h
|
||||
Added M3200 sensor for oil temp and pressure. */
|
||||
|
||||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
#include <Wire.h>
|
||||
#include <Adafruit_GFX.h>
|
||||
#include <Adafruit_SH110X.h>
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#define i2c_Address 0x3C // OLED Adress.
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1
|
||||
|
||||
int M3200address = 0x28; // 0x28, 0x36, or 0x46, depending on the sensor.
|
||||
float maxPressure = 100; // pressure in PSI for this sensor, 100, 250, 500, ... 10k.
|
||||
float pressure;
|
||||
float temperature;
|
||||
byte status;
|
||||
|
||||
float tempForFanStartup = 85.0; // 175 target low temp. below this temperature, the fan will be off
|
||||
float tempForFanOnFull = 100.0; // 210 target High temp. above this temperature, the fan will be on at full power
|
||||
|
||||
float voltsForFanStartup = 2.0; // Roughly the signal voltage that triggers the slowest speed.
|
||||
|
||||
const int fanPwmOutPin = 12; // Arduino forces this pin to 0 or 5 volts.
|
||||
const int tempSensorPin = 7; // Pin to read analog voltage from the temp sensor.
|
||||
int pwmDuty; // The calculated PWM duty is stored here
|
||||
float pwmMinStartupDuty; // the starting duty is stored here (mazda module starts fans at about 24 % duty)
|
||||
float currTemperature; // the temperature in F is stored here
|
||||
float fanSpeedPct;
|
||||
|
||||
OneWire oneWire1 (tempSensorPin);
|
||||
DallasTemperature sensorClt1(&oneWire1);
|
||||
|
||||
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||
|
||||
unsigned long previousMillis = 0; // Variable to store the last time the serial data was sent
|
||||
const long interval = 5000; // Interval between serial data transmissions (in milliseconds)
|
||||
|
||||
unsigned long previous2Millis = 0;
|
||||
const int pressureTiming = 1000; // 500ms every data acquisition
|
||||
|
||||
void setup() {
|
||||
wdt_enable(WDTO_4S);
|
||||
Serial.begin(9600);
|
||||
Wire.begin();
|
||||
|
||||
if (!display.begin(i2c_Address)) {
|
||||
Serial.println(F("SH110X allocation failed"));
|
||||
for (;;);
|
||||
}
|
||||
display.clearDisplay(); // Clear the display buffer
|
||||
|
||||
sensorClt1.begin();
|
||||
sensorClt1.requestTemperatures();
|
||||
|
||||
currTemperature = sensorClt1.getTempCByIndex(0);
|
||||
pwmMinStartupDuty = (voltsForFanStartup / 5.0) * 255.0; // convert the Mazda starting voltage to a PWM duty
|
||||
|
||||
delay(500);
|
||||
Serial.print("F20.0");
|
||||
delay(20);
|
||||
Serial.print("D000");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
unsigned long currentMillis = millis();
|
||||
unsigned long pressureMillis = millis();
|
||||
|
||||
//Pull data from M3200 every second.
|
||||
if (pressureMillis - previous2Millis >= pressureTiming) {
|
||||
get_data_from_M3200();
|
||||
previous2Millis = pressureMillis;
|
||||
}
|
||||
|
||||
|
||||
readAndTranslateTempSensor();
|
||||
calculate_and_send_PWM();
|
||||
//print_to_serial_port(); // uncomment this line for testing and calibration to the laptop.
|
||||
|
||||
// Check if it's time to send serial data
|
||||
if (currentMillis - previousMillis >= interval) {
|
||||
serial_to_signal_generator(); // Send serial data
|
||||
previousMillis = currentMillis; // Save the last time serial data was sent
|
||||
}
|
||||
displayOutput();
|
||||
wdt_reset();
|
||||
}
|
||||
|
||||
void calculate_and_send_PWM() { /* ++++++++ subroutine to calculate PWM duty cycle ++++++++++++++*/
|
||||
|
||||
if (currTemperature < tempForFanStartup) { // If the temperature is below the lowest setpoint, turn fan off
|
||||
//analogWrite(fanPwmOutPin, 0); // PWM duty = 0 percent
|
||||
pwmDuty = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (currTemperature > tempForFanOnFull) { // If the temperature is above the highest setpoint, turn fan on full
|
||||
//analogWrite(fanPwmOutPin, 255); // PWM duty = 100 percent
|
||||
pwmDuty = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
float tempRange = tempForFanOnFull - tempForFanStartup ; // start calculating duty cycle
|
||||
float pwmRange = 255.0 - pwmMinStartupDuty ;
|
||||
float pwmDutyPct = (currTemperature - tempForFanStartup) / tempRange ;
|
||||
|
||||
pwmDuty = (int) (pwmMinStartupDuty + (pwmDutyPct * pwmRange) +.5); // actual PWM duty is calculated here
|
||||
|
||||
fanSpeedPct = map(pwmDuty, 0, 255, 0, 100);
|
||||
|
||||
if (pwmDuty > 255) { // make sure duty ended up between 255 and 0
|
||||
pwmDuty = 255;
|
||||
}
|
||||
if (pwmDuty < 0) {
|
||||
pwmDuty = 0;
|
||||
}
|
||||
|
||||
//analogWrite(fanPwmOutPin, pwmDuty); // write PWM duty to PWM output pin
|
||||
|
||||
} // end calculate_and_send_PWM
|
||||
|
||||
void readAndTranslateTempSensor() {
|
||||
// Request temperature readings
|
||||
sensorClt1.requestTemperatures();
|
||||
|
||||
// Read the temperature from the sensor
|
||||
float tempC = sensorClt1.getTempCByIndex(0);
|
||||
|
||||
// Check if the temperature reading is within the valid range
|
||||
if (tempC > -30 && tempC < 130) {
|
||||
// If the reading is within the valid range, update the current temperature
|
||||
currTemperature = tempC;
|
||||
}
|
||||
// If the reading is outside the valid range, do not update the current temperature
|
||||
}
|
||||
|
||||
void displayOutput() {
|
||||
display.clearDisplay();
|
||||
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(SH110X_WHITE);
|
||||
|
||||
// Display temperature on the screen in Celsius with one decimal place
|
||||
display.setCursor(12, 0);
|
||||
display.print("Pontiac LeMans '69");
|
||||
display.drawLine(2, 10, 126, 10, SH110X_WHITE);
|
||||
|
||||
display.setCursor(0, 16);
|
||||
display.print("Water temp:");
|
||||
display.setCursor(70, 16);
|
||||
display.print(currTemperature, 1); // Display one decimal place
|
||||
display.print(" C");
|
||||
|
||||
// Calculate and display fan speed percentage
|
||||
if (currTemperature < tempForFanStartup) {
|
||||
fanSpeedPct = 0; // Set fan speed to 0% if temperature is below startup threshold
|
||||
} else {
|
||||
fanSpeedPct = map(pwmDuty, 0, 255, 0, 100); // Calculate fan speed percentage
|
||||
}
|
||||
|
||||
display.setCursor(0, 26);
|
||||
display.print("Fan Speed :");
|
||||
display.setCursor(70, 26);
|
||||
display.print((int)fanSpeedPct);
|
||||
display.print(" %");
|
||||
|
||||
display.setCursor(0, 46);
|
||||
display.print("Oil Pressr:");
|
||||
display.setCursor(70, 46);
|
||||
display.print(pressure, 1);
|
||||
display.print(" b");
|
||||
|
||||
display.setCursor(0, 56);
|
||||
display.print("Oil Temp :");
|
||||
display.setCursor(70, 56);
|
||||
display.print(temperature, 1);
|
||||
display.print(" C");
|
||||
|
||||
// Update the display
|
||||
display.display();
|
||||
}
|
||||
|
||||
void print_to_serial_port() { /* ++++++++++ optional prints values to laptop usb port for debugging and calibration ++*/
|
||||
Serial.print(F("currTemperature C: ")); Serial.print(currTemperature);
|
||||
Serial.print(F(" pwmDuty: ")); Serial.println(pwmDuty);
|
||||
Serial.print(F("Percentage: ")); Serial.println((int)fanSpeedPct);
|
||||
}
|
||||
|
||||
void serial_to_signal_generator() {
|
||||
// Determine fan speed percentage to send
|
||||
int speedToSend = (int)fanSpeedPct;
|
||||
|
||||
// Ensure fan speed is 0 if temperature is below startup threshold
|
||||
if (currTemperature < tempForFanStartup) {
|
||||
speedToSend = 0;
|
||||
}
|
||||
|
||||
// Check the length of fanSpeedPct
|
||||
if (speedToSend < 10) {
|
||||
Serial.print(F("D00")); // Add "D00" prefix for single-digit fan speed
|
||||
} else if (speedToSend < 100) {
|
||||
Serial.print(F("D0")); // Add "D0" prefix for double-digit fan speed
|
||||
} else {
|
||||
Serial.print(F("D")); // Add "D" prefix for triple-digit fan speed
|
||||
}
|
||||
|
||||
Serial.print(speedToSend); // Send fan speed
|
||||
}
|
||||
|
||||
void get_data_from_M3200() {
|
||||
Wire.requestFrom(M3200address, 4); // request 4 bytes
|
||||
int n = Wire.available();
|
||||
|
||||
if (n == 4) {
|
||||
status = 0;
|
||||
uint16_t rawP; // pressure data from sensor
|
||||
uint16_t rawT; // temperature data from sensor
|
||||
rawP = (uint16_t) Wire.read(); // upper 8 bits
|
||||
rawP <<= 8;
|
||||
rawP |= (uint16_t) Wire.read(); // lower 8 bits
|
||||
rawT = (uint16_t) Wire.read(); // upper 8 bits
|
||||
rawT <<= 8;
|
||||
rawT |= (uint16_t) Wire.read(); // lower 8 bits
|
||||
|
||||
status = rawP >> 14; // The status is 0, 1, 2, or 3
|
||||
rawP &= 0x3FFF; // keep 14 bits, remove status bits
|
||||
|
||||
rawT >>= 5; // the lowest 5 bits are not used
|
||||
|
||||
pressure = ((rawP - 1000.0) / (15000.0 - 1000.0)) * maxPressure;
|
||||
temperature = ((rawT - 512.0) / (1075.0 - 512.0)) * 55.0;
|
||||
|
||||
// Serial.println("--- Values from M3200 ---");
|
||||
// Serial.println(temperature);
|
||||
// Serial.println(pressure);
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
Serial.println("M3200 Pressure Transducer not Detected");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user