Arduino-based Sensor Cluster - Page 2 - Defender Source
Defender Source  

Go Back   Defender Source > Defender & Series Technical Discussions > Defender Technical Discussions


Reply
 
Thread Tools
  #21  
Old February 19th, 2015, 11:29 AM
Jonesy's Avatar
Jonesy
Status: Offline
Craig
87 D110 (Ruby)
Member
 
Join Date: Dec 2011
Location: Leesburg, VA
Posts: 4,445
Registry
Was meant as a complement...I have 50 or so GTech grads who work for me...talk about Geeks!

Btw, coulda just grabbed a 200tdi with a few gauges to measure all you need (EGT & EOT & ET & Boost) And be rolling down the road getting 20plus mpg no worries.

I get what you are doing, applaud the innovation, love the kiddie involvement .... Just sayin...
__________________
"The difference between stupidity and genius, is that genius has its limits." - Albert Einstein
Reply With Quote
Sponsored Links
Advertisement
 
  #22  
Old February 19th, 2015, 12:12 PM
leastonce's Avatar
leastonce
Status: Offline
Jason England
D-90 White 95 SW #65
Site Team
 
Join Date: Jul 2009
Location: NYC
Posts: 6,078
Registry
Quote:
Originally Posted by Azarur View Post
My truck doesn't have an ECU either! That's what's beautiful about this setup. The sensors and signals do not interfere or in any way affect or depend on the core functions of the truck.

A more important question is: Are these sensors really needed???

A few are very important for me: Exhaust temperature, fuel consumption, open doors.
Here's why:
- Exhaust temperature: Our engine had to be rebuilt and a new turbo added. Need to keep an eye on performance to avoid blowing another gasket. Planning to keep this baby for a long time.
- Fuel consumption: The whole point of this project was to trade in our disgusting gas guzzler (9 MPG) for a functional vehicle with good fuel economy (20+ mpg). This is very important for my kids and I
- Door open sensors. I have three young children. This is critical for my piece of mind.

The other sensors: Tilt, bearing, altitude, outside temperature, etc. are just nice to have. But constructing a system to do the ones that were really important basically gave us a free platform to do the rest... so why not?

------ Follow up post added February 19th, 2015 11:24 AM ------



PS. BTW, at my house, geek is a compliment
Mine has a door open sensor .... it's the dome light!
__________________
Quote:
Soapy water / KY jelly, etc. is is basically a must. Yes, good idea to remove trim panels - only takes 5 more minutes to do so.
Car Camping Collective founding member and Chief Executive Officer
Cat Camping Collective founding member and Chief Executive Officer
Reply With Quote
  #23  
Old February 19th, 2015, 01:15 PM
Azarur
Status: Offline
AZ
LR 1984 110
Member
 
Join Date: Mar 2014
Location: California
Posts: 292
Quote:
Originally Posted by leastonce View Post
Mine has a door open sensor .... it's the dome light!
LOL
Mine didn't... have a sensor or even a dome light!
Reply With Quote
Sponsored Links
Advertisement
 
  #24  
Old February 19th, 2015, 01:24 PM
Rocky's Avatar
Rocky
Status: Offline
Chris
72 + D1 drivetrain
Member
 
Join Date: Sep 2006
Location: Colonies Aka Boston
Posts: 8,776
Take a look at the products Garmin has on general aviation (Pipe/Cessna etc) just phenomenal.
__________________
A friend of mine runs a land rover / range rover specialty repair shop. Based on his experience, they are capable of stopping anywhere, anytime, at any cost.

I don't know about the brakes, only their unreliability.
Reply With Quote
  #25  
Old February 19th, 2015, 07:52 PM
chris snell's Avatar
chris snell
Status: Offline
Chris Snell
87 Ex-MOD 110
Member
 
Join Date: Aug 2005
Location: Kansas
Posts: 2,439
Quote:
Originally Posted by Azarur View Post
O
In one word: Interrupts. The DUE can collect virtually unlimited interrupts without messing up, and we have multiple interrupts that we need to measure:
- Speed pulses
- Alternator pulses (for RPM)
- Fuel supply and fuel return pulses (for fuel consumption)
- Open door signals x 5 (we want to indicate WHICH door is open, not just an open door signal)
Depending on your skill level, you don't need an Arduino to measure these pulses. If you're crafty, you could use ripple counter ICs to count them. If you want something easier, you could use an ATtiny85, ATtiny2313, or similar to measure them. These ATtiny chips are dirt cheap and will run your Arduino programs if you cross-compile them.

There are at least two ways to skin this cat:

You can use an Arduino board to program the ATtiny

or

You can can compile your Arduino programs to .hex files on your desktop computer using these instructions and then use a homebrew ZIF socket programmer with a $15 USB AVR programmer board from Sparkfun. I wrote a tutorial with instructions: http://output.chrissnell.com/post/36...avr-programmer

The idea here is that you would measure your pulses on the ATtiny(s) and use IC to share the measurements with your BBB or RasPi. If you've never used it before, IC uses just a few wires to connect devices. Linux makes it really easy to read/write the IC protocol.
__________________
1987 Ex-MOD 110 Tithonus LHD
2013 LR4


To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.
/
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.
/
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.
/
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.
/
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.
Reply With Quote
  #26  
Old February 19th, 2015, 08:14 PM
samer0214's Avatar
samer0214
Status: Offline
Samer Hijazi
1997 P38 Vitesse
Member
 
Join Date: Apr 2013
Location: Irvine, CA
Posts: 390
Registry
Quote:
Originally Posted by Azarur View Post
And once it's done, people will be able to build an identical system for very little...


Now, the display side of things... what a pain! The Arduino based TFTs are slow as heck!
I, for one, am very much interested in this build, as I would like to do something similar, but not quite as complicated, as I don't need to monitor the same parameters. My build will consist of the following:

1) Monitor outside temperature, altitude, bearing
2) Monitor pitch, roll and yaw and display that data digitally, but also graphically: I would like my TFT to display the silhouette of a D110, which would change "attitude" along with the changes of that data
3) Trigger 4 relays on an Arduino relay shield (using bluetooth), to control 4 different accessories (lights, air compressor, etc..)

I'm an Arduino noob, but have already purchased an Arduino UNO, a Bluetooth shield, the Relay shield, and a 2.4" TFT LCD Touch Shield, to experiment with, and looking forward to the code.
__________________
Thank you - Samer
1997 P38 Vitesse (Red)
2003 Discovery II
Defenderless, for now!
Reply With Quote
  #27  
Old February 20th, 2015, 06:55 AM
Azarur
Status: Offline
AZ
LR 1984 110
Member
 
Join Date: Mar 2014
Location: California
Posts: 292
Chris,
You hit the nail on the head: Level of skill is just not there for me!! As some here know, cancer I can help you with; electronics: hmmm. Not so much!!!

If you ask me to program an arduino in C, I can deal with that. Ask me to understand the inner works of an IC. Nope. Nada.

Plus, the other thing is I want the kids to help, and actually understand what they are doing. Not just blindly follow instructions, but rationalize and contribute. Arduinos make that super easy to do.

Thanks for your ideas though.

------ Follow up post added February 20th, 2015 06:58 AM ------

Samer

All your ideas are doable. I would be cautious with what you want the TFT to do. TFTs on arduinos are notoriously slow. Showing a tilting 110 may pose a refresh challenge. Especially running off an UNO.

You may use some of the widgets that come in the LCD library, such as an analog meter to show tilt graphically, but it won't be nearly as cool as what you have in mind.
Reply With Quote
  #28  
Old February 21st, 2015, 02:47 AM
samer0214's Avatar
samer0214
Status: Offline
Samer Hijazi
1997 P38 Vitesse
Member
 
Join Date: Apr 2013
Location: Irvine, CA
Posts: 390
Registry
Earlier today, I ordered a Mega to run the TFT. Inspired by your setup, I will run the Bluetooth shield and sensors on the UNO, and will send that data to the MEGA which will have the 4-Relay shield and TFT display. What do you think?
__________________
Thank you - Samer
1997 P38 Vitesse (Red)
2003 Discovery II
Defenderless, for now!
Reply With Quote
  #29  
Old February 21st, 2015, 07:06 AM
Azarur
Status: Offline
AZ
LR 1984 110
Member
 
Join Date: Mar 2014
Location: California
Posts: 292
I think you should be able to run everything of the Mega. You'll have more than enough pins.
You will still need to figure out how to get images or bit maps (such as the outline of the 110 from different angles) to tilt at an acceptable refresh rate and without having to redraw the whole screen.

My TFT cycles through five screens. Each time there's a screen transition it takes a good second to redraw everything. Once the screen has been loaded, then changing values is done through widgets, which reside on this particular LCD's library, and are fast refresh. But you are limited to simple options; a digital meter, an analog meter, menu displays and checkboxes.
Reply With Quote
  #30  
Old February 21st, 2015, 08:08 AM
samer0214's Avatar
samer0214
Status: Offline
Samer Hijazi
1997 P38 Vitesse
Member
 
Join Date: Apr 2013
Location: Irvine, CA
Posts: 390
Registry
The pin configurations of the shields are all so they can be stacked on top of each other, even the TFT. The issue though, is that the relay board doesn't allow to. be "sandwiched" because of the height of the relays, which means that it has to be in the topmost position, leaving the TFT out.

As for storing the images, the BT shield has a built in slot for an SD card. My idea which I still have to test out, is to store the various images there, and call them out to the display as needed. I don't know if they will draw fast enough though, based on your experience with your TFT. What seems to be the issue in your case? Is it the processing power (or lack thereof) of the TFT or the Arduino? If it's the TFT, is this inherent in all of them?
__________________
Thank you - Samer
1997 P38 Vitesse (Red)
2003 Discovery II
Defenderless, for now!
Reply With Quote
  #31  
Old February 21st, 2015, 10:47 AM
Azarur
Status: Offline
AZ
LR 1984 110
Member
 
Join Date: Mar 2014
Location: California
Posts: 292
There are some newer TFTs with a GPU that might be better, but I have not tested them.
Loading the images from the SD (as opposed to drawing bitmaps through code) will be faster. It will depend on the actual TFT to determine how fast it will actually be. Most of the standard ones (arduino, adafruit, arLCD) take a good 500 ms to 1 sec to load images.
Reply With Quote
  #32  
Old September 21st, 2015, 04:13 AM
GliderKing's Avatar
GliderKing
Status: Offline
Robert Bingham
97 ST D90
Member
 
Join Date: Sep 2003
Location: San Diego, CA USA
Posts: 74
Registry
This is awesome, and can't wait to see where it ends up. The idea to push this to a iOS Android and not worry so much about a TFT. Then you could keep the truck stock looking but give you the data you need while driving.
__________________
Robert Bingham

1997 NAS 90 ST
1985 110 RHD 300tdi ROW
@gliderking instagram, twitter
Reply With Quote
  #33  
Old September 21st, 2015, 07:43 AM
Roverlab
Status: Offline
Trevor Griffiths
85 110, 92 110, 92 RR, 06 LR3
Member
 
Join Date: Jan 2008
Location: Elizabethotwn, PA
Posts: 1,647
Well, that's it. It wasn't enough to have the challenge of learning a modern Rover's electronics, now you guys want to take non-modern Rovers and fill them with technology that would most likely not be on my radar and terms I probably would likely not hear on a regular basis.
Just when I was considering the pros and cons of purchasing my next Autologic upgrade.....horse and buggy maintenance is where it's at.
I'm sure of it.
__________________
Roverlab is now British 4x4 Specialists.
Email is
To view links or images in signatures your post count must be 10 or greater. You currently have 0 posts.

Same place, new dogs.
Reply With Quote
  #34  
Old October 15th, 2015, 05:44 AM
Azarur
Status: Offline
AZ
LR 1984 110
Member
 
Join Date: Mar 2014
Location: California
Posts: 292
Update to all of those who were interested in this. The system is finally complete and after much (much!) work I was able to consolidate everything into a single board (an Arduino DUE) with a brand new touchscreen display.
I'll upload pictures this pm. The system does 4 temperatures (cabin, ambient, exhaust and coolant), heading, altitude, tilt angles, instantaneous and average speed and mpg, timer, chronometer, odometer and all warning messages (doors, low fuel, etc.)
If you want the code just pm me.
Reply With Quote
  #35  
Old October 17th, 2015, 01:35 AM
samer0214's Avatar
samer0214
Status: Offline
Samer Hijazi
1997 P38 Vitesse
Member
 
Join Date: Apr 2013
Location: Irvine, CA
Posts: 390
Registry
Azarur, you've got a PM.
__________________
Thank you - Samer
1997 P38 Vitesse (Red)
2003 Discovery II
Defenderless, for now!
Reply With Quote
  #36  
Old November 18th, 2015, 08:59 AM
Azarur
Status: Offline
AZ
LR 1984 110
Member
 
Join Date: Mar 2014
Location: California
Posts: 292
Hey guys,

As promised here's the latest code that works with the ARDUINO DUE and the 4D Systems Diablo based screen. If you have any questions or issues, let me know.

AZ
Code:


//Include Libraries
#include <genieArduino.h>
#include <flash_efc.h>
#include <efc.h>
#include <DueFlashStorage.h>
#include <Wire.h>
#include <HMC5883L.h>

Genie genie;
DueFlashStorage dueFlashStorage;

#define RESETLINE 4  // Change this if you are not using an Arduino Adaptor Shield Version 2 (see code below)


//Initialize Pins for Doors
const int DriverDoorPin=49;
const int PassengerDoorPin = 50;
const int RearRightDoorPin = 51;
const int RearLeftDoorPin = 52;
const int TrunkGatePin=53;

//Initialize Physical Buttons and LED
const int OutputLEDPin=13;
const int ArrowUp=22;
const int ArrowDown =23;
const int ResetButton = 24;
const int OKButton = 25;
volatile int LEDState = LOW;
int ResetFlag=0;

//Initialize Compass Variables
// Store  compass as a variable.
HMC5883L compass;
// Record any errors that may occur in the compass.
int error = 0;


// Define Variables for Interrupt Measurements Distance and Fuel Consumption

 volatile unsigned long MeasuredRevolutions;
 volatile unsigned long MeasuredVolumeIn;
 volatile unsigned long MeasuredVolumeReturn;
 
 unsigned long TotalRevolutions;
 
 const int SpeedometerPin = 43;
 const int FuelPumpInPin = 45;
 const int FuelPumpReturnPin = 47;
 
 double CalculatedSpeed = 0;
 int DisplayCurrentSpeed = 0;
 unsigned long CalculatedFuelConsumption = 0;
 double CalculatedDistance = 0;
 double CalculatedFuelEconomy = 0;
 int DisplayFuelEconomy = 0;

 double TotalDistanceTraveled = 0;
 int TotalDistanceTraveledInt = 0;
 int TotalDistanceTraveledDec = 0;
 

 double AverageFuelConsumption = 0;
 int DisplayAverageFuelConsumptionInt = 0;
 double AverageFuelConsumptionDec = 0;
 int DisplayAverageFuelConsumptionDec = 0;
 long TotalFuelConsumed = 0;

 
 double AverageSpeed = 0;
 int DisplayAverageSpeed = 0;
 
 const double DistancePerRevolution = 1.56186868e-3; //Miles per revolution
 const double VolumePerRevolution = 1.08;//Mililiters per turn of flow meter
 const double DistanceScaleFactor = 8; //Number of Pulses per Revolution of the Tire
 const double SpeedScaleFactor = 3600;
 const double FuelConversionFactor = 3785.41;//Gallons to Mililiter Conversion
 
  
 //Define Environmental Variables
 int CabinTemperature = 72;
 int AmbientTemperature = 72;
 int AmbientHumidity = 45;
 int ExhaustTemperature = 1000;
 int CoolantTemperature = 125;
 
 int CabinTempVoltage = 0;
 int AmbientTempVoltage = 0;
 int HumidityVoltage = 0;
 int CoolantTempVoltage = 0;
 
 //Define OffRoad Navigation Variables

 int Heading=0;
 int Altitude = 0;
 int XTilt = 0;
 int YTilt = 0;
 
 //Define Display Navigation Variables
 int PageIndex = 1;
 int DisplayFlag = 1;
 
 volatile int PressedArrowUp = 0;
 volatile int PressedArrowDown = 0;
 volatile int PressedResetButton = 0;
 volatile int PressedOKButton = 0;
 
 //Define Counters
 int Counter1=0;
 unsigned long Counter2=0;
 unsigned long ResetTimer=0;
 int DisplayCounter2=0;
 unsigned long TimeCounter=0;
 unsigned long PreviousTimeCounter=0;
 unsigned long EllapsedTimeCounter=0;
 
 
//Define Time Variables

 unsigned long InitialAbsoluteTime = 0;
 unsigned long EllapsedAbsoluteTime = 0;
 unsigned long FinalAbsoluteTime = 0;
 
 unsigned long InitialMeasuringTime;
 unsigned long FinalMeasuringTime;
 unsigned long EllapsedMeasuringTime;
 
 const int IntegrationPeriod1=10;
 const int IntegrationPeriod2=10;
 const unsigned long IntegrationTime=100;
 
  //Chronometer Declarations
 int TotalHours = 0;
 int TotalMinutes = 0;
 int TotalSeconds = 0;
 
 // The struct of the configuration.
struct SavedLogData {
  unsigned long SavedInitialAbsoluteTime;
  unsigned long SavedTotalRevolutions;
  unsigned long SavedTotalFuelConsumed;
  int SavedPageIndex;
  char* SavedMessage;
  }; 
  
char* InitialDisplayMessage;
char* Message;
  
SavedLogData ReadLogData;  
 
 void setup()
 {
   InitialMeasuringTime = millis();
   InitialAbsoluteTime = millis();
   
   InitializeFlashStorage();
   
   //Initialize Compass
    Wire.begin(); // Start the I2C interface.
    compass = HMC5883L(); // Construct a new HMC5883 compass.
    error = compass.SetScale(1.3); // Set the scale of the compass.
    error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous
    
   
   //Initialize Interrupts for Measurements Distance and Fuel Consumption
   attachInterrupt(digitalPinToInterrupt(SpeedometerPin), TriggeredMeasuredRevolutions, RISING);
   attachInterrupt(digitalPinToInterrupt(FuelPumpInPin), TriggeredMeasuredVolumeIn, RISING);
   attachInterrupt(digitalPinToInterrupt(FuelPumpReturnPin), TriggeredMeasuredVolumeReturn, RISING);
   
   //Initialize Interrupts for Display Navigation
   attachInterrupt(digitalPinToInterrupt(ArrowUp), TriggeredArrowUp, RISING);
   attachInterrupt(digitalPinToInterrupt(ArrowDown), TriggeredArrowDown, RISING);

   //Initialize Interrupt for Display Reset
   attachInterrupt(digitalPinToInterrupt(ResetButton), TriggeredResetButton, CHANGE);
   attachInterrupt(digitalPinToInterrupt(OKButton), TriggeredOKButton, CHANGE);
   
   //Initialize Activity LED
   pinMode(OutputLEDPin, OUTPUT);
   pinMode(31, INPUT_PULLUP);
   
   MeasuredRevolutions = 0;
   MeasuredVolumeIn = 0;
   MeasuredVolumeReturn = 0;

  InitializeDisplay();
   
 
 }



//MAIN CODE

 void loop()
 {
   
  int IgnitionSwitch = digitalRead(31);
  if (IgnitionSwitch==LOW){
    ShutDownRoutine();
  } 
   
  EllapsedAbsoluteTime = millis()+InitialAbsoluteTime;
  /*
  //Check for Arrow Buttons
        if (PressedArrowUp){
          PageIndex++;
          PressedArrowUp=0;
        }

        if (PressedArrowDown){
          PageIndex = PageIndex-1;
          PressedArrowDown=0;
        }
 */ 
  
   genie.DoEvents();
          
          if(PageIndex>5){
          PageIndex=1;
          DisplayFlag=1;
            }
            
          if(PageIndex<1){
          PageIndex=5;
          DisplayFlag=1;
            }
          
          if(DisplayFlag==1){
          genie.WriteObject(GENIE_OBJ_FORM, PageIndex,0);
          DisplayFlag=0;
            }

    TimeCounter= millis();
    EllapsedTimeCounter=TimeCounter-PreviousTimeCounter;
    
    if (EllapsedTimeCounter > IntegrationTime) {
      PreviousTimeCounter = TimeCounter;
      ActivateDisplayMeasurements();
      CalculateTimeVariables();
      Counter1++;

        //Display Navigation If Routines --> Check Button States every 200 ms
        

        if (PressedResetButton) ResetRoutine();
      
    }
   
   if (Counter1>IntegrationPeriod1){
      CalculateSpeedAndFuel();
      MeasureTemperatures();
      MeasureHeadingAndAngles();
      Counter1=0;
    
   }
   
    FinalMeasuringTime= millis();
  
    EllapsedMeasuringTime=FinalMeasuringTime-InitialMeasuringTime;
  
        
   }


   

//FUNCTION DEFINITION
 
 void TriggeredMeasuredRevolutions()
 {
   MeasuredRevolutions++;
   }

void TriggeredMeasuredVolumeIn()
 {
   MeasuredVolumeIn++;
   }

void TriggeredMeasuredVolumeReturn()
 {
   MeasuredVolumeReturn++;
   }      
   
void TriggeredArrowUp(){
//  PressedArrowUp = 1;
PageIndex++;
DisplayFlag=1;
  }

void TriggeredArrowDown(){
//  PressedArrowDown = 1;
PageIndex = PageIndex-1;
DisplayFlag=1;
  }

void TriggeredResetButton(){
  PressedResetButton = 1;  
  }

void TriggeredOKButton(){
  PressedOKButton=1;
  ResetFlag=1;
}
   
//Funtions to Gather External Data
//Speed And Fuel
 void CalculateSpeedAndFuel()
 {
    
    //Total Trip Time (Stored in Flash) is EllapsedAbsoluteTime (in Millis)
    // Total Distance Stored in Flash is TotalRevolutions --> New TotalRevolutions = TotalRevolutions + MeasuredRevolutions
    // Total Fuel consumption stored in flash is Total Fuel Consumed  
    
    //Interval Time for Instantaneous measurements is EllapsedMeasuringTime (in Millis)
    
    
   //Calculate Interval Distance and Instantaneous Speed  
    CalculatedDistance = MeasuredRevolutions * DistancePerRevolution/DistanceScaleFactor; // In Miles (Small Number!!)
    CalculatedSpeed = CalculatedDistance*SpeedScaleFactor*1000/EllapsedMeasuringTime; // In Miles per Hour
    
    DisplayCurrentSpeed = CalculatedSpeed;
    
    
    //Calculate Trip Distance and Average Speed
    TotalRevolutions = TotalRevolutions + MeasuredRevolutions;
    TotalDistanceTraveled = TotalRevolutions * DistancePerRevolution/DistanceScaleFactor; //In Miles
    
    TotalDistanceTraveledInt = TotalDistanceTraveled;// In Miles
    TotalDistanceTraveledDec = (TotalDistanceTraveled*10)-(TotalDistanceTraveledInt*10);// In Tenths of a Mile
    
    AverageSpeed = TotalDistanceTraveled*3600000/EllapsedAbsoluteTime; // In Miles per Hour
    DisplayAverageSpeed = AverageSpeed;
    
    
    
    //Calculate Instantaneous Fuel Consumption      
    CalculatedFuelConsumption = MeasuredVolumeIn-MeasuredVolumeReturn;
    //TotalFuelConsumed = TotalFuelConsumed + CalculatedFuelConsumption;//In Milliliters
    
    if (CalculatedFuelConsumption<=0) CalculatedFuelConsumption = 5;
    CalculatedFuelEconomy = CalculatedDistance *FuelConversionFactor/ CalculatedFuelConsumption; //In MPG

    DisplayFuelEconomy = CalculatedFuelEconomy;
    if(DisplayFuelEconomy>40) DisplayFuelEconomy = 40;
    
    
    //Calculate Average Fuel Economy
    TotalFuelConsumed = TotalFuelConsumed + CalculatedFuelConsumption;//In Milliliters
    AverageFuelConsumption = TotalDistanceTraveled*FuelConversionFactor/TotalFuelConsumed; // In Miles per Gallon
    DisplayAverageFuelConsumptionInt = AverageFuelConsumption;
    AverageFuelConsumptionDec = (AverageFuelConsumption*10)-DisplayAverageFuelConsumptionInt*10;
        
    
    
    
    MeasuredRevolutions = 0;
    MeasuredVolumeIn =0 ;
    MeasuredVolumeReturn = 0;

    InitialMeasuringTime = millis();
    FinalMeasuringTime = InitialMeasuringTime;
    
  }
  
// Temperature Measurements
void MeasureTemperatures() {
    CabinTempVoltage = analogRead(A9);
    AmbientTempVoltage = analogRead(A10);
    HumidityVoltage = analogRead(A8);
    CoolantTempVoltage = analogRead(A11);

  CabinTemperature = CabinTempVoltage*900/1024-58;
  AmbientTemperature = AmbientTempVoltage*900/1024-58;
  AmbientHumidity = HumidityVoltage/10;
  ExhaustTemperature = 1000+random(100);
  CoolantTemperature = CoolantTempVoltage*900/1024-58;
    
}



//Off Road Navigation
void MeasureHeadingAndAngles(){
  
   // Retrive the raw values from the compass (not scaled).
  MagnetometerRaw raw = compass.ReadRawAxis();
  // Retrived the scaled values from the compass (scaled to the configured scale).
  MagnetometerScaled scaled = compass.ReadScaledAxis();
  
  // Values are accessed like so:
  int MilliGauss_OnThe_XAxis = scaled.XAxis;// (or YAxis, or ZAxis)

  // Calculate heading when the magnetometer is level, then correct for signs of axis.
  float heading = atan2(scaled.YAxis, scaled.XAxis);
  
  // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the magnetic field in your location.
  // Find yours here: http://www.magnetic-declination.com/
  // Mine is: 2� 37' W, which is 2.617 Degrees, or (which we need) 0.0456752665 radians, I will use 0.0457
  // If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
  float declinationAngle = 0.0457;
  heading += declinationAngle;
  
  // Correct for when signs are reversed.
  if(heading < 0)
    heading += 2*PI;
    
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)
    heading -= 2*PI;
   
  // Convert radians to degrees for readability.
  float headingDegrees = heading * 180/M_PI; 
  Heading = headingDegrees;

  Altitude = 1000+random(20);
  XTilt = random(50);
  YTilt = random(50);
  
}

//Time Variables
void CalculateTimeVariables(){
 TotalHours= EllapsedAbsoluteTime/3600/1000;
 TotalMinutes = EllapsedAbsoluteTime/60/1000-TotalHours*60;
 TotalSeconds = EllapsedAbsoluteTime/1000-TotalHours*3600-TotalMinutes*60;
  }
  
  
void InitializeFlashStorage()
{
    /* Flash is erased every time new code is uploaded. Write the default configuration to flash if first time */
  // running for the first time?
  uint8_t codeRunningForTheFirstTime = dueFlashStorage.read(0); // flash bytes will be 255 at first run
  
  if (codeRunningForTheFirstTime) {
    InitialDisplayMessage = "CRFFT: Yes";
  
    /* OK first time running, set defaults */
    ReadLogData.SavedTotalRevolutions = 0;
    ReadLogData.SavedTotalFuelConsumed = 0;
    ReadLogData.SavedInitialAbsoluteTime = 0;
    ReadLogData.SavedPageIndex = 1;
    
    ReadLogData.SavedMessage = "Initializing Values...";


    // write configuration struct to flash at adress 4
    byte ByteArraySaved[sizeof(SavedLogData)]; // create byte array to store the struct
    memcpy(ByteArraySaved, &ReadLogData, sizeof(SavedLogData)); // copy the struct to the byte array
    dueFlashStorage.write(4, ByteArraySaved, sizeof(SavedLogData)); // write byte array to flash

    // write 0 to address 0 to indicate that it is not the first time running anymore
    dueFlashStorage.write(0, 0); 
  }
  else {
    InitialDisplayMessage = "CRFFT: No";
    }
  
  
  /* read configuration struct from flash */
  byte* ByteArrayRead = dueFlashStorage.readAddress(4); // byte array which is read from flash at adress 4
  SavedLogData TempLogData; // create a temporary struct
  memcpy(&TempLogData, ByteArrayRead, sizeof(SavedLogData)); // copy byte array to temporary struct
  
   InitialAbsoluteTime=TempLogData.SavedInitialAbsoluteTime;
   TotalRevolutions=TempLogData.SavedTotalRevolutions;
   TotalFuelConsumed=TempLogData.SavedTotalFuelConsumed;
   
   PageIndex=TempLogData.SavedPageIndex;
   Message=TempLogData.SavedMessage;
}
  
void InitializeDisplay()
{
  Serial.begin(57600);  // Serial0 @ 200000 (200K) Baud
  genie.Begin(Serial);   // Use Serial0 for talking to the Genie Library, and to the 4D Systems display
  
  genie.AttachEventHandler(myGenieEventHandler);
 
  pinMode(RESETLINE, OUTPUT);  // Set D4 on Arduino to Output (4D Arduino Adaptor V2 - Display Reset)
  digitalWrite(RESETLINE, 1);  // Reset the Display via D4
  delay(100);
  digitalWrite(RESETLINE, 0);  // unReset the Display via D4

  delay (3500); //let the display start up after the reset (This is important)

  //Turn the Display on (Contrast) - (Not needed but illustrates how)
  genie.WriteContrast(15); // 1 = Display ON, 0 = Display OFF.
  //For uLCD43, uLCD-70DT, and uLCD-35DT, use 0-15 for Brightness Control, where 0 = Display OFF, though to 15 = Max Brightness ON.
  
  delay (2000);
  
  genie.WriteStr(0,InitialDisplayMessage);
  
  delay(500);
  
}

void myGenieEventHandler(void)
{
  genieFrame Event;
  
  PageIndex++;
  DisplayFlag=1;
  LEDState=HIGH;
  genie.DequeueEvent(&Event);
}

void ActivateDisplayMeasurements()
{
          if (DisplayCurrentSpeed>139) DisplayCurrentSpeed = 139;  
      //FORM 1
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x00, CabinTemperature);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x01, AmbientTemperature);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x02, AmbientHumidity);
          
      //FORM 2
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x03, DisplayAverageFuelConsumptionInt);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x06, AverageFuelConsumptionDec);
          
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x04, DisplayAverageSpeed);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x05, TotalDistanceTraveledInt);
          
          genie.WriteObject(GENIE_OBJ_GAUGE, 0x00, DisplayFuelEconomy);
          
      //FORM 3
          
//          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x07, ExhaustTemperature);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x08, CoolantTemperature);
          
          genie.WriteObject(GENIE_OBJ_METER, 0x00, DisplayCurrentSpeed);
          
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x07, DisplayAverageFuelConsumptionInt);

          
      //FORM 4
          
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x09, Heading);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0A, Altitude);
          
          genie.WriteObject(GENIE_OBJ_GAUGE, 0x01, XTilt);
          genie.WriteObject(GENIE_OBJ_GAUGE, 0x02, YTilt);
          
      //FORM 5
          
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0D, TotalHours);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0C, TotalMinutes);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0B, TotalSeconds);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0E, TotalDistanceTraveledInt);
          genie.WriteObject(GENIE_OBJ_CUSTOM_DIGITS, 0x0F, TotalDistanceTraveledDec);
          
}

void ShutDownRoutine() {

  
  //Set Values to Store
    ReadLogData.SavedInitialAbsoluteTime = EllapsedAbsoluteTime;
    ReadLogData.SavedTotalRevolutions = TotalRevolutions;
    ReadLogData.SavedTotalFuelConsumed = TotalFuelConsumed;
    
    ReadLogData.SavedPageIndex = PageIndex;
    
    ReadLogData.SavedMessage = "Shutting Down...";
    
     
 // write configuration struct to flash at adress 4
  byte ByteArraySaved[sizeof(SavedLogData)]; // create byte array to store the struct
  memcpy(ByteArraySaved, &ReadLogData, sizeof(SavedLogData)); // copy the struct to the byte array
  dueFlashStorage.write(4, ByteArraySaved, sizeof(SavedLogData)); // write byte array to flash
  
//  genie.WriteObject(GENIE_OBJ_FORM, 7,0);
  
//  delay(3000);
  
  genie.WriteContrast(0);  
  
  delay(2000);
  
  pmc_enable_backupmode();

}

void ResetRoutine()
{
  //Ask for Confirmation -- Then proceed with Reset
  genie.WriteObject(GENIE_OBJ_FORM, 7,0);
  
  delay(1000);
  
 /* while (PageIndex){
    delay(200);
    genie.WriteObject(GENIE_OBJ_FORM, 7,0);
  }
*/
  //NEED TO ADD MESSAGE: PRESS OK TO CONFIRM, RESET TO EXIT
  
  PressedResetButton = 0;
  PressedOKButton = 0;
  ResetTimer=millis();
  DisplayCounter2=5;
 
  while (Counter2<5000){
    Counter2=millis()-ResetTimer;
    DisplayCounter2=5-Counter2/1000;
    genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0x00, DisplayCounter2);
    if (PressedOKButton) break;
    if (PressedResetButton) break;
   
  }

if (ResetFlag){
    genie.WriteObject(GENIE_OBJ_LED_DIGITS, 0x00, 9);
    delay(500);
    InitialAbsoluteTime=0;
    TotalRevolutions=0;
    TotalFuelConsumed=0;
    ResetFlag=0;
    
}

  PressedOKButton = 0;
  PressedResetButton = 0;

  genie.WriteObject(GENIE_OBJ_FORM, PageIndex ,0);
  Counter2=0;
  
}
Reply With Quote
Reply

Lower Navigation
Go Back   Defender Source > Defender & Series Technical Discussions > Defender Technical Discussions

Tags
sensor

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
UK Based Team Gigglepin, at King of the Hammers 2013 Willo Trips, Trails and Events 81 February 21st, 2013 12:56 PM
Fire and Ice Edition based on a 1985 LHD Defender 90 rivermike For Sale - Vehicles 9 May 5th, 2012 03:21 PM
Rough / X-tec Edition based on a 1985 LHD 90 rivermike For Sale - Vehicles 2 September 9th, 2011 04:35 AM
Bowler Wild Cat based on Land Rover rolaro Misc. Chit-Chat 2 December 18th, 2004 09:56 AM
Ford going after another LR based company chrisvonc Misc. Chit-Chat 14 July 29th, 2004 04:19 AM


All times are GMT -5. The time now is 03:35 AM.


Copyright