📄 sensors.c
字号:
case MSG_END:
free(d->dp);
d->dp = NULL;
break;
case MSG_DRAW:
{
int circle_color;
if ((comport.status == READY) && device_connected)
circle_color = C_GREEN;
else if ((comport.status == NOT_OPEN) || (comport.status == USER_IGNORED))
circle_color = C_RED;
else
circle_color = C_DARK_YELLOW;
circlefill(screen, d->x-d->h/2, d->y+d->h/2-3, d->h/2-2, circle_color);
circle(screen, d->x-d->h/2, d->y+d->h/2-3, d->h/2-2, C_BLACK);
rectfill(screen, d->x, d->y, d->x+d->w-1, d->y+d->h-1, d->bg); // clear the text area
break;
}
case MSG_IDLE:
if ((d->d1 != device_connected) || (d->d2 != comport.status))
{
d->d1 = device_connected;
d->d2 = comport.status;
if (comport.status == READY)
{
if (device_connected)
sprintf(d->dp, " COM%i ready (device connected)", comport.number + 1);
else
sprintf(d->dp, " COM%i ready (device not responding)", comport.number + 1);
}
else
sprintf(d->dp, " COM%i could not be opened", comport.number + 1);
return D_REDRAWME;
}
}
return d_text_proc(msg, d, c);
}
#define SENSOR_LABEL_MARGIN 245
#define SENSOR_VALUE_INDENT 8
int sensor_proc(int msg, DIALOG *d, int c)
{
static int current_sensor = 0; // sensor we're working on
static int new_page = FALSE;
static int receiving_response = FALSE; // flag: receiving or sending
static int num_of_sensors_timed_out = 0;
static int ignore_device_not_connected = FALSE;
static int retry_attempts = NUM_OF_RETRIES;
static int active_sensor_found = FALSE;
static char vehicle_response[1024];
char buf[256];
char cmd[8];
int response_status = EMPTY; //status of the response: EMPTY, DATA, PROMPT
int response_type;
int ret = 0;
SENSOR *sensor = (SENSOR *)d->dp3; // create a pointer to SENSOR structure in dp3 (vm)
if ((msg == MSG_IDLE) && reset_hardware && comport.status == READY) // if user hit "Reset Chip" button, and we're doing nothing
{
reset_hardware = FALSE;
receiving_response = FALSE;
reset_chip();
return D_O_K;
}
if (!sensor && (msg != MSG_DRAW)) // don't wanna handle any messages for an empty sensor line except MSG_DRAW
return D_O_K;
switch (msg)
{
case MSG_START:
if (d->d1 == 0)
{
stop_serial_timer();
receiving_response = FALSE;
device_connected = FALSE;
ignore_device_not_connected = FALSE;
num_of_disabled_sensors = 0;
}
d->d2 = 0;
d->flags &= ~D_DISABLED;
// fall through
case MSG_UPDATE:
if (d->d1 == 0) // if it's the first sensors in sensor_dialog
{
current_sensor = 0;
num_of_sensors_timed_out = 0;
active_sensor_found = FALSE;
new_page = TRUE;
// page was flipped, reset refresh rate variables
inst_refresh_rate = 0;
avg_refresh_rate = 0;
refresh_time = 0;
}
if ((sensor->enabled && d->flags & D_DISABLED) || (!sensor->enabled && !(d->flags & D_DISABLED)))
d->d2 = 1;
d->flags |= D_DIRTY;
break;
case MSG_END:
if (d->d1 == sensors_on_page - 1)
stop_serial_timer();
d->dp3 = NULL;
break;
case MSG_TOGGLE:
if((d->d1 == c) || ((c == -2) && !(d->flags & D_DISABLED)) || ((c == -1) && (d->flags & D_DISABLED)))
{
if (d->flags & D_DISABLED)
{
d->flags &= ~D_DISABLED;
sensor->enabled = TRUE;
num_of_disabled_sensors--;
strcpy(sensor->screen_buf, "N/A");
}
else
{
d->flags |= D_DISABLED;
sensor->enabled = FALSE;
num_of_disabled_sensors++;
strcpy(sensor->screen_buf, "not monitoring");
if (d->d1 == current_sensor)
{
receiving_response = FALSE;
stop_serial_timer();
}
if (num_of_disabled_sensors == sensors_on_page) // if all of the sensors are disabled
num_of_sensors_timed_out = 0; // reset timeout counter
}
return D_REDRAWME;
}
break;
case MSG_DRAW:
if (d->d2)
{
d->d2 = 0;
broadcast_dialog_message(MSG_TOGGLE, d->d1);
}
rectfill(screen, d->x, d->y, d->x+d->w-1, d->y+d->h-1, d->bg); // clear the element
if (sensor)
{
gui_textout_ex(screen, sensor->label, d->x + SENSOR_LABEL_MARGIN - gui_strlen(sensor->label), d->y, d->fg, d->bg, FALSE);
gui_textout_ex(screen, sensor->screen_buf, d->x + SENSOR_LABEL_MARGIN + SENSOR_VALUE_INDENT, d->y, ((d->flags & D_DISABLED) ? gui_mg_color : d->fg), d->bg, FALSE);
}
return D_O_K;
case MSG_IDLE:
if (d->d1 == current_sensor)
{
if (comport.status == READY)
{
if (d->flags & D_DISABLED)
calculate_refresh_rate(SENSOR_OFF); // calculate instantaneous/average refresh rates
if (!receiving_response)
{
if (d->flags & D_DISABLED) // if the sensor is disabled
{
current_sensor = (current_sensor == sensors_on_page - 1) ? 0 : current_sensor + 1; // go to the next sensor
return D_O_K;
}
sprintf(cmd, "01%s", sensor->pid);
send_command(cmd); // send command for that particular sensor
new_page = FALSE;
receiving_response = TRUE; // now we're waiting for response
start_serial_timer(OBD_REQUEST_TIMEOUT); // start the timer
vehicle_response[0] = '\0'; // clear string
}
else // if we are receiving response
{
response_status = read_comport(buf); // read comport
if (d->flags & D_DISABLED) // if the sensor is disabled
{
current_sensor = (current_sensor == sensors_on_page - 1) ? 0 : current_sensor + 1; // go to the next sensor
return D_O_K;
}
if (response_status == DATA) // if data detected in com port buffer
{
strcat(vehicle_response, buf); // append contents of buf to vehicle_response
}
else if (response_status == PROMPT) // if '>' detected
{
device_connected = TRUE;
num_of_sensors_timed_out = 0;
receiving_response = FALSE; // we're not waiting for response any more
stop_serial_timer();
if (new_page)
break;
strcat(vehicle_response, buf); // append contents of buf to vehicle_response
sprintf(cmd, "01%s", sensor->pid);
response_type = process_response(cmd, vehicle_response);
if (response_type == HEX_DATA) // HEX_DATA received
{
sprintf(cmd, "41%s", sensor->pid);
if (find_valid_response(buf, vehicle_response, cmd, NULL))
{
active_sensor_found = TRUE;
calculate_refresh_rate(SENSOR_ACTIVE); // calculate instantaneous/average refresh rates
buf[4 + sensor->bytes * 2] = 0; // solves problem where response is padded with zeroes (i.e., '41 05 7C 00 00 00')
sensor->formula((int)strtol(buf + 4, NULL, 16), buf); //plug the value into formula
strcpy(sensor->screen_buf, buf); // and copy result in screen buffer
/* if current_sensor is the last sensor, set it to 0; otherwise current_sensor++ */
current_sensor = (current_sensor == sensors_on_page - 1) ? 0 : current_sensor + 1;
retry_attempts = NUM_OF_RETRIES;
return D_REDRAWME;
}
else
response_type = ERR_NO_DATA;
}
strcpy(sensor->screen_buf, "N/A");
if (active_sensor_found)
calculate_refresh_rate(SENSOR_NA); // calculate instantaneous/average refresh rates
if (response_type == ERR_NO_DATA) // if we received "NO DATA", "N/A" will be printed
{
current_sensor = (current_sensor == sensors_on_page - 1) ? 0 : current_sensor + 1; // next time poll next sensor
retry_attempts = NUM_OF_RETRIES;
}
else if (response_type == BUS_ERROR || response_type == UNABLE_TO_CONNECT || response_type == BUS_INIT_ERROR)
{
display_error_message(response_type, FALSE);
retry_attempts = NUM_OF_RETRIES;
}
// for other errors, try to re-send the request, do nothing if successful and alert user if failed
else
{
if (retry_attempts > 0)
{
retry_attempts--;
return D_O_K;
}
else
{
display_error_message(response_type, FALSE);
retry_attempts = NUM_OF_RETRIES; // reset the number of retry attempts
}
}
return D_REDRAWME; //tell the parent control to redraw itself
}
}
}
if (serial_time_out) // if timeout occured,
{
receiving_response = FALSE; // we're not waiting for a response any more
strcpy(sensor->screen_buf, "N/A");
if (num_of_sensors_timed_out >= SENSORS_TO_TIME_OUT)
{
num_of_sensors_timed_out = 0;
device_connected = FALSE;
if (!ignore_device_not_connected)
{
ret = alert3("Device is not responding.", "Please check that it is connected", "and the port settings are correct", "&OK", "&Configure Port", "&Ignore", 'o', 'c', 'i');
if (ret == 2)
display_options(); // let the user choose correct settings
else if (ret == 3)
ignore_device_not_connected = TRUE;
}
}
else
num_of_sensors_timed_out++;
while (comport.status == NOT_OPEN)
{
if (alert("Port is not ready.", "Please check that you specified the correct port", "and that no other application is using it", "&Configure Port", "&Ignore", 'c', 'i') == 1)
display_options(); // let the user choose correct settings
else
comport.status = USER_IGNORED;
}
stop_serial_timer();
/* if current_sensor is the last sensor, set it to 0; otherwise current_sensor++ */
current_sensor = (current_sensor == sensors_on_page - 1) ? 0 : current_sensor + 1;
return D_REDRAWME;
}
}
break;
} // end of switch (msg)
if (d->flags & D_DISABLED)
{
strcpy(sensor->screen_buf, "not monitoring");
}
return D_O_K;
}
void engine_rpm_formula(int data, char *buf)
{
if (system_of_measurements == METRIC)
sprintf(buf, "%i r/min", (int)((float)data/4));
else // if the system is IMPERIAL
sprintf(buf, "%i rpm", (int)((float)data/4));
}
void engine_load_formula(int data, char *buf)
{
sprintf(buf, "%.1f%%", (float)data*100/255);
}
void coolant_temp_formula(int data, char *buf)
{
if (system_of_measurements == METRIC)
sprintf(buf, "%i%c C", data-40, 0xB0);
else // if the system is IMPERIAL
sprintf(buf, "%i%c F", (int)(((float)data-40)*9/5 + 32), 0xB0);
}
void fuel_system_status_formula(int data, char *buf)
{
if (data == 0)
sprintf(buf, "unused");
else if (data == 0x01)
sprintf(buf, "open loop");
else if (data == 0x02)
sprintf(buf, "closed loop");
else if (data == 0x04)
sprintf(buf, "open loop (driving conditions)");
else if (data == 0x08)
sprintf(buf, "open loop (system fault)");
else if (data == 0x10)
sprintf(buf, "closed loop, O2 sensor fault");
else
sprintf(buf, "unknown: 0x%02X", data);
}
void fuel_system1_status_formula(int data, char *buf)
{
fuel_system_status_formula((data >> 8) & 0xFF, buf); // Fuel System 1 status: Data A
}
void fuel_system2_status_formula(int data, char *buf)
{
fuel_system_status_formula(data & 0xFF, buf); // Fuel System 2 status: Data B
}
void vehicle_speed_formula(int data, char *buf)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -