Страница 1 из 3 123 ПоследняяПоследняя
Показано с 1 по 10 из 24
  1. #1
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Нужна помощь с разроботкой для AEM EMS

    В общем стоит у меня карпс и блок управления двигателем AEM
    Нажмите на изображение для увеличения. 

Название:	AEM_EMS.jpg 
Просмотров:	936 
Размер:	71.0 Кб 
ID:	17647
    софт для блока управления бесплатный AEMPro http://www.aemelectronics.com/files/...ease070406.EXE
    В софте этом есть кнопка Dash, которое открывает отдельное окно с показаниями датчиков
    Нажмите на изображение для увеличения. 

Название:	AEMPro_Dash.jpg 
Просмотров:	1068 
Размер:	49.7 Кб 
ID:	17648

    Общается блок управления с карпс через переходник usb/com
    Настраивать мотор конечно не удобно через капс, а вот смотреть на показания датчиков очень бы хотелось через карпс, в то время пока я просто гоняю по дорогам общего пользования.
    Собственно мне как нить вытащить бы этот dash из AEMPro и засунуть в отдельную прогу которая просто коннектилась к мозгу выводила бы данные приборов без запуска AEMPro. Денег у меня конечно не вагон, но в долгу не останусь $$$

  2. #2
    Местный
    Регистрация
    20.09.2013
    Возраст
    43
    Сообщений
    131
    Вес репутации
    245

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    На диске случаем нет описания протокола работы?? Либо запускать СОМ -логгер и разбираться в алгоритме, но это гемор еще тот..

    А вот это на карпс не ставится чтоли http://www.aemelectronics.com/engine...s-software-78/
    Последний раз редактировалось Dim252; 08.04.2014 в 20:36.

  3. #3
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    AemData это все равно что пушкой по воробьям. Как то буржуи решают это дело

    http://www.youtube.com/watch?v=wOpP3CNgoEE
    http://www.youtube.com/watch?v=n3gq1LFmX4g

  4. #4
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Судя по этому видео, в кором чел рассказывает как подключать его софт, мозг умеет отдавать данные телеметрии


    Еще к мозгу можно подключать serial кабель и на него вешать показомеры. Что то мне подсказывает что решение совсем рядом и оно элегантно. Но я ни че не понимаю в программинге в среде win =(
    Последний раз редактировалось alexzlo; 12.04.2014 в 04:39.

  5. #5
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Оказывается в мозге можно включить телеметрию, тогда через rs232 он начинает отдавать данные для показа датчиков, температура, обороты и тд. Есть датчик (AEM Serial Data Gauge), уже установил, он берет сигнал с мозга (телеметрию) и выводит на экран. На основе этого буржуи разработали коробочку GaugeART, стоит бешеных денег и выводит все на андройд или IOS, нашел у них немного инфы по протаколу.

    Вот какое никакое описаниие протокола.
    Byte: Also known as data channel. There are nineteen data channels in the serial data stream. The numbered byte channel corresponds to the same numbered channel that gaugeART uses (eg. if “gauge 1″ is selected in gaugeDesigner, it will read the engine speed parameter.

    Name: Indicates which data parameter is being streamed in that data channel.

    Units: Units that the data channel is streamed in. The information is not important for the user, as gaugeART converts this to the unit displayed in gaugeDesigner.
    Min, Max, and Scalar: There are 256 bytes or “data buckets” that make up each data channel. The minimum and maximum values are spread over these 0-255 buckets where Min = 0 data bucket and Max = 255 data buckets. The separation of each bucket is the scalar.Example: if you view byte or channel 1, for engine speed, you will find that the minimum is 0 and the maximum is 25,600 (rounded to the ones decimal position). Each bucket is separated by 100. So, data bucket 0 = 0, 1 = 100, 2 = 200, 3 = 300, and so forth until 0 = 25,600.
    Вложение 18420

    Последний раз редактировалось alexzlo; 10.02.2015 в 15:34.

  6. #6
    Местный
    Регистрация
    20.09.2013
    Возраст
    43
    Сообщений
    131
    Вес репутации
    245

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Подключи комп.. запусти на нем программу Putty.exe и сними полный лог...
    Хотя и так впринципе понятно..
    Единственно интересно данные льются постоянно или по запросу..
    Неизвестна скорость отдачи данных 9600-115200 б\сек??

  7. #7
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Скорость 4800 или 9600 точно не помню. В принципе я умею программить на php, js. Посмотрел синтаксис C++ ничего сложного. Поставил себе Code::Blocks , написал первую в жизни программу "hello world"))) . Сейчас ищу инфу как сканировать usb порт.

  8. #8
    Местный
    Регистрация
    20.09.2013
    Возраст
    43
    Сообщений
    131
    Вес репутации
    245

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Цитата Сообщение от alexzlo Посмотреть сообщение
    Скорость 4800 или 9600 точно не помню. В принципе я умею программить на php, js. Посмотрел синтаксис C++ ничего сложного. Поставил себе Code::Blocks , написал первую в жизни программу "hello world"))) . Сейчас ищу инфу как сканировать usb порт.
    Вот зачем ты вперед паровоза побежал??? Сними лог.. Нафига тебе USB порт?? Тебе полюбому придется пользовать конвертер USB-COM

  9. #9
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Вот пошерстил еще по инету, нашел у буржуев

    1. confirmed AEM EMS is setup properly.
    2. connected PC directly to AEM EMS and monitored serial traffic with TTY application - confirmed AEM EMS is outputing telemetry.
    3. connected AEM to RT serial adaptor, and configured as "PC monitor only" using RT supplied null modem cable between serial adaptor and PC. Checked Monitor Lite and TTY application, and confirmed that no telemetry is reaching the PC.

    I have also swapped null modem cables with two others to confirm that it is not a null model problem. The issue appears to be with the RT serial adaptor. Can you please confirm?
    Here are screen shots to verify:

    AEM telemetry settings:



    Lite Monitor - this was with the "DL1 and PC Monitor" configuration - shows communication with DL1 is good, but no serial output:



    TTY output - PC & AEM EMS linked directly:



    no TTY output - configured as "PC monitor only" with serial data out to powered terminator and serial data in connected to PC with supplied RT null modem cable:


  10. #10
    Пользователь Аватар для alexzlo
    Регистрация
    20.01.2009
    Сообщений
    41
    Вес репутации
    203

    По умолчанию Re: Нужна помощь с разроботкой для AEM EMS

    Продолжаем. Я связался с парнем, который сделал лсд экранчик для мозга, он скинул мне ссылку, где он расписал как и что он делал:
    тут он разобрался с сигналом
    Исходный код его прошивки (сохраню для будущих поколений)
    ////////////////////////////////////////////////////////////////////////////////
    //
    // Author: Me
    //
    // Filename: MikroC Senior Project v1.3.c
    //
    // Title: AEM EMS Serial Data Display with Analog Sensors
    //
    // Date: 23FEB14
    //
    // Version: 1.3
    //
    // MCU: PIC16F887
    //
    // FOSC: External 20.0 MHz
    //
    // Config: CONFIG1 :$2007 : 0x23EA
    // CONFIG2 :$2008 : 0x0700
    //
    // Function: The program will read in data bytes via UART from an AEM Engine
    // Management System (EMS). It will then convert these bytes to a
    // human readable format and display them on a 40X2 character LCD
    // display.
    //
    // The program will also receive analog voltage values from two
    // external sensors. It will then scale these values to a human
    // readable format and display the values on the LCD display.
    //
    // Compiler: MikroC PRO for PIC v.6.0.1
    //
    ////////////////////////////////////////////////////////////////////////////////


    ////////////////////////////////////////////////////////////////////////////////
    // Changelog
    ////////////////////////////////////////////////////////////////////////////////
    //
    // 17FEB14 v1.0
    // - Initial Release
    // 19FEB14 v1.0.1
    // - Changed CONFIG2 to 0x0700 for BOR = 4.0V
    // - Added a delay at the beginning of the program to ensure voltage is
    // stable before writing to the LCD. Eliminates corruption on LCD from
    // voltage sag during engine start
    // 20FEB14 v1.1
    // - Removed constant float array for offset and scalar. Discovered that
    // memory would overflow and corrupt display. Placed offset and scalar
    // values inline with their respective functions. Overflow condition
    // has been eliminated.
    // - Removed constant offset and scalar for sensor ADC conversions
    // 21FEB14 v1.1.1
    // - Changed RA and RB debug output routine to always output so that
    // operations can be verified without PIC board. Also improves
    // stability of LCD display.
    // 22FEB14 v1.2
    // - Memory bug still persisted. Went into ICD mode and discovered that
    // if an input string into the UART was exceptionally long and
    // incorrect the code would lose its place after about 20 incorrect
    // input bytes. Removed the --stream_counter statement to break the
    // while loop. If checksum fails the stream_counter is reset to its
    // maximum value to avoid a major stream_counter overflow once it
    // rolls over 0. Tested with over 100 incorrect bytes and the system
    // remains still as expected vice creating havoc like corrupting
    // the LCD, locking up the UART, and causing a WDT reset event.
    // - Recreated offset and scalar arrays for simplified editing of the
    // values. Padded the first value of the array "[0]" with a null so
    // that the offset and scalar values can be changed in accordance with
    // what is provided in the telemetry settings. Byte 1 = offset and
    // scalar [1] vice offset and scalar [0]
    // - Removed most functions out of main and placed them in their own
    // space for better memory allocation.
    // - Removed the sprinti() function from the AFR calculations. Was
    // causing the function to overlap pages forcing a manual IRP address
    // condition. Removing this function saved 2655 program words and
    // 56 bytes of RAM! Manually recreated the AFR function similar to the
    // knock volts function. This causes an ugly leading 0 if the number
    // is less than 10. Ideally this should never be seen unless the O2
    // sensor is having issues. 7-9.99 AFR is just too rich for any normal
    // condition and should be eliminated immediately within the engine
    // tune. The leading 0 is tolerable given the major code savings.
    // - Generated preliminary code for the alarm function. The initial code
    // is located in the get_oil_psi() function and will need to be
    // relocated to main as a separate function. A case/switch
    // function needs to be developed to identify which parameter is in a
    // alarm condition along with a timer so that the user can identify
    // which one alarmed. Currently the function is too fast to identify
    // where the alarm came from if the faulty condition immediately
    // clears. Alarm sound is output on RC2 @ 5kHz 50% duty cycle.
    // - Fixed leading 0 in the AFR location. Added an if/else statement.
    // - Removed persistent RA and RB output as they had nothing to do with
    // LCD stability. That small time delay was only masking the dirty
    // little secret that the --stream_counter statement was causing.
    // 23FEB14 - Added alarm functions to boost, knock volts, and oil pressure.
    // Duration that alarm is active is about 3 seconds after clearing the
    // alarm condition so that the alarm can be recognized by the driver.
    // - Alarm sound is output on RC2 PWM output
    // - Alarm LED pulse is output on RC0

    ////////////////////////////////////////////////////////////////////////////////
    // Included Precompiled Libraries (c)2013 Mikroelektronika
    ////////////////////////////////////////////////////////////////////////////////
    // ADC
    // Conversions
    // C_String
    // C_Type
    // Lcd
    // Lcd_Constants
    // UART
    // PWM

    ////////////////////////////////////////////////////////////////////////////////
    // Define the connections from the PIC to the LCD display
    ////////////////////////////////////////////////////////////////////////////////

    // Corresponding LCD pin to PIC pin
    sbit LCD_RS at RD6_bit;
    sbit LCD_EN at RD7_bit;
    sbit LCD_D4 at RD0_bit;
    sbit LCD_D5 at RD1_bit;
    sbit LCD_D6 at RD2_bit;
    sbit LCD_D7 at RD3_bit;

    // Corresponding TRIS bit to change direction of the pin
    sbit LCD_RS_Direction at TRISD6_bit;
    sbit LCD_EN_Direction at TRISD7_bit;
    sbit LCD_D4_Direction at TRISD0_bit;
    sbit LCD_D5_Direction at TRISD1_bit;
    sbit LCD_D6_Direction at TRISD2_bit;
    sbit LCD_D7_Direction at TRISD3_bit;

    ////////////////////////////////////////////////////////////////////////////////
    // **Debug for testing project on EasyPICv7 Development Board
    ////////////////////////////////////////////////////////////////////////////////

    // Corresponding LCD pin to PIC pin
    // sbit LCD_RS at RB4_bit;
    // sbit LCD_EN at RB5_bit;
    // sbit LCD_D4 at RB0_bit;
    // sbit LCD_D5 at RB1_bit;
    // sbit LCD_D6 at RB2_bit;
    // sbit LCD_D7 at RB3_bit;

    // Corresponding TRIS bit to change direction of the pin
    // sbit LCD_RS_Direction at TRISB4_bit;
    // sbit LCD_EN_Direction at TRISB5_bit;
    // sbit LCD_D4_Direction at TRISB0_bit;
    // sbit LCD_D5_Direction at TRISB1_bit;
    // sbit LCD_D6_Direction at TRISB2_bit;
    // sbit LCD_D7_Direction at TRISB3_bit;

    ////////////////////////////////////////////////////////////////////////////////
    // Variables
    // All of the variables will be defined below
    ////////////////////////////////////////////////////////////////////////////////

    // Define the parameters that will be displayed on the LCD upon first
    // turn on. The write pids function will display this information.

    char pid_1 [] = "AFR:";
    char pid_2 [] = "OPSI:";
    char pid_3 [] = "kPa:";
    char pid_4 [] = "KNKV:";
    char pid_5 [] = "BST:";
    char pid_6 [] = "FPSI:";
    char pid_7 [] = "IDC:";
    char pid_8 [] = "TMNG:";
    char pid_9 [] = "";
    char pid_10 [] = "";
    char pid_11 [] = "";
    char pid_12 [] = "";
    char pid_13 [] = "";
    char pid_14 [] = "";
    char pid_15 [] = "";
    char pid_16 [] = "";
    char pid_17 [] = "";
    char pid_18 [] = "";
    char pid_19 [] = "";
    char vacuum [] = "VAC:";
    char warning [] = "**** ";

    const char pids = 8; // Baseline amount of items that will be shown on the LCD

    unsigned int pid_count = pids; // Establish the initial background LCD display

    const unsigned long baud_rate = 19200; // Establish baud rate for UART

    unsigned opsi_temp, fpsi_temp; // Raw values read from A/D converter

    char data_temp; // Temporary storage of data bytes read from UART

    char opsi_raw[4]; // Value to be displayed as oil pressure

    char fpsi_raw[4]; // Value to be displayed as fuel pressure

    char data_to_display[15]; // Untrimmed display data

    const int stream_size = 6; // Given by parameters in AEM configuration.
    // Subtract by one to get number of data bytes
    // which includes the checksum for later
    // calculation

    char stream_counter; // Temporary counter to store incoming data

    unsigned short data_bytes[stream_size]; // Create an array to store the input data bytes

    float conversion_buffer; // This is the buffer space to conduct calculations

    char output[15]; // Output array that will be displayed on the LCD

    char checksum; // Checksum variable to be evaluated against data_bytes[0]

    char i; // Simple one byte variable to be used in a for loop

    unsigned long eliminate_float; // Variable to eliminate scientific notation from a
    // floating point number that has fractional
    // values

    const float sensor_scalar = 0.4902; // Scalar value for analog sensors
    const float sensor_offset = -12.5; // Offset value for analog sensors
    const float scalar[]= // Scalar values that correspond with AEM telemetry settings
    {
    '\0', // Pad first location
    0.057188, // Byte 1
    1.226563, // Byte 2
    0.976563, // Byte 3
    0.019531, // Byte 4
    0.351562 // Byte 5
    };
    const float offset[]= // Offset values that correspond with AEM telemetry settings
    {
    '\0', // Pad first location
    7.32, // Byte 1
    2, // Byte 2
    0, // Byte 3
    0, // Byte 4
    -17 // Byte 5
    };

    char alarm_identifier; // Identifies which alarm is present
    const char low_oil_threshold = 10; // Threshold value for low oil pressure
    const char overboost_threshold = 170; // Threshold value for overboost condition in kPa
    const char knock_volts_threshold = 1.00; // Knock volts threshold
    char alarm_timer; // Variable to allow the alarm condition to persist after clearing


    ////////////////////////////////////////////////////////////////////////////////
    // Functions
    // Define and prototype functions to be used by the main program
    ////////////////////////////////////////////////////////////////////////////////

    void write_pids(pid_count) {

    //
    // Input the pid_count variable and traverse down the list of display values
    // decrementing the pid_count until 0 is reached. This will allow the
    // programmer to scale the program to accommodate a different LCD size
    //
    // Once the value of 0 has been reached exit the function as all desired
    // background characters have been written to the LCD
    //

    if (pid_count == 0)
    return;
    Lcd_Out(1,1,pid_1);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(1,11,pid_2);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(1,21,pid_3);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(1,31,pid_4);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(2,1,pid_5);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(2,11,pid_6);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(2,21,pid_7);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out(2,31,pid_8);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_9);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_10);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_11);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_12);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_13);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_14);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_15);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_16);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_17);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_18);
    --pid_count;

    if (pid_count == 0)
    return;
    Lcd_Out_Cp(pid_19);
    return;
    }

    void get_oil_pressure(){
    opsi_temp = ADC_Read(5); // Read from analog 5 for oil pressure
    ByteToStr(((opsi_temp >> 2)*sensor_scalar)+sensor_offset, opsi_raw); // Shift right by 2 and scale raw value to parameters given by sensor
    if ((((opsi_temp >> 2)*sensor_scalar)+sensor_offset) < low_oil_threshold){ // If OPSI is less than 10 set alarm_identifier to 1
    alarm_identifier=1;
    alarm_timer = 10;
    }
    Lcd_Out(1,17,opsi_raw); // Display actual pressure on the LCD
    return; // Exit the function with no return value
    }

    void get_fuel_pressure(){
    fpsi_temp = ADC_Read(6); // Read from analog 6 for fuel pressure
    ByteToStr(((fpsi_temp >> 2)*sensor_scalar)+sensor_offset, fpsi_raw); // Shift right by 2 and scale raw value to parameters given by sensor
    Lcd_Out(2,17,fpsi_raw); // Display actual pressure on the LCD
    return; // Exit the function with no return value
    }

    void fill_array(){
    --stream_counter; // Decrement counter to align with first position of array
    data_bytes[stream_counter] = data_temp; // If data byte received is not a header we need to store it
    // Save current data byte in first position of array
    return; // Exit the function with no return value
    }

    void calculate_checksum(){
    for(checksum = 0, i=1 ; i <= (stream_size-1); ++i){ // Set the checksum value to 0
    // Set the value of i to 1
    // Increment i for each loop
    // Loop while i <= stream_size-1
    checksum += data_bytes[i]; // sum each byte from the data_bytes array in the checksum location
    }
    return; // return with no value once all values have been summed
    }

    void display_AFR(){
    // Air to Fuel Ratio
    // Unit: AFR
    // Calculate the input byte in hex to a decimal value to be displayed
    // Format: ((data_byte[x]*offset value)+scalar value) = value in decimal

    // Save the calculated value in the conversion buffer
    conversion_buffer = ((data_bytes[5]*scalar[1])+offset[1]);
    // Multiply the value by 10 to remove the decimal points
    eliminate_float = conversion_buffer*10;

    if (eliminate_float >= 100) {
    // Determine the tens digit in the whole number section
    // Once determined add the character value of '0' to convert the
    // number to a writeable character
    output[0] = eliminate_float/100 + '0';
    // Determine the ones digit and find the modulo of 10
    // Add the character value of '0' to convert the number to a
    // writeable character
    output[1] = (eliminate_float/10) %10 + '0';
    // Add a decimal point character
    output[2] = '.';
    // Determine the tenths digit and find the modulo of 10
    // Add the character value of '0' to convert the number to a
    // writeable character
    output[3] = eliminate_float % 10 + '0';
    // Write a null to the array to symbolize the end of the string
    output[4] = '\0';
    // Display the data on the LCD at Row 1, Column 6
    Lcd_Out(1,6,output);
    }
    else {
    // Pad a blank space
    output[0] = 0x20;
    // Determine the ones digit and find the modulo of 10
    // Add the character value of '0' to convert the number to a
    // writeable character
    output[1] = (eliminate_float/10) %10 + '0';
    // Add a decimal point character
    output[2] = '.';
    // Determine the tenths digit and find the modulo of 10
    // Add the character value of '0' to convert the number to a
    // writeable character
    output[3] = eliminate_float % 10 + '0';
    // Write a null to the array to symbolize the end of the string
    output[4] = '\0';
    // Display the data on the LCD at Row 1, Column 6
    Lcd_Out(1,6,output);
    }
    return;
    }

    void display_engine_load(){
    // Engine Load
    // Unit: kPa
    // Calculate the input byte in hex to a decimal value to be displayed
    // Format: ((data_byte[x]*offset value)+scalar value) = value in decimal

    // Save the calculated value in the conversion buffer
    conversion_buffer = ((data_bytes[4]*scalar[2])+offset[2]);
    if (conversion_buffer > overboost_threshold) {
    alarm_identifier=3;
    alarm_timer = 10;
    }
    // Convert the value to a character string to the greatest whole number
    BytetoStr(conversion_buffer, output);
    // Display the data on the LCD at Row 1, Column 26
    Lcd_Out(1,26,output);
    return;
    }

    void display_boost_vac(){
    // Boost/Vac
    // Unit: PSIG or inHg
    // Calculate the input byte in hex to a decimal value to be displayed
    // Format: ((data_byte[x]*offset value)+scalar value) = value in decimal

    // Save the calculated value in the conversion buffer
    conversion_buffer = ((data_bytes[4]*scalar[2])+offset[2]);
    // If the manifold pressure is in a vacuum condition or <= 101.325 kPa
    if (conversion_buffer <= 101.325){
    // Convert the value to a character string to the greatest whole number in inHg
    BytetoStr(((conversion_buffer*-0.2953)+29.92), output);
    // Change the display to show VAC at Row 2, Column 1
    Lcd_Out(2,1,vacuum);
    // Display the data on the LCD at Row 2, Column 6
    Lcd_Out(2,6,output);
    }
    // If the manifold pressure is in a boost condition or > 101.325 kPa
    else {
    // Convert the value to a character string to the greatest whole number in PSIG
    BytetoStr(((conversion_buffer*0.145037738)-14.6959),output);
    // Change the display to show BST at Row 2, Column 1
    Lcd_Out(2,1,pid_5);
    // Display the data on the LCD at Row 2, Column 6
    Lcd_Out(2,6,output);
    return;
    }
    }

    void display_injector_duty(){
    // Injector Duty
    // Unit: Percentage
    // Calculate the input byte in hex to a decimal value to be displayed
    // Format: ((data_byte[x]*offset value)+scalar value) = value in decimal

    // Save the calculated value in the conversion buffer
    conversion_buffer = ((data_bytes[3]*scalar[3])+offset[3]);
    // Convert the value to a character string to the greatest whole number
    BytetoStr(conversion_buffer, output);
    // Display the data on the LCD at Row 2, Column 26
    Lcd_Out(2,26,output);
    // Add the percentage symbol after the data
    Lcd_Out(2,29,"%");
    return;
    }

    void display_knock_volts(){
    // Knock Volts
    // Unit: 0.00 - 5.00 Volts
    // Calculate the input byte in hex to a decimal value to be displayed
    // Format: ((data_byte[x]*offset value)+scalar value) = value in decimal to be displayed.

    // Save the calculated value in the conversion buffer
    conversion_buffer = ((data_bytes[2]*scalar[4])+offset[4]);
    if(conversion_buffer > knock_volts_threshold){
    alarm_identifier=2;
    alarm_timer = 10;
    }
    // Multiply the value by 100 to remove the decimal points
    eliminate_float = conversion_buffer*100;
    // Determine the first digit in the whole number section
    // Once determined add the character value of '0' to convert the
    // number to a writable character
    output[0] = eliminate_float/100 + '0';
    // Add a decimal point character
    output[1] = '.';
    // Determine the tenths digit and find the modulo of 10
    // Add the character value of '0' to convert the number to a
    // writable character
    output[2] = (eliminate_float/10) %10 + '0';
    // Determine the ones digit and find the modulo of 10
    // Add the character value of '0' to convert the number to a
    // writable character
    output[3] = eliminate_float % 10 + '0';
    // Write a null to the array to symbolize the end of the string
    output[4] = '\0';
    Lcd_Out(1,37,output);
    return;
    }

    void display_timing(){
    // Timing
    // Unit: Degrees
    // Calculate the input byte in hex to a decimal value to be displayed
    // Format: ((data_byte[x]*offset value)+scalar value) = value in decimal to be displayed.

    // Save the calculated value in the conversion buffer
    conversion_buffer = ((data_bytes[1]*scalar[5])+offset[5]);
    // Convert the value to a character string to the greatest whole number
    BytetoStr(conversion_buffer, output);
    // Display the data on the LCD at Row 2, Column 37
    Lcd_Out(2,37,output);
    // Add the degree symbol after the data
    // Character code is from LCD datasheet = 0xDF
    // Shows as German letter esszett below
    Lcd_Out(2,40,"&#223;");
    return;
    }

    void oil_pressure_alarm(){
    PWM1_Start(); // Turn on piezo speaker
    Lcd_Out(1,11,warning); // Output warning message **** on LCD
    return;
    }

    void knock_volts_alarm(){
    PWM1_Start(); // Turn on piezo speaker
    Lcd_Out(1,31,warning); // Output warning message **** on LCD
    return;
    }

    void overboost_alarm(){
    PWM1_Start(); // Turn on piezo speaker
    Lcd_Out(2,1,warning); // Output warning message **** on LCD
    return;
    }


    void check_alarm(){
    switch (alarm_identifier){
    case 0: // No alarm. Silence active alarms and exit
    PWM1_Stop(); // Turn off PWM output to RC2
    alarm_timer = 0; // Ensure that the timer is cleared
    break;
    case 1: // Low oil pressure
    oil_pressure_alarm();
    break;
    case 2: // High knock volts
    knock_volts_alarm();
    break;
    case 3: // Overboost
    overboost_alarm();
    break;
    default:
    return;
    }
    }

    void refresh_display(){ // This function will refresh the background labels on the LCD
    if (alarm_timer == 0){ // If alarm_timer has reached 0
    pid_count=pids; // Reset pid_count
    write_pids(); // Redisplay the background labels
    alarm_identifier = 0; // Set alarm_identifier to 0
    PORTC.B0 = 0; // Ensure that RC0 is cleared
    }
    else // If alarm_timer is != 0 then exit the function
    return;
    }

    void alarm_time_out(){ // Function to allow alarm to persist after condition is cleared
    if (alarm_timer > 0 ){ // If there is an active alarm decay the alarm_timer variable until 0
    -- alarm_timer;
    PORTC.B0 = ~PORTC.B0; // Invert RC0 to either illuminate or extinguish the LED
    refresh_display(); // Once 0 is reached refresh the background messages if not then carry on
    }
    else alarm_identifier = 0; // If alarm_timer == 0 them clear alarm by setting alarm identifier to 0
    return;
    }


    ////////////////////////////////////////////////////////////////////////////////
    // Main program
    ////////////////////////////////////////////////////////////////////////////////

    void main(){

    ////////////////////////////////////////////////////////////////////////////////
    // Initial setup
    ////////////////////////////////////////////////////////////////////////////////

    Delay_ms(2000); // 2 second delay to ensure voltage is stable
    TRISA = 0x00; // Set all of PORTA to outputs
    TRISB = 0x00; // Set all of PORTB to outputs
    TRISC = 0x80; // Set RC(7) as input rest as outputs
    TRISD = 0x00; // Set all of PORTD to outputs
    TRISE = 0x03; // Set RE(0:1) as input rest as outputs
    ANSEL = 0b0110000; // Configure AN(5:6) as analog and the rest as digital I/O
    ANSELH = 0x00; // Configure the rest of the analog pins to digital I/O
    C1ON_bit = 0; // Disable comparators
    C2ON_bit = 0; // Disable comparators
    UART1_Init(baud_rate); // Initialize UART module at 19200 bps
    Delay_ms(100); // Wait for UART to stabilize
    PWM1_Init(5000); // Init PWM output @ 5kHz on RC2
    PWM1_Set_Duty(128); // Set PWM for 50% duty cycle
    alarm_identifier = 0; // Set alarm identifier to 0
    PORTA = 0; // Clear all ports
    PORTB = 0;
    PORTC = 0;
    PORTD = 0;
    PORTE = 0;
    Lcd_Init(); // Initialize LCD for 4-bit communications
    Lcd_Cmd(_LCD_CLEAR); // Clear display
    Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
    write_pids(); // Write the background PIDS and prepare for data


    ////////////////////////////////////////////////////////////////////////////////
    // Main Loop
    ////////////////////////////////////////////////////////////////////////////////

    while(1){ // Infinite loop
    if(UART1_Data_Ready()) { // Is there a byte in the UART data buffer?
    data_temp = UART1_Read(); // If so then read the UART data buffer
    // PORTA = RCSTA; // **debug display RCSTA on PORTA (LED array) to show serial port status
    // PORTB = data_temp; // **debug display raw hex on PORTB (LED array) showing input serial data
    if (data_temp == 0x55){ // Header is received and need to gather data bytes
    stream_counter = stream_size; // Set counter to prepare for first data byte
    }
    else{ // If a header has not been received then the byte is usable data
    fill_array(); // Fill the data array with all data bytes and the checksum in (data_bytes[0])
    }

    while (stream_counter == 0) { // All bytes have been filled now it is time to manipulate and display them
    calculate_checksum(); // Verify that the last byte of the stream == the sum of data_bytes[5:1]

    if(checksum == data_bytes[0]) { // If checksum is correct proceed to manipulate and display the data
    // If checksum is not correct fall off the end and reset
    // the stream_counter to break the while loop also check oil and fuel pressures
    display_AFR(); // Display AFR on the LCD
    display_engine_load(); // Display load in kPa on the LCD
    display_boost_vac(); // Display boost or vacuum condition on the LCD
    display_injector_duty(); // Display injector duty cycle on the LCD
    display_knock_volts(); // Display knock volts on the LCD
    display_timing(); // Display timing degrees on the LCD
    }
    stream_counter = stream_size; // Reset stream_counter so that it breaks the loop
    get_fuel_pressure(); // Get and display fuel pressure from analog input
    get_oil_pressure(); // Get and display oil pressure from analog input
    check_alarm(); // Check if an alarm condition has been set
    alarm_time_out(); // Sound and display alarm for a specified time after cleared
    }
    }
    else; // No byte is ready to be read CLRWDT and loop back around
    asm{CLRWDT}; // Clear the watchdog after every pass if not then reset
    }
    }
    Схемы:
    Общая схема

    Блок питания

    Rs 232 конвертер

    Микронтроллер


    Вобщем в его борт журнале все есть, надеюсь на помощь....

Страница 1 из 3 123 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •