Problem with my car project using MAX31850's

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
Avinitlarge
 
Posts: 9
Joined: Tue Jun 10, 2014 7:53 am

Problem with my car project using MAX31850's

Post by Avinitlarge »

Right, I will try and explain this the best I can, I am a total noob BTW
I am using an Arduino Mega 2560 with 2 MAX31850's to record ait and exhaust gas temperature. The date is send from the cars ECU to the arduino then to the laptop, This part works fine. Now, I am trying to add the data from the thermo couples into the ECU datastream. Using the sketch below but the Computer isnt seeing the data from the onewire.

I tried the dallas multiple example and it all worked fine

I didnt write the sketch BTW, is from someone working on the same project but they are non using onewire

Code: Select all

/* Written by Venderbroeck. */
/*free to use, but a reference would be nice =) */

//setting up onewire temperature stuff
  #include <OneWire.h>
  #include <DallasTemperature.h>
  #include <LiquidCrystal.h>
  
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 6

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
  
  //pass oneWire reference to Dallas Temperature
  DallasTemperature sensors(&oneWire);

  // assign device address manually.  the addresses below will beed to be changed
  // to valid device addresses on your bus. So find these first with a seperate sketch.
  uint8_t Thermo1[8] = {0x3B, 0x08, 0x2F, 0x18, 0x00, 0x00, 0x00, 0xB0};
  uint8_t Thermo2[8] = {0x3B, 0x89, 0x32, 0x18, 0x00, 0x00, 0x00, 0xFD};
 
 //Setting up LCD
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // set LCD interface pins
 
/*declaring some variables to use in the code*/
 //creating arrays to store dataframes in.
 //'storage' is used to store a ECU dataframe. Arduino can make use of the data present in the array.
 //The array is refreshed everytime a new dataframe comes in.
 //storage2 is used for the arduino dataframe to send arduino data to pc.
 //storage2 will need to be bigger if you want to store
 //more variables from additional inputs.
 int storage[60];  //ecudataframe[60]
 int storage2[26]; //arddataframe[26]
 
 //declaring variables byteIn, and byteIn2 in which to temporarely store bytes recieved by
 //the two serial connections.
 int byteIn = 0;   //same
 int byteIn2 = 0; //same
 
 //declaring bools for header recognition script
 bool checkheader1 = false;
 bool checkheader2 = false;
 
 //declaring trigger bool, used to trigger void loop script
 bool trigger = false; //frametrigger
 
 //counter for the loop filling the storage array with data from the ECU 
 int i = 1; // same
 
 //counter for sending storage2 contents to PC.
 int j = 1; // same
 
 //header and footer used when sending arduino frame
 int header1 = 95;  //0x5F
 int header2 = 175; //0xAF
 int footer1 = 180; //0xB4
 int footer2 = 100; //0x64

 //vars for EGT
 long egttemp = 0;
 byte egtfinal = 0;

 //vars for IAT
 int iattemp = 0;
 byte iatfinal = 0;
 
 //Declaring the vars first. I just do this to keep track of the
 //vars I'm using, and their function. Making them 0 first, their value
 //will be updated when the trigger is set, indicating new ECU data has
 //been received.
 int RPMvalue = 0;
 int IDCvalue = 0;
 int TPSvalue = 0;
 int AFRvalue = storage[12];

/*void setup is ran once at startup. Here the (empty) arduino dataframe skeleton
is created, and the serial connections are initialized*/
void setup() {
  
 /*configuring lcd stuff*/
 
 lcd.begin(20, 4); // set the LCD's columns and rows
 
// Setup static characters on the lcd

lcd.setCursor(2,0);
lcd.print("RPM:");
lcd.setCursor(2,1);
lcd.print("IDC:");
lcd.setCursor(2,2);
lcd.print("TPS:");
lcd.setCursor(2,3);
lcd.print("AFR:");
 
  
/*configuring onewire temperature stuff*/

  // Start up the library
  sensors.begin();
  
  // set the resolution to 9 bit
  sensors.setResolution(Thermo1, 9);
  sensors.setResolution(Thermo2, 9);

/*storing the header and footer data  in the storage2 array, thus constructing
the arduino data frame skeleton. if you want to store more data in the frame, 
the footer bytes need to be moved (and the array enlarged) to allow for the data to 
be stored in between. So in this example four variables can be sent with the arduino frame.*/
 storage2[1] = header1;
 storage2[2] = header2;
 storage2[7] = footer1;
 storage2[8] = footer2;

/*start up the serial connections
serial (=serial0) is used for USB connectivity.
serial3 is connected to the ECU k-line through a MC33290 chip connected to pins 14, and 15*/

 Serial.begin(125000); 
 Serial3.begin(125000);

}



/* Void loop is the main loop which is ran continuously.
The script it contains sends the arduino dataframe to the pc, when the storing 
of the incoming ECU frame is completed. 
Instead or alongside of this, you can add any code you want, to manipulate the data in the arrays. 
Things like lcd screens, buzzers, and buttons come to mind.*/

void loop() {
  
  /* this script get data from some arduino analog pins and stores them in storage2 
  in between header and footer. 
  It's important to realize, the arduino uses values 0-1023 to define the state of an analog
  pin. To be able to store it in a byte (0-255) I just divide by 4.

  The script only runs when the array is fully updated (trigger == true). 
  This is to maintain synchronisation between the ECU and Arduino dataframes.
  This may not allways be needed, but it can provide a way of throtteling things
  like lcd refreshes etc.*/
   if (trigger == true) { 
    
   //example of fetch and calculation of egt temp
   //here egt temperature is devided by 4 to make it fit into a single byte
   //you need to multiply the value by 4 again in Tunerpro.
   egttemp = sensors.getTempC(Thermo1);
   egttemp = egttemp / 4;
   egtfinal = egttemp;
   storage2[3] = egtfinal;
   
   //example of fetch and calculation of IAT temp
   //here division by 4 isn't needed because the iat temp isn't expected
   //to reach over 255 degrees C. (Both these temps are in celcius they can be converted
   //to fahrenheid like in the example).
   iattemp = sensors.getTempC(Thermo2);
   iattemp = iattemp / 4;
   iatfinal = iattemp;
   storage2[4] = iatfinal;

   //fetching analog pin 0
  // storage2[5] = analogRead(0) / 4;
   
   //fetching analog pin 10
 //  storage2[6] = analogRead(10) / 4;
   


  /*the following script sends data from storage2 through serial (USB).  */
    //reset j first
   j = 1;
   //send the frame byte by byte from the storage2 array
   while (j < 9){
      Serial.write(storage2[j]);
      j++;
   }

  /*all the extra stuff has been sent to the PC, so now we update the LCD*/
  
  //rpm start
    // calculations to get rpm
     RPMvalue = (RPMvalue * 30);
     lcd.setCursor(8,0);
     lcd.print(RPMvalue,1); // Prints the rpm figure
  //rpm end  
  
  //idc start
    // calculations to get idc
     IDCvalue = (((IDCvalue *2)/1000)/1200);
     lcd.setCursor(8,1);
     lcd.print(IDCvalue,1); // Prints the idc figure
  //idc end
  
  //tps start
    // calculations to get rpm
    TPSvalue = (TPSvalue *0.4166667);
    lcd.setCursor(8,2);
    lcd.print(TPSvalue,1); // Prints the tps figure
  //tps end
    
  //afr start
    // calculations to get rpm
    AFRvalue = (AFRvalue -80);
    lcd.setCursor(8,3);
    lcd.print(AFRvalue,1); // Prints the afr figure
  //afr end
 
 /*end of lcd updating procedure*/
 
  //reset the trigger to exit the script after sending the frame
   trigger = false;
   


}

  }
  
  
  
/*the next script runs when the arduino recieves bytes on serial (= serial0 = USB) from the computer.
void serialEvent runs in between individual void loop iterations, so if the void 
loop takes too long to complete, serial data will build up and fill the buffer, 
probably causing a crash. Using delay() in the main loop is, therefore, not recommended.

Incoming bytes are sent directly through to the ECU over serial3, 
so commands can be given to the ECU in the usual way.*/

 void serialEvent() {
     //Run the while loop for as long as serial data is available.
      while (Serial.available() ) {
      //reset byteIn variable. Might be redundant.
       byteIn2 = 0;
      //take byte out of the buffer and store it in byteIn2.
       byteIn2 = Serial.read();
      }
      //send byteIn2 to ECU
       Serial3.write(byteIn2);
       
       //If the hex number 0xEE is sent from the PC, Arduino responds with dataframe
       //This can be used for testing in realterm for example.
       if(byteIn2 == 0xEE) {
        trigger = true; 
       }
   }
  
  
  

/*the next script runs when the arduino recieves bytes on serial3 (from the ECU).
void serialEvent3 runs in between individual void loop iterations, so if the void 
loop takes too long to complete, serial data will build up and fill the buffer, 
probably causing a crash. Using delay() in the main loop is, therefore, not recommended.

Any recieved bytes are sent directly through to the PC via serial, to ensure the datastream 
to the PC isn't interrupted.
Meanwhile it will look for the ECU headerstring in the data it recieves 
from the ECU. If the headerstring is found, it will store the next 46 bytes
(the body of the ECU dataframe) at the corresponding positions in the array 'storage'. 
The ECU header and footer bytes are clipped off, so rpm will be at storage[1] etc.).
All the positions of the data in the ECU dataframe can be found in the standard adx file.
Keep in mind the adx file starts at 0, and the 'storage' array starts at 1, so increment the 
position of the value in the adx file by 1 to find it in the 'storage' array.
This means the dataframe from the ECU can be used by the arduino to do whatever 
you want with. 
Finally when the array is fully updated, the frame is assumed to be received, and so 
the trigger is set to true to trigger the script in void loop to do work and send the arduino frame
directly after the ECU frame. 
This way the arduino, and the ECU dataframes are allways synced.*/

 void serialEvent3() {
  //Run the while loop for as long as serial data is available.
  //Keep in mind the whole loop will iterate once for each incoming byte.
   while (Serial3.available() ) {
    //reset byteIn variable. Might be redundant.
    byteIn = 0;
    //take byte out of the serial 3 buffer and store it.
    byteIn = Serial3.read();
    //send the byte directly through serial connection 0 (USB)
    Serial.write(byteIn);


    /*the next if statements need to be ran in this specific order.
    They look for the header and store the ECU dataframe in 'storage' for 
    later use by the arduino. The bytes they store have allready been forwarded to 
    the USB serial connection, so this array is purely meant for use by the arduino.
    This pile of statements still needs refinement
    ECU header = 5A A5
    ECU footer = AA 5F */


    //If both the headerbytes have been recieved and i == 49,
    //the loop storing the body has allready been completed, so 
    //both checkheader triggers reset to false and i resets to 1
    //Also it will set the void loop trigger to true to run the script it contains.
      if (checkheader1 == true && checkheader2 == true && i == 47) {
       checkheader1 = false;
       checkheader2 = false;
       trigger = true;
       i = 1; 

     }

    //ERRORCHECK
    //If first headerbyte was recieved, and the second was not, 
    //and the byte stored isn't A5, something went 
    //wrong and checkheader1, and i both reset.
      if (checkheader1 == true && checkheader2 == false && byteIn != 0xA5) {
       checkheader1 = false;
       i = 1;
      }

    /*The actual part filling the array. Everytime the while(serial available())
    loop iterates, and the headertriggers are set true, and nothing was changed 
    above this will write the byte stored in byteIn to the proper place in storage. 
    Note that i is incremented here each iteration. When it reaches 47 (all bytes recieved)
    all triggers, including i are reset above in the next loop iteration. */
     if(checkheader1 == true && checkheader2 == true) {
        storage[i] = byteIn;
     i++;

     }
     
    //if byteIn contains the first headerbyte, checkheader1 is set to true
     if (checkheader1 == false && byteIn == 0x5A) {
         checkheader1 = true;
     }
   

    //if the first headerbyte has been received, and byteIn contains the 
    //second headerbyte, checkheader 2 is set to true
      if(checkheader1 == true && byteIn == 0xA5) {
        checkheader2 = true;
      }
   
   //end of while serial3.available loop
   }    
 //end of void serial.event3 
 }
Last edited by Avinitlarge on Fri Jun 13, 2014 12:25 pm, edited 1 time in total.

User avatar
Franklin97355
 
Posts: 23939
Joined: Mon Apr 21, 2008 2:33 pm

Re: Problem with my car project using MAX31850's

Post by Franklin97355 »

Have you tried any sample code to see if the MAX31850's and the Arduino are communicating without any other processes going on?

Avinitlarge
 
Posts: 9
Joined: Tue Jun 10, 2014 7:53 am

Re: Problem with my car project using MAX31850's

Post by Avinitlarge »

HI
I tried the multiple sketch and it worked fine
Dallas Temperature intercooler Control Library Demo
Locating devices...Found 2 devices.
Parasite power is: OFF
Device 0 Address: 3B082F18000000B0
Device 1 Address: 3B893218000000FD
Device 0 Resolution: 12
Device 1 Resolution: 12
Requesting temperatures...DONE
Device Address: 3B082F18000000B0 Temp C: 26.25 Temp F: 79.25
Device Address: 3B893218000000FD Temp C: 26.00 Temp F: 78.80

User avatar
Franklin97355
 
Posts: 23939
Joined: Mon Apr 21, 2008 2:33 pm

Re: Problem with my car project using MAX31850's

Post by Franklin97355 »

OK, if the devices are sending data to the Arduino and the Arduino is sending data to the computer the problem is either in your code or any other items you are adding to the mix. Try putting the laptop in the car and running a test with the actual data you get when running. If that works add parts one at a time until it all works or it breaks. You will then know where to look for your answer, if you need help please come back and ask.

Avinitlarge
 
Posts: 9
Joined: Tue Jun 10, 2014 7:53 am

Re: Problem with my car project using MAX31850's

Post by Avinitlarge »

Ive spent a good few hours on this now. I believe is has something to do with the address. Using the example I got these addresses, Device 0 Address: 3B082F18000000B0 and Device 1 Address: 3B893218000000FD

Im not 100% sure but I think It has something to do with something in the below lines, as to what, I have no idea what so ever.

uint8_t Thermo1[8] = {0x3B, 0x08, 0x2F, 0x18, 0x00, 0x00, 0x00, 0xB0};
uint8_t Thermo2[8] = {0x3B, 0x89, 0x32, 0x18, 0x00, 0x00, 0x00, 0xFD};

and this

egttemp = sensors.getTempC(Thermo1);
egttemp = egttemp / 4;
egtfinal = egttemp;
storage2[3] = egtfinal; // TP Offset 0x01

iattemp = sensors.getTempC(Thermo2);
iatfinal = iattemp;
storage2[4] = iatfinal; // TP Offset 0x02

In the multiple example, if I enter the addresses for my devices, it wont work either

Code: Select all

#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 6
#define TEMPERATURE_PRECISION 9

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress insideThermometer, outsideThermometer;

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();

  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: "); 
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  // assign address manually.  the addresses below will beed to be changed
  // to valid device addresses on your bus.  device address can be retrieved
  // by using either oneWire.search(deviceAddress) or individually via
  // sensors.getAddress(deviceAddress, index)
  //insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };
  //outsideThermometer   = { 0x28, 0x3F, 0x1C, 0x31, 0x2, 0x0, 0x0, 0x2 };
  
    uint8_t insideThermometer[8]= { 0x3B, 0x08, 0x2F, 0x18, 0x00, 0x00, 0x00, 0xB0 };
    uint8_t outsideThermometer[8]= { 0x3B, 0x89, 0x32, 0x18, 0x00, 0x00, 0x00, 0xFD };
    
    
  // search for devices on the bus and assign based on an index.  ideally,
  // you would do this to initially discover addresses on the bus and then 
  // use those addresses and manually assign them (see above) once you know 
  // the devices on your bus (and assuming they don't change).
  // 
  // method 1: by index
  if (!sensors.getAddress(insideThermometer, 0)) Serial.println("Unable to find address for Device 0"); 
  if (!sensors.getAddress(outsideThermometer, 1)) Serial.println("Unable to find address for Device 1"); 

  // method 2: search()
  // search() looks for the next device. Returns 1 if a new address has been
  // returned. A zero might mean that the bus is shorted, there are no devices, 
  // or you have already retrieved all of them.  It might be a good idea to 
  // check the CRC to make sure you didn't get garbage.  The order is 
  // deterministic. You will always get the same devices in the same order
  //
  // Must be called before search()
  //oneWire.reset_search();
  // assigns the first address found to insideThermometer
  //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");
  // assigns the seconds address found to outsideThermometer
  //if (!oneWire.search(outsideThermometer)) Serial.println("Unable to find address for outsideThermometer");

  // show the addresses we found on the bus
  Serial.print("Device 0 Address: ");
  printAddress(insideThermometer);
  Serial.println();

  Serial.print("Device 1 Address: ");
  printAddress(outsideThermometer);
  Serial.println();

  // set the resolution to 9 bit
  sensors.setResolution(insideThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(outsideThermometer, TEMPERATURE_PRECISION);

  Serial.print("Device 0 Resolution: ");
  Serial.print(sensors.getResolution(insideThermometer), DEC); 
  Serial.println();

  Serial.print("Device 1 Resolution: ");
  Serial.print(sensors.getResolution(outsideThermometer), DEC); 
  Serial.println();
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
}

// function to print a device's resolution
void printResolution(DeviceAddress deviceAddress)
{
  Serial.print("Resolution: ");
  Serial.print(sensors.getResolution(deviceAddress));
  Serial.println();    
}

// main function to print information about a device
void printData(DeviceAddress deviceAddress)
{
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
  printTemperature(deviceAddress);
  Serial.println();
}

void loop(void)
{ 
  // call sensors.requestTemperatures() to issue a global temperature 
  // request to all devices on the bus
  Serial.print("Requesting temperatures...");
  sensors.requestTemperatures();
  Serial.println("DONE");

  // print the device information
  printData(insideThermometer);
  printData(outsideThermometer);
}

Avinitlarge
 
Posts: 9
Joined: Tue Jun 10, 2014 7:53 am

Re: Problem with my car project using MAX31850's

Post by Avinitlarge »

Its finally working. Only one very slight problem. The frame rate is quite a bit slower than the rest of my other sensors. Ive been told thats just how the MAX31850's are.

User avatar
Franklin97355
 
Posts: 23939
Joined: Mon Apr 21, 2008 2:33 pm

Re: Problem with my car project using MAX31850's

Post by Franklin97355 »

Its finally working.
What did you find to be the problem? I'd like to know.

Avinitlarge
 
Posts: 9
Joined: Tue Jun 10, 2014 7:53 am

Re: Problem with my car project using MAX31850's

Post by Avinitlarge »

Errr, not sure. I am in the UK and the person helping was in the Netherlands, He wrote the original code. Last night we spent a couple of hours going through things. He hasn't used the one wire sensors before so wasn't too sure what was what. He wrote some alterations for me to try in the sketch and it wouldn't work. In the end, he wrote a little sketch for me to do some testing with. In the end he knew what was what and came up with more mods for the original sketch. Ive removed all the LCD side of things as we have decided leave the mega to do all the ECU side of things and to use an Adruino nano just for the LCD function.

Code: Select all

/* Written by Venderbroeck. */
/*free to use, but a reference would be nice =) */

//setting up onewire temperature stuff
  #include <OneWire.h>
  #include <DallasTemperature.h>

  // Data wire is plugged into port 6 on the Arduino
  #define ONE_WIRE_BUS 6
 
  // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
  OneWire oneWire(ONE_WIRE_BUS);
  
  //pass oneWire reference to Dallas Temperature
  DallasTemperature sensors(&oneWire);

  // assign device address manually.  the addresses below will beed to be changed
  // to valid device addresses on your bus. So find these first with a seperate sketch.
    
  uint8_t Thermo1 [8]= { 0x3B, 0x08, 0x2F, 0x18, 0x00, 0x00, 0x00, 0xB0 };
  uint8_t Thermo2 [8]= { 0x3B, 0x89, 0x32, 0x18, 0x00, 0x00, 0x00, 0xFD };
 
 
 
/*declaring some variables to use in the code*/
 //creating arrays to store dataframes in.
 //'storage' is used to store a ECU dataframe. Arduino can make use of the data present in the array.
 //The array is refreshed everytime a new dataframe comes in.
 //storage2 is used for the arduino dataframe to send arduino data to pc.
 //storage2 will need to be bigger if you want to store
 //more variables from additional inputs.
 int storage[60];  //ecudataframe[60]
 int storage2[26]; //arddataframe[26]
 
 //declaring variables byteIn, and byteIn2 in which to temporarely store bytes recieved by
 //the two serial connections.
 int byteIn = 0;   //same
 int byteIn2 = 0; //same
 
 //declaring bools for header recognition script
 bool checkheader1 = false;
 bool checkheader2 = false;
 
 //declaring trigger bool, used to trigger void loop script
 bool trigger = true; //frametrigger
 
 //counter for the loop filling the storage array with data from the ECU 
 int i = 1; // same
 
 //counter for sending storage2 contents to PC.
 int j = 1; // same
 
 //header and footer used when sending arduino frame
 int header1 = 95;  //0x5F
 int header2 = 175; //0xAF
 int footer1 = 180; //0xB4
 int footer2 = 100; //0x64

 //vars for EGT
 long egttemp = 0;
 byte egtfinal = 0;

 //vars for IAT
 int iattemp = 0;
 byte iatfinal = 0;
 
 unsigned long time = 0;
 unsigned long counter = 0;
 bool tempupdated = false;


/*void setup is ran once at startup. Here the (empty) arduino dataframe skeleton
is created, and the serial connections are initialized*/
void setup() {
   
/*configuring onewire temperature stuff*/

  // Start up the library
  sensors.begin();

  //desynchronise temperature conversion
  sensors.setWaitForConversion(false);
  
  // set the resolution to 9 bit
  sensors.setResolution(Thermo1, 9);
  sensors.setResolution(Thermo2, 9);


/*storing the header and footer data  in the storage2 array, thus constructing
the arduino data frame skeleton. if you want to store more data in the frame, 
the footer bytes need to be moved (and the array enlarged) to allow for the data to 
be stored in between. So in this example four variables can be sent with the arduino frame.*/
 storage2[1] = header1;
 storage2[2] = header2;
 storage2[7] = footer1;
 storage2[8] = footer2;

/*start up the serial connections
serial (=serial0) is used for USB connectivity.
serial3 is connected to the ECU k-line through a MC33290 chip connected to pins 14, and 15*/

 Serial.begin(125000); 
 Serial3.begin(125000);

}

/* Void loop is the main loop which is ran continuously.
The script it contains sends the arduino dataframe to the pc, when the storing 
of the incoming ECU frame is completed. 
Instead or alongside of this, you can add any code you want, to manipulate the data in the arrays. 
Things like lcd screens, buzzers, and buttons come to mind.*/

void loop() {
  
  /* this script get data from some arduino analog pins and stores them in storage2 
  in between header and footer. 
  It's important to realize, the arduino uses values 0-1023 to define the state of an analog
  pin. To be able to store it in a byte (0-255) I just divide by 4.

  The script only runs when the array is fully updated (trigger == true). 
  This is to maintain synchronisation between the ECU and Arduino dataframes.
  This may not allways be needed, but it can provide a way of throtteling things
  like lcd refreshes etc.*/
   if (trigger == true) { 
     
time = millis();
  if ((time > (counter + 0)) && tempupdated == false ) {
   
   //example of fetch and calculation of egt temp
   //here egt temperature is devided by 4 to make it fit into a single byte
   //you need to multiply the value by 4 again in Tunerpro.

   egttemp = sensors.getTempC(Thermo1);
   egttemp = egttemp / 4;
   egtfinal = egttemp;
   storage2[3] = egtfinal;
   
   //example of fetch and calculation of IAT temp
   //here division by 4 isn't needed because the iat temp isn't expected
   //to reach over 255 degrees C. (Both these temps are in celcius they can be converted
   //to fahrenheid like in the example).
   iattemp = sensors.getTempC(Thermo2);
   iatfinal = iattemp;
   storage2[4] = iatfinal;

   tempupdated = true;
}


  /*the following script sends data from storage2 through serial (USB).  */
    //reset j first
   j = 1;
   //send the frame byte by byte from the storage2 array
   while (j < 9){
      Serial.write(storage2[j]);
      j++;
   }
 
  //reset the trigger to exit the script after sending the frame
   trigger = false;
   


}
if(tempupdated == true) {
  sensors.requestTemperatures();
  counter = millis();
  tempupdated = false;
  
}
  }
  
    
/*the next script runs when the arduino recieves bytes on serial (= serial0 = USB) from the computer.
void serialEvent runs in between individual void loop iterations, so if the void 
loop takes too long to complete, serial data will build up and fill the buffer, 
probably causing a crash. Using delay() in the main loop is, therefore, not recommended.

Incoming bytes are sent directly through to the ECU over serial3, 
so commands can be given to the ECU in the usual way.*/

 void serialEvent() {
     //Run the while loop for as long as serial data is available.
      while (Serial.available() ) {
      //reset byteIn variable. Might be redundant.
       byteIn2 = 0;
      //take byte out of the buffer and store it in byteIn2.
       byteIn2 = Serial.read();
      }
      //send byteIn2 to ECU
       Serial3.write(byteIn2);
       
       //If the hex number 0xEE is sent from the PC, Arduino responds with dataframe
       //This can be used for testing in realterm for example.
       if(byteIn2 == 0xEE) {
        trigger = true; 
       }
   }
  
  
  

/*the next script runs when the arduino recieves bytes on serial3 (from the ECU).
void serialEvent3 runs in between individual void loop iterations, so if the void 
loop takes too long to complete, serial data will build up and fill the buffer, 
probably causing a crash. Using delay() in the main loop is, therefore, not recommended.

Any recieved bytes are sent directly through to the PC via serial, to ensure the datastream 
to the PC isn't interrupted.
Meanwhile it will look for the ECU headerstring in the data it recieves 
from the ECU. If the headerstring is found, it will store the next 46 bytes
(the body of the ECU dataframe) at the corresponding positions in the array 'storage'. 
The ECU header and footer bytes are clipped off, so rpm will be at storage[1] etc.).
All the positions of the data in the ECU dataframe can be found in the standard adx file.
Keep in mind the adx file starts at 0, and the 'storage' array starts at 1, so increment the 
position of the value in the adx file by 1 to find it in the 'storage' array.
This means the dataframe from the ECU can be used by the arduino to do whatever 
you want with. 
Finally when the array is fully updated, the frame is assumed to be received, and so 
the trigger is set to true to trigger the script in void loop to do work and send the arduino frame
directly after the ECU frame. 
This way the arduino, and the ECU dataframes are allways synced.*/

 void serialEvent3() {
  //Run the while loop for as long as serial data is available.
  //Keep in mind the whole loop will iterate once for each incoming byte.
   while (Serial3.available() ) {
    //reset byteIn variable. Might be redundant.
    byteIn = 0;
    //take byte out of the serial 3 buffer and store it.
    byteIn = Serial3.read();
    //send the byte directly through serial connection 0 (USB)
    Serial.write(byteIn);


    /*the next if statements need to be ran in this specific order.
    They look for the header and store the ECU dataframe in 'storage' for 
    later use by the arduino. The bytes they store have allready been forwarded to 
    the USB serial connection, so this array is purely meant for use by the arduino.
    This pile of statements still needs refinement
    ECU header = 5A A5
    ECU footer = AA 5F */


    //If both the headerbytes have been recieved and i == 49,
    //the loop storing the body has allready been completed, so 
    //both checkheader triggers reset to false and i resets to 1
    //Also it will set the void loop trigger to true to run the script it contains.
      if (checkheader1 == true && checkheader2 == true && i == 47) {
       checkheader1 = false;
       checkheader2 = false;
       trigger = true;
       i = 1; 

     }

    //ERRORCHECK
    //If first headerbyte was recieved, and the second was not, 
    //and the byte stored isn't A5, something went 
    //wrong and checkheader1, and i both reset.
      if (checkheader1 == true && checkheader2 == false && byteIn != 0xA5) {
       checkheader1 = false;
       i = 1;
      }

    /*The actual part filling the array. Everytime the while(serial available())
    loop iterates, and the headertriggers are set true, and nothing was changed 
    above this will write the byte stored in byteIn to the proper place in storage. 
    Note that i is incremented here each iteration. When it reaches 47 (all bytes recieved)
    all triggers, including i are reset above in the next loop iteration. */
     if(checkheader1 == true && checkheader2 == true) {
        storage[i] = byteIn;
     i++;

     }
     
    //if byteIn contains the first headerbyte, checkheader1 is set to true
     if (checkheader1 == false && byteIn == 0x5A) {
         checkheader1 = true;
     }
   

    //if the first headerbyte has been received, and byteIn contains the 
    //second headerbyte, checkheader 2 is set to true
      if(checkheader1 == true && byteIn == 0xA5) {
        checkheader2 = true;
      }
   
   //end of while serial3.available loop
   }    
 //end of void serial.event3 
 }

User avatar
killerin
 
Posts: 9
Joined: Sun Nov 09, 2014 9:45 pm

Re: Problem with my car project using MAX31850's

Post by killerin »

What was the sketch that you use to get the addresses?? Im very new to Arduino I have no idea how to write that sketch

thanks

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”