TELEMATICS LCD SHIELD V1.0

            <img alt="" src="http://images.ncnynl.com/arduino/2016/Lcd-obd.png" width="279" height="466" class="thumbimage" />  <img src="http://images.ncnynl.com/arduino/2016/magnify-clip.png" width="15" height="11" alt="" />DFR0355 TELEMATICS LCD SHIELD V1.0

目录

1 概 述
2 技术规格
3 接口示意图
4 使用教程
5 更多

概 述
TELEMATICS LCD SHIELD是DFRobot最新开发的一款针对MEGA主板接口的LCD显示板。
该Shield显示板包括了SPI通信的SD接口,三个串口接口,以及一个IIC接口。完全支持Mega1280、Mega2560。

技术规格 电源:5V 背景光控制方式 PWM(高电平亮) 支持SD卡 支持触屏 大小:100*57mm

接口示意图
Lcd.png

1 SD卡插槽

如图所示位置,SD卡插槽位于LCD背面,不影响美观(主板背面有详细的标注)。

2 电源切换开关

如图所示位置,切换开关位于LCD背面,不影响美观,背面有明确的丝印表示,主要用于切换触摸芯片的电源,当主芯片使用3.3V供电时切换到3.3V端(主板背面有详细的标注)。

3 复位按钮

如图所示位置,复位按钮位于LCD背面,不影响美观,背面有明确的丝印表示,主要用于复位主芯片(主板背面有详细的标注)。

4 扩展接口

如图所示位置,其他扩展接口位于LCD背面,不影响美观,背面有明确的丝印表示,其中包括串口1~3,IIC接口(主板背面有详细的标注)。

使用教程
请先下载TELEMATICS LCD SHIELD相关库文件并安装库文件。点击下载
将下载的所有库文件安装导入到你的编译器下面,即可使用

注意:megalogger.rar是应用程序,不属于库文件。

/*************************************************************************

  • Reference code for OBD-II/GPS/9-Axis Data Logger
  • Works with Freematics OBD-II Telematics Advanced Kit
  • Visit http://freematics.com for more information
  • Distributed under GPL v2.0
  • Written by Stanley Huang <stanleyhuangyc@gmail.com>
    *************************************************************************/

#include <Arduino.h>
#include <Wire.h>
#include <OBD.h>
#include <SPI.h>
#include <MultiLCD.h>
#include <TinyGPS.h>
#include <I2Cdev.h>
#include <MPU9150.h>
#include "config.h"
#if ENABLE_DATA_LOG
#include <SD.h>
#endif
#include "Narcoleptic.h"
#include "images.h"
#if ENABLE_DATA_OUT && USE_SOFTSERIAL
#include <SoftwareSerial.h>
#endif
#include "datalogger.h"

// logger states
#define STATE_SD_READY 0x1
#define STATE_OBD_READY 0x2
#define STATE_GPS_CONNECTED 0x4
#define STATE_GPS_READY 0x8
#define STATE_MEMS_READY 0x10
#define STATE_GUI_ON 0x20

// adapter type
#define OBD_ADAPTER_I2C 0
#define OBD_ADAPTER_UART 1

#if USE_GPS
// GPS logging can only be enabled when there is additional hardware serial UART
#define GPSUART Serial2
TinyGPS gps;
#endif

#if USE_MPU6050 || USE_MPU9150
MPU6050 accelgyro;
static uint32_t lastMemsDataTime = 0;
#endif

static uint8_t lastFileSize = 0;
static uint32_t lastRefreshTime = 0;
static uint32_t distance = 0;
static uint32_t startTime = 0;
static uint16_t lastSpeed = 0;
static uint32_t lastSpeedTime = 0;
static uint32_t gpsDate = 0;
static uint32_t obdTime = 0;
static uint8_t obdCount = 0;
#if USE_GPS
static uint32_t lastGPSDataTime = 0;
static int gpsSpeed = -1;
#endif

static const byte PROGMEM pidTier1[]= {PID_RPM, PID_SPEED, PID_ENGINE_LOAD, PID_THROTTLE};
static const byte PROGMEM pidTier2[] = {PID_INTAKE_MAP, PID_MAF_FLOW, PID_TIMING_ADVANCE};
static const byte PROGMEM pidTier3[] = {PID_COOLANT_TEMP, PID_INTAKE_TEMP, PID_AMBIENT_TEMP, PID_ENGINE_FUEL_RATE};

#define TIER_NUM1 sizeof(pidTier1)
#define TIER_NUM2 sizeof(pidTier2)
#define TIER_NUM3 sizeof(pidTier3)

byte state = 0;

void processAccelerometer();
void processGPS();

CDataLogger logger;

class CMyOBD : public COBD
{
public:
void dataIdleLoop()
{
if (!(state & STATE_GUI_ON)) return;

    if (state &amp; STATE_MEMS_READY) {
        processAccelerometer();
    }

#if USE_GPS
uint32_t t = millis();
while (GPSUART.available() && millis() - t < MAX_GPS_PROCESS_TIME) {
processGPS();
}
#endif
}
};

class CMyOBDI2C : public COBDI2C
{
public:
void dataIdleLoop()
{
if (!(state & STATE_GUI_ON)) return;

    if (state &amp; STATE_MEMS_READY) {
        processAccelerometer();
    }

#if USE_GPS
uint32_t t = millis();
while (GPSUART.available() && millis() - t < MAX_GPS_PROCESS_TIME) {
processGPS();
}
#endif
}
};

#if OBD_ADAPTER_MODEL == OBD_MODEL_I2C
CMyOBDI2C obd;
#else
CMyOBD obd;
#endif

void setColorByValue(int value, int threshold1, int threshold2, int threshold3)
{
if (value < 0) value = -value;
if (value < threshold1) {
lcd.setColor(RGB16_WHITE);
} else if (value < threshold2) {
byte n = (uint32_t)(threshold2 - value) * 255 / (threshold2 - threshold1);
lcd.setColor(255, 255, n);
} else if (value < threshold3) {
byte n = (uint32_t)(threshold3 - value) * 255 / (threshold3 - threshold2);
lcd.setColor(255, n, 0);
} else {
lcd.setColor(255, 0, 0);
}
}

void showPIDData(byte pid, int value)
{
char buf[8];
switch (pid) {
case PID_RPM:
lcd.setFontSize(FONT_SIZE_XLARGE);
lcd.setCursor(32, 6);
if (value >= 10000) break;
setColorByValue(value, 2500, 3500, 5000);
lcd.printInt(value, 4);
break;
case PID_SPEED:
if (value < 1000) {
lcd.setFontSize(FONT_SIZE_XLARGE);
lcd.setCursor(50, 2);
setColorByValue(value, 60, 100, 160);
lcd.printInt(value, 3);

#if USE_GPS
if (gpsSpeed != -1) {
lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setCursor(110, 2);
lcd.setColor(RGB16_YELLOW);
int diff = gpsSpeed - value;
if (diff >= 0) {
lcd.write('+');
lcd.printInt(diff);
} else {
lcd.write('-');
lcd.printInt(-diff);
}
lcd.write(' ');
}
#endif
}
break;
case PID_ENGINE_LOAD:
lcd.setFontSize(FONT_SIZE_XLARGE);
lcd.setCursor(50, 10);
if (value >= 100) value = 99;
setColorByValue(value, 75, 80, 100);
lcd.printInt(value, 3);
break;
case PID_THROTTLE:
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.setCursor(92, 21);
if (value >= 100) value = 99;
setColorByValue(value, 50, 75, 100);
lcd.printInt(value, 2);
break;
case PID_ENGINE_FUEL_RATE:
if (value < 100) {
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.setCursor(92, 24);
lcd.printInt(value, 2);
}
break;
case PID_INTAKE_TEMP:
if (value >= 0 && value < 100) {
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.setCursor(92, 27);
lcd.printInt(value, 2);
}
break;
}
lcd.setColor(RGB16_WHITE);
}

void ShowVoltage(float v)
{
lcd.setFontSize(FONT_SIZE_LARGE);
lcd.setCursor(84, 18);
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.print(v);
}

void fadeOutScreen()
{
// fade out backlight
for (int n = 254; n >= 0; n--) {
lcd.setBackLight(n);
delay(5);
}
}

void fadeInScreen()
{
for (int n = 1; n <= 255; n++) {
lcd.setBackLight(n);
delay(10);
}
}

void initScreen()
{
lcd.clear();
lcd.draw4bpp(frame0[

lcd.setColor(RGB16_CYAN);
lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setCursor(110, 4);
lcd.print(&quot;km/h&quot;);
lcd.setCursor(110, 8);
lcd.print(&quot;RPM&quot;);
lcd.setCursor(110, 11);
lcd.print(&quot;ENGINE&quot;);
lcd.setCursor(110, 12);
lcd.print(&quot;LOAD&#160;%&quot;);

//lcd.setFont(FONT_SIZE_MEDIUM);
lcd.setColor(RGB16_CYAN);
lcd.setCursor(184, 2);
lcd.print(&quot;ELAPSED:&quot;);
lcd.setCursor(184, 5);
lcd.print(&quot;DISTANCE:        km&quot;);
lcd.setCursor(184, 8);
lcd.print(&quot;AVG SPEED:       kph&quot;);
lcd.setCursor(184, 11);
lcd.print(&quot;ALTITUDE:        m&quot;);

lcd.setCursor(18, 18);
lcd.print(&quot;BATTERY:           V&quot;);
lcd.setCursor(18, 21);
lcd.print(&quot;THROTTLE:      &#160;%&quot;);
lcd.setCursor(18, 24);
lcd.print(&quot;FUEL RATE:      L/h&quot;);
lcd.setCursor(18, 27);
lcd.print(&quot;INTAKE:         C&quot;);

lcd.setCursor(184, 18);
lcd.print(&quot;UTC:&quot;);
lcd.setCursor(184, 19);
lcd.print(&quot;LAT:&quot;);
lcd.setCursor(280, 19);
lcd.print(&quot;SAT:&quot;);
lcd.setCursor(184, 20);
lcd.print(&quot;LON:&quot;);

lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setCursor(184, 22);
lcd.print(&quot;ACC:&quot;);
lcd.setCursor(184, 23);
lcd.print(&quot;GYR:&quot;);
lcd.setCursor(184, 24);
lcd.print(&quot;MAG:&quot;);

lcd.setCursor(184, 26);
lcd.print(&quot;OBD FREQ:&quot;);

lcd.setCursor(184, 27);
lcd.print(&quot;GPS FREQ:&quot;);

lcd.setCursor(184, 28);
lcd.print(&quot;LOG SIZE:&quot;);

//lcd.setColor(0xFFFF);
/*
lcd.setCursor(32, 4);
lcd.print(&quot;%&quot;);
lcd.setCursor(68, 5);
lcd.print(&quot;Intake Air&quot;);
lcd.setCursor(112, 4);
lcd.print(&quot;C&quot;);
*/

state |= STATE_GUI_ON;

fadeInScreen();

}

#if ENABLE_DATA_LOG
bool checkSD()
{
Sd2Card card;
SdVolume volume;
state &= ~STATE_SD_READY;
pinMode(SS, OUTPUT);

lcd.setFontSize(FONT_SIZE_MEDIUM);
if (card.init(SPI_HALF_SPEED, SD_CS_PIN)) {
    const char* type;
    switch(card.type()) {
    case SD_CARD_TYPE_SD1:
        type = &quot;SD1&quot;;
        break;
    case SD_CARD_TYPE_SD2:
        type = &quot;SD2&quot;;
        break;
    case SD_CARD_TYPE_SDHC:
        type = &quot;SDHC&quot;;
        break;
    default:
        type = &quot;SDx&quot;;
    }

    lcd.print(type);
    lcd.write(' ');
    if (!volume.init(card)) {
        lcd.print(&quot;No FAT!&quot;);
        return false;
    }

    uint32_t volumesize = volume.blocksPerCluster();
    volumesize &gt;&gt;= 1; // 512 bytes per block
    volumesize *= volume.clusterCount();
    volumesize &gt;&gt;= 10;

    lcd.print((int)volumesize);
    lcd.print(&quot;MB&quot;);
} else {
    lcd.println(&quot;No SD Card&quot;);
    return false;
}

if (!SD.begin(SD_CS_PIN)) {
    lcd.println(&quot;Bad SD&quot;);
    return false;
}

state |= STATE_SD_READY;
return true;

}
#endif

#if USE_GPS
void processGPS()
{
// process GPS data
char c = GPSUART.read();
if (!gps.encode(c))
return;

// parsed GPS data is ready
uint32_t time;
uint32_t date;

logger.dataTime = millis();

gps.get_datetime(&amp;date, &amp;time, 0);
if (date&#160;!= gpsDate) {
    // log date only if it's changed and valid
    int year = date&#160;% 100;
    if (date &lt; 1000000 &amp;&amp; date &gt;= 10000 &amp;&amp; year &gt;= 15 &amp;&amp; (gpsDate == 0 || year - (gpsDate&#160;% 100) &lt;= 1)) {
      logger.logData(PID_GPS_DATE, (int32_t)date);
      gpsDate = date;
    }
}
logger.logData(PID_GPS_TIME, (int32_t)time);

int32_t lat, lon;
gps.get_position(&amp;lat, &amp;lon, 0);

byte sat = gps.satellites();

// show GPS data interval
lcd.setFontSize(FONT_SIZE_SMALL);
if (lastGPSDataTime) {
    lcd.setCursor(242, 27);
    lcd.printInt((uint16_t)logger.dataTime - lastGPSDataTime);
    lcd.print(&quot;ms&quot;);
    lcd.printSpace(2);
}

// keep current data time as last GPS time
lastGPSDataTime = logger.dataTime;

// display UTC date/time
lcd.write(' ');
lcd.setCursor(214, 18);
lcd.setFlags(FLAG_PAD_ZERO);
lcd.printLong(date, 6);
lcd.write(' ');
lcd.printLong(time, 8);

// display latitude
lcd.setCursor(214, 19);
lcd.print(lat / 100000);
lcd.write('.');
lcd.printLong(abs(lat)&#160;% 100000, 5);
// display longitude
lcd.setCursor(214, 20);
lcd.print(lon / 100000);
lcd.write('.');
lcd.printLong(abs(lon)&#160;% 100000, 5);
// log latitude/longitude
logger.logData(PID_GPS_LATITUDE, lat);
logger.logData(PID_GPS_LONGITUDE, lon);

// display number of satellites
if (sat &lt; 100) {
    lcd.setCursor(280, 20);
    lcd.printInt(sat);
    lcd.write(' ');
}
// display altitude
int32_t alt = gps.altitude();
lcd.setFlags(0);
if (alt &gt; -1000000 &amp;&amp; alt &lt; 1000000) {
    lcd.setFontSize(FONT_SIZE_MEDIUM);
    lcd.setCursor(250, 11);
    lcd.print(alt / 100);
    lcd.write(' ');
    // log altitude
    logger.logData(PID_GPS_ALTITUDE, (int)(alt / 100));
}

// only log these data when satellite status is good
if (sat &gt;= 3) {
    gpsSpeed = gps.speed() * 1852 / 100000;
    logger.logData(PID_GPS_SPEED, gpsSpeed);
}

}
#endif

void processAccelerometer()
{
#if USE_MPU6050 || USE_MPU9150
int16_t ax, ay, az;
int16_t gx, gy, gz;
#if USE_MPU9150
int16_t mx, my, mz;
#endif
int temp;

if (logger.dataTime - lastMemsDataTime &lt; ACC_DATA_INTERVAL) {
    return;
}

#if USE_MPU9150
accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
#else
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
#endif

logger.dataTime = millis();

temp = accelgyro.getTemperature();

ax /= ACC_DATA_RATIO;
ay /= ACC_DATA_RATIO;
az /= ACC_DATA_RATIO;
gx /= GYRO_DATA_RATIO;
gy /= GYRO_DATA_RATIO;
gz /= GYRO_DATA_RATIO;

#if USE_MPU9150
mx /= COMPASS_DATA_RATIO;
my /= COMPASS_DATA_RATIO;
mz /= COMPASS_DATA_RATIO;
#endif
// display MEMS data
lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setCursor(214, 22);
setColorByValue(ax, 50, 100, 200);
lcd.print(ax);
setColorByValue(ay, 50, 100, 200);
lcd.write('/');
lcd.print(ay);
setColorByValue(az, 50, 100, 200);
lcd.write('/');
lcd.print(az);
lcd.printSpace(8);

// display gyro data
lcd.setCursor(214, 23);
lcd.setColor(RGB16_WHITE);
lcd.print(gx);
lcd.write('/');
lcd.print(gy);
lcd.write('/');
lcd.print(gz);
lcd.printSpace(8);

#if USE_MPU9150
// display compass data
lcd.setCursor(214, 24);
lcd.setColor(RGB16_WHITE);
lcd.print(mx);
lcd.write('/');
lcd.print(my);
lcd.write('/');
lcd.print(mz);
lcd.printSpace(8);
#endif

// log x/y/z of accelerometer
logger.logData(PID_ACC, ax, ay, az);
// log x/y/z of gyro meter
logger.logData(PID_GYRO, gx, gy, gz);

#if USE_MPU9150
// log x/y/z of compass
logger.logData(PID_COMPASS, mx, my, mz);
#endif
logger.logData(PID_MEMS_TEMP, temp);

lastMemsDataTime = logger.dataTime;

#endif
}

void logOBDData(byte pid)
{
char buffer[OBD_RECV_BUF_SIZE];
uint32_t start = millis();
int value;

// send query for OBD-II PID
obd.sendQuery(pid);
// let PID parsed from response
pid = 0;
// read responded PID and data
if (!obd.getResult(pid, value)) {
    return;
}
logger.dataTime = millis();
if (obdCount == 255) {
  obdTime = 0; 
  obdCount = 0;
}
obdTime += logger.dataTime - start;
obdCount++;
// display data
showPIDData(pid, value);

// log data to SD card
logger.logData(0x100 | pid, value);

if (pid == PID_SPEED) {
    // estimate distance travelled since last speed update
    distance += (uint32_t)(value + lastSpeed) * (logger.dataTime - lastSpeedTime) / 6000;
    // display speed
    lcd.setFontSize(FONT_SIZE_MEDIUM);
    lcd.setCursor(250, 5);
    lcd.printInt(distance / 1000);
    lcd.write('.');
    lcd.printInt(((uint16_t)distance&#160;% 1000) / 100);
    // calculate and display average speed
    int avgSpeed = (unsigned long)distance * 3600 / (millis() - startTime);
    lcd.setCursor(250, 8);
    lcd.printInt(avgSpeed);

    lastSpeed = value;
    lastSpeedTime = logger.dataTime;
}

#if ENABLE_DATA_LOG
// flush SD data every 1KB
if ((logger.dataSize >> 10) != lastFileSize) {
logger.flushFile();
// display logged data size
lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setCursor(242, 28);
lcd.print((unsigned int)(logger.dataSize >> 10));
lcd.print("KB");
lastFileSize = logger.dataSize >> 10;
}
#endif

// if OBD response is very fast, go on processing other data for a while

#ifdef OBD_MIN_INTERVAL
while (millis() - start < OBD_MIN_INTERVAL) {
obd.dataIdleLoop();
}
#endif
}

void showECUCap()
{
static const byte PROGMEM pidlist[] = {PID_ENGINE_LOAD, PID_COOLANT_TEMP, PID_FUEL_PRESSURE, PID_INTAKE_MAP, PID_RPM, PID_SPEED, PID_TIMING_ADVANCE, PID_INTAKE_TEMP, PID_MAF_FLOW, PID_THROTTLE, PID_AUX_INPUT,
PID_EGR_ERROR, PID_COMMANDED_EVAPORATIVE_PURGE, PID_FUEL_LEVEL, PID_CONTROL_MODULE_VOLTAGE, PID_ABSOLUTE_ENGINE_LOAD, PID_AMBIENT_TEMP, PID_COMMANDED_THROTTLE_ACTUATOR, PID_ETHANOL_FUEL,
PID_FUEL_RAIL_PRESSURE, PID_HYBRID_BATTERY_PERCENTAGE, PID_ENGINE_OIL_TEMP, PID_FUEL_INJECTION_TIMING, PID_ENGINE_FUEL_RATE, PID_ENGINE_TORQUE_DEMANDED, PID_ENGINE_TORQUE_PERCENTAGE};

lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setColor(RGB16_WHITE);
for (byte i = 0, n = 4; i &lt; sizeof(pidlist) / sizeof(pidlist[0]); i++) {
  byte pid = pgm_read_byte(pidlist + i);
  if (obd.isValidPID(pid)) {
    lcd.setCursor(252, n++);
    lcd.write('0');
    lcd.print((int)pid | 0x100, HEX);
  }
}
int values[sizeof(pidlist)];
bool scanned = false;
for (uint32_t t = millis(); millis() - t &lt; GUI_PID_LIST_DURATION * 1000; ) {
  for (byte i = 0, n = 4; i &lt; sizeof(pidlist) / sizeof(pidlist[0]); i++) {
      byte pid = pgm_read_byte(pidlist + i);
      if (obd.isValidPID(pid)) {
          int value;
          lcd.setCursor(280 , n++);
          if (obd.read(pid, value)) {
            if (!scanned || value == values[i])
              lcd.setColor(RGB16_CYAN);
            else if (value &gt; values[i])
              lcd.setColor(RGB16_GREEN);
            else
              lcd.setColor(RGB16_RED);
            byte n = lcd.print(value);
            for (; n &lt; 4; n++) lcd.print(' ');
            values[i] = value;
          } else {
            lcd.setColor(RGB16_YELLOW);
            lcd.print(&quot;N/A&quot;);
          }
      }
   }
   scanned = true;
}

}

void reconnect()
{
fadeOutScreen();
#if ENABLE_DATA_LOG
logger.closeFile();
#endif
lcd.clear();
state &= ~(STATE_OBD_READY | STATE_GUI_ON);
//digitalWrite(SD_CS_PIN, LOW);
for (;;) {
if (!obd.init())
continue;

    int value;
    if (obd.read(PID_RPM, value) &amp;&amp; value &gt; 0)
        break;

    Narcoleptic.delay(1000);
}
// re-initialize
state |= STATE_OBD_READY;
startTime = millis();
lastSpeedTime = startTime;
lastSpeed = 0;
distance = 0;

#if ENABLE_DATA_LOG
logger.openFile();
#endif
initScreen();
}

// screen layout related stuff
void showStates()
{
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.setColor(RGB16_WHITE);
lcd.setCursor(0, 8);
lcd.print("MEMS ");
lcd.setColor((state & STATE_MEMS_READY) ? RGB16_GREEN : RGB16_RED);
lcd.draw((state & STATE_MEMS_READY) ? tick : cross, 16, 16);

#if USE_GPS
lcd.setColor(RGB16_WHITE);
lcd.setCursor(60, 8);
lcd.print(" GPS ");
if (state & STATE_GPS_CONNECTED) {
lcd.setColor(RGB16_GREEN);
lcd.draw(tick, 16, 16);
} else {
lcd.setColor(RGB16_RED);
lcd.draw(cross, 16, 16);
}
#endif
lcd.setColor(RGB16_WHITE);
}

void testOut()
{
static const char PROGMEM cmds[][6] = {"ATZ\r", "ATL1\r", "ATRV\r", "0100\r", "010C\r", "0902\r"};
char buf[OBD_RECV_BUF_SIZE];
lcd.setFontSize(FONT_SIZE_SMALL);
lcd.setCursor(0, 11);

for (byte i = 0; i &lt; sizeof(cmds) / sizeof(cmds[0]); i++) {
    char cmd[6];
    memcpy_P(cmd, cmds[i], sizeof(cmd));
    lcd.setColor(RGB16_WHITE);
    lcd.print(&quot;Sending &quot;);
    lcd.println(cmd);
    lcd.setColor(RGB16_CYAN);
    if (obd.sendCommand(cmd, buf)) {
        char *p = strstr(buf, cmd);
        if (p)
            p += strlen(cmd);
        else
            p = buf;
        while (*p == '\r') p++;
        while (*p) {
            lcd.write(*p);
            if (*p == '\r' &amp;&amp; *(p + 1)&#160;!= '\r')
                lcd.write('\n');
            p++;
        }
    } else {
        lcd.println(&quot;Timeout&quot;);
    }
    delay(500);
}
lcd.println();

}

void setup()
{
lcd.begin();
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.setColor(0xFFE0);
lcd.println("MEGA LOGGER - OBD-II/GPS/MEMS");
lcd.println();
lcd.setColor(RGB16_WHITE);

#if USE_GPS
GPSUART.begin(GPS_BAUDRATE);
// switching to 10Hz mode, effective only for MTK3329
//GPSUART.println(PMTK_SET_NMEA_OUTPUT_ALLDATA);
//GPSUART.println(PMTK_SET_NMEA_UPDATE_10HZ);
lastGPSDataTime = 0;
#endif

logger.initSender();

#if ENABLE_DATA_LOG
if (checkSD()) {
uint16_t index = logger.openFile();
lcd.println();
if (index > 0) {
lcd.print("File ID:");
lcd.println(index);
} else {
lcd.print("No File");
}
}
#endif

#if USE_MPU6050 || USE_MPU9150
Wire.begin();
accelgyro.initialize();
if (accelgyro.testConnection()) state |= STATE_MEMS_READY;
#endif
showStates();

#if USE_GPS
unsigned long t = millis();
do {
if (GPSUART.available() && GPSUART.read() == '\r') {
state |= STATE_GPS_CONNECTED;
break;
}
} while (millis() - t <= 2000);
showStates();
#endif

obd.begin();

// this will send a bunch of commands and display response
testOut();

// initialize the OBD until success
while (!obd.init(OBD_PROTOCOL));

state |= STATE_OBD_READY;

lcd.setColor(RGB16_GREEN);
lcd.setFontSize(FONT_SIZE_MEDIUM);
lcd.println(&quot;READY!&quot;);

char buf[OBD_RECV_BUF_SIZE];
if (obd.getVIN(buf)) {
    lcd.setFontSize(FONT_SIZE_SMALL);
    lcd.setColor(RGB16_WHITE);
    lcd.print(&quot;VIN:&quot;);
    lcd.setColor(RGB16_YELLOW);
    lcd.print(buf);
}

//lcd.setFont(FONT_SIZE_MEDIUM);
//lcd.setCursor(0, 14);
//lcd.print(&quot;VIN: XXXXXXXX&quot;);

showECUCap();
delay(3000);

fadeOutScreen();
initScreen();

startTime = millis();
lastSpeedTime = startTime;
lastRefreshTime = millis();

}

void loop()
{
static byte index = 0;
static byte index2 = 0;
static byte index3 = 0;
byte pid = pgm_read_byte(pidTier1 + index++);
logOBDData(pid);
if (index == TIER_NUM1) {
index = 0;
if (index2 == TIER_NUM2) {
index2 = 0;
pid = pgm_read_byte(pidTier3 + index3);
if (obd.isValidPID(pid)) {
logOBDData(pid);
}
index3 = (index3 + 1) % TIER_NUM3;
if (index3 == 0) {
float v = obd.getVoltage();
ShowVoltage(v);
logger.logData(PID_BATTERY_VOLTAGE, (int)(v * 100));
}
} else {
pid = pgm_read_byte(pidTier2 + index2);
if (obd.isValidPID(pid)) {
logOBDData(pid);
}
index2++;
}
}

if (logger.dataTime -  lastRefreshTime &gt;= 1000) {
    char buf[12];
    // display elapsed time
    unsigned int sec = (logger.dataTime - startTime) / 1000;
    sprintf(buf, &quot;%02u:%02u&quot;, sec / 60, sec&#160;% 60);
    lcd.setFontSize(FONT_SIZE_MEDIUM);
    lcd.setCursor(250, 2);
    lcd.print(buf);
    // display OBD time
    if (obdTime) {
      lcd.setFontSize(FONT_SIZE_SMALL);
      lcd.setCursor(242, 26);
      lcd.print((uint16_t)(obdTime / obdCount));
      lcd.print(&quot;ms &quot;);
    }
    lastRefreshTime = logger.dataTime;
}

if (obd.errors &gt;= 3) {
    reconnect();
}

#if USE_GPS
if (millis() - lastGPSDataTime > GPS_DATA_TIMEOUT || gps.satellites() < 3) {
// GPS not ready
state &= ~STATE_GPS_READY;
} else {
// GPS ready
state |= STATE_GPS_READY;
}
#endif
}

更多问题及有趣的应用,可以 访问论坛 进行查阅或发帖!

更多
相关文档
文档一:TELEMATICS LCD SHIELD库文件

DFshopping car1.png [Link ]

标签: Arduino传感器