Show first bars of data

This commit is contained in:
Sem van der Hoeven
2025-04-03 00:22:07 +02:00
parent 2f325e3254
commit 48933e2bab
6 changed files with 218 additions and 92 deletions

View File

@@ -11,6 +11,17 @@ void bar_draw_horizontal(int start_x, int start_y, int width, int height, int va
display->fillRect(start_x, start_y, start_x + bar_width, start_y + height);
}
void bar_draw_horizontal(int start_x, int start_y, int width, int height, int value, int max_value, byte r, byte g, byte b, char fill_outline, UTFT *display)
{
display->setColor(r,g,b);
int bar_width = (int)((float)value / (float)max_value * width);
if (fill_outline)
{
display->drawRect(start_x, start_y, start_x + width, start_y + height);
}
display->fillRect(start_x, start_y, start_x + bar_width, start_y + height);
}
void bar_draw_vertical(int start_x, int start_y, int width, int height, int value, int max_value, uint color, char fill_outline, UTFT *display)
{
display->setColor(color);
@@ -22,6 +33,17 @@ void bar_draw_vertical(int start_x, int start_y, int width, int height, int valu
display->fillRect(start_x, (start_y + height) - bar_height, start_x + width, start_y + height);
}
void bar_draw_vertical(int start_x, int start_y, int width, int height, int value, int max_value, byte r, byte g, byte b, char fill_outline, UTFT *display)
{
display->setColor(r,g,b);
int bar_height = (int)((float)value / (float)max_value * height);
if (fill_outline)
{
display->drawRect(start_x, start_y, start_x + width, start_y + height);
}
display->fillRect(start_x, (start_y + height) - bar_height, start_x + width, start_y + height);
}
void bar_clear_part_horizontal(int start_x, int start_y, int width, int height, int value_from, int max_value, char clear_color, char clear_outline, UTFT *display)
{
display->setColor(clear_color);

View File

@@ -17,6 +17,22 @@
*/
void bar_draw_horizontal(int start_x, int start_y, int width, int height, int value, int max_value, uint color, char fill_outline, UTFT *display);
/**
* @brief Draws a horizontal bar on the display
* @param start_x The start x position (top left)
* @param start_y The start y position (top left)
* @param width The width of the bar
* @param height The height of the bar
* @param value The value to be displayed
* @param max_value The maximum value of the bar
* @param r The red color value of the bar
* @param g The green color value of the bar
* @param b The blue color value of the bar
* @param fill_outline Whether to fill the outline of the bar
* @param display The display object
*/
void bar_draw_horizontal(int start_x, int start_y, int width, int height, int value, int max_value, byte r, byte g, byte b, char fill_outline, UTFT *display);
/**
* @brief Draws a vertical bar on the display
* @param start_x The start x position (top left)
@@ -31,6 +47,22 @@ void bar_draw_horizontal(int start_x, int start_y, int width, int height, int va
*/
void bar_draw_vertical(int start_x, int start_y, int width, int height, int value, int max_value, uint color, char fill_outline, UTFT *display);
/**
* @brief Draws a vertical bar on the display
* @param start_x The start x position (top left)
* @param start_y The start y position (top left)
* @param width The width of the bar
* @param height The height of the bar
* @param value The value to be displayed
* @param max_value The maximum value of the bar
* @param r The red color value of the bar
* @param g The green color value of the bar
* @param b The blue color value of the bar
* @param fill_outline Whether to fill the outline of the bar
* @param display The display object
*/
void bar_draw_vertical(int start_x, int start_y, int width, int height, int value, int max_value, byte r, byte g, byte b, char fill_outline, UTFT *display);
/**
* @brief Clears a part of a horizontal bar
* @param start_x The start x position (top left)

68
due_obd2/defines.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef DEFINES_H
#define DEFINES_H
#define DEBUG 1
#define SKIP_BT_CHECK 1
// #define RTT_MR 0x400E1A30U
#define MS(x) x * 1000
#define S(x) MS(x) * 1000
#define OBD2_SLOW_VALUES_QUERY_INTERVAL_MS 5000
#define INIT_TEXT_WIDTH 15
#define INIT_PERCENTAGE_WIDTH 4
#define FLAG_INIT_UPDATE_TEXT_POS 0x01
#define FLAG_INIT_CLEAR_POS 0x02
#define FLAG_INIT_UPDATE_PERCENT_POS 0x03
#define FLAG_DEVICE_LABEL_UPDATE_POS 0x04
#define FLAG_DEVICE_LABEL_SHOULD_UPDATE_POS 0x05 /* 0 if label should be updated, 1 if valyue should be updated */
#define FLAG_DEVICE_LABEL_UPDATE_KB_POS 0x06 /* count KB up */
#define FLAG_INIT_ELM327_DONE_POS 0x07 /* elm327 done initializing */
#define LOGO_MIN_STEP 20
#define LOGO_MAX_POS_Y 124
#define FLAG_LOGO_UPDATE 0x00
#define LOGO_TEXT_WIDTH 16
#define RAM_AMOUNT_KB 96
#define RAM_AMOUNT_B 98304
#define RAM_TEXT_WIDTH 9
#define DEV_LABEL_LENGTH 10
#define COLOR_ORANGE 255, 96, 33
/****************************************/
/* x and y positions for several gauges */
/****************************************/
/* box that holds temperature gauges */
#define TEMP_BOX_PADDING 5
#define TEMP_BOX_X_START 300
#define TEMP_BOX_Y_START TEMP_BOX_PADDING
#define TEMP_BOX_CONTENT_WIDTH 180 // witdth of the box to calculate the content in it
#define TEMP_BOX_WIDTH TEMP_BOX_CONTENT_WIDTH - TEMP_BOX_PADDING // width of the box to draw the outline
#define TEMP_BOX_HEIGHT 210 - TEMP_BOX_PADDING
#define TEMP_BOX_COLOR VGA_GRAY
#define TEMP_BOX_BAR_AMOUNT 4 // amount of bars to display in the temperature box
#define TEMP_BOX_BAR_PADDING 2
#define TEMP_BOX_BAR_HEIGHT (((TEMP_BOX_HEIGHT) / ((TEMP_BOX_BAR_AMOUNT) * 2)) - TEMP_BOX_BAR_PADDING)
#define TEMP_BOX_BAR_WIDTH TEMP_BOX_CONTENT_WIDTH - (TEMP_BOX_BAR_PADDING * 4)
#define TEMP_BOX_COOLANT_POS 0
#define TEMP_BOX_INTAKE_AIR_POS 1
#define TEMP_BOX_AMBIENT_AIR_POS 2
#define TEMP_BOX_OIL_POS 3
#define TEMP_BOX_CONTENT_X_START TEMP_BOX_X_START + TEMP_BOX_BAR_PADDING
#define TEMP_BOX_COOLANT_TEXT_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + (2 * TEMP_BOX_COOLANT_POS * TEMP_BOX_BAR_HEIGHT)
#define TEMP_BOX_COOLANT_BAR_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + ((2 * TEMP_BOX_COOLANT_POS * TEMP_BOX_BAR_HEIGHT) + TEMP_BOX_BAR_HEIGHT)
#define TEMP_BOX_INTAKE_AIR_TEXT_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + (2 * TEMP_BOX_INTAKE_AIR_POS * TEMP_BOX_BAR_HEIGHT) + 2
#define TEMP_BOX_INTAKE_AIR_BAR_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + (2 * (TEMP_BOX_INTAKE_AIR_POS * TEMP_BOX_BAR_HEIGHT) + TEMP_BOX_BAR_HEIGHT)
#define TEMP_BOX_AMBIENT_AIR_TEXT_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + (2 * TEMP_BOX_AMBIENT_AIR_POS * TEMP_BOX_BAR_HEIGHT) + 2
#define TEMP_BOX_AMBIENT_AIR_BAR_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + ((2 * TEMP_BOX_AMBIENT_AIR_POS * TEMP_BOX_BAR_HEIGHT) + TEMP_BOX_BAR_HEIGHT)
#define TEMP_BOX_OIL_TEXT_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + (2 * TEMP_BOX_OIL_POS * TEMP_BOX_BAR_HEIGHT) + 2
#define TEMP_BOX_OIL_BAR_Y_START TEMP_BOX_Y_START + TEMP_BOX_BAR_PADDING + ((2 * TEMP_BOX_OIL_POS * TEMP_BOX_BAR_HEIGHT) + TEMP_BOX_BAR_HEIGHT)
#endif // !DEFINES_H

View File

@@ -19,48 +19,7 @@ Program to create a car monitor display using:
#include "obd2_util.h"
#include "obd2_elm327.h"
#include "bars.h"
#define DEBUG 1
#define SKIP_BT_CHECK 1
// #define RTT_MR 0x400E1A30U
#define MS(x) x * 1000
#define S(x) MS(x) * 1000
#define INIT_TEXT_WIDTH 15
#define INIT_PERCENTAGE_WIDTH 4
#define FLAG_INIT_UPDATE_TEXT_POS 0x01
#define FLAG_INIT_CLEAR_POS 0x02
#define FLAG_INIT_UPDATE_PERCENT_POS 0x03
#define FLAG_DEVICE_LABEL_UPDATE_POS 0x04
#define FLAG_DEVICE_LABEL_SHOULD_UPDATE_POS 0x05 /* 0 if label should be updated, 1 if valyue should be updated */
#define FLAG_DEVICE_LABEL_UPDATE_KB_POS 0x06 /* count KB up */
#define FLAG_INIT_ELM327_DONE_POS 0x07 /* elm327 done initializing */
#define LOGO_MIN_STEP 20
#define LOGO_MAX_POS_Y 124
#define FLAG_LOGO_UPDATE 0x00
#define LOGO_TEXT_WIDTH 16
#define RAM_AMOUNT_KB 96
#define RAM_AMOUNT_B 98304
#define RAM_TEXT_WIDTH 9
#define DEV_LABEL_LENGTH 10
#define COLOR_ORANGE 255, 96, 33
/****************************************/
/* x and y positions for several gauges */
/****************************************/
/* box that holds temperature gauges */
#define TEMP_BOX_PADDING 5
#define TEMP_BOX_X_START 300
#define TEMP_BOX_Y_START TEMP_BOX_PADDING
#define TEMP_BOX_CONTENT_WIDTH 180 // witdth of the box to calculate the content in it
#define TEMP_BOX_WIDTH TEMP_BOX_CONTENT_WIDTH - TEMP_BOX_PADDING // width of the box to draw the outline
#define TEMP_BOX_HEIGHT 200 - TEMP_BOX_PADDING
#define TEMP_BOX_COLOR VGA_GRAY
#include "defines.h"
enum DeviceLabel
{
@@ -327,13 +286,16 @@ void on_main_enter()
Serial.println("Entering main loop");
#endif
Timer0.attachInterrupt(query_slow_obd2_values);
Timer0.start(MS(5000));
Timer0.start(MS(OBD2_SLOW_VALUES_QUERY_INTERVAL_MS));
// draw section for temps
display.setColor(TEMP_BOX_COLOR);
display.drawRect(TEMP_BOX_X_START, TEMP_BOX_Y_START, TEMP_BOX_X_START + TEMP_BOX_WIDTH, TEMP_BOX_Y_START + TEMP_BOX_HEIGHT);
display.setColor(VGA_AQUA);
// update slow values so we don't have to wait for the first time the timer fires
query_slow_obd2_values();
}
/**
@@ -343,6 +305,9 @@ void on_main_run()
{
if (update_slow)
{
#if (DEBUG == 1)
Serial.println("Updating slow values");
#endif
update_slow = 0;
obd2_elm327_process_slow(&elm327);
}
@@ -351,22 +316,22 @@ void on_main_run()
obd2_elm327_process_fast(&elm327);
}
if (elm327.value_updates & (1 << UPDATE_RPM_POS))
{
elm327.value_updates &= ~(1 << UPDATE_RPM_POS);
int width = (int)(display.getDisplayXSize() * ((float)elm327.rpm / 7000.0));
display.fillRect(0, 20, width, 20);
display.setColor(VGA_FUCHSIA);
display.print("rpm", 0, 20);
display.printNumI(elm327.engine_load, 30, 20, 4, '0');
display.setColor(VGA_AQUA);
}
if (elm327.value_updates & (1 << UPDATE_COOLANT_TEMP_POS))
{
elm327.value_updates &= ~(1 << UPDATE_COOLANT_TEMP_POS);
display.print("coolant temp", 0, 100);
display.printNumI(elm327.engine_coolant_temp, 200, 100, 4, '0');
display.setColor(VGA_FUCHSIA);
display.print("coo ", TEMP_BOX_CONTENT_X_START, TEMP_BOX_COOLANT_TEXT_Y_START);
display.setColor(VGA_AQUA);
display.printNumI(elm327.engine_coolant_temp, TEMP_BOX_CONTENT_X_START + (4 * display.getFontXsize()), TEMP_BOX_COOLANT_TEXT_Y_START, 4, '0');
bar_draw_horizontal(TEMP_BOX_CONTENT_X_START, TEMP_BOX_COOLANT_BAR_Y_START, TEMP_BOX_BAR_WIDTH, TEMP_BOX_BAR_HEIGHT, elm327.engine_coolant_temp, COOLANT_TEMP_MAX, COLOR_ORANGE, 1, &display);
#if (DEBUG == 1)
Serial.print("bar height ");
Serial.println(TEMP_BOX_BAR_HEIGHT);
Serial.print("coolant temp: ");
Serial.println(elm327.engine_coolant_temp);
#endif
}
if (elm327.value_updates & (1 << UPDATE_FUEL_PRESSURE_POS))
@@ -383,26 +348,50 @@ void on_main_run()
display.printNumF(elm327.fuel_level, 200, 140, 4, '0');
}
// if (elm327.value_updates & (1 << UPDATE_INTAKE_AIR_TEMP_POS))
// {
// elm327.value_updates &= ~(1 << UPDATE_INTAKE_AIR_TEMP_POS);
// display.print("intake air temp", 0, 160);
// display.printNumI(elm327.intake_air_temp, 200, 160, 4, '0');
// }
if (elm327.value_updates & (1 << UPDATE_INTAKE_AIR_TEMP_POS))
{
elm327.value_updates &= ~(1 << UPDATE_INTAKE_AIR_TEMP_POS);
display.setColor(VGA_FUCHSIA);
display.print("int ", TEMP_BOX_CONTENT_X_START, TEMP_BOX_INTAKE_AIR_TEXT_Y_START);
display.setColor(VGA_AQUA);
display.printNumI(elm327.intake_air_temp, TEMP_BOX_CONTENT_X_START + (4 * display.getFontXsize()), TEMP_BOX_INTAKE_AIR_TEXT_Y_START, 4, '0');
bar_draw_horizontal(TEMP_BOX_CONTENT_X_START, TEMP_BOX_INTAKE_AIR_BAR_Y_START, TEMP_BOX_BAR_WIDTH, TEMP_BOX_BAR_HEIGHT, elm327.intake_air_temp, INTAKE_AIR_TEMP_MAX, COLOR_ORANGE, 1, &display);
// if (elm327.value_updates & (1 << UPDATE_AMBIENT_AIR_TEMP_POS))
// {
// elm327.value_updates &= ~(1 << UPDATE_AMBIENT_AIR_TEMP_POS);
// display.print("ambient air temp", 0, 180);
// display.printNumI(elm327.ambient_air_temp, 200, 180, 4, '0');
// }
#if (DEBUG == 1)
Serial.print("intake air temp: ");
Serial.println(elm327.intake_air_temp);
#endif
}
// if (elm327.value_updates & (1 << UPDATE_OIL_TEMP_POS))
// {
// elm327.value_updates &= ~(1 << UPDATE_OIL_TEMP_POS);
// display.print("oil temp", 0, 200);
// display.printNumF(elm327.engine_oil_temp, 200, 200, 4, '0');
// }
if (elm327.value_updates & (1 << UPDATE_AMBIENT_AIR_TEMP_POS))
{
elm327.value_updates &= ~(1 << UPDATE_AMBIENT_AIR_TEMP_POS);
display.setColor(VGA_FUCHSIA);
display.print("amb ", TEMP_BOX_CONTENT_X_START, TEMP_BOX_AMBIENT_AIR_TEXT_Y_START);
display.setColor(VGA_AQUA);
display.printNumI(elm327.ambient_air_temp, TEMP_BOX_CONTENT_X_START + (4 * display.getFontXsize()), TEMP_BOX_AMBIENT_AIR_TEXT_Y_START, 4, '0');
bar_draw_horizontal(TEMP_BOX_CONTENT_X_START, TEMP_BOX_AMBIENT_AIR_BAR_Y_START, TEMP_BOX_BAR_WIDTH, TEMP_BOX_BAR_HEIGHT, elm327.ambient_air_temp, AMBIENT_AIR_TEMP_MAX, COLOR_ORANGE, 1, &display);
#if (DEBUG == 1)
Serial.print("ambient air temp: ");
Serial.println(elm327.ambient_air_temp);
#endif
}
if (elm327.value_updates & (1 << UPDATE_OIL_TEMP_POS))
{
elm327.value_updates &= ~(1 << UPDATE_OIL_TEMP_POS);
display.setColor(VGA_FUCHSIA);
display.print("oil ", TEMP_BOX_CONTENT_X_START, TEMP_BOX_OIL_TEXT_Y_START);
display.setColor(VGA_AQUA);
display.printNumI(elm327.engine_oil_temp, TEMP_BOX_CONTENT_X_START + (4 * display.getFontXsize()), TEMP_BOX_OIL_TEXT_Y_START, 4, '0');
bar_draw_horizontal(TEMP_BOX_CONTENT_X_START, TEMP_BOX_OIL_BAR_Y_START, TEMP_BOX_BAR_WIDTH, TEMP_BOX_BAR_HEIGHT, elm327.engine_oil_temp, OIL_TEMP_MAX, COLOR_ORANGE, 1, &display);
#if (DEBUG == 1)
Serial.print("oil temp: ");
Serial.println(elm327.engine_oil_temp);
#endif
}
if (elm327.value_updates & (1 << UPDATE_ENGINE_LOAD_POS))
{
@@ -574,16 +563,16 @@ void setup()
#endif
if (!obd2_elm327_init(&elm327))
{
#if (DEBUG == 1)
#if (DEBUG == 1)
Serial.println("Shit man its fucked");
#endif
#endif
}
elm327.on_state_change = &bt_state_changed;
#if (DEBUG == 1)
#if (DEBUG == 1)
Serial.println("done with elm327 init");
Serial.println(elm327.elm327->connected);
#endif
#endif
#if (SKIP_BT_CHECK == 1)
update_percent(10);
#endif

View File

@@ -2,6 +2,7 @@
#include <string.h>
#include "obd2_elm327.h"
#include "defines.h"
#define DEBUG_VALUES 1
@@ -37,15 +38,21 @@ char obd2_elm327_init(obd2_elm327_t *elm327)
#if (DEBUG == 1)
Serial.println("initting elm327");
#endif
current_value_slow = COOLANT_TEMP_V;
current_value_fast = ENGINE_LOAD_V;
ELM327_SERIAL.begin(ELM327_BAUD);
elm327->bt_state = BT_INITIALISING;
elm327->elm327 = &elm327_obj;
#if (SKIP_BT_CHECK == 0)
if (!elm327->elm327->begin(ELM327_SERIAL, false, 2000))
{
return 0;
}
#endif // !SKIP_BT_CHECK
return 1;
}
@@ -92,9 +99,9 @@ void obd2_elm327_process_fast(obd2_elm327_t *elm327)
{
#if (DEBUG_VALUES == 1)
current_value_fast = FUEL_PRESSURE_V;
elm327->engine_load = ++elm327->engine_load % 100;
elm327->engine_load = (elm327->engine_load + 1) % 100;
elm327->value_updates |= (1 << UPDATE_ENGINE_LOAD_POS);
#else
#else
float engine_load = elm327->elm327->engineLoad();
if (elm327->elm327->nb_rx_state == ELM_SUCCESS)
{
@@ -113,7 +120,7 @@ void obd2_elm327_process_fast(obd2_elm327_t *elm327)
case FUEL_PRESSURE_V:
{
#if (DEBUG_VALUES == 1)
elm327->fuel_pressure = ++elm327->fuel_pressure % 20;
elm327->fuel_pressure = (elm327->fuel_pressure + 1) % 20;
elm327->value_updates |= (1 << UPDATE_FUEL_PRESSURE_POS);
current_value_fast = MANIFOLD_PRESSURE_V;
#else
@@ -135,7 +142,7 @@ void obd2_elm327_process_fast(obd2_elm327_t *elm327)
case MANIFOLD_PRESSURE_V:
{
#if (DEBUG_VALUES == 1)
elm327->manifold_pressure = ++elm327->manifold_pressure % 20;
elm327->manifold_pressure = (elm327->manifold_pressure + 1) % 20;
elm327->value_updates |= (1 << UPDATE_MANIFOLD_PRESSURE_POS);
current_value_fast = ENGINE_LOAD_V;
#else
@@ -165,7 +172,7 @@ void obd2_elm327_process_slow(obd2_elm327_t *elm327)
case COOLANT_TEMP_V:
{
#if (DEBUG_VALUES == 1)
elm327->engine_coolant_temp = ++elm327->engine_coolant_temp % 150;
elm327->engine_coolant_temp = (elm327->engine_coolant_temp + 10) % 150;
elm327->value_updates |= (1 << UPDATE_COOLANT_TEMP_POS);
current_value_slow = INTAKE_AIR_TEMP_V;
#else
@@ -187,7 +194,7 @@ void obd2_elm327_process_slow(obd2_elm327_t *elm327)
case INTAKE_AIR_TEMP_V:
{
#if (DEBUG_VALUES == 1)
elm327->intake_air_temp = ++elm327->intake_air_temp % 60;
elm327->intake_air_temp = (elm327->intake_air_temp + 10) % 60;
elm327->value_updates |= (1 << UPDATE_INTAKE_AIR_TEMP_POS);
current_value_slow = AMBIENT_AIR_TEMP_V;
#else
@@ -209,7 +216,7 @@ void obd2_elm327_process_slow(obd2_elm327_t *elm327)
case AMBIENT_AIR_TEMP_V:
{
#if (DEBUG_VALUES == 1)
elm327->ambient_air_temp = ++elm327->ambient_air_temp % 60;
elm327->ambient_air_temp = (elm327->ambient_air_temp + 10) % 60;
elm327->value_updates |= (1 << UPDATE_AMBIENT_AIR_TEMP_POS);
current_value_slow = OIL_TEMP_V;
#else
@@ -231,7 +238,7 @@ void obd2_elm327_process_slow(obd2_elm327_t *elm327)
case OIL_TEMP_V:
{
#if (DEBUG_VALUES == 1)
elm327->engine_oil_temp = ++elm327->engine_oil_temp % 150;
elm327->engine_oil_temp = (elm327->engine_oil_temp + 10) % 150;
elm327->value_updates |= (1 << UPDATE_OIL_TEMP_POS);
current_value_slow = FUEL_LEVEL_V;
#else
@@ -253,7 +260,7 @@ void obd2_elm327_process_slow(obd2_elm327_t *elm327)
case FUEL_LEVEL_V:
{
#if (DEBUG_VALUES == 1)
elm327->fuel_level = ++elm327->fuel_level % 100;
elm327->fuel_level = (elm327->fuel_level + 1) % 100;
elm327->value_updates |= (1 << UPDATE_FUEL_LEVEL_POS);
current_value_slow = COOLANT_TEMP_V;
#else

View File

@@ -57,6 +57,14 @@ Be sure to disconnect the TX and RX pins from the BT module when programming the
#define UPDATE_RPM_POS 0x00
#define UPDATE_THROTTLE_POS 0x01
/**
* Temperatures:
* - coolant
* - intake air
* - ambient air
* - oil
*/
#define UPDATE_COOLANT_TEMP_POS 0x02
#define UPDATE_INTAKE_AIR_TEMP_POS 0x03
#define UPDATE_AMBIENT_AIR_TEMP_POS 0x04
@@ -72,10 +80,10 @@ Be sure to disconnect the TX and RX pins from the BT module when programming the
#define COOLANT_TEMP_MAX 120
#define INTAKE_AIR_TEMP_MIN -40
#define INTAKE_AIR_TEMP_MAX 120
#define AMBIENT_AIR_TEMP_MIN -40
#define AMBIENT_AIR_TEMP_MAX 120
#define OIL_TEMP_MIN -40
#define OIL_TEMP_MAX 120
#define AMBIENT_AIR_TEMP_MIN -30
#define AMBIENT_AIR_TEMP_MAX 50
#define OIL_TEMP_MIN 0
#define OIL_TEMP_MAX 130
#define ENGINE_LOAD_MIN 0
#define ENGINE_LOAD_MAX 100
#define BATTERY_VOLTAGE_MIN 0