Huge cleanup and new work. Not in working state

EEPROM storage initial commit - Incomplete
Removal of significant code from .h files
Expansion of MS serial protocol
This commit is contained in:
Josh Stewart 2013-08-26 14:11:47 +10:00
parent d26171614d
commit 2af9c4be6f
5 changed files with 113 additions and 106 deletions

View File

@ -80,9 +80,9 @@ void sendValues(int length)
boolean a = 0; //inj_port1.status;
boolean b = 0; //inj_port2.status;
response[1] = ((a & 0x01) << 0) | ((a & 0x02) << 1) | ((a & 0x04) << 1) | ((b & 0x01) << 1) | ((b & 0x02) << 3) | ((b & 0x04) << 3); //squirt NOT YET WORKING
response[1] = currentStatus.squirt; //((a & 0x01) << 0) | ((a & 0x02) << 1) | ((a & 0x04) << 1) | ((b & 0x01) << 1) | ((b & 0x02) << 3) | ((b & 0x04) << 3); //squirt NOT YET WORKING
response[2] = (byte)128; // Engine Status NOT YET WORKING
response[2] = currentStatus.engine; // Engine Status NOT YET WORKING
response[3] = 0x00; //baro
response[4] = currentStatus.MAP; //map
response[5] = 0x00; //mat
@ -126,13 +126,15 @@ void receiveValue(byte offset, byte newValue)
if (offset < 72)
{
//X Axis
*(pnt_configPage + offset) = newValue * 100; //The RPM values sent by megasquirt are divided by 100, need to multiple it back by 100 to make it correct
//*(pnt_configPage + offset) = newValue * 100; //The RPM values sent by megasquirt are divided by 100, need to multiple it back by 100 to make it correct
fuelTable.axisX[(offset-64)] = newValue * 100; //The RPM values sent by megasquirt are divided by 100, need to multiple it back by 100 to make it correct
}
else
{
//Y Axis
offset = 7-(offset-72); //Need to do a translation to flip the order (Due to us using (0,0) in the top left rather than bottom right
*(pnt_configPage + offset) = newValue;
//*(pnt_configPage + offset) = newValue;
fuelTable.axisY[offset] = newValue;
}
}
else //New value is one of the remaining config items
@ -174,6 +176,11 @@ void receiveValue(byte offset, byte newValue)
}
}
/*
sendPage() packs the data within the current page (As set with the 'P' command)
into a buffer and sends it.
Note that some translation of the data is required to lay it out in the way Megasqurit / TunerStudio expect it
*/
void sendPage()
{
byte response[page_size];
@ -185,7 +192,7 @@ void sendPage()
case vePage:
//Need to perform a translation of the values[MAP/TPS][RPM] into the MS expected format
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
for(byte x=0;x<64;x++) { response[x] = fuelTable.values[7-x/8][x%8]; }
for(byte x=0;x<64;x++) { response[x] = fuelTable.values[7-x/8][x%8]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged
for(byte x=64;x<72;x++) { response[x] = fuelTable.axisX[(x-64)] / 100; } //RPM Bins for VE table (Need to be dvidied by 100)
for(byte y=72;y<80;y++) { response[y] = fuelTable.axisY[7-(y-72)]; } //MAP or TPS bins for VE table
@ -196,44 +203,6 @@ void sendPage()
{
response[offset] = *(pnt_configPage + offset + x); //Each byte is simply the location in memory of configPage1 + the offset + the variable number (x)
}
/*
response[80] = configPage1.crankCold; //Cold cranking pulsewidth. This is added to the fuel pulsewidth when cranking under a temp threshold (ms)
response[81] = configPage1.crankHot; //Warm cranking pulsewidth. This is added to the fuel pulsewidth when cranking (ms)
response[82] = configPage1.asePct; //Afterstart enrichment (%)
response[83] = configPage1.aseCount; //Afterstart enrichment cycles. This is the number of ignition cycles that the afterstart enrichment % lasts for
for(byte x=84;x<94;x++) { response[x] = configPage1.wueBins[x-84]; } //Warm up enrichment array (10 bytes, % values)
response[94] = configPage1.taeBins1; //TPS based acceleration enrichment bin 1 of 4 (ms)
response[95] = configPage1.taeBins2; //TPS based acceleration enrichment bin 2 of 4 (ms)
response[96] = configPage1.taeBins3; //TPS based acceleration enrichment bin 3 of 4 (ms)
response[97] = configPage1.taeBins4; //TPS based acceleration enrichment bin 4 of 4 (ms)
response[98] = 0;
response[99] = 0;
response[100] = 0;
response[101] = 0;
response[102] = 0;
response[103] = 0;
response[104] = 0;
response[105] = 0;
response[106] = configPage1.reqFuel;
response[107] = 0;
response[108] = 0;
response[109] = 0;
response[110] = 0;
response[111] = 0;
response[112] = 0;
response[113] = 0;
response[114] = 0; //rpmk (16 bits)
response[116] = ((configPage1.nCylinders-1) * 16) + (1 * 8) + ((configPage1.strokes / 4) * 4) + 2; // (engineCylinders * 16) + (1 * 8) + ((engineStrokes / 4) * 4) + 4
response[117] = 0;
response[118] = 0;
response[119] = 0;
response[120] = 0;
response[121] = 0;
response[122] = 0;
response[123] = 0;
response[124] = 0;
*/
Serial.write((byte *)&response, sizeof(response));
break;

View File

@ -12,8 +12,16 @@ struct statuses {
byte MAP;
byte TPS;
byte VE;
byte squirt;
byte engine;
unsigned long PW; //In uS
//Helpful bitwise operations:
//Useful reference: http://playground.arduino.cc/Code/BitMath
// y = (x >> n) & 1; // n=0..15. stores nth bit of x in y. y becomes 0 or 1.
// x &= ~(1 << n); // forces nth bit of x to be 0. all other bits left alone.
// x |= (1 << n); // forces nth bit of x to be 1. all other bits left alone.
};

View File

@ -28,7 +28,7 @@ Need to calculate the req_fuel figure here, preferably in pre-processor macro
#include "comms.h"
#include "fastAnalog.h"
#include "digitalIOPerformance.h"
//#include "digitalIOPerformance.h"
//NEED TO LOAD FROM EEPROM HERE
struct config1 configPage1;
@ -45,6 +45,8 @@ int triggerToothAngle = 360 / configPage2.triggerTeeth; //The number of degrees
volatile int toothCurrentCount = 0; //The current number of teeth (Onec sync has been achieved, this can never actually be 0
volatile unsigned long toothLastToothTime = 0; //The time (micros()) that the last tooth was registered
volatile unsigned long toothLastMinusOneToothTime = 0; //The time (micros()) that the tooth before the last tooth was registered
volatile unsigned long toothOneTime = 0; //The time (micros()) that tooth 1 last triggered
volatile unsigned long toothOneMinusOneTime = 0; //The 2nd to last time (micros()) that tooth 1 last triggered
struct table fuelTable;
struct table ignitionTable;
@ -69,7 +71,6 @@ void setup() {
switch (pinTrigger) {
//Arduino Mega 2560 mapping (Uncomment to use)
/*
case 2:
triggerInterrupt = 0; break;
case 3:
@ -82,9 +83,10 @@ void setup() {
triggerInterrupt = 3; break;
case 21:
triggerInterrupt = 2; break;
*/
//Arduino Leo(nardo/stick) mapping (Comment this section if using a mega)
/*
case 3:
triggerInterrupt = 0; break;
case 2:
@ -95,8 +97,11 @@ void setup() {
triggerInterrupt = 3; break;
case 7:
triggerInterrupt = 4; break;
*/
}
attachInterrupt(triggerInterrupt, trigger, FALLING); // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
pinMode(pinTrigger, INPUT);
digitalWrite(pinTrigger, HIGH);
attachInterrupt(triggerInterrupt, trigger, RISING); // Attach the crank trigger wheel interrupt (Hall sensor drags to ground when triggering)
//End crank triger interrupt attachment
req_fuel_uS = req_fuel_uS / engineSquirtsPerCycle; //The req_fuel calculation above gives the total required fuel (At VE 100%) in the full cycle. If we're doing more than 1 squirt per cycle then we need to split the amount accordingly. (Note that in a non-sequential 4-stroke setup you cannot have less than 2 squirts as you cannot determine the stroke to make the single squirt on)
@ -120,6 +125,11 @@ void setup() {
initialiseScheduler();
counter = 0;
configPage2.triggerTeeth = 12; //TESTING ONLY!
configPage2.triggerMissingTeeth = 1; //TESTING ONLY!
triggerActualTeeth = configPage2.triggerTeeth - configPage2.triggerMissingTeeth; //The number of physical teeth on the wheel. Doing this here saves us a calculation each time in the interrupt
triggerToothAngle = 360 / configPage2.triggerTeeth;
//Setup some LEDs for testing
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
@ -127,6 +137,31 @@ void setup() {
void loop()
{
//Check for any requets from serial
//Serial.println(toothCurrentCount);
//if (toothCurrentCount == 1) //Only check the serial buffer (And hence process serial commands) once per revolution
//{
if (Serial.available() > 0)
{
command();
}
//Serial.print("Trigger Teeth: ");
//Serial.println(configPage2.triggerTeeth);
/*
Serial.print("Tooth last time: ");
Serial.println(toothLastToothTime);
Serial.print("Tooth last minus one time: ");
Serial.println(toothLastMinusOneToothTime);
*/
Serial.print("RPM: ");
Serial.println(currentStatus.RPM);
/*
//Serial.print("toothLastToothTime: ");
//Serial.println(toothLastToothTime);
*/
//}
//delay(2500);
//Always check for sync
//Main loop runs within this clause
@ -134,15 +169,19 @@ void loop()
{
//Calculate the RPM based on the time between the last 2 teeth. I have no idea whether this will be accurate AT ALL, but it's fairly efficient and means there doesn't need to be another variable placed into the trigger interrupt
if (toothCurrentCount != 1) //We can't perform the RPM calculation if we're at the first tooth as the timing would be double (Well, we can, but it would need a different calculation and I don't think it's worth it, just use the last RPM value)
if (toothCurrentCount != 1 && toothLastMinusOneToothTime != 0) //We can't perform the RPM calculation if we're at the first tooth as the timing would be double (Well, we can, but it would need a different calculation and I don't think it's worth it, just use the last RPM value)
{
long revolutionTime = (configPage2.triggerTeeth * (toothLastToothTime - toothLastMinusOneToothTime)); //The time in uS that one revolution would take at current speed
//unsigned long revolutionTime = ((long)configPage2.triggerTeeth * (toothLastToothTime - toothLastMinusOneToothTime)); //The time in uS that one revolution would take at current speed
unsigned long revolutionTime = (toothOneTime - toothOneMinusOneTime); //The time in uS that one revolution would take at current speed
//Serial.println((toothLastToothTime - toothLastMinusOneToothTime));
currentStatus.RPM = US_IN_MINUTE / revolutionTime;
}
if ( (micros() - toothLastToothTime) > 100000L ) { currentStatus.RPM = 0; toothLastMinusOneToothTime = 0;}
//Get the current MAP value
//currentStatus.MAP = 100; //Placeholder
currentStatus.MAP = map(analogRead(pinMAP), 0, 1023, 0, 100);
currentStatus.TPS = 20; //Placeholder
//currentStatus.TPS = map(analogRead(pinTPS), 0, 1023, 0, 100);
//Begin the fuel calculation
//Perform lookup into fuel map for RPM vs MAP value
@ -189,53 +228,9 @@ void loop()
);
}
//Check for any requets from serial
//Serial.println(toothCurrentCount);
if (toothCurrentCount == 1) //Only check the serial buffer (And hence process serial commands) once per revolution
{
if (Serial.available() > 0)
{
command();
}
}
//Serial.println(VE);
//Serial.print("VE: ");
//Serial.println(VE);
//Serial.print("Injector pulsewidth: ");
//Serial.println(pulseWidth);
//Serial.println(req_fuel * (float)(VE/100.0) * (float)(MAP/100.0) * (float)(100/100.0) + engineInjectorDeadTime);
//Serial.println( (float)(req_fuel * (float)(VE/100)) );
//Serial.println( (float)(VE/100.0));
/*
if (counter > 100000) {
scheduleStart = micros();
setSchedule1(openInjector2, 1000000);
counter = 0;
}
counter++;
if (scheduleEnd != 0) {
Serial.print("The schedule took (uS): ");
Serial.println(scheduleEnd - scheduleStart);
scheduleEnd = 0;
}
*/
trigger();
delay(1);
}
else
{ getSync(); }
//Serial.println(toothLastToothTime);
//Serial.println(toothLastMinusOneToothTime);
//Serial.println(rpm);
//delay(100);
}
@ -254,7 +249,7 @@ void getSync()
//The are some placeholder values so we can get a fake RPM
toothLastMinusOneToothTime = micros();
delay(1); //A 1000us delay should make for about a 5000rpm test speed with a 12 tooth wheel(60000000us / (1000us * triggerTeeth)
//delay(1); //A 1000us delay should make for about a 5000rpm test speed with a 12 tooth wheel(60000000us / (1000us * triggerTeeth)
toothLastToothTime = micros();
currentStatus.hasSync = true;
@ -275,18 +270,28 @@ void trigger()
{
// http://www.msextra.com/forums/viewtopic.php?f=94&t=22976
// http://www.megamanual.com/ms2/wheel.htm
unsigned long curTime = micros();
toothCurrentCount++; //Increment the tooth counter
if ( (curTime - toothLastToothTime) < 500) { return; } //Debounce check. Pulses should never be less than 100uS, so if they are it means a false trigger. (A 36-1 wheel at 8000pm will have triggers approx. every 200uS)
toothCurrentCount++; //Increment the tooth counter
//Serial.println("Got trigger");
//Begin the missing tooth detection
//If the time between the current tooth and the last is greater than 1.5x the time between the last tooth and the tooth before that, we make the assertion that we must be at the first tooth after the gap
//if ( (curTime - toothLastToothTime) > (1.5 * (toothLastToothTime - toothLastMinusOneToothTime))) { toothCurrentCount = 1; }
if ( (curTime - toothLastToothTime) > ((3 * (toothLastToothTime - toothLastMinusOneToothTime))>>1)) { toothCurrentCount = 1; } //Same as above, but uses bitshift instead of multiplying by 1.5
if (toothCurrentCount > triggerActualTeeth) { toothCurrentCount = 1; } //For testing ONLY
//if ( (curTime - toothLastToothTime) > ((3 * (toothLastToothTime - toothLastMinusOneToothTime))>>1)) { toothCurrentCount = 1; } //Same as above, but uses bitshift instead of multiplying by 1.5
if (toothCurrentCount > triggerActualTeeth)
{
toothCurrentCount = 1;
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
} //For testing ONLY
// Update the last few tooth times
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
// Update the last few tooth times
//toothLastMinusOneToothTime = toothLastToothTime;
//toothLastToothTime = curTime;
}

View File

@ -30,7 +30,7 @@ Current layout of EEPROM data (Version 1) is as follows (All sizes are in bytes)
#define EEPROM_CONFIG1_MAP 3
#define EEPROM_CONFIG1_XBINS 67
#define EEPROM_CONFIG1_YBINS 75
#define EEPROM_CONFIG1_SETTINGS 85
#define EEPROM_CONFIG1_SETTINGS 83
#define EEPROM_CONFIG2_XSIZE 128
#define EEPROM_CONFIG2_YSIZE 129
#define EEPROM_CONFIG2_MAP 130

View File

@ -1,5 +1,9 @@
#include <EEPROM.h>
/*
Takes the current configuration (config pages and maps)
and writes the to EEPROM in the layout defined in storage.h
*/
void writeConfig()
{
/*
@ -7,16 +11,37 @@ void writeConfig()
This is due to the limited write life of the EEPROM (Approximately 100,000 writes)
*/
int offset;
//Create a pointer to the config page
byte* pnt_configPage;
pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 1 in memory
if(EEPROM.read(0) != data_structure_version) { EEPROM.write(0,data_structure_version); } //Write the data structure version
//Fuel table (See storage.h for data layout)
if(EEPROM.read(EEPROM_CONFIG1_XSIZE) != fuelTable.xSize) { EEPROM.write(EEPROM_CONFIG1_XSIZE, fuelTable.xSize); } //Write the VE Tables RPM dimension size
if(EEPROM.read(EEPROM_CONFIG1_YSIZE) != fuelTable.ySize) { EEPROM.write(EEPROM_CONFIG1_YSIZE, fuelTable.ySize); } //Write the VE Tables MAP/TPS dimension size
byte* pnt_configPage;
//The next 125 bytes can simply be pulled straight from the fuelTable
pnt_configPage = (byte *)&configPage1; //Create a pointer to Page 1 in memory
for(int x=EEPROM_CONFIG1_MAP; x<EEPROM_CONFIG2_XSIZE; x++)
for(int x=EEPROM_CONFIG1_MAP; x<EEPROM_CONFIG1_XBINS; x++)
{
if(EEPROM.read(x) != *(pnt_configPage + x)) { EEPROM.write(x, *(pnt_configPage + x)); }
offset = x - EEPROM_CONFIG1_MAP;
if(EEPROM.read(x) != fuelTable.values[7-offset/8][offset%8]) { EEPROM.write(x, fuelTable.values[7-offset/8][offset%8]); } //Write the 8x8 map
}
//RPM bins
for(int x=EEPROM_CONFIG1_XBINS; x<EEPROM_CONFIG1_YBINS; x++)
{
offset = x - EEPROM_CONFIG1_XBINS;
if(EEPROM.read(x) != (byte)(fuelTable.axisX[offset]/100)) { EEPROM.write(x, (byte)(fuelTable.axisX[offset]/100)); } //RPM bins are divided by 100 and converted to a byte
}
//TPS/MAP bins
for(int x=EEPROM_CONFIG1_YBINS; x<EEPROM_CONFIG1_SETTINGS; x++)
{
offset = x - EEPROM_CONFIG1_YBINS;
if(EEPROM.read(x) != fuelTable.axisY[offset]) { EEPROM.write(x, fuelTable.axisY[offset]); }
}
//The next 125 bytes can simply be pulled straight from the configTable
for(int x=EEPROM_CONFIG1_SETTINGS; x<EEPROM_CONFIG2_XSIZE; x++)
{
if(EEPROM.read(x) != *(pnt_configPage - EEPROM_CONFIG1_SETTINGS + x)) { EEPROM.write(x, *(pnt_configPage - EEPROM_CONFIG1_SETTINGS + x)); }
}
//That concludes the writing of the VE table
@ -26,7 +51,7 @@ void writeConfig()
//The next 125 bytes can simply be pulled straight from the ignitionTable
pnt_configPage = (byte *)&configPage2; //Create a pointer to Page 2 in memory
for(int x=EEPROM_CONFIG2_MAP; x<EEPROM_SIZE; x++)
for(int x=EEPROM_CONFIG2_YBINS; x<EEPROM_SIZE; x++)
{
if(EEPROM.read(x) != *(pnt_configPage + x)) { EEPROM.write(x, *(pnt_configPage + x)); }
}