// MEMS thread handler
void mems(void const * arg){
	// Kalman filter state initilization
	KalmanState kstate;
	kstate.p = 0.0;
	kstate.k = 0.0;
	kstate.r = 50;
	kstate.q = 0.5;
	kstate.x = 0.0;
	
	float pitch = 0.0;
	
	mems_init();
	
	while(1){
		osSignalWait(MEMS_READY, osWaitForever);
	
		pitch = kalmanFilter(get_pitch_angle(), &kstate);
		
		// send a message to the display thread
		send_message(pitch, pitch_queue);
	}
}
示例#2
0
int main(int argc, char **argv)
{
  bool success = false;
  int cmd_idx = 0;
  mems_data data;
  mems_data_frame_80 frame80;
  mems_data_frame_7d frame7d;
  librosco_version ver;
  mems_info info;
  uint8_t* frameptr;
  uint8_t bufidx;
  uint8_t readval = 0;
  uint8_t iac_limit_count = 80; // number of times to re-send an IAC move command when

  // the ECU is already reporting that the valve has
  // reached its requested position
  int read_loop_count = 1;
  bool read_inf = false;

  // this is twice as large as the micro's on-chip ROM, so it's probably sufficient
  uint8_t response_buffer[16384];

  char win32devicename[16];

  ver = mems_get_lib_version();

  if (argc < 3)
  {
    printf("readmems using librosco v%d.%d.%d\n", ver.major, ver.minor, ver.patch);
    printf("Diagnostic utility using ROSCO protocol for MEMS 1.6 systems\n");
    printf("Usage: %s <serial device> <command> [read-loop-count]\n", basename(argv[0]));
    printf(" where <command> is one of the following:\n");
    for (cmd_idx = 0; cmd_idx < MC_Num_Commands; ++cmd_idx)
    {
      printf("\t%s\n", commands[cmd_idx]);
    }
    printf(" and [read-loop-count] is either a number or 'inf' to read forever.\n");

    return 0;
  }

  while ((cmd_idx < MC_Num_Commands) && (strcasecmp(argv[2], commands[cmd_idx]) != 0))
  {
    cmd_idx += 1;
  }

  if (cmd_idx >= MC_Num_Commands)
  {
    printf("Invalid command: %s\n", argv[2]);
    return -1;
  }

  if (argc >= 4)
  {
    if (strcmp(argv[3], "inf") == 0)
    {
      read_inf = true;
    }
    else
    {
      read_loop_count = strtoul(argv[3], NULL, 0);
    }
  }

  if (cmd_idx != MC_Interactive)
  {
    printf("Running command: %s\n", commands[cmd_idx]);
  }

  mems_init(&info);

#if defined(WIN32)
  // correct for microsoft's legacy nonsense by prefixing with "\\.\"
  strcpy(win32devicename, "\\\\.\\");
  strncat(win32devicename, argv[1], 16);
  if (mems_connect(&info, win32devicename))
#else
  if (mems_connect(&info, argv[1]))
#endif
  {
    if (mems_init_link(&info, response_buffer))
    {
      printf("ECU responded to D0 command with: %02X %02X %02X %02X\n\n",
             response_buffer[0], response_buffer[1], response_buffer[2], response_buffer[3]);

      switch (cmd_idx)
      {
      case MC_Read:
        while (read_inf || (read_loop_count-- > 0))
        {
          if (mems_read(&info, &data))
          {
            printf("RPM: %u\nCoolant (deg F): %u\nAmbient (deg F): %u\nIntake air (deg F): %u\n"
                   "Fuel temp (deg F): %u\nMAP (kPa): %f\nMain voltage: %f\nThrottle pot voltage: %f\n"
                   "Idle switch: %u\nPark/neutral switch: %u\nFault codes: %u\nIAC position: %u\n"
                   "-------------\n",
                   data.engine_rpm, data.coolant_temp_f, data.ambient_temp_f,
                   data.intake_air_temp_f, data.fuel_temp_f, data.map_kpa, data.battery_voltage,
                   data.throttle_pot_voltage, data.idle_switch, data.park_neutral_switch,
                   data.fault_codes, data.iac_position);
            success = true;
          }
        }
        break;

      case MC_Read_Raw:
        while (read_inf || (read_loop_count-- > 0))
        {
          if (mems_read_raw(&info, &frame80, &frame7d))
          {
            frameptr = (uint8_t*)&frame80;
            printf("80: ");
            for (bufidx = 0; bufidx < sizeof(mems_data_frame_80); ++bufidx)
            {
              printf("%02X ", frameptr[bufidx]);
            }
            printf("\n");

            frameptr = (uint8_t*)&frame7d;
            printf("7D: ");
            for (bufidx = 0; bufidx < sizeof(mems_data_frame_7d); ++bufidx)
            {
              printf("%02X ", frameptr[bufidx]);
            }
            printf("\n");

            success = true;
          }
        }
        break;

      case MC_Read_IAC:
        if (mems_read_iac_position(&info, &readval))
        {
          printf("0x%02X\n", readval);
          success = true;
        }
        break;

      case MC_PTC:
        if (mems_test_actuator(&info, MEMS_PTCRelayOn, NULL))
        {
          sleep(2);
          success = mems_test_actuator(&info, MEMS_PTCRelayOff, NULL);
        }
        break;

      case MC_FuelPump:
        if (mems_test_actuator(&info, MEMS_FuelPumpOn, NULL))
        {
          sleep(2);
          success = mems_test_actuator(&info, MEMS_FuelPumpOff, NULL);
        }
        break;

      case MC_IAC_Close:
        do
        {
          success = mems_test_actuator(&info, MEMS_CloseIAC, &readval);

          // For some reason, diagnostic tools will continue to send send the
          // 'close' command many times after the IAC has already reached the
          // fully-closed position. Emulate that behavior here.
          if (success && (readval == 0x00))
          {
            iac_limit_count -= 1;
          }
        } while (success && iac_limit_count);
        break;

      case MC_IAC_Open:
        // The SP Rover 1 pod considers a value of 0xB4 to represent an opened
        // IAC valve, so repeat the open command until the valve is opened to
        // that point.
        do
        {
          success = mems_test_actuator(&info, MEMS_OpenIAC, &readval);
        } while (success && (readval < 0xB4));
        break;

      case MC_AC:
        if (mems_test_actuator(&info, MEMS_ACRelayOn, NULL))
        {
          sleep(2);
          success = mems_test_actuator(&info, MEMS_ACRelayOff, NULL);
        }
        break;

      case MC_Coil:
        success = mems_test_actuator(&info, MEMS_FireCoil, NULL);
        break;

      case MC_Injectors:
        success = mems_test_actuator(&info, MEMS_TestInjectors, NULL);
        break;

      case MC_Interactive:
        success = interactive_mode(&info, response_buffer);
        break;

      default:
        printf("Error: invalid command\n");
        break;
      }
    }
    else
    {
      printf("Error in initialization sequence.\n");
    }
    mems_disconnect(&info);
  }
  else
  {
#if defined(WIN32)
    printf("Error: could not open serial device (%s).\n", win32devicename);
#else
    printf("Error: could not open serial device (%s).\n", argv[1]);
#endif
  }

  mems_cleanup(&info);

  return success ? 0 : -2;
}
示例#3
0
int main()
{
	lcd_init();
	uart1_init();
	mems_init();
	
	lcd_cmd(1);
	delay(1000);
	lcd_cmd(0x85);
	lcd_string("WELCOME");

	
	while(1)
	{
		delay(500);
		ch=mems_start();
		lcd_cmd(1);
		lcd_string("MEMS DATA");
		delay(500);


		if(ch==1)
		{
			delay(1000);
			uart1_data('S');
			lcd_cmd(1);
			lcd_cmd(0x80);
			lcd_data('S');
			lcd_cmd(0xc0);
			lcd_num(ch);
		}
		else if(ch==5)
		{
			delay(1000);
			uart1_data('F');
			lcd_cmd(1);
			lcd_cmd(0x80);
			lcd_data('F');
			lcd_cmd(0xc0);
			lcd_num(ch);
		}
		else if((ch==8)||(ch==9))
		{
			delay(1000);
			uart1_data('B');
			lcd_cmd(1);
			lcd_cmd(0x80);
			lcd_data('B');
			lcd_cmd(0xc0);
			lcd_num(ch);
		}

		else if((ch==21)||(ch==22))
		{
			delay(1000);
			uart1_data('L');
			lcd_cmd(1);
			lcd_cmd(0x80);
			lcd_data('L');
			lcd_cmd(0xc0);
			lcd_num(ch);
		}
		else if((ch==24)||(ch==25))
		{
			delay(1000);
			uart1_data('R');
			lcd_cmd(1);
			lcd_cmd(0x80);
			lcd_data('R');
			lcd_cmd(0xc0);
			lcd_num(ch);
		}
		mems_stop();
	}
}