View Single Post
Old 07-11-2008, 10:39 AM   #92 (permalink)
n8thegr8
EcoModding Lurker
 
Join Date: Jun 2008
Location: USA
Posts: 32

N8sPony - '98 Ford Mustang
Thanks: 0
Thanked 0 Times in 0 Posts
the arduino software has the serial monitor, so after you compile and load it, you can click the serial monitor button on the top right and watch what's going through the serial tx/rx. I've been using serial.println() to send my variables to the console to make sure I've got the correct values. you just set the baud rate to whatever you set it to when you did Serial.begin() in your code. As far as the lcd goes, I think you'd be better off using LCD4Bit, it's a lot cleaner and simpler. I couldn't figure out how to check in my code to the repository, so I'll just post it here if you want to see how I'm doing the LCD stuff:

Code:
/*
    OpenScanGauge PWM
    Author: Nathan Weigl
    
    This program sends commands to and reads responses from a vehicle's ECU using the
    J1850-PWM OBDII Protocol (mostly ford vehicles). This program could be easily 
    adapted to work on the J1850-VPW Protocol (mostly General Motors) as well 
    with slight modifications, and may be done in future versions. This program was
    also built with scalability in mind, so it is relatively easy to add more commands
    as you please.
*/

#undef int
#include <LCD4Bit.h> 
#include <stdio.h>

//create lcd object for 4 lines
LCD4Bit lcd = LCD4Bit(4); 

double vss;
double maf;
double mpg;
int rpm;

//pins to use for data
int busneg=3;
int buspos=4;

//arrays to store values returned from ECU
int vss_byte[4]={0,0,0,0};
int maf_byte[4]={0,0,0,0};
int rpm_byte[4]={0,0,0,0};

//hex commands for speed, MAF, and rpm
char *vss_cmd[] = {"61", "6A", "F1", "01", "0D", "8B"};
char *maf_cmd[] = {"61", "6A", "F1", "01", "10", "C7"};
char *rpm_cmd[] = {"61", "6A", "F1", "01", "0C", "96"};

//array to look up binary values for hex chars
char *hexconvert[16][2] = {{"0","0000"},{"1","0001"},{"2","0010"},{"3","0011"},{"4","0100"},{"5","0101"},{"6","0110"},{"7","0111"},{"8","1000"},{"9","1001"},{"A","1010"},{"B","1011"},{"C","1100"},{"D","1101"},{"E","1110"},{"F","1111"}};
char vss_str[5];
char mpg_str[4];
char rpm_str[5];
void pwm_send(char **cmd);

void setup() {
   lcd.init();
}

void loop() {  
  getValues();
  printOutput();
}

/* Format and Display data on LCD */
void printOutput() {
  lcd.clear();
  lcd.cursorTo(1,0);
  lcd.printIn("MPG: ");
  lcd.cursorTo(1,5);
  mpg =(7107 * vss) / maf;
  sprintf(mpg_str, "%d.%d", mpg/10, mpg-((mpg/10)*10));
  lcd.printIn(mpg_str);
  lcd.cursorTo(1,9);
  lcd.printIn("Speed: ");
  lcd.cursorTo(1,16);
  vss = ((vss * 6214)/10000);
  sprintf(vss_str, "%d", vss);
  lcd.printIn(vss_str);
  lcd.cursorTo(3,0);
  lcd.printIn("RPM: ");
  lcd.cursorTo(3,5);
  sprintf(rpm_str, "%d", rpm);
  lcd.printIn(rpm_str);
  delay (1000);
}

/* retrieve data for display */
void getValues() {
    pwm_send(vss_cmd);
    pwm_read(vss_byte);
    vss = vss_byte[0];
    pwm_send(rpm_cmd);
    pwm_read(rpm_byte);
    rpm = (rpm_byte[0] * 256 + rpm_byte[1])/4;
    pwm_send(maf_cmd);
    pwm_read(maf_byte);
    maf = ((256 * maf_byte[0]) + maf_byte[1])/100;
}

/* send command to ECU */
void pwm_send(char **cmd) {
    char bincmd[48];
    hex2bin(cmd, bincmd);
    pinMode(busneg, OUTPUT);
    pinMode(buspos, OUTPUT);
    
    //send SOF and drop back to neutral
    digitalWrite(buspos, HIGH);
    digitalWrite(busneg, LOW);
    delayMicroseconds(32);
    digitalWrite(buspos, LOW);
    digitalWrite(busneg, LOW);
    
    //loop through array of bits
    for (int i=0; i < 48; i++) {
        //send 0
        if (bincmd[i] == '0') {
            digitalWrite(buspos, HIGH);
            digitalWrite(busneg, LOW);
            delayMicroseconds(16);          //bus active for 16us represents a 0
            digitalWrite(buspos, LOW);
            digitalWrite(busneg, LOW);
        }
        //send 1 
        else if (bincmd[i] == '1') {
            digitalWrite(buspos, HIGH);
            digitalWrite(busneg, LOW);
            delayMicroseconds(8);           //bus active for 8us represents a 1
            if (i != 47) {
            digitalWrite(buspos, LOW);
            digitalWrite(busneg, LOW);
            } else {
            delayMicroseconds(72);          //if last bit, send EOF
            }
        }
    }
}

/* Read transmission from ECU */
void pwm_read(int *bytes) {
    char bitread[32];               //store data bits that we actually care about
    unsigned long duration[80];     //store all bits for processing
    pinMode(busneg, INPUT);
    pinMode(buspos, INPUT);
    for (int i=0; i < 80; i++) {
        duration[i]=pulseIn(buspos, HIGH);      //fill array with microsec. times for interpretation later
        if (duration[i] < 48) {
            i = 83;                             //if EOF detected, kill loop
        }
    }
    int j=0;
    
    /* translate data portion of frame to bits */
    for (int i=40; i < 72; i++) {
        if (duration[i] < 14) {
            bitread[j] = '1';
        } else if (duration[i] > 14 and duration[i] < 24) {
            bitread[j] = '0';
        }
        j++;
    }
    bin2dec(bitread, bytes);             //send bits off for processing to ints
}

/* convert hex command to binary */
void hex2bin(char **cmd, char *bincmd) {
    int binloc = 0;
    for(int i=0; i < 6; i++) {
        for(int j=0; j < 16; j++) {
            if (cmd[i][0] == hexconvert[j][0][0]) {
                for (int k=0; k < 4; k++) {
                    bincmd[binloc] = hexconvert[j][1][k];
                    binloc++;
                }
              }
        }
        for(int j=0; j < 16; j++) {
            if (cmd[i][1] == hexconvert[j][0][0]) {
                for (int k=0; k < 4; k++) {
                bincmd[binloc] = hexconvert[j][1][k];
                binloc++;
                }
            }
        }
    }
}

/* convert binary bits to decimal numbers */
void bin2dec(char *cmd, int *numbers) {
    int val = 128;
    int i=0;
    for (int j=0; j < 32; j++) {
        if (cmd[j] == '1') {
            numbers[i] = numbers[i] + val;
            val = val/2;
        } else if (cmd[j] == '0') {
            val = val/2;
        }
        if (val < 1) {
            val = 128;
            i++;
        }
    }
}
  Reply With Quote