Some initial ground work for the SD logging

This commit is contained in:
Josh Stewart 2019-12-19 17:31:02 +11:00
parent 3265f1b937
commit b3a7ba8eac
8 changed files with 213 additions and 7 deletions

32
speeduino/SD_logger.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef SD_H
#define SD_H
#ifdef SD_LOGGING
#include <SPI.h>
#include <SD.h>
#define SD_STATUS_OFF 0
#define SD_STATUS_READY 1
#define SD_STATUS_ERROR_NO_CARD 2
#define SD_STATUS_ERROR_NO_FS 3
#define SD_STATUS_ERROR_NO_WRITE 4
#ifdef CORE_TEENSY
#define SD_CS_PIN BUILTIN_SDCARD
#else
#define SD_CS_PIN 10 //This is a made up value for now
#endif
//Sd2Card SD;
//SdVolume SD_volume;
File logFile;
uint8_t SD_status = SD_STATUS_OFF;
void initSD();
void writeSDLog();
void endSD();
#endif //SD_LOGGING
#endif //SD_H

34
speeduino/SD_logger.ino Normal file
View File

@ -0,0 +1,34 @@
#ifdef SD_LOGGING
#include <SPI.h>
#include <SD.h>
#include "SD_logger.h"
#include "logger.h"
void initSD()
{
//Init the SPI connection to the card reader
if (SD.begin(SD_CS_PIN))
{
//Attempt to create a log file for writing
logFile = SD.open("datalog.csv", FILE_WRITE);
if(!logFile) { SD_status = SD_STATUS_ERROR_NO_WRITE; } //Cannot write to SD card
else { SD_status = SD_STATUS_READY; }
}
else { SD_status = SD_STATUS_ERROR_NO_CARD; }
}
void endSD()
{
}
void writeSDLog()
{
uint8_t logEntry[LOG_ENTRY_SIZE];
}
#endif

View File

@ -22,8 +22,6 @@
#define warmupPage 10 //Config Page 10
#define fuelMap2Page 11
#define SERIAL_PACKET_SIZE 99 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
byte currentPage = 1;//Not the same as the speeduino config page numbers
bool isMap = true; /**< Whether or not the currentPage contains only a 3D map that would require translation */
unsigned long requestCount = 0; /**< The number of times the A command has been issued. This is used to track whether a reset has recently been performed on the controller */

View File

@ -6,12 +6,12 @@ A full copy of the license may be found in the projects root directory
#include "globals.h"
#include "comms.h"
#include "cancomms.h"
#include "errors.h"
#include "storage.h"
#include "maths.h"
#include "utils.h"
#include "decoders.h"
#include "scheduledIO.h"
#include "logger.h"
/*
Processes the data on the serial buffer.
@ -39,7 +39,7 @@ void command()
break;
case 'A': // send x bytes of realtime values
sendValues(0, SERIAL_PACKET_SIZE, 0x30, 0); //send values to serial0
sendValues(0, LOG_ENTRY_SIZE, 0x30, 0); //send values to serial0
break;
@ -495,7 +495,7 @@ This function returns the current values of a fixed group of variables
//void sendValues(int packetlength, byte portNum)
void sendValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum)
{
byte fullStatus[SERIAL_PACKET_SIZE];
byte fullStatus[LOG_ENTRY_SIZE];
if (portNum == 3)
{

View File

@ -19,6 +19,7 @@
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define CORE_TEENSY35
#define BOARD_H "board_teensy35.h"
#define SD_LOGGING //SD logging enabled by default for Teensy 3.5 as it has the slot built in
#elif defined(__IMXRT1062__)
#define CORE_TEENSY40
#define BOARD_H "board_teensy40.h"

View File

@ -1692,8 +1692,10 @@ void setPinMapping(byte boardID)
pinFan = 25; //Pin for the fan output
pinResetControl = 46; //Reset control output PLACEHOLDER value for now
pinMC33810_1_CS = 10;
pinMC33810_2_CS = 9;
#ifdef USE_MC33810
pinMC33810_1_CS = 10;
pinMC33810_2_CS = 9;
#endif
#endif
break;

16
speeduino/logger.h Normal file
View File

@ -0,0 +1,16 @@
/** \file logger.h
* @brief File for generating log files and meta data
* @author Josh Stewart
*
* This file contains functions for creating a log file for use eith by TunerStudio directly or to be written to an SD card
*
*/
#ifndef LOGGER_H
#define LOGGER_H
#define LOG_ENTRY_SIZE 99 /**< The size of the live data packet. This MUST match ochBlockSize setting in the ini file */
void createLog(uint8_t *array);
#endif

123
speeduino/logger.ino Normal file
View File

@ -0,0 +1,123 @@
#include "globals.h"
#include "errors.h"
void createLog(uint8_t *logBuffer)
{
currentStatus.spark ^= (-currentStatus.hasSync ^ currentStatus.spark) & (1U << BIT_SPARK_SYNC); //Set the sync bit of the Spark variable to match the hasSync variable
logBuffer[0] = currentStatus.secl; //secl is simply a counter that increments each second. Used to track unexpected resets (Which will reset this count to 0)
logBuffer[1] = currentStatus.status1; //status1 Bitfield
logBuffer[2] = currentStatus.engine; //Engine Status Bitfield
logBuffer[3] = currentStatus.syncLossCounter;
logBuffer[4] = lowByte(currentStatus.MAP); //2 bytes for MAP
logBuffer[5] = highByte(currentStatus.MAP);
logBuffer[6] = (byte)(currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //mat
logBuffer[7] = (byte)(currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET); //Coolant ADC
logBuffer[8] = currentStatus.batCorrection; //Battery voltage correction (%)
logBuffer[9] = currentStatus.battery10; //battery voltage
logBuffer[10] = currentStatus.O2; //O2
logBuffer[11] = currentStatus.egoCorrection; //Exhaust gas correction (%)
logBuffer[12] = currentStatus.iatCorrection; //Air temperature Correction (%)
logBuffer[13] = currentStatus.wueCorrection; //Warmup enrichment (%)
logBuffer[14] = lowByte(currentStatus.RPM); //rpm HB
logBuffer[15] = highByte(currentStatus.RPM); //rpm LB
logBuffer[16] = (byte)(currentStatus.AEamount >> 1); //TPS acceleration enrichment (%) divided by 2 (Can exceed 255)
logBuffer[17] = currentStatus.corrections; //Total GammaE (%)
logBuffer[18] = currentStatus.VE; //Current VE (%). Can be equal to VE1 or VE2 or a calculated value from both of them
logBuffer[19] = currentStatus.VE1; //VE 1 (%)
logBuffer[20] = currentStatus.VE2; //VE 2 (%)
logBuffer[21] = currentStatus.afrTarget;
logBuffer[22] = currentStatus.tpsDOT; //TPS DOT
logBuffer[23] = currentStatus.advance;
logBuffer[24] = currentStatus.TPS; // TPS (0% to 100%)
//Need to split the int loopsPerSecond value into 2 bytes
if(currentStatus.loopsPerSecond > 60000) { currentStatus.loopsPerSecond = 60000;}
logBuffer[25] = lowByte(currentStatus.loopsPerSecond);
logBuffer[26] = highByte(currentStatus.loopsPerSecond);
//The following can be used to show the amount of free memory
currentStatus.freeRAM = freeRam();
logBuffer[27] = lowByte(currentStatus.freeRAM); //(byte)((currentStatus.loopsPerSecond >> 8) & 0xFF);
logBuffer[28] = highByte(currentStatus.freeRAM);
logBuffer[29] = (byte)(currentStatus.boostTarget >> 1); //Divide boost target by 2 to fit in a byte
logBuffer[30] = (byte)(currentStatus.boostDuty / 100);
logBuffer[31] = currentStatus.spark; //Spark related bitfield
//rpmDOT must be sent as a signed integer
logBuffer[32] = lowByte(currentStatus.rpmDOT);
logBuffer[33] = highByte(currentStatus.rpmDOT);
logBuffer[34] = currentStatus.ethanolPct; //Flex sensor value (or 0 if not used)
logBuffer[35] = currentStatus.flexCorrection; //Flex fuel correction (% above or below 100)
logBuffer[36] = currentStatus.flexIgnCorrection; //Ignition correction (Increased degrees of advance) for flex fuel
logBuffer[37] = currentStatus.idleLoad;
logBuffer[38] = currentStatus.testOutputs;
logBuffer[39] = currentStatus.O2_2; //O2
logBuffer[40] = currentStatus.baro; //Barometer value
logBuffer[41] = lowByte(currentStatus.canin[0]);
logBuffer[42] = highByte(currentStatus.canin[0]);
logBuffer[43] = lowByte(currentStatus.canin[1]);
logBuffer[44] = highByte(currentStatus.canin[1]);
logBuffer[45] = lowByte(currentStatus.canin[2]);
logBuffer[46] = highByte(currentStatus.canin[2]);
logBuffer[47] = lowByte(currentStatus.canin[3]);
logBuffer[48] = highByte(currentStatus.canin[3]);
logBuffer[49] = lowByte(currentStatus.canin[4]);
logBuffer[50] = highByte(currentStatus.canin[4]);
logBuffer[51] = lowByte(currentStatus.canin[5]);
logBuffer[52] = highByte(currentStatus.canin[5]);
logBuffer[53] = lowByte(currentStatus.canin[6]);
logBuffer[54] = highByte(currentStatus.canin[6]);
logBuffer[55] = lowByte(currentStatus.canin[7]);
logBuffer[56] = highByte(currentStatus.canin[7]);
logBuffer[57] = lowByte(currentStatus.canin[8]);
logBuffer[58] = highByte(currentStatus.canin[8]);
logBuffer[59] = lowByte(currentStatus.canin[9]);
logBuffer[60] = highByte(currentStatus.canin[9]);
logBuffer[61] = lowByte(currentStatus.canin[10]);
logBuffer[62] = highByte(currentStatus.canin[10]);
logBuffer[63] = lowByte(currentStatus.canin[11]);
logBuffer[64] = highByte(currentStatus.canin[11]);
logBuffer[65] = lowByte(currentStatus.canin[12]);
logBuffer[66] = highByte(currentStatus.canin[12]);
logBuffer[67] = lowByte(currentStatus.canin[13]);
logBuffer[68] = highByte(currentStatus.canin[13]);
logBuffer[69] = lowByte(currentStatus.canin[14]);
logBuffer[70] = highByte(currentStatus.canin[14]);
logBuffer[71] = lowByte(currentStatus.canin[15]);
logBuffer[72] = highByte(currentStatus.canin[15]);
logBuffer[73] = currentStatus.tpsADC;
logBuffer[74] = getNextError();
logBuffer[75] = lowByte(currentStatus.PW1); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[76] = highByte(currentStatus.PW1); //Pulsewidth 1 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[77] = lowByte(currentStatus.PW2); //Pulsewidth 2 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[78] = highByte(currentStatus.PW2); //Pulsewidth 2 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[79] = lowByte(currentStatus.PW3); //Pulsewidth 3 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[80] = highByte(currentStatus.PW3); //Pulsewidth 3 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[81] = lowByte(currentStatus.PW4); //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[82] = highByte(currentStatus.PW4); //Pulsewidth 4 multiplied by 10 in ms. Have to convert from uS to mS.
logBuffer[83] = currentStatus.status3;
logBuffer[84] = currentStatus.nChannels;
logBuffer[85] = lowByte(currentStatus.fuelLoad);
logBuffer[86] = highByte(currentStatus.fuelLoad);
logBuffer[87] = lowByte(currentStatus.ignLoad);
logBuffer[88] = highByte(currentStatus.ignLoad);
logBuffer[89] = lowByte(currentStatus.dwell);
logBuffer[90] = highByte(currentStatus.dwell);
logBuffer[91] = currentStatus.CLIdleTarget;
logBuffer[92] = currentStatus.mapDOT;
logBuffer[93] = (int8_t)currentStatus.vvtAngle;
logBuffer[94] = currentStatus.vvtTargetAngle;
logBuffer[95] = currentStatus.vvtDuty;
logBuffer[96] = lowByte(currentStatus.flexBoostCorrection);
logBuffer[97] = highByte(currentStatus.flexBoostCorrection);
logBuffer[98] = currentStatus.baroCorrection;
}