⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensors.c

📁 OBDII的ScanTool源码,对此有兴趣的朋友可以参考一下
💻 C
📖 第 1 页 / 共 4 页
字号:
      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 + -