Merge pull request #39 from noisymime/master

update with josh 10062017
This commit is contained in:
Autohome2 2017-06-10 18:05:28 +01:00 committed by GitHub
commit 5428715eb4
38 changed files with 41270 additions and 39656 deletions

View File

@ -24,20 +24,20 @@
# Template #1: General project. Test it using existing `platformio.ini`.
#
# language: python
# python:
# - "2.7"
#
# sudo: false
# cache:
# directories:
# - "~/.platformio"
#
# install:
# - pip install -U platformio
#
# script:
# - platformio run
language: python
python:
- "2.7"
sudo: false
cache:
directories:
- "~/.platformio"
install:
- pip install -U platformio
script:
- platformio run
#

View File

@ -22,11 +22,12 @@ board=teensy35
framework=arduino
lib_deps = EEPROM, FlexCAN
[env:LaunchPad_tm4c1294ncpdt]
platform = titiva
framework = energia
board = lptm4c1294ncpdt
lib_deps = EEPROM
;Not currently working
;[env:LaunchPad_tm4c1294ncpdt]
;platform = titiva
;framework = energia
;board = lptm4c1294ncpdt
;lib_deps = EEPROM
[env:genericSTM32F103RB]
platform = ststm32
@ -47,7 +48,7 @@ build_flags = -fpermissive -std=gnu++11
[platformio]
src_dir=speeduino
env_default = megaatmega2560
env_default = megaatmega2560, teensy35
;The following lines are for testing / experimentation only. Comment the line above to try them out
;env_default = teensy35
;env_default = LaunchPad_tm4c1294ncpdt

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<msq xmlns="http://www.msefi.com/:msq">
<bibliography author="TunerStudio MS(Beta) 3.0.22 - EFI Analytics, Inc." tuneComment="" writeDate="Sat May 06 23:43:36 AEST 2017"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2017.03" nPages="10" signature="speeduino 201704"/>
<bibliography author="TunerStudio MS(Beta) 3.0.22 - EFI Analytics, Inc." tuneComment="" writeDate="Mon Jun 05 14:40:33 AEST 2017"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2017.05" nPages="10" signature="speeduino 201705"/>
<page>
<pcVariable name="tsCanId">"0"</pcVariable>
<pcVariable name="tsCanId">"CAN ID 0"</pcVariable>
</page>
<page number="0" size="288">
<constant cols="16" digits="0" name="veTable" rows="16" units="%">
@ -62,8 +62,8 @@
</constant>
</page>
<page number="1" size="64">
<constant digits="1" name="unused2-1" units="ms">5.0</constant>
<constant digits="1" name="unused2-2" units="ms">2.3</constant>
<constant digits="0" name="flexBoostLow" units="kPa">0.0</constant>
<constant digits="0" name="flexBoostHigh" units="kPa">50.0</constant>
<constant digits="0" name="asePct" units="%">25.0</constant>
<constant digits="0" name="aseCount" units="s">8.0</constant>
<constant cols="1" digits="0" name="wueRates" rows="10" units="%">
@ -121,7 +121,7 @@
<constant name="algorithm">"Speed Density"</constant>
<constant name="baroCorr">"Off"</constant>
<constant name="injLayout">"Paired"</constant>
<constant name="canEnable">"Disable"</constant>
<constant name="unused2-38f">"ONE"</constant>
<constant name="unused2-38h">"No"</constant>
<constant digits="1" name="primePulse" units="ms">1.0</constant>
<constant digits="0" name="dutyLim" units="%">85.0</constant>
@ -214,6 +214,7 @@
<constant name="TrigEdgeSec">"Leading"</constant>
<constant name="fuelPumpPin">"Board Default"</constant>
<constant name="useResync">"No"</constant>
<constant digits="1" name="sparkDur" units="ms">25.5</constant>
<constant digits="0" name="IdleAdvRPM" units="RPM">3200.0</constant>
<constant digits="1" name="IdleAdvCLT" units="C">-21.0</constant>
<constant digits="0" name="IdleDelayTime" units="sec">38.0</constant>
@ -684,6 +685,34 @@
</constant>
</page>
<page number="9" size="128">
<constant name="enable_canbus">"Disable"</constant>
<constant name="enable_candata_in">"On"</constant>
<constant name="caninput_sel1">"On"</constant>
<constant name="caninput_sel2">"On"</constant>
<constant name="caninput_sel3">"On"</constant>
<constant name="caninput_sel4">"On"</constant>
<constant name="caninput_sel5">"On"</constant>
<constant name="caninput_sel6">"On"</constant>
<constant name="caninput_sel7">"On"</constant>
<constant name="caninput_sel8">"On"</constant>
<constant cols="1" digits="0" name="caninput_param_group" rows="8">
65535.0
65535.0
65535.0
65535.0
65535.0
65535.0
65535.0
65535.0
</constant>
<constant name="caninput_param_start_byte1">"8"</constant>
<constant name="caninput_param_start_byte2">"8"</constant>
<constant name="caninput_param_start_byte3">"8"</constant>
<constant name="caninput_param_start_byte4">"8"</constant>
<constant name="caninput_param_start_byte5">"8"</constant>
<constant name="caninput_param_start_byte6">"8"</constant>
<constant name="caninput_param_start_byte7">"8"</constant>
<constant name="caninput_param_start_byte8">"8"</constant>
<constant digits="0" name="unused10_41">255.0</constant>
<constant digits="0" name="unused10_42">255.0</constant>
<constant digits="0" name="unused10_43">255.0</constant>
@ -693,32 +722,33 @@
<constant digits="0" name="unused10_47">255.0</constant>
<constant digits="0" name="unused10_48">255.0</constant>
<constant digits="0" name="unused10_49">255.0</constant>
<constant digits="0" name="unused10_51">255.0</constant>
<constant digits="0" name="unused10_52">255.0</constant>
<constant digits="0" name="unused10_53">255.0</constant>
<constant digits="0" name="unused10_54">255.0</constant>
<constant digits="0" name="unused10_55">255.0</constant>
<constant digits="0" name="unused10_56">255.0</constant>
<constant digits="0" name="unused10_57">255.0</constant>
<constant digits="0" name="unused10_58">255.0</constant>
<constant digits="0" name="unused10_59">255.0</constant>
<constant digits="0" name="unused10_60">255.0</constant>
<constant digits="0" name="unused10_61">255.0</constant>
<constant digits="0" name="unused10_62">255.0</constant>
<constant digits="0" name="unused10_63">255.0</constant>
<constant digits="0" name="unused10_64">255.0</constant>
<constant digits="0" name="unused10_65">255.0</constant>
<constant digits="0" name="unused10_66">255.0</constant>
<constant digits="0" name="unused10_67">255.0</constant>
<constant digits="0" name="unused10_68">255.0</constant>
<constant digits="0" name="unused10_69">255.0</constant>
<constant digits="0" name="unused10_70">255.0</constant>
<constant digits="0" name="unused10_71">255.0</constant>
<constant digits="0" name="unused10_72">255.0</constant>
<constant digits="0" name="unused10_73">255.0</constant>
<constant digits="0" name="unused10_74">255.0</constant>
<constant digits="0" name="unused10_75">255.0</constant>
<constant digits="0" name="unused10_76">255.0</constant>
<constant name="enable_candata_out">"On"</constant>
<constant name="canoutput_sel1">"On"</constant>
<constant name="canoutput_sel2">"On"</constant>
<constant name="canoutput_sel3">"On"</constant>
<constant name="canoutput_sel4">"On"</constant>
<constant name="canoutput_sel5">"On"</constant>
<constant name="canoutput_sel6">"On"</constant>
<constant name="canoutput_sel7">"On"</constant>
<constant name="canoutput_sel8">"On"</constant>
<constant cols="1" digits="0" name="canoutput_param_group" rows="8">
65535.0
65535.0
65535.0
65535.0
65535.0
65535.0
65535.0
65535.0
</constant>
<constant name="canoutput_param_start_byte1">"8"</constant>
<constant name="canoutput_param_start_byte2">"8"</constant>
<constant name="canoutput_param_start_byte3">"8"</constant>
<constant name="canoutput_param_start_byte4">"8"</constant>
<constant name="canoutput_param_start_byte5">"8"</constant>
<constant name="canoutput_param_start_byte6">"8"</constant>
<constant name="canoutput_param_start_byte7">"8"</constant>
<constant name="canoutput_param_start_byte8">"8"</constant>
<constant digits="0" name="unused10_77">255.0</constant>
<constant digits="0" name="unused10_78">255.0</constant>
<constant digits="0" name="unused10_79">255.0</constant>
@ -742,13 +772,9 @@
<constant digits="0" name="unused10_97">255.0</constant>
<constant digits="0" name="unused10_98">255.0</constant>
<constant digits="0" name="unused10_99">255.0</constant>
<constant digits="0" name="unused10_100">255.0</constant>
<constant digits="0" name="unused10_101">255.0</constant>
<constant digits="0" name="unused10_102">255.0</constant>
<constant digits="0" name="unused10_103">255.0</constant>
<constant digits="0" name="unused10_104">255.0</constant>
<constant digits="0" name="unused10_105">255.0</constant>
<constant digits="0" name="unused10_106">255.0</constant>
<constant digits="0" name="unused10_107">255.0</constant>
<constant digits="0" name="unused10_108">255.0</constant>
<constant digits="0" name="unused10_109">255.0</constant>
@ -776,6 +802,7 @@
<setting name="SPEED_DENSITY" value="SPEED_DENSITY"/>
<setting name="CAN_COMMANDS_OFF" value="CAN_COMMANDS_OFF"/>
<setting name="CELSIUS" value="CELSIUS"/>
<setting name="AFR" value="AFR"/>
</settings>
<userComments Comment="These are user comments that can be related to a particular setting or dialog."/>
</msq>

File diff suppressed because it is too large Load Diff

View File

@ -2,61 +2,32 @@
; THROUGH (PLATED) HOLES START AT T100
M48
INCH
T1C0.165354
T2C0.125984
T100C0.031496
T101C0.030000
T102C0.038000
T103C0.043302
T104C0.035433
T105C0.038194
T106C0.042000
T107C0.015748
T108C0.040000
T1C0.033465
T2C0.165354
T3C0.125984
T100C0.038000
T101C0.043302
T102C0.035433
T103C0.038194
T104C0.042000
T105C0.015748
T106C0.040000
T107C0.031496
T108C0.030000
%
T1
X016821Y017668
X018002Y017668
T2
X030651Y022829
X001895Y003148
X030651Y013731
X001895Y036497
X001895Y018448
T2
T3
X037661Y012030
X035411Y030780
T100
X022161Y007733
X022161Y004780
T101
X026906Y028285
X027906Y028285
X026906Y033285
X030906Y028285
X027906Y033285
X028906Y028285
X029906Y028285
X030906Y033285
X031906Y028285
X028906Y033285
X032906Y028285
X029906Y033285
X033906Y028285
X031906Y033285
X032906Y033285
X033906Y033285
T102
X037911Y032030
X012911Y022280
X017911Y020280
X010911Y025280
X015911Y023280
X021911Y022280
X013911Y026280
X018911Y024280
X022911Y026280
X012911Y021280
X010911Y024280
X015911Y022280
X021911Y021280
X018911Y023280
X013911Y025280
X016911Y026280
@ -77,9 +48,8 @@ X018911Y021280
X011911Y026280
X022911Y023280
X016911Y024280
X019911Y025280
X020911Y026280
X004911Y003280
X019911Y025280
X010911Y021280
X013911Y022280
X018911Y020280
@ -87,8 +57,8 @@ X011911Y025280
X016911Y023280
X022911Y022280
X014911Y026280
X019911Y024280
X020911Y025280
X019911Y024280
X023911Y026280
X010911Y020280
X013911Y021280
@ -104,29 +74,29 @@ X013911Y020280
X011911Y023280
X016911Y021280
X022911Y020280
X020911Y023280
X019911Y022280
X014911Y024280
X020911Y023280
X004661Y003280
X037911Y037030
X017911Y025280
X023911Y024280
X011911Y022280
X016911Y020280
X014911Y023280
X019911Y021280
X020911Y022280
X019911Y021280
X012911Y026280
X037911Y036030
X023911Y023280
X017911Y024280
X021911Y026280
X005911Y003280
X011911Y021280
X034911Y015030
X029661Y027030
X014911Y022280
X019911Y020280
X020911Y021280
X019911Y020280
X037911Y035030
X017911Y023280
X023911Y022280
@ -136,8 +106,8 @@ X021911Y025280
X011911Y020280
X034911Y014030
X030661Y027030
X014911Y021280
X033911Y026280
X014911Y021280
X020911Y020280
X037911Y034030
X017911Y022280
@ -147,8 +117,8 @@ X015911Y025280
X021911Y024280
X018911Y026280
X034911Y013030
X014911Y020280
X033911Y025280
X014911Y020280
X037911Y033030
X012911Y023280
X017911Y021280
@ -157,11 +127,20 @@ X010911Y026280
X021911Y023280
X015911Y024280
X018911Y025280
X003911Y003280
T103
X005911Y025810
X004141Y033131
X005911Y010098
X037911Y032030
X012911Y022280
X017911Y020280
X010911Y025280
X015911Y023280
X021911Y022280
X013911Y026280
X018911Y024280
X022911Y026280
X012911Y021280
X010911Y024280
X015911Y022280
X021911Y021280
T101
X004141Y014823
X005911Y017223
X004141Y006515
@ -200,29 +179,22 @@ X005911Y006515
X004141Y029356
X005911Y021047
X004141Y007740
X004141Y026989
X005911Y024631
X004141Y026989
X004141Y031756
X004141Y023447
X004141Y013644
X004141Y008919
X005911Y030535
T104
X005911Y025810
X004141Y033131
X005911Y010098
T102
X037661Y004480
X037661Y007280
X037661Y011030
X037661Y008230
T105
X036911Y021780
X014911Y011780
X037911Y025780
X023911Y011780
X036911Y017780
X008311Y030780
X023911Y030780
X032911Y011780
X032911Y030780
X036911Y020780
T103
X037911Y024780
X036911Y016780
X017911Y011780
@ -233,8 +205,8 @@ X035911Y011780
X037911Y023780
X036911Y015780
X012311Y030780
X029911Y011780
X037911Y019780
X029911Y011780
X029911Y030780
X037911Y022780
X012911Y011780
@ -242,15 +214,15 @@ X036911Y014780
X021911Y011780
X021911Y030780
X037911Y018780
X015311Y030780
X030911Y011780
X015311Y030780
X030911Y030780
X036911Y029780
X037911Y021780
X036911Y013780
X015911Y011780
X024911Y011780
X037911Y017780
X024911Y011780
X009311Y030780
X024911Y030780
X036911Y028780
@ -269,8 +241,8 @@ X036911Y026780
X013311Y030780
X013911Y011780
X037911Y014780
X022911Y011780
X036911Y025780
X022911Y011780
X007311Y030780
X022911Y030780
X031911Y011780
@ -278,8 +250,8 @@ X016311Y030780
X031911Y030780
X037911Y029780
X037911Y013780
X016911Y011780
X036911Y024780
X016911Y011780
X025911Y011780
X037911Y028780
X034911Y011780
@ -299,52 +271,54 @@ X020911Y030780
X037911Y026780
X036911Y018780
X014311Y030780
T106
X036911Y021780
X014911Y011780
X037911Y025780
X023911Y011780
X036911Y017780
X008311Y030780
X023911Y030780
X032911Y011780
X036911Y020780
X032911Y030780
T104
X023681Y004280
X026661Y004280
T107
X029661Y020530
X011161Y028780
X035661Y004280
X025411Y030280
X013911Y017530
X013911Y005030
T105
X035161Y018280
X030911Y020030
X018161Y017530
X020161Y010530
X020661Y014030
X016911Y005030
X006411Y035280
X024911Y028530
X012911Y007530
X014661Y015280
X015911Y009780
X007161Y006030
X029161Y013780
X037661Y005530
X017161Y015280
X026661Y016280
X022161Y006280
X017161Y015280
X018911Y029780
X022161Y006280
X017161Y033030
X018411Y015030
X027911Y029780
X024661Y002030
X035661Y031780
X009411Y007530
X002161Y026030
X028423Y006894
X027833Y004925
X028423Y006894
X006911Y013030
X035161Y033280
X033161Y016030
X025411Y029530
X026161Y028030
X005161Y007030
X032951Y003941
X002161Y021530
X007411Y012530
X035911Y018530
X007411Y012530
X006661Y028780
X001911Y033030
X008911Y017530
X031661Y004280
X023161Y010030
@ -357,24 +331,25 @@ X011661Y017530
X028661Y020530
X035661Y008030
X029161Y008030
X009161Y015280
X007661Y019280
X009161Y015280
X023411Y014530
X007661Y037030
X024911Y027280
X028411Y008530
X008661Y006030
X035661Y004780
X009411Y011280
X008661Y022780
X026661Y019780
X018161Y014280
X009411Y006030
X033411Y010280
X033911Y006030
X034911Y034280
X034911Y033030
X009411Y010280
X008411Y032530
X023161Y035780
X033911Y005030
X024411Y016530
X030161Y025030
X011911Y015280
X025411Y008030
@ -382,12 +357,40 @@ X029161Y020530
X032557Y005910
X014411Y008780
X026911Y009530
T108
X029661Y020530
X007161Y006530
X011161Y028780
X035661Y004280
X017661Y018030
X025411Y030280
X013911Y017530
X013911Y005030
T106
X025927Y019780
X025927Y016780
X025927Y020780
X025927Y017780
X025927Y015779
X025927Y018780
X025927Y019780
T107
X022161Y004780
X022161Y007733
T108
X031906Y028285
X028906Y033285
X032906Y028285
X029906Y033285
X031906Y033285
X032906Y033285
X033906Y028285
X026906Y028285
X033906Y033285
X027906Y028285
X026906Y033285
X030906Y028285
X027906Y033285
X028906Y028285
X029906Y028285
X030906Y033285
T00
M30

View File

@ -28,6 +28,7 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
G90*
G70*
G54D10*
X191Y3303D03*
X2541Y3028D03*
X2491Y2728D03*
X2541Y2953D03*
@ -39,7 +40,7 @@ X641Y3528D03*
X1116Y2878D03*
X2541Y803D03*
X516Y703D03*
X1816Y1428D03*
X1841Y1503D03*
X3016Y2503D03*
X2666Y1628D03*
X3766Y553D03*
@ -52,13 +53,11 @@ X2842Y689D03*
X3256Y591D03*
X1891Y2978D03*
X841Y3253D03*
X941Y603D03*
X741Y3403D03*
X766Y3703D03*
X216Y2603D03*
X216Y2153D03*
X1816Y1753D03*
X2066Y1403D03*
X1766Y1803D03*
X1391Y503D03*
X741Y1253D03*
X766Y1928D03*
@ -180,6 +179,7 @@ X1491Y2028D03*
X1491Y2428D03*
X1491Y2528D03*
X1391Y2528D03*
X466Y328D03*
X1391Y2028D03*
X1291Y2528D03*
X1391Y2428D03*
@ -193,9 +193,6 @@ X1591Y2428D03*
X1691Y2428D03*
X1591Y2528D03*
X1591Y2028D03*
X591Y328D03*
X491Y328D03*
X391Y328D03*
X1291Y2128D03*
X2091Y2128D03*
X2191Y2128D03*
@ -241,7 +238,7 @@ X2616Y2803D03*
X1716Y3303D03*
X2316Y3578D03*
X3591Y1853D03*
X2441Y1653D03*
X2341Y1453D03*
X666Y2878D03*
X1591Y978D03*
X1441Y878D03*
@ -250,7 +247,7 @@ G54D13*
X3766Y1103D03*
X3766Y823D03*
G54D10*
X2016Y1053D03*
X941Y1128D03*
X3341Y1028D03*
G54D13*
X3766Y728D03*
@ -279,7 +276,7 @@ G54D10*
X941Y1028D03*
X941Y928D03*
X866Y603D03*
X716Y603D03*
X716Y653D03*
X941Y753D03*
G54D16*
X414Y514D03*
@ -470,12 +467,14 @@ X1791Y2628D03*
X1691Y2628D03*
X1591Y2628D03*
G54D10*
X3516Y3328D03*
X3491Y3303D03*
X2901Y552D03*
X3295Y394D03*
X3166Y428D03*
X3391Y503D03*
X2783Y493D03*
X3491Y3428D03*
X3566Y3178D03*
G54D21*
X2916Y1003D03*
X2884Y1003D03*

View File

@ -9,39 +9,46 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10C,0.049370*%
%ADD11C,0.082917*%
%ADD12C,0.088000*%
%ADD13C,0.065433*%
%ADD14C,0.084000*%
%ADD15C,0.175354*%
%ADD16C,0.092672*%
%ADD17C,0.080000*%
%ADD18C,0.135984*%
%ADD19C,0.092000*%
%ADD20C,0.061496*%
%ADD21R,0.065118X0.069055*%
%ADD22R,0.020000X0.055000*%
%ADD23R,0.055000X0.020000*%
%ADD24R,0.045433X0.041496*%
%ADD25R,0.072992X0.112362*%
%ADD26R,0.080866X0.049370*%
%ADD27R,0.069055X0.065118*%
%ADD28R,0.042677X0.034803*%
%ADD29R,0.097000X0.034000*%
%ADD30R,0.084000X0.084000*%
%ADD31R,0.080000X0.080000*%
%ADD32R,0.092000X0.092000*%
%ADD33R,0.034803X0.042677*%
%ADD34R,0.104488X0.112362*%
%ADD35R,0.084803X0.072992*%
%ADD36R,0.096614X0.088740*%
%ADD37R,0.090000X0.036000*%
%ADD38R,0.214724X0.214724*%
%ADD39R,0.001000X0.001000*%
%ADD11C,0.043465*%
%ADD12C,0.082917*%
%ADD13C,0.088000*%
%ADD14C,0.065433*%
%ADD15C,0.084000*%
%ADD16C,0.175354*%
%ADD17C,0.092672*%
%ADD18C,0.080000*%
%ADD19C,0.135984*%
%ADD20C,0.092000*%
%ADD21C,0.061496*%
%ADD22R,0.049370X0.055276*%
%ADD23R,0.065118X0.069055*%
%ADD24R,0.020000X0.055000*%
%ADD25R,0.055000X0.020000*%
%ADD26R,0.045433X0.041496*%
%ADD27R,0.072992X0.112362*%
%ADD28R,0.049370X0.080866*%
%ADD29R,0.069055X0.065118*%
%ADD30R,0.034803X0.042677*%
%ADD31R,0.042677X0.034803*%
%ADD32R,0.097000X0.034000*%
%ADD33R,0.084000X0.084000*%
%ADD34R,0.080000X0.080000*%
%ADD35R,0.092000X0.092000*%
%ADD36R,0.104488X0.112362*%
%ADD37R,0.084803X0.072992*%
%ADD38R,0.096614X0.088740*%
%ADD39R,0.036000X0.090000*%
%ADD40R,0.214724X0.214724*%
%ADD41R,0.001000X0.001000*%
%LNMASK1*%
G90*
G70*
G54D10*
X191Y3303D03*
G54D11*
X1800Y1767D03*
X1682Y1767D03*
G54D10*
X2541Y3028D03*
X2491Y2728D03*
X2541Y2953D03*
@ -53,7 +60,7 @@ X641Y3528D03*
X1116Y2878D03*
X2541Y803D03*
X516Y703D03*
X1816Y1428D03*
X1841Y1503D03*
X3016Y2503D03*
X2666Y1628D03*
X3766Y553D03*
@ -66,13 +73,11 @@ X2842Y689D03*
X3256Y591D03*
X1891Y2978D03*
X841Y3253D03*
X941Y603D03*
X741Y3403D03*
X766Y3703D03*
X216Y2603D03*
X216Y2153D03*
X1816Y1753D03*
X2066Y1403D03*
X1766Y1803D03*
X1391Y503D03*
X741Y1253D03*
X766Y1928D03*
@ -80,7 +85,7 @@ X2816Y2053D03*
X2866Y2053D03*
X2916Y2053D03*
X2966Y2053D03*
G54D11*
G54D12*
X2991Y1178D03*
X1391Y1178D03*
X3091Y1178D03*
@ -170,7 +175,7 @@ X2891Y1178D03*
G54D10*
X3566Y803D03*
X2316Y1003D03*
G54D12*
G54D13*
X1291Y2428D03*
X2091Y2028D03*
X2091Y2428D03*
@ -194,6 +199,7 @@ X1491Y2028D03*
X1491Y2428D03*
X1491Y2528D03*
X1391Y2528D03*
X466Y328D03*
X1391Y2028D03*
X1291Y2528D03*
X1391Y2428D03*
@ -207,9 +213,6 @@ X1591Y2428D03*
X1691Y2428D03*
X1591Y2528D03*
X1591Y2028D03*
X591Y328D03*
X491Y328D03*
X391Y328D03*
X1291Y2128D03*
X2091Y2128D03*
X2191Y2128D03*
@ -255,41 +258,41 @@ X2616Y2803D03*
X1716Y3303D03*
X2316Y3578D03*
X3591Y1853D03*
X2441Y1653D03*
X2341Y1453D03*
X666Y2878D03*
X1591Y978D03*
X1441Y878D03*
X1291Y753D03*
G54D13*
G54D14*
X3766Y1103D03*
X3766Y823D03*
X3766Y1103D03*
X3766Y823D03*
G54D10*
X2016Y1053D03*
X941Y1128D03*
X3341Y1028D03*
G54D13*
X3766Y728D03*
X3766Y448D03*
X3766Y728D03*
X3766Y448D03*
G54D14*
X3766Y728D03*
X3766Y448D03*
X3766Y728D03*
X3766Y448D03*
G54D15*
X2593Y2078D03*
X2593Y1978D03*
X2593Y1878D03*
X2593Y1778D03*
X2593Y1678D03*
X2593Y1578D03*
G54D15*
G54D16*
X3065Y2283D03*
X3065Y1373D03*
G54D10*
X941Y1028D03*
X941Y928D03*
X866Y603D03*
X716Y603D03*
X716Y653D03*
X941Y753D03*
G54D16*
G54D17*
X414Y514D03*
X414Y652D03*
X591Y652D03*
@ -338,7 +341,7 @@ X414Y3451D03*
X591Y3451D03*
X591Y514D03*
X591Y1966D03*
G54D15*
G54D16*
X190Y315D03*
X190Y3650D03*
X190Y1845D03*
@ -346,7 +349,7 @@ G54D10*
X3316Y1603D03*
X2916Y1378D03*
X2491Y2853D03*
G54D17*
G54D18*
X3391Y3329D03*
X3391Y2829D03*
X3291Y3329D03*
@ -365,13 +368,13 @@ X2691Y3329D03*
X2691Y2829D03*
G54D10*
X3516Y1828D03*
G54D18*
G54D19*
X3766Y1203D03*
X3541Y3078D03*
G54D19*
G54D20*
X2666Y428D03*
X2368Y428D03*
G54D20*
G54D21*
X2216Y478D03*
X2216Y773D03*
X2216Y478D03*
@ -386,7 +389,7 @@ X866Y2278D03*
X1391Y1753D03*
X1166Y1753D03*
X891Y1753D03*
G54D12*
G54D13*
X3791Y3203D03*
X3791Y3303D03*
X3791Y3403D03*
@ -427,16 +430,27 @@ X1791Y2628D03*
X1691Y2628D03*
X1591Y2628D03*
G54D10*
X3516Y3328D03*
X3491Y3303D03*
X2901Y552D03*
X3295Y394D03*
X3166Y428D03*
X3391Y503D03*
X2783Y493D03*
G54D21*
X3491Y3428D03*
X3566Y3178D03*
G54D22*
X1840Y1878D03*
X1741Y1878D03*
X1643Y1878D03*
X1840Y1656D03*
X1741Y1656D03*
X1643Y1656D03*
G54D23*
X1897Y1303D03*
X1816Y1303D03*
X2641Y2728D03*
X2722Y2728D03*
G54D22*
G54D24*
X3039Y532D03*
X3059Y532D03*
X3079Y532D03*
@ -449,7 +463,7 @@ X3197Y532D03*
X3216Y532D03*
X3236Y532D03*
X3256Y532D03*
G54D23*
G54D25*
X3315Y591D03*
X3315Y611D03*
X3315Y630D03*
@ -462,7 +476,7 @@ X3315Y748D03*
X3315Y768D03*
X3315Y788D03*
X3315Y808D03*
G54D22*
G54D24*
X3256Y867D03*
X3236Y867D03*
X3216Y867D03*
@ -475,7 +489,7 @@ X3098Y867D03*
X3079Y867D03*
X3059Y867D03*
X3039Y867D03*
G54D23*
G54D25*
X2980Y808D03*
X2980Y788D03*
X2980Y768D03*
@ -488,49 +502,50 @@ X2980Y650D03*
X2980Y630D03*
X2980Y611D03*
X2980Y591D03*
G54D24*
G54D26*
X2921Y493D03*
X2921Y418D03*
X3004Y455D03*
G54D25*
G54D27*
X2691Y561D03*
X2691Y703D03*
G54D26*
X716Y778D03*
X716Y668D03*
G54D21*
G54D28*
X776Y778D03*
X666Y778D03*
G54D23*
X2641Y1278D03*
X2560Y1278D03*
X2561Y1378D03*
X2641Y1378D03*
X2641Y1478D03*
X2560Y1478D03*
G54D27*
G54D29*
X2391Y2978D03*
X2391Y2897D03*
X2291Y2978D03*
X2291Y2897D03*
G54D21*
G54D23*
X2066Y3603D03*
X2147Y3603D03*
X2466Y3603D03*
X2385Y3603D03*
G54D27*
G54D29*
X2091Y2978D03*
X2091Y2897D03*
X2191Y2978D03*
X2191Y2897D03*
G54D21*
X2366Y1778D03*
X2447Y1778D03*
X2466Y1372D03*
X2466Y1453D03*
G54D23*
X716Y2978D03*
X797Y2978D03*
G54D28*
X1966Y1253D03*
X1966Y1344D03*
G54D30*
X1932Y1403D03*
X1841Y1403D03*
G54D31*
X916Y2978D03*
X916Y2887D03*
G54D29*
G54D32*
X1066Y928D03*
X860Y878D03*
X860Y978D03*
@ -547,19 +562,19 @@ X860Y703D03*
X1066Y803D03*
X860Y803D03*
X1066Y653D03*
G54D30*
G54D33*
X2593Y2078D03*
G54D21*
G54D23*
X1941Y978D03*
X1860Y978D03*
X760Y1578D03*
X841Y1578D03*
G54D31*
G54D34*
X2691Y2829D03*
X3291Y2829D03*
G54D32*
G54D35*
X2667Y428D03*
G54D21*
G54D23*
X760Y1678D03*
X841Y1678D03*
X1566Y1478D03*
@ -568,10 +583,10 @@ X1566Y1578D03*
X1647Y1578D03*
X1866Y878D03*
X1947Y878D03*
G54D33*
G54D30*
X2166Y978D03*
X2257Y978D03*
G54D21*
G54D23*
X841Y1178D03*
X760Y1178D03*
X798Y2228D03*
@ -580,23 +595,23 @@ X716Y2428D03*
X797Y2428D03*
X716Y2128D03*
X797Y2128D03*
G54D27*
G54D29*
X1166Y272D03*
X1166Y353D03*
X1016Y272D03*
X1016Y353D03*
X716Y278D03*
X716Y359D03*
X866Y278D03*
X866Y359D03*
X716Y272D03*
X716Y352D03*
X866Y272D03*
X866Y353D03*
X866Y453D03*
X866Y534D03*
X1541Y703D03*
X1541Y622D03*
G54D21*
G54D23*
X798Y2328D03*
X717Y2328D03*
G54D27*
G54D29*
X716Y453D03*
X716Y534D03*
X1391Y703D03*
@ -605,13 +620,13 @@ X1166Y447D03*
X1166Y528D03*
X1016Y447D03*
X1016Y528D03*
G54D34*
G54D36*
X2016Y476D03*
X2016Y728D03*
G54D21*
G54D23*
X1866Y3178D03*
X1947Y3178D03*
G54D33*
G54D30*
X1666Y3653D03*
X1757Y3653D03*
X1666Y3728D03*
@ -620,17 +635,17 @@ X1666Y3503D03*
X1757Y3503D03*
X1666Y3578D03*
X1757Y3578D03*
G54D21*
G54D23*
X841Y1478D03*
X760Y1478D03*
X2316Y3478D03*
X2235Y3478D03*
G54D27*
G54D29*
X1316Y453D03*
X1316Y534D03*
X1466Y453D03*
X1466Y534D03*
G54D21*
G54D23*
X841Y1378D03*
X760Y1378D03*
X2766Y428D03*
@ -645,26 +660,26 @@ X1391Y1378D03*
X1310Y1378D03*
X1648Y1378D03*
X1567Y1378D03*
G54D35*
G54D37*
X3641Y853D03*
X3641Y975D03*
X3641Y553D03*
X3641Y675D03*
X1866Y603D03*
X1866Y481D03*
G54D21*
G54D23*
X1866Y3478D03*
X1947Y3478D03*
X2316Y3378D03*
X2235Y3378D03*
X1866Y3378D03*
X1947Y3378D03*
G54D36*
G54D38*
X3466Y971D03*
X3466Y853D03*
X3491Y671D03*
X3491Y553D03*
G54D27*
G54D29*
X1516Y2978D03*
X1516Y2897D03*
X1316Y2978D03*
@ -673,7 +688,7 @@ X1616Y2978D03*
X1616Y2897D03*
X1416Y2978D03*
X1416Y2897D03*
G54D21*
G54D23*
X1166Y3453D03*
X1085Y3453D03*
X1166Y3203D03*
@ -688,7 +703,7 @@ X2316Y3178D03*
X2235Y3178D03*
X1866Y3278D03*
X1947Y3278D03*
G54D29*
G54D32*
X1991Y2878D03*
X1785Y2828D03*
X1785Y2928D03*
@ -713,12 +728,12 @@ X760Y3253D03*
X966Y3353D03*
X760Y3353D03*
X966Y3203D03*
G54D21*
G54D23*
X1122Y1478D03*
X1041Y1478D03*
X1122Y1378D03*
X1041Y1378D03*
G54D27*
G54D29*
X1766Y453D03*
X1766Y534D03*
X1616Y453D03*
@ -727,31 +742,31 @@ X1691Y628D03*
X1691Y709D03*
X1691Y909D03*
X1691Y828D03*
G54D21*
G54D23*
X2391Y853D03*
X2472Y853D03*
X1041Y1578D03*
X1121Y1578D03*
X1041Y1678D03*
X1122Y1678D03*
G54D37*
X2183Y1428D03*
X2183Y1478D03*
X2183Y1528D03*
X2183Y1578D03*
X2183Y1628D03*
X2183Y1678D03*
X2183Y1728D03*
X2183Y1778D03*
X1941Y1778D03*
X1941Y1728D03*
X1941Y1678D03*
X1941Y1628D03*
X1941Y1578D03*
X1941Y1528D03*
X1941Y1478D03*
X1941Y1428D03*
G54D21*
G54D39*
X2016Y1603D03*
X2066Y1603D03*
X2116Y1603D03*
X2166Y1603D03*
X2216Y1603D03*
X2266Y1603D03*
X2316Y1603D03*
X2366Y1603D03*
X2366Y1845D03*
X2316Y1845D03*
X2266Y1845D03*
X2216Y1845D03*
X2166Y1845D03*
X2116Y1845D03*
X2066Y1845D03*
X2016Y1845D03*
G54D23*
X1310Y1578D03*
X1391Y1578D03*
X1310Y1478D03*
@ -766,9 +781,9 @@ X691Y928D03*
X772Y928D03*
X772Y1028D03*
X691Y1028D03*
G54D38*
G54D40*
X3148Y701D03*
G54D39*
G54D41*
X545Y2013D02*
X636Y2013D01*
X545Y2012D02*

View File

@ -8,41 +8,55 @@ G04 CONTOUR ON CENTER OF CONTOUR VECTOR*
%MOIN*%
%OFA0B0*%
%SFA1.0B1.0*%
%ADD10C,0.074000*%
%ADD11C,0.165354*%
%ADD12R,0.055118X0.059055*%
%ADD13R,0.010000X0.045000*%
%ADD14R,0.045000X0.010000*%
%ADD15R,0.035433X0.031496*%
%ADD16R,0.062992X0.102362*%
%ADD17R,0.070866X0.039370*%
%ADD18R,0.059055X0.055118*%
%ADD19R,0.032677X0.024803*%
%ADD20R,0.087000X0.024000*%
%ADD10C,0.033465*%
%ADD11C,0.074000*%
%ADD12C,0.165354*%
%ADD13R,0.039370X0.045276*%
%ADD14R,0.055118X0.059055*%
%ADD15R,0.010000X0.045000*%
%ADD16R,0.045000X0.010000*%
%ADD17R,0.035433X0.031496*%
%ADD18R,0.062992X0.102362*%
%ADD19R,0.039370X0.070866*%
%ADD20R,0.059055X0.055118*%
%ADD21R,0.024803X0.032677*%
%ADD22R,0.094488X0.102362*%
%ADD23R,0.074803X0.062992*%
%ADD24R,0.086614X0.078740*%
%ADD25R,0.080000X0.026000*%
%ADD26R,0.204724X0.204724*%
%ADD27R,0.001000X0.001000*%
%ADD22R,0.032677X0.024803*%
%ADD23R,0.087000X0.024000*%
%ADD24R,0.094488X0.102362*%
%ADD25R,0.074803X0.062992*%
%ADD26R,0.086614X0.078740*%
%ADD27R,0.026000X0.080000*%
%ADD28R,0.204724X0.204724*%
%ADD29R,0.001000X0.001000*%
%LNPASTEMASK1*%
G90*
G70*
G54D10*
X1800Y1767D03*
X1682Y1767D03*
G54D11*
X2593Y1778D03*
X2593Y1678D03*
X2593Y1578D03*
G54D11*
G54D12*
X3065Y2283D03*
X3065Y1373D03*
X190Y315D03*
X190Y3650D03*
X190Y1845D03*
G54D12*
G54D13*
X1840Y1878D03*
X1741Y1878D03*
X1643Y1878D03*
X1840Y1656D03*
X1741Y1656D03*
X1643Y1656D03*
G54D14*
X1897Y1303D03*
X1816Y1303D03*
X2641Y2728D03*
X2722Y2728D03*
G54D13*
G54D15*
X3039Y532D03*
X3059Y532D03*
X3079Y532D03*
@ -55,7 +69,7 @@ X3197Y532D03*
X3216Y532D03*
X3236Y532D03*
X3256Y532D03*
G54D14*
G54D16*
X3315Y591D03*
X3315Y611D03*
X3315Y630D03*
@ -68,7 +82,7 @@ X3315Y748D03*
X3315Y768D03*
X3315Y788D03*
X3315Y808D03*
G54D13*
G54D15*
X3256Y867D03*
X3236Y867D03*
X3216Y867D03*
@ -81,7 +95,7 @@ X3098Y867D03*
X3079Y867D03*
X3059Y867D03*
X3039Y867D03*
G54D14*
G54D16*
X2980Y808D03*
X2980Y788D03*
X2980Y768D03*
@ -94,49 +108,50 @@ X2980Y650D03*
X2980Y630D03*
X2980Y611D03*
X2980Y591D03*
G54D15*
G54D17*
X2921Y493D03*
X2921Y418D03*
X3004Y455D03*
G54D16*
G54D18*
X2691Y561D03*
X2691Y703D03*
G54D17*
X716Y778D03*
X716Y668D03*
G54D12*
G54D19*
X776Y778D03*
X666Y778D03*
G54D14*
X2641Y1278D03*
X2560Y1278D03*
X2561Y1378D03*
X2641Y1378D03*
X2641Y1478D03*
X2560Y1478D03*
G54D18*
G54D20*
X2391Y2978D03*
X2391Y2897D03*
X2291Y2978D03*
X2291Y2897D03*
G54D12*
G54D14*
X2066Y3603D03*
X2147Y3603D03*
X2466Y3603D03*
X2385Y3603D03*
G54D18*
G54D20*
X2091Y2978D03*
X2091Y2897D03*
X2191Y2978D03*
X2191Y2897D03*
G54D12*
X2366Y1778D03*
X2447Y1778D03*
X2466Y1372D03*
X2466Y1453D03*
G54D14*
X716Y2978D03*
X797Y2978D03*
G54D19*
X1966Y1253D03*
X1966Y1344D03*
G54D21*
X1932Y1403D03*
X1841Y1403D03*
G54D22*
X916Y2978D03*
X916Y2887D03*
G54D20*
G54D23*
X1066Y928D03*
X860Y878D03*
X860Y978D03*
@ -153,7 +168,7 @@ X860Y703D03*
X1066Y803D03*
X860Y803D03*
X1066Y653D03*
G54D12*
G54D14*
X1941Y978D03*
X1860Y978D03*
X760Y1578D03*
@ -169,7 +184,7 @@ X1947Y878D03*
G54D21*
X2166Y978D03*
X2257Y978D03*
G54D12*
G54D14*
X841Y1178D03*
X760Y1178D03*
X798Y2228D03*
@ -178,23 +193,23 @@ X716Y2428D03*
X797Y2428D03*
X716Y2128D03*
X797Y2128D03*
G54D18*
G54D20*
X1166Y272D03*
X1166Y353D03*
X1016Y272D03*
X1016Y353D03*
X716Y278D03*
X716Y359D03*
X866Y278D03*
X866Y359D03*
X716Y272D03*
X716Y352D03*
X866Y272D03*
X866Y353D03*
X866Y453D03*
X866Y534D03*
X1541Y703D03*
X1541Y622D03*
G54D12*
G54D14*
X798Y2328D03*
X717Y2328D03*
G54D18*
G54D20*
X716Y453D03*
X716Y534D03*
X1391Y703D03*
@ -203,10 +218,10 @@ X1166Y447D03*
X1166Y528D03*
X1016Y447D03*
X1016Y528D03*
G54D22*
G54D24*
X2016Y476D03*
X2016Y728D03*
G54D12*
G54D14*
X1866Y3178D03*
X1947Y3178D03*
G54D21*
@ -218,17 +233,17 @@ X1666Y3503D03*
X1757Y3503D03*
X1666Y3578D03*
X1757Y3578D03*
G54D12*
G54D14*
X841Y1478D03*
X760Y1478D03*
X2316Y3478D03*
X2235Y3478D03*
G54D18*
G54D20*
X1316Y453D03*
X1316Y534D03*
X1466Y453D03*
X1466Y534D03*
G54D12*
G54D14*
X841Y1378D03*
X760Y1378D03*
X2766Y428D03*
@ -243,26 +258,26 @@ X1391Y1378D03*
X1310Y1378D03*
X1648Y1378D03*
X1567Y1378D03*
G54D23*
G54D25*
X3641Y853D03*
X3641Y975D03*
X3641Y553D03*
X3641Y675D03*
X1866Y603D03*
X1866Y481D03*
G54D12*
G54D14*
X1866Y3478D03*
X1947Y3478D03*
X2316Y3378D03*
X2235Y3378D03*
X1866Y3378D03*
X1947Y3378D03*
G54D24*
G54D26*
X3466Y971D03*
X3466Y853D03*
X3491Y671D03*
X3491Y553D03*
G54D18*
G54D20*
X1516Y2978D03*
X1516Y2897D03*
X1316Y2978D03*
@ -271,7 +286,7 @@ X1616Y2978D03*
X1616Y2897D03*
X1416Y2978D03*
X1416Y2897D03*
G54D12*
G54D14*
X1166Y3453D03*
X1085Y3453D03*
X1166Y3203D03*
@ -286,7 +301,7 @@ X2316Y3178D03*
X2235Y3178D03*
X1866Y3278D03*
X1947Y3278D03*
G54D20*
G54D23*
X1991Y2878D03*
X1785Y2828D03*
X1785Y2928D03*
@ -311,12 +326,12 @@ X760Y3253D03*
X966Y3353D03*
X760Y3353D03*
X966Y3203D03*
G54D12*
G54D14*
X1122Y1478D03*
X1041Y1478D03*
X1122Y1378D03*
X1041Y1378D03*
G54D18*
G54D20*
X1766Y453D03*
X1766Y534D03*
X1616Y453D03*
@ -325,31 +340,31 @@ X1691Y628D03*
X1691Y709D03*
X1691Y909D03*
X1691Y828D03*
G54D12*
G54D14*
X2391Y853D03*
X2472Y853D03*
X1041Y1578D03*
X1121Y1578D03*
X1041Y1678D03*
X1122Y1678D03*
G54D25*
X2183Y1428D03*
X2183Y1478D03*
X2183Y1528D03*
X2183Y1578D03*
X2183Y1628D03*
X2183Y1678D03*
X2183Y1728D03*
X2183Y1778D03*
X1941Y1778D03*
X1941Y1728D03*
X1941Y1678D03*
X1941Y1628D03*
X1941Y1578D03*
X1941Y1528D03*
X1941Y1478D03*
X1941Y1428D03*
G54D12*
G54D27*
X2016Y1603D03*
X2066Y1603D03*
X2116Y1603D03*
X2166Y1603D03*
X2216Y1603D03*
X2266Y1603D03*
X2316Y1603D03*
X2366Y1603D03*
X2366Y1845D03*
X2316Y1845D03*
X2266Y1845D03*
X2216Y1845D03*
X2166Y1845D03*
X2116Y1845D03*
X2066Y1845D03*
X2016Y1845D03*
G54D14*
X1310Y1578D03*
X1391Y1578D03*
X1310Y1478D03*
@ -364,9 +379,9 @@ X691Y928D03*
X772Y928D03*
X772Y1028D03*
X691Y1028D03*
G54D26*
G54D28*
X3148Y701D03*
G54D27*
G54D29*
D02*
G04 End of PasteMask1*
M02*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 KiB

After

Width:  |  Height:  |  Size: 487 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -7,10 +7,9 @@
queryCommand = "Q"
;signature = 20
signature = "speeduino 201704"
signature = "speeduino 201706-dev"
versionInfo = "S" ; Put this in the title bar.
;[TunerStudio]
; iniSpecVersion = 3.24
@ -28,6 +27,7 @@
;settingOption = BOOSTPSI, "PSI"
settingGroup = enablehardware_test, "Enable Hardware Test Page"
[PcVariables]
; valid types: boolean, double, int, list
;
@ -38,6 +38,7 @@
; name = type, min, max;
;
; type List: value will be index.
tsCanId = bits, U08, [0:3], "CAN ID 0", "CAN ID 1", "CAN ID 2", "CAN ID 3", "CAN ID 4", "CAN ID 5", "CAN ID 6", "CAN ID 7", "CAN ID 8", "CAN ID 9", "CAN ID 10","CAN ID 11","CAN ID 12","CAN ID 13","CAN ID 14","INVALID"
rpmhigh = scalar, U16, "rpm", 1, 0, 0, 30000, 0
rpmwarn = scalar, U16, "rpm", 1, 0, 0, 30000, 0
rpmdang = scalar, U16, "rpm", 1, 0, 0, 30000, 0
@ -99,6 +100,7 @@
nPages = 10
burnCommand = "B"
pageSize = 288, 64, 288, 64, 288, 64, 64, 160, 192, 128
; pageIdentifier = "\$tsCanId\x01", "\$tsCanId\x02", "\$tsCanId\x03", "\$tsCanId\x04", "\$tsCanId\x05", "\$tsCanId\x06", "\$tsCanId\x07", "\$tsCanId\x08", "\$tsCanId\x09", "\$tsCanId\x0A"
pageActivationDelay = 10
pageActivate = "P\001", "P\002", "P\003", "P\004", "P\005", "P\006", "P\007", "P\010", "P\011", "P\012"
pageReadCommand = "V", "V", "V", "V", "V", "V", "V", "V", "V", "V"
@ -114,6 +116,21 @@
;writeBlocks = off
interWriteDelay = 10
;New for TS 3.0.08ish upwards, define lists of standard I/O options
#define tsCanId_list = "CAN ID 0", "CAN ID 1", "CAN ID 2", "CAN ID 3", "CAN ID 4", "CAN ID 5", "CAN ID 6", "CAN ID 7", "CAN ID 8", "CAN ID 9", "CAN ID 10","CAN ID 11","CAN ID 12","CAN ID 13","CAN ID 14","INVALID"
#define CAN_ADDRESS_HEX_02XX = "0x200", "0x201", "0x202", "0x203", "0x204", "0x205", "0x206", "0x207", "0x208", "0x209", "0x20A", "0x20B", "0x20C", "0x20D", "0x20E", "0x20F", "0x210", "0x211", "0x212", "0x213", "0x214", "0x215", "0x216", "0x217", "0x218", "0x219", "0x21A", "0x21B", "0x21C", "0x21D", "0x21E", "0x21F", "0x220", "0x221", "0x222", "0x223", "0x224", "0x225", "0x226", "0x227", "0x228", "0x229", "0x22A", "0x22B", "0x22C", "0x22D", "0x22E", "0x22F", "0x230", "0x231", "0x232", "0x233", "0x234", "0x235", "0x236", "0x237", "0x238", "0x239", "0x23A", "0x23B", "0x23C", "0x23D", "0x23E", "0x23F", "0x240", "0x241", "0x242", "0x243", "0x244", "0x245", "0x246", "0x247", "0x248", "0x249", "0x24A", "0x24B", "0x24C", "0x24D", "0x24E", "0x24F", "0x250", "0x251", "0x252", "0x253", "0x254", "0x255", "0x256", "0x257", "0x258", "0x259", "0x25A", "0x25B", "0x25C", "0x25D", "0x25E", "0x25F" ,"0x260", "0x261", "0x262", "0x263", "0x264", "0x265", "0x266", "0x267", "0x268", "0x269", "0x26A", "0x26B", "0x26C", "0x26D", "0x26E", "0x26F", "0x270", "0x271", "0x272", "0x273", "0x274", "0x275", "0x276", "0x277", "0x278", "0x279", "0x27A", "0x27B", "0x27C", "0x27D", "0x27E", "0x27F", "0x280", "0x281", "0x282", "0x283", "0x284", "0x285", "0x286", "0x287", "0x288", "0x289", "0x28A", "0x28B", "0x28C", "0x28D", "0x28E", "0x28F" ,"0x290", "0x291", "0x292", "0x293", "0x294", "0x295", "0x296", "0x297", "0x298", "0x299", "0x29A", "0x29B", "0x29C", "0x29D", "0x29E", "0x29F", "0x2A0", "0x2A1", "0x2A2", "0x2A3", "0x2A4", "0x2A5", "0x2A6", "0x2A7", "0x2A8", "0x2A9", "0x2AA", "0x2AB", "0x2AC", "0x2AD", "0x2AE", "0x2AF", "0x2B0", "0x2B1", "0x2B2", "0x2B3", "0x2B4", "0x2B5", "0x2B6", "0x2B7", "0x2B8", "0x2B9", "0x2BA", "0x2BB", "0x2BC", "0x2BD", "0x2BE", "0x2BF" ,"0x2C0", "0x2C1", "0x2C2", "0x2C3", "0x2C4", "0x2C5", "0x2C6", "0x2C7", "0x2C8", "0x2C9", "0x2CA", "0x2CB", "0x2CC", "0x2CD", "0x2CE", "0x2CF", "0x2D0", "0x2D1", "0x2D2", "0x2D3", "0x2D4", "0x2D5", "0x2D6", "0x2D7", "0x2D8", "0x2D9", "0x2DA", "0x2DB", "0x2DC", "0x2DD", "0x2DE", "0x2DF", "0x2E0", "0x2E1", "0x2E2", "0x2E3", "0x2E4", "0x2E5", "0x2E6", "0x2E7", "0x2E8", "0x2E9", "0x2EA", "0x2EB", "0x2EC", "0x2ED", "0x2EE", "0x2EF" ,"0x2F0", "0x2F1", "0x2F2", "0x2F3", "0x2F4", "0x2F5", "0x2F6", "0x2F7", "0x2F8", "0x2F9", "0x2FA", "0x2FB", "0x2FC", "0x2FD", "0x2FE", "0x2FF"
#define CAN_ADDRESS_HEX_03XX = "0x300", "0x301", "0x302", "0x303", "0x304", "0x305", "0x306", "0x307", "0x308", "0x309", "0x30A", "0x30B", "0x30C", "0x30D", "0x30E", "0x30F", "0x310", "0x311", "0x312", "0x313", "0x314", "0x315", "0x316", "0x317", "0x318", "0x319", "0x31A", "0x31B", "0x31C", "0x31D", "0x31E", "0x31F", "0x320", "0x321", "0x322", "0x323", "0x324", "0x325", "0x326", "0x327", "0x328", "0x329", "0x32A", "0x32B", "0x32C", "0x32D", "0x32E", "0x32F", "0x330", "0x331", "0x332", "0x333", "0x334", "0x335", "0x336", "0x337", "0x338", "0x339", "0x33A", "0x33B", "0x33C", "0x33D", "0x33E", "0x33F", "0x340", "0x341", "0x342", "0x343", "0x344", "0x345", "0x346", "0x347", "0x348", "0x349", "0x34A", "0x34B", "0x34C", "0x34D", "0x34E", "0x34F", "0x350", "0x351", "0x352", "0x353", "0x354", "0x355", "0x356", "0x357", "0x358", "0x359", "0x35A", "0x35B", "0x35C", "0x35D", "0x35E", "0x35F" ,"0x360", "0x361", "0x362", "0x363", "0x364", "0x365", "0x366", "0x367", "0x368", "0x369", "0x36A", "0x36B", "0x36C", "0x36D", "0x36E", "0x36F", "0x370", "0x371", "0x372", "0x373", "0x374", "0x375", "0x376", "0x377", "0x378", "0x379", "0x37A", "0x37B", "0x37C", "0x37D", "0x37E", "0x37F", "0x380", "0x381", "0x382", "0x383", "0x384", "0x385", "0x386", "0x387", "0x388", "0x389", "0x38A", "0x38B", "0x38C", "0x38D", "0x38E", "0x38F" ,"0x390", "0x391", "0x392", "0x393", "0x394", "0x395", "0x396", "0x397", "0x398", "0x399", "0x39A", "0x39B", "0x39C", "0x39D", "0x39E", "0x39F", "0x3A0", "0x3A1", "0x3A2", "0x3A3", "0x3A4", "0x3A5", "0x3A6", "0x3A7", "0x3A8", "0x3A9", "0x3AA", "0x3AB", "0x3AC", "0x3AD", "0x3AE", "0x3AF", "0x3B0", "0x3B1", "0x3B2", "0x3B3", "0x3B4", "0x3B5", "0x3B6", "0x3B7", "0x3B8", "0x3B9", "0x3BA", "0x3BB", "0x3BC", "0x3BD", "0x3BE", "0x3BF" ,"0x3C0", "0x3C1", "0x3C2", "0x3C3", "0x3C4", "0x3C5", "0x3C6", "0x3C7", "0x3C8", "0x3C9", "0x3CA", "0x3CB", "0x3CC", "0x3CD", "0x3CE", "0x3CF", "0x3D0", "0x3D1", "0x3D2", "0x3D3", "0x3D4", "0x3D5", "0x3D6", "0x3D7", "0x3D8", "0x3D9", "0x3DA", "0x3DB", "0x3DC", "0x3DD", "0x3DE", "0x3DF", "0x3E0", "0x3E1", "0x3E2", "0x3E3", "0x3E4", "0x3E5", "0x3E6", "0x3E7", "0x3E8", "0x3E9", "0x3EA", "0x3EB", "0x3EC", "0x3ED", "0x3EE", "0x3EF" ,"0x3F0", "0x3F1", "0x3F2", "0x3F3", "0x3F4", "0x3F5", "0x3F6", "0x3F7", "0x3F8", "0x3F9", "0x3FA", "0x3FB", "0x3FC", "0x3FD", "0x3FE", "0x3FF"
#define CAN_ADDRESS_HEX_04XX = "0x400", "0x401", "0x402", "0x403", "0x404", "0x405", "0x406", "0x407", "0x408", "0x409", "0x40A", "0x40B", "0x40C", "0x40D", "0x40E", "0x40F", "0x410", "0x411", "0x412", "0x413", "0x414", "0x415", "0x416", "0x417", "0x418", "0x419", "0x41A", "0x41B", "0x41C", "0x41D", "0x41E", "0x41F", "0x420", "0x421", "0x422", "0x423", "0x424", "0x425", "0x426", "0x427", "0x428", "0x429", "0x42A", "0x42B", "0x42C", "0x42D", "0x42E", "0x42F", "0x430", "0x431", "0x432", "0x433", "0x434", "0x435", "0x436", "0x437", "0x438", "0x439", "0x43A", "0x43B", "0x43C", "0x43D", "0x43E", "0x43F", "0x440", "0x441", "0x442", "0x443", "0x444", "0x445", "0x446", "0x447", "0x448", "0x449", "0x44A", "0x44B", "0x44C", "0x44D", "0x44E", "0x44F", "0x450", "0x451", "0x452", "0x453", "0x454", "0x455", "0x456", "0x457", "0x458", "0x459", "0x45A", "0x45B", "0x45C", "0x45D", "0x45E", "0x45F" ,"0x460", "0x461", "0x462", "0x463", "0x464", "0x465", "0x466", "0x467", "0x468", "0x469", "0x46A", "0x46B", "0x46C", "0x46D", "0x46E", "0x46F", "0x470", "0x471", "0x472", "0x473", "0x474", "0x475", "0x476", "0x477", "0x478", "0x479", "0x47A", "0x47B", "0x47C", "0x47D", "0x47E", "0x47F", "0x480", "0x481", "0x482", "0x483", "0x484", "0x485", "0x486", "0x487", "0x488", "0x489", "0x48A", "0x48B", "0x48C", "0x48D", "0x48E", "0x48F" ,"0x490", "0x491", "0x492", "0x493", "0x494", "0x495", "0x496", "0x497", "0x498", "0x499", "0x49A", "0x49B", "0x49C", "0x49D", "0x49E", "0x49F", "0x4A0", "0x4A1", "0x4A2", "0x4A3", "0x4A4", "0x4A5", "0x4A6", "0x4A7", "0x4A8", "0x4A9", "0x4AA", "0x4AB", "0x4AC", "0x4AD", "0x4AE", "0x4AF", "0x4B0", "0x4B1", "0x4B2", "0x4B3", "0x4B4", "0x4B5", "0x4B6", "0x4B7", "0x4B8", "0x4B9", "0x4BA", "0x4BB", "0x4BC", "0x4BD", "0x4BE", "0x4BF" ,"0x4C0", "0x4C1", "0x4C2", "0x4C3", "0x4C4", "0x4C5", "0x4C6", "0x4C7", "0x4C8", "0x4C9", "0x4CA", "0x4CB", "0x4CC", "0x4CD", "0x4CE", "0x4CF", "0x4D0", "0x4D1", "0x4D2", "0x4D3", "0x4D4", "0x4D5", "0x4D6", "0x4D7", "0x4D8", "0x4D9", "0x4DA", "0x4DB", "0x4DC", "0x4DD", "0x4DE", "0x4DF", "0x4E0", "0x4E1", "0x4E2", "0x4E3", "0x4E4", "0x4E5", "0x4E6", "0x4E7", "0x4E8", "0x4E9", "0x4EA", "0x4EB", "0x4EC", "0x4ED", "0x4EE", "0x4EF" ,"0x4F0", "0x4F1", "0x4F2", "0x4F3", "0x4F4", "0x4F5", "0x4F6", "0x4F7", "0x4F8", "0x4F9", "0x4FA", "0x4FB", "0x4FC", "0x4FD", "0x4FE", "0x4FF"
#define CAN_ADDRESS_HEX_05XX = "0x500", "0x501", "0x502", "0x503", "0x504", "0x505", "0x506", "0x507", "0x508", "0x509", "0x50A", "0x50B", "0x50C", "0x50D", "0x50E", "0x50F", "0x510", "0x511", "0x512", "0x513", "0x514", "0x515", "0x516", "0x517", "0x518", "0x519", "0x51A", "0x51B", "0x51C", "0x51D", "0x51E", "0x51F", "0x520", "0x521", "0x522", "0x523", "0x524", "0x525", "0x526", "0x527", "0x528", "0x529", "0x52A", "0x52B", "0x52C", "0x52D", "0x52E", "0x52F", "0x530", "0x531", "0x532", "0x533", "0x534", "0x535", "0x536", "0x537", "0x538", "0x539", "0x53A", "0x53B", "0x53C", "0x53D", "0x53E", "0x53F", "0x540", "0x541", "0x542", "0x543", "0x544", "0x545", "0x546", "0x547", "0x548", "0x549", "0x54A", "0x54B", "0x54C", "0x54D", "0x54E", "0x54F", "0x550", "0x551", "0x552", "0x553", "0x554", "0x555", "0x556", "0x557", "0x558", "0x559", "0x55A", "0x55B", "0x55C", "0x55D", "0x55E", "0x55F" ,"0x560", "0x561", "0x562", "0x563", "0x564", "0x565", "0x566", "0x567", "0x568", "0x569", "0x56A", "0x56B", "0x56C", "0x56D", "0x56E", "0x56F", "0x570", "0x571", "0x572", "0x573", "0x574", "0x575", "0x576", "0x577", "0x578", "0x579", "0x57A", "0x57B", "0x57C", "0x57D", "0x57E", "0x57F", "0x580", "0x581", "0x582", "0x583", "0x584", "0x585", "0x586", "0x587", "0x588", "0x589", "0x58A", "0x58B", "0x58C", "0x58D", "0x58E", "0x58F" ,"0x590", "0x591", "0x592", "0x593", "0x594", "0x595", "0x596", "0x597", "0x598", "0x599", "0x59A", "0x59B", "0x59C", "0x59D", "0x59E", "0x59F", "0x5A0", "0x5A1", "0x5A2", "0x5A3", "0x5A4", "0x5A5", "0x5A6", "0x5A7", "0x5A8", "0x5A9", "0x5AA", "0x5AB", "0x5AC", "0x5AD", "0x5AE", "0x5AF", "0x5B0", "0x5B1", "0x5B2", "0x5B3", "0x5B4", "0x5B5", "0x5B6", "0x5B7", "0x5B8", "0x5B9", "0x5BA", "0x5BB", "0x5BC", "0x5BD", "0x5BE", "0x5BF" ,"0x5C0", "0x5C1", "0x5C2", "0x5C3", "0x5C4", "0x5C5", "0x5C6", "0x5C7", "0x5C8", "0x5C9", "0x5CA", "0x5CB", "0x5CC", "0x5CD", "0x5CE", "0x5CF", "0x5D0", "0x5D1", "0x5D2", "0x5D3", "0x5D4", "0x5D5", "0x5D6", "0x5D7", "0x5D8", "0x5D9", "0x5DA", "0x5DB", "0x5DC", "0x5DD", "0x5DE", "0x5DF", "0x5E0", "0x5E1", "0x5E2", "0x5E3", "0x5E4", "0x5E5", "0x5E6", "0x5E7", "0x5E8", "0x5E9", "0x5EA", "0x5EB", "0x5EC", "0x5ED", "0x5EE", "0x5EF" ,"0x5F0", "0x5F1", "0x5F2", "0x5F3", "0x5F4", "0x5F5", "0x5F6", "0x5F7", "0x5F8", "0x5F9", "0x5FA", "0x5FB", "0x5FC", "0x5FD", "0x5FE", "0x5FF"
#define CAN_ADDRESS_HEX_06XX = "0x600", "0x601", "0x602", "0x603", "0x604", "0x605", "0x606", "0x607", "0x608", "0x609", "0x60A", "0x60B", "0x60C", "0x60D", "0x60E", "0x60F", "0x610", "0x611", "0x612", "0x613", "0x614", "0x615", "0x616", "0x617", "0x618", "0x619", "0x61A", "0x61B", "0x61C", "0x61D", "0x61E", "0x61F", "0x620", "0x621", "0x622", "0x623", "0x624", "0x625", "0x626", "0x627", "0x628", "0x629", "0x62A", "0x62B", "0x62C", "0x62D", "0x62E", "0x62F", "0x630", "0x631", "0x632", "0x633", "0x634", "0x635", "0x636", "0x637", "0x638", "0x639", "0x63A", "0x63B", "0x63C", "0x63D", "0x63E", "0x63F", "0x640", "0x641", "0x642", "0x643", "0x644", "0x645", "0x646", "0x647", "0x648", "0x649", "0x64A", "0x64B", "0x64C", "0x64D", "0x64E", "0x64F", "0x650", "0x651", "0x652", "0x653", "0x654", "0x655", "0x656", "0x657", "0x658", "0x659", "0x65A", "0x65B", "0x65C", "0x65D", "0x65E", "0x65F" ,"0x660", "0x661", "0x662", "0x663", "0x664", "0x665", "0x666", "0x667", "0x668", "0x669", "0x66A", "0x66B", "0x66C", "0x66D", "0x66E", "0x66F", "0x670", "0x671", "0x672", "0x673", "0x674", "0x675", "0x676", "0x677", "0x678", "0x679", "0x67A", "0x67B", "0x67C", "0x67D", "0x67E", "0x67F", "0x680", "0x681", "0x682", "0x683", "0x684", "0x685", "0x686", "0x687", "0x688", "0x689", "0x68A", "0x68B", "0x68C", "0x68D", "0x68E", "0x68F" ,"0x690", "0x691", "0x692", "0x693", "0x694", "0x695", "0x696", "0x697", "0x698", "0x699", "0x69A", "0x69B", "0x69C", "0x69D", "0x69E", "0x69F", "0x6A0", "0x6A1", "0x6A2", "0x6A3", "0x6A4", "0x6A5", "0x6A6", "0x6A7", "0x6A8", "0x6A9", "0x6AA", "0x6AB", "0x6AC", "0x6AD", "0x6AE", "0x6AF", "0x6B0", "0x6B1", "0x6B2", "0x6B3", "0x6B4", "0x6B5", "0x6B6", "0x6B7", "0x6B8", "0x6B9", "0x6BA", "0x6BB", "0x6BC", "0x6BD", "0x6BE", "0x6BF" ,"0x6C0", "0x6C1", "0x6C2", "0x6C3", "0x6C4", "0x6C5", "0x6C6", "0x6C7", "0x6C8", "0x6C9", "0x6CA", "0x6CB", "0x6CC", "0x6CD", "0x6CE", "0x6CF", "0x6D0", "0x6D1", "0x6D2", "0x6D3", "0x6D4", "0x6D5", "0x6D6", "0x6D7", "0x6D8", "0x6D9", "0x6DA", "0x6DB", "0x6DC", "0x6DD", "0x6DE", "0x6DF", "0x6E0", "0x6E1", "0x6E2", "0x6E3", "0x6E4", "0x6E5", "0x6E6", "0x6E7", "0x6E8", "0x6E9", "0x6EA", "0x6EB", "0x6EC", "0x6ED", "0x6EE", "0x6EF" ,"0x6F0", "0x6F1", "0x6F2", "0x6F3", "0x6F4", "0x6F5", "0x6F6", "0x6F7", "0x6F8", "0x6F9", "0x6FA", "0x6FB", "0x6FC", "0x6FD", "0x6FE", "0x6FF"
#define CAN_ADDRESS_HEX_07XX = "0x700", "0x701", "0x702", "0x703", "0x704", "0x705", "0x706", "0x707", "0x708", "0x709", "0x70A", "0x70B", "0x70C", "0x70D", "0x70E", "0x70F", "0x710", "0x711", "0x712", "0x713", "0x714", "0x715", "0x716", "0x717", "0x718", "0x719", "0x71A", "0x71B", "0x71C", "0x71D", "0x71E", "0x71F", "0x720", "0x721", "0x722", "0x723", "0x724", "0x725", "0x726", "0x727", "0x728", "0x729", "0x72A", "0x72B", "0x72C", "0x72D", "0x72E", "0x72F", "0x730", "0x731", "0x732", "0x733", "0x734", "0x735", "0x736", "0x737", "0x738", "0x739", "0x73A", "0x73B", "0x73C", "0x73D", "0x73E", "0x73F", "0x740", "0x741", "0x742", "0x743", "0x744", "0x745", "0x746", "0x747", "0x748", "0x749", "0x74A", "0x74B", "0x74C", "0x74D", "0x74E", "0x74F", "0x750", "0x751", "0x752", "0x753", "0x754", "0x755", "0x756", "0x757", "0x758", "0x759", "0x75A", "0x75B", "0x75C", "0x75D", "0x75E", "0x75F" ,"0x760", "0x761", "0x762", "0x763", "0x764", "0x765", "0x766", "0x767", "0x768", "0x769", "0x76A", "0x76B", "0x76C", "0x76D", "0x76E", "0x76F", "0x770", "0x771", "0x772", "0x773", "0x774", "0x775", "0x776", "0x777", "0x778", "0x779", "0x77A", "0x77B", "0x77C", "0x77D", "0x77E", "0x77F", "0x780", "0x781", "0x782", "0x783", "0x784", "0x785", "0x786", "0x787", "0x788", "0x789", "0x78A", "0x78B", "0x78C", "0x78D", "0x78E", "0x78F" ,"0x790", "0x791", "0x792", "0x793", "0x794", "0x795", "0x796", "0x797", "0x798", "0x799", "0x79A", "0x79B", "0x79C", "0x79D", "0x79E", "0x79F", "0x7A0", "0x7A1", "0x7A2", "0x7A3", "0x7A4", "0x7A5", "0x7A6", "0x7A7", "0x7A8", "0x7A9", "0x7AA", "0x7AB", "0x7AC", "0x7AD", "0x7AE", "0x7AF", "0x7B0", "0x7B1", "0x7B2", "0x7B3", "0x7B4", "0x7B5", "0x7B6", "0x7B7", "0x7B8", "0x7B9", "0x7BA", "0x7BB", "0x7BC", "0x7BD", "0x7BE", "0x7BF" ,"0x7C0", "0x7C1", "0x7C2", "0x7C3", "0x7C4", "0x7C5", "0x7C6", "0x7C7", "0x7C8", "0x7C9", "0x7CA", "0x7CB", "0x7CC", "0x7CD", "0x7CE", "0x7CF", "0x7D0", "0x7D1", "0x7D2", "0x7D3", "0x7D4", "0x7D5", "0x7D6", "0x7D7", "0x7D8", "0x7D9", "0x7DA", "0x7DB", "0x7DC", "0x7DD", "0x7DE", "0x7DF", "0x7E0", "0x7E1", "0x7E2", "0x7E3", "0x7E4", "0x7E5", "0x7E6", "0x7E7", "0x7E8", "0x7E9", "0x7EA", "0x7EB", "0x7EC", "0x7ED", "0x7EE", "0x7EF" ,"0x7F0", "0x7F1", "0x7F2", "0x7F3", "0x7F4", "0x7F5", "0x7F6", "0x7F7", "0x7F8", "0x7F9", "0x7FA", "0x7FB", "0x7FC", "0x7FD", "0x7FE", "0x7FF"
#define CAN_ADDRESS_HEX = $CAN_ADDRESS_HEX_02XX, $CAN_ADDRESS_HEX_03XX, $CAN_ADDRESS_HEX_04XX, $CAN_ADDRESS_HEX_05XX, $CAN_ADDRESS_HEX_06XX, $CAN_ADDRESS_HEX_07XX
#define PIN_OUT10inv = "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
#define PIN_OUT16inv = "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
;Page 1 is the fuel map and axis bins only
page = 1
; name = bits, type, offset, bits
@ -137,8 +154,8 @@ page = 1
;Page 2 is all general settings (Previously part of page 1)
;--------------------------------------------------
page = 2
unused2-1 = scalar, U08, 0, "ms", 0.1, 0.0, 0.0, 25.5, 1
unused2-2 = scalar, U08, 1, "ms", 0.1, 0.0, 0.0, 25.5, 1
flexBoostLow = scalar, S08, 0, "kPa", 1.0, 0.0, -127, 127, 0
flexBoostHigh = scalar, U08, 1, "kPa", 1.0, 0.0, 0.0, 255, 0
asePct = scalar, U08, 2, "%", 1.0, 0.0, 0.0, 95.0, 0
aseCount = scalar, U08, 3, "s", 1.0, 0.0, 0.0, 255, 0
wueRates = array, U08, 4, [10], "%", 1.0, 0.0, 0.0, 255, 0
@ -196,7 +213,7 @@ page = 2
algorithm = bits, U08, 38, [2:2], "Speed Density", "Alpha-N"
baroCorr = bits, U08, 38, [3:3], "Off", "On"
injLayout = bits, U08, 38, [4:5], "Paired", "Semi-Sequential", "INVALID", "Sequential"
canEnable = bits, U08, 38, [6:6], "Disable", "Enable"
unused2-38f= bits, U08, 38, [6:6], "ONE", "INVALID"
unused2-38h= bits, U08, 38, [7:7], "No", "Yes"
primePulse = scalar, U08, 39, "ms", 0.1, 0.0, 0.0, 25.5, 1
@ -230,7 +247,7 @@ page = 2
;Start Ignition table (Page 3)
;--------------------------------------------------
page = 3
advTable1 = array, U08, 0,[16x16], "deg", 1.0, 0.0, 0.0, 255.0, 0
advTable1 = array, U08, 0,[16x16], "deg", 1.0, -40, -40, 215.0, 0
rpmBins2 = array, U08, 256,[ 16], "RPM", 100.0, 0.0, 100, 25500, 0
#if SPEED_DENSITY
@ -255,7 +272,7 @@ page = 4
TrigSpeed = bits, U08, 5,[1:1], "Crank Speed", "Cam Speed"
IgInv = bits, U08, 5,[2:2], "Going Low", "Going High"
oddfire = bits, U08, 5,[3:3], "No", "Yes"
TrigPattern= bits, U08, 5,[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "INVALID", "INVALID"
TrigPattern= bits, U08, 5,[4:7], "Missing Tooth", "Basic Distributor", "Dual Wheel", "GM 7X", "4G63 / Miata / 3000GT", "GM 24X", "Jeep 2000", "Audi 135", "Honda D17", "Miata 99-05", "Mazda AU", "Non-360 Dual", "Nissan 360", "Subaru 6/7", "INVALID", "INVALID"
TrigEdgeSec= bits, U08, 6,[0:0], "Leading", "Trailing"
fuelPumpPin= bits , U08, 6,[1:6], "Board Default", "INVALID", "INVALID", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
useResync = bits, U08, 6,[7:7], "No", "Yes"
@ -272,15 +289,14 @@ page = 4
; name = array, type, offset, shape, units, scale, translate, lo, hi, digits
; name = scalar, type, offset, units, scale, translate, lo, hi, digits
;Dwell control
;running dwell variable railed to 8 - who needs more than 8ms?
dwellcont = bits, U08, 12, [0:0], "INVALID", "Dwell control"
useDwellLim= bits, U08, 12, [1:1], "Off", "On"
useDwellLim= bits, U08, 12, [1:1], "Off", "On"
sparkMode = bits, U08, 12, [2:3], "Wasted Spark", "Single Channel", "Wasted COP", "Sequential"
dfcoEnabled= bits, U08, 12, [4:4], "Off", "On"
dfcoEnabled= bits, U08, 12, [4:4], "Off", "On"
TrigFilter = bits, U08, 12, [5:6], "Off", "Weak", "Medium", "Aggressive"
ignCranklock=bits, U08, 12, [7:7], "Off", "On"
dwellcrank = scalar, U08, 13, "ms", 0.1, 0, 0, 25, 1
dwellrun = scalar, U08, 14, "ms", 0.1, 0, 0, 8, 1
dwellrun = scalar, U08, 14, "ms", 0.1, 0, 0, 8, 1 ;running dwell variable railed to 8 - who needs more than 8ms?
numteeth = scalar, U08, 15, "teeth", 1.0, 0.0, 0.0, 255, 0
onetwo = scalar, U08, 16, "teeth", 1.0, 0.0, 0.0, 255, 0
@ -327,7 +343,12 @@ page = 4
;Start AFR page
;--------------------------------------------------
page = 5
#if LAMBDA
afrTable = array, U08, 0,[16x16], "Lambda", { 0.1 / stoich }, 0.0000, 0.00, 2.00, 3
#else
afrTable = array, U08, 0,[16x16], "AFR", 0.1, 0.0, 7, 25.5, 1
#endif
rpmBinsAFR = array, U08, 256,[ 16], "RPM", 100.0, 0.0, 100, 25500, 0
#if SPEED_DENSITY
mapBinsAFR = array, U08, 272,[ 16], "kPa", 2.0, 0.0, 0.0, 511.0, 0
@ -524,32 +545,37 @@ page = 9
;CANBUS control (Page 10)
;--------------------------------------------------
page = 10
enable_candata_in = bits, U08, 0, [0:0], "Off", "On"
#if CAN_COMMANDS
enable_canbus = bits, U08, 0, [0:1], "Off", "On Via Secondary Serial", "ON via Internal CAN ", "INVALID"
#else
enable_canbus = bits, U08, 0, [0:1], "Disable", "Enable", "INVALID", "INVALID"
#endif
enable_candata_in = bits, U08, 0, [2:2], "Off", "On"
caninput_sel1 = bits, U08, 1, [0:0], "Off", "On"
caninput_sel2 = bits, U08, 2, [0:0], "Off", "On"
caninput_sel3 = bits, U08, 3, [0:0], "Off", "On"
caninput_sel4 = bits, U08, 4, [0:0], "Off", "On"
caninput_sel5 = bits, U08, 5, [0:0], "Off", "On"
caninput_sel6 = bits, U08, 6, [0:0], "Off", "On"
caninput_sel7 = bits, U08, 7, [0:0], "Off", "On"
caninput_sel8 = bits, U08, 8, [0:0], "Off", "On"
caninput_param_group = array , U16, 9, [ 8], "", 1, 0, 0, 65535, 0
caninput_param_start_byte1 = bits, U08, 25, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_sel3 = bits, U08, 3, [0:0], "Off", "On"
caninput_sel4 = bits, U08, 4, [0:0], "Off", "On"
caninput_sel5 = bits, U08, 5, [0:0], "Off", "On"
caninput_sel6 = bits, U08, 6, [0:0], "Off", "On"
caninput_sel7 = bits, U08, 7, [0:0], "Off", "On"
caninput_sel8 = bits, U08, 8, [0:0], "Off", "On"
caninput_param_group = array , U16, 9, [ 8], "", 1, 0, 0, 65535, 0
caninput_param_start_byte1 = bits, U08, 25, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte2 = bits, U08, 26, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte3 = bits, U08, 27, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte4 = bits, U08, 28, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte5 = bits, U08, 29, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte6 = bits, U08, 30, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte7 = bits, U08, 31, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte8 = bits, U08, 32, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_num_bytes1 = bits, U08, 33, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_start_byte7 = bits, U08, 31, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_start_byte8 = bits, U08, 32, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
caninput_param_num_bytes1 = bits, U08, 33, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes2 = bits, U08, 34, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes3 = bits, U08, 35, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes4 = bits, U08, 36, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes5 = bits, U08, 37, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes6 = bits, U08, 38, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes7 = bits, U08, 39, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes8 = bits, U08, 40, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes7 = bits, U08, 39, [0:1], "INVALID", "1", "2", "INVALID"
caninput_param_num_bytes8 = bits, U08, 40, [0:1], "INVALID", "1", "2", "INVALID"
unused10_41 = scalar, U08, 41, "", 1, 0, 0, 255, 0
unused10_42 = scalar, U08, 42, "", 1, 0, 0, 255, 0
unused10_43 = scalar, U08, 43, "", 1, 0, 0, 255, 0
@ -559,33 +585,32 @@ page = 10
unused10_47 = scalar, U08, 47, "", 1, 0, 0, 255, 0
unused10_48 = scalar, U08, 48, "", 1, 0, 0, 255, 0
unused10_49 = scalar, U08, 49, "", 1, 0, 0, 255, 0
enable_candata_out = bits, U08, 50, [0:0], "Off", "On"
unused10_51 = scalar, U08, 51, "", 1, 0, 0, 255, 0
unused10_52 = scalar, U08, 52, "", 1, 0, 0, 255, 0
unused10_53 = scalar, U08, 53, "", 1, 0, 0, 255, 0
unused10_54 = scalar, U08, 54, "", 1, 0, 0, 255, 0
unused10_55 = scalar, U08, 55, "", 1, 0, 0, 255, 0
unused10_56 = scalar, U08, 56, "", 1, 0, 0, 255, 0
unused10_57 = scalar, U08, 57, "", 1, 0, 0, 255, 0
unused10_58 = scalar, U08, 58, "", 1, 0, 0, 255, 0
unused10_59 = scalar, U08, 59, "", 1, 0, 0, 255, 0
unused10_60 = scalar, U08, 60, "", 1, 0, 0, 255, 0
unused10_61 = scalar, U08, 61, "", 1, 0, 0, 255, 0
unused10_62 = scalar, U08, 62, "", 1, 0, 0, 255, 0
unused10_63 = scalar, U08, 63, "", 1, 0, 0, 255, 0
unused10_64 = scalar, U08, 64, "", 1, 0, 0, 255, 0
unused10_65 = scalar, U08, 65, "", 1, 0, 0, 255, 0
unused10_66 = scalar, U08, 66, "", 1, 0, 0, 255, 0
unused10_67 = scalar, U08, 67, "", 1, 0, 0, 255, 0
unused10_68 = scalar, U08, 68, "", 1, 0, 0, 255, 0
unused10_69 = scalar, U08, 69, "", 1, 0, 0, 255, 0
unused10_70 = scalar, U08, 70, "", 1, 0, 0, 255, 0
unused10_71 = scalar, U08, 71, "", 1, 0, 0, 255, 0
unused10_72 = scalar, U08, 72, "", 1, 0, 0, 255, 0
unused10_73 = scalar, U08, 73, "", 1, 0, 0, 255, 0
unused10_74 = scalar, U08, 74, "", 1, 0, 0, 255, 0
unused10_75 = scalar, U08, 75, "", 1, 0, 0, 255, 0
unused10_76 = scalar, U08, 76, "", 1, 0, 0, 255, 0
enable_candata_out = bits, U08, 50, [0:0], "Off", "On"
canoutput_sel1 = bits, U08, 51, [0:0], "Off", "On"
canoutput_sel2 = bits, U08, 52, [0:0], "Off", "On"
canoutput_sel3 = bits, U08, 53, [0:0], "Off", "On"
canoutput_sel4 = bits, U08, 54, [0:0], "Off", "On"
canoutput_sel5 = bits, U08, 55, [0:0], "Off", "On"
canoutput_sel6 = bits, U08, 56, [0:0], "Off", "On"
canoutput_sel7 = bits, U08, 57, [0:0], "Off", "On"
canoutput_sel8 = bits, U08, 58, [0:0], "Off", "On"
canoutput_param_group = array , U16, 59, [ 8], "", 1, 0, 0, 65535, 0
canoutput_param_start_byte1 = bits, U08, 61, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte2 = bits, U08, 62, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte3 = bits, U08, 63, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte4 = bits, U08, 64, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte5 = bits, U08, 65, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte6 = bits, U08, 66, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte7 = bits, U08, 67, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_start_byte8 = bits, U08, 68, [0:2], "1", "2", "3", "4", "5", "6", "7", "8"
canoutput_param_num_bytes1 = bits, U08, 69, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes2 = bits, U08, 70, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes3 = bits, U08, 71, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes4 = bits, U08, 72, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes5 = bits, U08, 73, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes6 = bits, U08, 74, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes7 = bits, U08, 75, [0:1], "INVALID", "1", "2", "INVALID"
canoutput_param_num_bytes8 = bits, U08, 76, [0:1], "INVALID", "1", "2", "INVALID"
unused10_77 = scalar, U08, 77, "", 1, 0, 0, 255, 0
unused10_78 = scalar, U08, 78, "", 1, 0, 0, 255, 0
unused10_79 = scalar, U08, 79, "", 1, 0, 0, 255, 0
@ -609,13 +634,18 @@ page = 10
unused10_97 = scalar, U08, 97, "", 1, 0, 0, 255, 0
unused10_98 = scalar, U08, 98, "", 1, 0, 0, 255, 0
unused10_99 = scalar, U08, 99, "", 1, 0, 0, 255, 0
unused10_100 = scalar, U08, 100, "", 1, 0, 0, 255, 0
unused10_101 = scalar, U08, 101, "", 1, 0, 0, 255, 0
unused10_102 = scalar, U08, 102, "", 1, 0, 0, 255, 0
unused10_103 = scalar, U08, 103, "", 1, 0, 0, 255, 0
unused10_104 = scalar, U08, 104, "", 1, 0, 0, 255, 0
unused10_105 = scalar, U08, 105, "", 1, 0, 0, 255, 0
unused10_106 = scalar, U08, 106, "", 1, 0, 0, 255, 0
speeduino_tsCanId = bits, U08, 100, [0:3], $tsCanId_list
;true_address = bits, U16, 101, [0:10], $CAN_ADDRESS_HEX
;realtime_base_address = bits, U16, 103, [0:10], $CAN_ADDRESS_HEX
;obd_address = bits, U16, 105, [0:10], $CAN_ADDRESS_HEX
unused10_101 = scalar, U16, 101, "", 1, 0, 0, 255, 0
unused10_103 = scalar, U16, 103, "", 1, 0, 0, 255, 0
unused10_105 = scalar, U16, 105, "", 1, 0, 0, 255, 0
;AFR offset for WUE VeAnalyze
;wueAFRRates = array, U08, 107, [10], "%", 1.0, 0.0, 0.0, 255, 0
;wueAFRBins = array, U08, 117, [10], "C", 1.0, -40, -40, 102.0, 0
unused10_107 = scalar, U08, 107, "", 1, 0, 0, 255, 0
unused10_108 = scalar, U08, 108, "", 1, 0, 0, 255, 0
unused10_109 = scalar, U08, 109, "", 1, 0, 0, 255, 0
@ -698,6 +728,8 @@ page = 10
defaultValue = flexFuelHigh,163
defaultValue = flexAdvLow, 0
defaultValue = flexAdvHigh, 13
defaultValue = flexBoostLow,0
defaultValue = flexBoostHigh,0
defaultValue = fuelPumpPin, 0
defaultValue = fanPin, 0
defaultValue = iacCLminDuty,0
@ -705,6 +737,10 @@ page = 10
defaultValue = boostMinDuty,0
defaultValue = boostMaxDuty,100
defaultValue = sparkDur, 1.0
defaultValue = speeduino_tsCanId, 0
;defaultValue = true_address, 0
;defaultValue = realtime_base_address, 0
;defaultValue = obd_address, 0
;Default pins
defaultValue = fanPin, 0
@ -799,13 +835,15 @@ menuDialog = main
subMenu = std_separator
subMenu = canIO, "Serial3 IO Interface"
#if CAN_COMMANDS
subMenu = std_separator
subMenu = can_serial3IO, "Canbus/Secondary Serial IO Interface"
subMenu = std_separator
subMenu = Canin_config, "Canbus Input Configuration"
;subMenu = std_separator
;subMenu = Canout_config, "Canbus Output Configuration"
#endif
#else
subMenu = serial3IO, "Secondary Serial IO Interface"
#endif
menuDialog = main
menu = "T&ools"
@ -899,12 +937,21 @@ menuDialog = main
flexFuelHigh = "Fuel % to be used for the highest ethanol reading (Typically 163% for 100% ethanol)"
flexAdvLow = "Additional advance (in degrees) at lowest ethanol reading (Typically 0)"
flexAdvHigh = "Additional advance (in degrees) at highest ethanol reading (Typically 10-20 degrees)"
flexBoostHigh = "This amount that will be added to the boost target at E100. Between E0 and E100, the amount added to the boost target will be scaled from 0 to this value"
flexBoostLow = "Typically should be set to 0, but can be used to lower boost at E0 if the bast tune is setup with some ethanol"
flatSArm = "The RPM switch point that determines whether an eganged clutch is for launch control or flat shift. Below this figure, an engaged clutch is considered to be for launch, above this figure an active clutch input will be considered a flat shift. This should be set at least several hundred RPM above idle"
flatSSoftWin= "The number of RPM below the flat shift point where the softlimit will be applied (aka Soft limit window). Recommended values are 200-1000"
flatSRetard = "The absolute timing (BTDC) that will be used when within the soft limit window"
canEnable = "This Enables the IO on serial3 on mega2560 processor "
#if CAN_COMMANDS
enable_canbus = "This Enables either the secondary serial port or output via internal Can module. Secondary serial is serial3 on mega2560 processor, and Serial2 on STM32 and Teensy processor "
#else
enable_canbus = "This Enables the IO on the secondary serial port. This is serial3 on mega2560 processor, and Serial2 on STM32 and Teensy processor "
#endif
speeduino_tsCanId = "This is the TsCanId that the Speeduino ECU will respond to. This should match the main controller CAN ID in project properties if it is connected directy to TunerStudio, Otherwise the device ID if connected via CAN passthrough"
true_address = "This is the 11bit Can address of the Speeduino ECU "
obd_address = "The 11bit Can address that the Speeduino ECU responds to for OBD2 diagnostic requests"
caninput_sel1 = "This Enables CAN data input channel 1 "
caninput_sel2 = "This Enables CAN data input channel 2 "
caninput_sel3 = "This Enables CAN data input channel 3 "
@ -1002,24 +1049,27 @@ menuDialog = main
field = "Sensor Frequency"
field = "Fuel Multiplier%"
field = "Additional advance"
field = "Additional boost", { boostEnabled }
#field = "#Temp Sense"
#field = "Sensor PW"
#field = "Fuel Temp"
dialog = flexl, ""
field = "Low"
field = "Low (E0)"
field = "", flexFreqLow, { flexEnabled }
field = "", flexFuelLow, { flexEnabled }
field = "", flexAdvLow, { flexEnabled }
field = "", flexAdvLow, { flexEnabled }
field = "", flexBoostLow, { boostEnabled }
#field = "Low"
#field = "", ff_tpw0, { flexEnabled && (fueltemp1 == 1)}
#field = "", ff_temp0, { flexEnabled && (fueltemp1 == 1)}
dialog = flexh, ""
field = "High"
field = "High (E100)"
field = "", flexFreqHigh, { flexEnabled }
field = "", flexFuelHigh, { flexEnabled }
field = "", flexAdvHigh, { flexEnabled }
field = "", flexAdvHigh, { flexEnabled }
field = "", flexBoostHigh, { boostEnabled }
#field = "High"
#field = "", ff_tpw1, { flexFuel && (fueltemp1 == 1)}
#field = "", ff_temp1, { flexFuel && (fueltemp1 == 1)}
@ -1050,9 +1100,6 @@ menuDialog = main
field = "Output pin", tachoPin
field = "Output speed", tachoDiv
dialog = canIO, "CanBus interface"
field = "Enable/Disable", canEnable
dialog = accelEnrichments_center, ""
field = "TPSdot Threshold", tpsThresh
field = "Accel Time", taeTime
@ -1401,7 +1448,7 @@ menuDialog = main
panel = outputtestspk4
dialog = outputtest1,"Test Output Hardware"
;topicHelp = ""
topicHelp = "http://speeduino.com/wiki/index.php/Hardware_testing_page"
panel = enableoutputtestbuttons
panel = outputtest_injectors
panel = outputtest_spark
@ -1469,13 +1516,86 @@ menuDialog = main
field = "Enable CanBus data input", enable_candata_in
dialog = Canin_config, "", border
topicHelp = "file://$getProjectsDirPath()/Docs/speeduino_canbus.txt"
topicHelp = "http://speeduino.com/wiki/index.php/Secondary_Serial_IO_interface#Read_external_analog_data"
panel = Canin_config2, North
panel = Canin_config1, South
dialog = Canout_config, "Can Data Out"
dialog = canoutput_sel, ""
;CAN outputs
field = "CAN Output Channel on/off"
field = "CAN Output 1", canoutput_sel1, { enable_candata_out}
field = "CAN Output 2", canoutput_sel2, { enable_candata_out }
field = "CAN Output 3", canoutput_sel3, { enable_candata_out }
field = "CAN Output 4", canoutput_sel4, { enable_candata_out }
field = "CAN Output 5", canoutput_sel5, { enable_candata_out }
field = "CAN Output 6", canoutput_sel6, { enable_candata_out }
field = "CAN Output 7", canoutput_sel7, { enable_candata_out }
field = "CAN Output 8", canoutput_sel8, { enable_candata_out }
dialog = canoutput_parameter_group, "", yAxis
field = "Output Parameter Group"
field = "", canoutput_param_group[0], { canoutput_sel1 && enable_candata_out }
field = "", canoutput_param_group[1], { canoutput_sel2 && enable_candata_out }
field = "", canoutput_param_group[2], { canoutput_sel3 && enable_candata_out }
field = "", canoutput_param_group[3], { canoutput_sel4 && enable_candata_out }
field = "", canoutput_param_group[4], { canoutput_sel5 && enable_candata_out }
field = "", canoutput_param_group[5], { canoutput_sel6 && enable_candata_out }
field = "", canoutput_param_group[6], { canoutput_sel7 && enable_candata_out }
field = "", canoutput_param_group[7], { canoutput_sel8 && enable_candata_out }
dialog = canoutput_parameter_start_byte, "", yAxis
field = "Output Parameter Start Byte"
field = "", canoutput_param_start_byte1, { canoutput_sel1 && enable_candata_out }
field = "", canoutput_param_start_byte2, { canoutput_sel2 && enable_candata_out }
field = "", canoutput_param_start_byte3, { canoutput_sel3 && enable_candata_out }
field = "", canoutput_param_start_byte4, { canoutput_sel4 && enable_candata_out }
field = "", canoutput_param_start_byte5, { canoutput_sel5 && enable_candata_out }
field = "", canoutput_param_start_byte6, { canoutput_sel6 && enable_candata_out }
field = "", canoutput_param_start_byte7, { canoutput_sel7 && enable_candata_out }
field = "", canoutput_param_start_byte8, { canoutput_sel8 && enable_candata_out }
dialog = canoutput_parameter_num_byte, "", yAxis
field = "Output Parameter Number of Bytes"
field = "", canoutput_param_num_bytes1, { canoutput_sel1 && enable_candata_out }
field = "", canoutput_param_num_bytes2, { canoutput_sel2 && enable_candata_out }
field = "", canoutput_param_num_bytes3, { canoutput_sel3 && enable_candata_out }
field = "", canoutput_param_num_bytes4, { canoutput_sel4 && enable_candata_out }
field = "", canoutput_param_num_bytes5, { canoutput_sel5 && enable_candata_out }
field = "", canoutput_param_num_bytes6, { canoutput_sel6 && enable_candata_out }
field = "", canoutput_param_num_bytes7, { canoutput_sel7 && enable_candata_out }
field = "", canoutput_param_num_bytes8, { canoutput_sel8 && enable_candata_out }
dialog = canoutconfig_blank1,""
field = ""
dialog = Canout_config1, "", xAxis
panel = canoutput_sel
panel = canoutconfig_blank1
panel = canoutput_parameter_group
panel = canoutconfig_blank1
panel = canoutput_parameter_start_byte
panel = canoutconfig_blank1
panel = canoutput_parameter_num_byte
dialog = Canout_config2, "CAN Data Out"
field = "Enable CanBus data Output", enable_candata_out
dialog = Canout_config, "", border
topicHelp = ""
panel = Canout_config2, North
panel = Canout_config1, South
dialog = can_serial3IO, "CanBus/Serial3 IO interface"
topicHelp = "http://speeduino.com/wiki/index.php/Secondary_Serial_IO_interface"
field = "Enable CanBus/Second Serial", enable_canbus
field = "Speeduino TsCanId", speeduino_tsCanId
field = "Realtime Data Base Can Address", realtime_base_address
field = "Speeduino OBD address", obd_address
dialog = serial3IO, "Serial3 IO interface"
topicHelp = "http://speeduino.com/wiki/index.php/Serial3_IO_interface"
field = "Enable Second Serial", enable_canbus
;-------------------------------------------------------------------------------
; General help text
@ -1631,6 +1751,14 @@ cmdtestspk450dc = "E\x03\x0C"
yBins = wueRates
gauge = cltGauge
; Warmup enrichment VEAL AFR adjustment curve (Not currently working)
;curve = warmup_afr_curve, "AFR Target Temperature Adustment"
; columnLabel = "Coolant Temp", "AFR Offset %"
; xAxis = -40, 210, 9
; yAxis = 0, 240, 6
; xBins = wueAFRBins, coolant
; yBins = wueAFRRates
[TableEditor]
; table_id, map3d_id, "title", page
@ -1958,7 +2086,7 @@ cmdtestspk450dc = "E\x03\x0C"
deadValue = { 0 } ; Convenient unchanging value.
ochGetCommand = "r\$tsCanId\x07%2o%2c"
ochGetCommand = "r\$tsCanId\x30%2o%2c"
ochBlockSize = 57
secl = scalar, U08, 0, "sec", 1.000, 0.000
@ -2145,6 +2273,7 @@ cmdtestspk450dc = "E\x03\x0C"
entry = flex, "Eth %", int, "%d", { flexEnabled }
entry = errorNum, "Error #", int, "%d"
entry = currentError, "Error ID", int, "%d"
entry = map_psi, "Boost PSI", float, "%.1f"
entry = boostTarget, "Boost Target",int, "%d", { boostEnabled }
entry = boostDuty, "Boost Duty", int, "%d", { boostEnabled }
entry = boostCutOut , "Boost cut", int, "%d"
@ -2204,3 +2333,19 @@ cmdtestspk450dc = "E\x03\x0C"
filter = aseFilter, "ASE Flag" , engine, & , 4, , false
filter = overrunFilter, "Overrun" , pulseWidth, = , 0, , false
filter = std_Custom ; Standard Custom Expression Filter.
;------------- WUE VEAL not currently working ----------------
;[WueAnalyze]
; tableName, lambdaTargetTableName, lambdaChannel, egoCorrectionChannel, activeCondition
; wueAnalyzeMap = veTable1Tbl, afrTable1Tbl, afr, egoCorrection
; wueAnalyzeMap = afrTable1Tbl, warmup_afr_curve, warmup_curve, afr, coolant, warmupEnrich ;warmup_afr_curve,
; lambdaTargetTables = afrTable1Tbl, afrTSCustom,
;filter = std_xAxisMin ; Auto build with appropriate axis channels
;filter = minRPMFilter, "Minimum RPM", rpm, < , 500, , true
;filter = std_xAxisMax ; Auto build with appropriate axis channels
;filter = std_yAxisMin ; Auto build with appropriate axis channels
;filter = std_yAxisMax ; Auto build with appropriate axis channels
;filter = std_DeadLambda ; Auto build
; filter = maxTPSFilter, "High Throttle", tps, < , 15, , true
;------------- WUE VEAL not currently working ----------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

View File

@ -3,7 +3,6 @@ Speeduino - Simple engine management for the Arduino Mega 2560 platform
Copyright (C) Josh Stewart
A full copy of the license may be found in the projects root directory
*/
//integerPID boostPID(&currentStatus.MAP, &boost_pwm_target_value, &boost_cl_target_boost, configPage3.boostKP, configPage3.boostKI, configPage3.boostKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
integerPID boostPID(&MAPx100, &boost_pwm_target_value, &boostTargetx100, configPage3.boostKP, configPage3.boostKI, configPage3.boostKD, DIRECT); //This is the PID object if that algorithm is used. Needs to be global as it maintains state outside of each function call
/*
@ -11,21 +10,21 @@ Fan control
*/
void initialiseFan()
{
if(configPage4.fanInv) { fanHIGH = LOW, fanLOW = HIGH; }
else { fanHIGH = HIGH, fanLOW = LOW; }
if( configPage4.fanInv == 1 ) { fanHIGH = LOW; fanLOW = HIGH; }
else { fanHIGH = HIGH; fanLOW = LOW; }
digitalWrite(pinFan, fanLOW); //Initiallise program with the fan in the off state
currentStatus.fanOn = false;
}
void fanControl()
{
if(configPage4.fanEnable)
if( configPage4.fanEnable == 1 )
{
int onTemp = (int)configPage4.fanSP - CALIBRATION_TEMPERATURE_OFFSET;
int offTemp = onTemp - configPage4.fanHyster;
if (!currentStatus.fanOn && currentStatus.coolant >= onTemp) { digitalWrite(pinFan,fanHIGH); currentStatus.fanOn = true; }
if (currentStatus.fanOn && currentStatus.coolant <= offTemp) { digitalWrite(pinFan, fanLOW); currentStatus.fanOn = false; }
if ( (!currentStatus.fanOn) && (currentStatus.coolant >= onTemp) ) { digitalWrite(pinFan,fanHIGH); currentStatus.fanOn = true; }
if ( (currentStatus.fanOn) && (currentStatus.coolant <= offTemp) ) { digitalWrite(pinFan, fanLOW); currentStatus.fanOn = false; }
}
}
@ -45,7 +44,7 @@ void initialiseAuxPWM()
boost_pwm_max_count = 1000000L / (16 * configPage3.boostFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle. The x2 is there because the frequency is stored at half value (in a byte) to allow freqneucies up to 511Hz
vvt_pwm_max_count = 1000000L / (16 * configPage3.vvtFreq * 2); //Converts the frequency in Hz to the number of ticks (at 16uS) it takes to complete 1 cycle
//TIMSK1 |= (1 << OCIE1A); //Turn on the A compare unit (ie turn on the interrupt) //Shouldn't be needed with closed loop as its turned on below
//TIMSK1 |= (1 << OCIE1A); <---- Not required as compare A is turned on when needed by boost control
TIMSK1 |= (1 << OCIE1B); //Turn on the B compare unit (ie turn on the interrupt)
boostPID.SetOutputLimits(percentage(configPage1.boostMinDuty, boost_pwm_max_count) , percentage(configPage1.boostMaxDuty, boost_pwm_max_count));
@ -58,21 +57,44 @@ void initialiseAuxPWM()
void boostControl()
{
if(configPage3.boostEnabled)
if( configPage3.boostEnabled==1 )
{
if(currentStatus.MAP < 100) { TIMSK1 &= ~(1 << OCIE1A); digitalWrite(pinBoost, LOW); return; } //Set duty to 0 and turn off timer compare
MAPx100 = currentStatus.MAP * 100;
if(currentStatus.MAP >= 100)
{
MAPx100 = currentStatus.MAP * 100;
boost_cl_target_boost = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM) * 2; //Boost target table is in kpa and divided by 2
boostTargetx100 = boost_cl_target_boost * 100;
currentStatus.boostTarget = boost_cl_target_boost >> 1; //Boost target is sent as a byte value to TS and so is divided by 2
if(currentStatus.boostTarget == 0) { TIMSK1 &= ~(1 << OCIE1A); digitalWrite(pinBoost, LOW); return; } //Set duty to 0 and turn off timer compare if the target is 0
boost_cl_target_boost = get3DTableValue(&boostTable, currentStatus.TPS, currentStatus.RPM) * 2; //Boost target table is in kpa and divided by 2
//If flex fuel is enabled, there can be an adder to the boost target based on ethanol content
if( configPage1.flexEnabled == 1 )
{
int16_t boostAdder = (((int16_t)configPage1.flexBoostHigh - (int16_t)configPage1.flexBoostLow) * currentStatus.ethanolPct) / 100;
boostAdder = boostAdder + configPage1.flexBoostLow; //Required in case flexBoostLow is less than 0
boost_cl_target_boost = boost_cl_target_boost + boostAdder;
}
if( (boostCounter & 31) == 1) { boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); } //This only needs to be run very infrequently, once every 32 calls to boostControl(). This is approx. once per second
boostTargetx100 = boost_cl_target_boost * 100;
currentStatus.boostTarget = boost_cl_target_boost >> 1; //Boost target is sent as a byte value to TS and so is divided by 2
if(currentStatus.boostTarget > 0)
{
if( (boostCounter & 31) == 1) { boostPID.SetTunings(configPage3.boostKP, configPage3.boostKI, configPage3.boostKD); } //This only needs to be run very infrequently, once every 32 calls to boostControl(). This is approx. once per second
boostPID.Compute();
currentStatus.boostDuty = (unsigned long)(boost_pwm_target_value * 100UL) / boost_pwm_max_count;
TIMSK1 |= (1 << OCIE1A); //Turn on the compare unit (ie turn on the interrupt)
boostPID.Compute();
currentStatus.boostDuty = (unsigned long)(boost_pwm_target_value * 100UL) / boost_pwm_max_count;
TIMSK1 |= (1 << OCIE1A); //Turn on the compare unit (ie turn on the interrupt)
}
else
{
//If boost target is 0, turn everything off
TIMSK1 &= ~(1 << OCIE1A); //Turn off timer
digitalWrite(pinBoost, LOW);
}
}
else
{
//Boost control does nothing if kPa below 100
TIMSK1 &= ~(1 << OCIE1A); //Turn off timer
digitalWrite(pinBoost, LOW); //Make sure solenoid is off (0% duty)
}
}
else { TIMSK1 &= ~(1 << OCIE1A); } // Disable timer channel
@ -81,7 +103,7 @@ void boostControl()
void vvtControl()
{
if(configPage3.vvtEnabled)
if( configPage3.vvtEnabled == 1 )
{
byte vvtDuty = get3DTableValue(&vvtTable, currentStatus.TPS, currentStatus.RPM);
vvt_pwm_target_value = percentage(vvtDuty, vvt_pwm_max_count);

View File

@ -3,17 +3,24 @@
//These are the page numbers that the Tuner Studio serial protocol uses to transverse the different map and config pages.
#define veMapPage 1
uint8_t currentcanCommand;
uint8_t currentCanPage = 1;//Not the same as the speeduino config page numbers
uint8_t nCanretry = 0; //no of retrys
uint8_t cancmdfail = 0; //command fail yes/no
uint8_t canlisten = 0;
uint8_t cancmdfail = 0; //command fail yes/no
uint8_t canlisten = 0;
uint8_t Lbuffer[8]; //8 byte buffer to store incomng can data
uint8_t Gdata[9];
uint8_t Glow, Ghigh;
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
HardwareSerial &CANSerial = Serial3;
#elif defined(CORE_STM32)
HardwareSerial &CANSerial = Serial2;
#elif defined(CORE_TEENSY)
HardwareSerial &CANSerial = Serial2;
#endif
void canCommand();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable.
void sendCancommand(uint8_t cmdtype , uint16_t canadddress, uint8_t candata1, uint8_t candata2, uint16_t paramgroup);
void testCanComm();
#endif // CANCOMMS_H

View File

@ -11,15 +11,11 @@ It parses the command and calls the relevant function
sendcancommand is called when a comman d is to be sent via serial3 to the Can interface
*/
//#include "cancomms.h"
//#include "globals.h"
//#include "storage.h"
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__)
void canCommand()
{
switch (Serial3.read())
currentcanCommand = CANSerial.read();
switch (currentcanCommand)
{
case 'A': // sends the bytes of realtime values
sendValues(0, packetSize,3); //send values to serial3
@ -27,14 +23,15 @@ void canCommand()
case 'G': // this is the reply command sent by the Can interface
//uint8_t Gdata;
while (Serial3.available() == 0) { }
cancmdfail = Serial3.read();
while (CANSerial.available() == 0) { }
cancmdfail = CANSerial.read();
if (cancmdfail != 0)
{
for (byte Gx = 0; Gx < 8; Gx++) //read all 8 bytes of data
{
while (Serial3.available() == 0) { }
Gdata[Gx] = Serial3.read();
while (CANSerial.available() == 0) { }
Gdata[Gx] = CANSerial.read();
}
Glow = Gdata[(configPage10.caninput_param_start_byte[currentStatus.current_caninchannel])];
@ -47,91 +44,125 @@ void canCommand()
}
else
{
Ghigh = 0;
Ghigh = 0;
}
currentStatus.canin[currentStatus.current_caninchannel] = word(Ghigh, Glow);
currentStatus.canin[currentStatus.current_caninchannel] = word(Ghigh, Glow);
}
else{} //continue as command request failed and/or data/device was not available
else{} //continue as command request failed and/or data/device was not available
if (currentStatus.current_caninchannel <= 6) // if channel is 0-7
{
currentStatus.current_caninchannel++; //inc to next channel
}
else
else
{
currentStatus.current_caninchannel = 0; //reset to start
}
}
break;
case 'L':
uint8_t Llength;
while (Serial3.available() == 0) { }
canlisten = Serial3.read();
while (CANSerial.available() == 0) { }
canlisten = CANSerial.read();
if (canlisten == 0)
{
//command request failed and/or data/device was not available
break;
}
while (Serial3.available() == 0) { }
Llength= Serial3.read(); // next the number of bytes expected value
while (CANSerial.available() == 0) { }
Llength= CANSerial.read(); // next the number of bytes expected value
for (uint8_t Lcount = 0; Lcount <Llength ;Lcount++)
{
while (Serial3.available() == 0){}
// receive all x bytes into "Lbuffer"
Lbuffer[Lcount] = Serial3.read();
}
break;
{
while (CANSerial.available() == 0){}
// receive all x bytes into "Lbuffer"
Lbuffer[Lcount] = CANSerial.read();
}
break;
case 'r': //New format for the optimised OutputChannels
byte cmd;
if (CANSerial.available() >= 6)
{
CANSerial.read(); //Read the $tsCanId
cmd = CANSerial.read();
uint16_t offset, length;
if(cmd == 0x30) //Send output channels command 0x30 is 48dec
{
byte tmp;
tmp = CANSerial.read();
offset = word(CANSerial.read(), tmp);
tmp = CANSerial.read();
length = word(CANSerial.read(), tmp);
sendValues(offset, length, 3);
}
else
{
//No other r/ commands should be called
}
}
break;
case 'S': // send code version
for (unsigned int sig = 0; sig < sizeof(displaySignature) - 1; sig++){
Serial3.write(displaySignature[sig]);
for (unsigned int sig = 0; sig < sizeof(displaySignature) - 1; sig++)
{
CANSerial.write(displaySignature[sig]);
}
//Serial3.print("speeduino 201609-dev");
break;
case 'Q': // send code version
for (unsigned int revn = 0; revn < sizeof( TSfirmwareVersion) - 1; revn++){
Serial3.write( TSfirmwareVersion[revn]);
for (unsigned int revn = 0; revn < sizeof( TSfirmwareVersion) - 1; revn++)
{
CANSerial.write( TSfirmwareVersion[revn]);
}
//Serial3.print("speeduino 201609-dev");
break;
case 'Z': //dev use
break;
default:
break;
}
}
// this routine sends a request(either "0" for a "G" or "1" for a "L" to the Can interface
// this routine sends a request(either "0" for a "G" , "1" for a "L" , "2" for a "R" to the Can interface or "3" sends the request via the actual local canbus
void sendCancommand(uint8_t cmdtype, uint16_t canaddress, uint8_t candata1, uint8_t candata2, uint16_t paramgroup)
{
switch (cmdtype)
{
case 0:
Serial3.print("G");
Serial3.write(canaddress); //tscanid of speeduino device
Serial3.write(candata1); // table id
Serial3.write(candata2); //table memory offset
break;
CANSerial.print("G");
CANSerial.write(canaddress); //tscanid of speeduino device
CANSerial.write(candata1); // table id
CANSerial.write(candata2); //table memory offset
break;
case 1: //send request to listen for a can message
Serial3.print("L");
Serial3.write(canaddress); //11 bit canaddress of device to listen for
break;
case 1: //send request to listen for a can message
CANSerial.print("L");
CANSerial.write(canaddress); //11 bit canaddress of device to listen for
break;
case 2:
Serial3.print("R");
Serial3.write( lowByte(paramgroup) ); //send lsb first
Serial3.write( lowByte(paramgroup >> 8) );
break;
CANSerial.print("R"); //send "R" to request data from the parmagroup whos value is sent next
CANSerial.write( lowByte(paramgroup) ); //send lsb first
CANSerial.write( lowByte(paramgroup >> 8) );
break;
case 3:
//send to truecan send routine
break;
default:
break;
}
}
#else
//Dummy functions for those that can't do Serial3
void canCommand() { return; }
void sendCancommand(uint8_t cmdtype, uint16_t canaddress, uint8_t candata1, uint8_t candata2, uint16_t paramgroup) { return; }
#endif

View File

@ -15,7 +15,7 @@
#define packetSize 57//41
byte currentPage = 1;//Not the same as the speeduino config page numbers
boolean isMap = true;
bool isMap = true;
unsigned long requestCount = 0; //The number of times the A command has been issued
byte currentCommand;
bool cmdPending = false;
@ -23,6 +23,7 @@ byte cmdGroup = 0;
byte cmdValue = 0;
int cmdCombined = 0; //the cmdgroup as high byte and cmdvalue as low byte
byte cmdStore[8]; //array storing pre test values
byte tsCanId = 0; // current tscanid requested
const char pageTitles[] PROGMEM //This is being stored in the avr flash instead of SRAM which there is not very much of
{

View File

@ -36,13 +36,15 @@ void command()
case 'E': // receive command button commands
cmdPending = true;
if(Serial.available() < 2) { return; }
cmdGroup = Serial.read();
cmdValue = Serial.read();
cmdCombined = word(cmdGroup, cmdValue);
if (currentStatus.RPM == 0) { commandButtons(); }
if(Serial.available() >= 2)
{
cmdGroup = Serial.read();
cmdValue = Serial.read();
cmdCombined = word(cmdGroup, cmdValue);
if (currentStatus.RPM == 0) { commandButtons(); }
cmdPending = false;
cmdPending = false;
}
break;
case 'L': // List the contents of current page in human readable form
@ -57,18 +59,20 @@ void command()
//A 2nd byte of data is required after the 'P' specifying the new page number.
cmdPending = true;
if (Serial.available() == 0) { return; }
currentPage = Serial.read();
if (currentPage >= '0') {//This converts the ascii number char into binary
currentPage -= '0';
if (Serial.available() > 0)
{
currentPage = Serial.read();
if (currentPage >= '0') {//This converts the ascii number char into binary
currentPage -= '0';
}
if ( (currentPage == veMapPage) || (currentPage == ignMapPage) || (currentPage == afrMapPage) ) { // Detecting if the current page is a table/map
isMap = true;
}
else {
isMap = false;
}
cmdPending = false;
}
if (currentPage == veMapPage || currentPage == ignMapPage || currentPage == afrMapPage) { // Detecting if the current page is a table/map
isMap = true;
}
else {
isMap = false;
}
cmdPending = false;
break;
case 'F': // send serial protocol version
@ -76,12 +80,12 @@ void command()
break;
case 'S': // send code version
Serial.print("Speeduino 2017.04");
Serial.print("Speeduino 2017.06-dev");
currentStatus.secl = 0; //This is required in TS3 due to its stricter timings
break;
case 'Q': // send code version
Serial.print("speeduino 201704");
Serial.print("speeduino 201706-dev");
break;
case 'V': // send VE table and constants in binary
@ -90,24 +94,31 @@ void command()
case 'W': // receive new VE obr constant at 'W'+<offset>+<newbyte>
cmdPending = true;
int valueOffset; //cannot use offset as a variable name, it is a reserved word for several teensy libraries
if (isMap)
{
if(Serial.available()< 3) { return; } // 1 additional byte is required on the MAP pages which are larger than 255 bytes
byte offset1, offset2;
offset1 = Serial.read();
offset2 = Serial.read();
valueOffset = word(offset2, offset1);
if(Serial.available() >= 3) // 1 additional byte is required on the MAP pages which are larger than 255 bytes
{
byte offset1, offset2;
offset1 = Serial.read();
offset2 = Serial.read();
valueOffset = word(offset2, offset1);
receiveValue(valueOffset, Serial.read());
cmdPending = false;
}
}
else
{
if(Serial.available()< 2) { return; }
valueOffset = Serial.read();
if(Serial.available() >= 2)
{
valueOffset = Serial.read();
receiveValue(valueOffset, Serial.read());
cmdPending = false;
}
}
receiveValue(valueOffset, Serial.read());
cmdPending = false;
break;
case 't': // receive new Calibration info. Command structure: "t", <tble_idx> <data array>. This is an MS2/Extra command, NOT part of MS1 spec
@ -124,12 +135,6 @@ void command()
break;
case 'Z': //Totally non-standard testing function. Will be removed once calibration testing is completed. This function takes 1.5kb of program space! :S
digitalWrite(pinInjector1, HIGH);
digitalWrite(pinInjector2, HIGH);
delay(20);
digitalWrite(pinInjector1, LOW);
digitalWrite(pinInjector2, LOW);
return;
Serial.println(F("Coolant"));
for (int x = 0; x < CALIBRATION_TABLE_SIZE; x++)
{
@ -172,25 +177,27 @@ void command()
case 'r': //New format for the optimised OutputChannels
cmdPending = true;
byte cmd;
if (Serial.available() < 6) { return; }
Serial.read(); //Read the $tsCanId
cmd = Serial.read();
if (Serial.available() >= 6)
{
tsCanId = Serial.read(); //Read the $tsCanId
cmd = Serial.read(); // read the command
uint16_t offset, length;
if(cmd == 0x07) //Send output channels command
{
byte tmp;
tmp = Serial.read();
offset = word(Serial.read(), tmp);
tmp = Serial.read();
length = word(Serial.read(), tmp);
sendValues(offset, length, 0);
uint16_t offset, length;
if(cmd == 0x30) //Send output channels command 0x30 is 48dec
{
byte tmp;
tmp = Serial.read();
offset = word(Serial.read(), tmp);
tmp = Serial.read();
length = word(Serial.read(), tmp);
sendValues(offset, length, 0);
}
else
{
//No other r/ commands should be called
}
cmdPending = false;
}
else
{
//No other r/ commands should be called
}
cmdPending = false;
break;
@ -240,16 +247,29 @@ This function returns the current values of a fixed group of variables
void sendValues(uint16_t offset, uint16_t packetLength, byte portNum)
{
byte fullStatus[packetSize];
byte response[packetLength];
if (portNum == 3)
{
//CAN serial
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
Serial3.write("A"); //confirm cmd type
if (offset == 0)
{
Serial3.write("A"); //confirm cmd type
}
else
{
Serial3.write("r"); //confirm cmd type
}
Serial3.write(packetLength); //confirm no of byte to be sent
#elif defined(CORE_STM32)
Serial2.write("A"); //confirm cmd type
#elif defined(CORE_STM32) || defined (CORE_TEENSY)
if (offset == 0)
{
Serial2.write("A"); //confirm cmd type
}
else
{
Serial2.write("r"); //confirm cmd type
}
Serial2.write(packetLength); //confirm no of byte to be sent
#endif
}
@ -329,18 +349,10 @@ void sendValues(uint16_t offset, uint16_t packetLength, byte portNum)
for(byte x=0; x<packetLength; x++)
{
response[x] = fullStatus[offset+x];
if (portNum == 0) { Serial.write(fullStatus[offset+x]); }
else if (portNum == 3) { CANSerial.write(fullStatus[offset+x]); }
}
//cli();
if (portNum == 0) { Serial.write(response, (size_t)packetLength); }
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
else if (portNum == 3) { Serial3.write(response, (size_t)packetLength); }
#elif defined(CORE_STM32)
else if (portNum == 3) { Serial2.write(response, (size_t)packetLength); }
#endif
//sei();
return;
}
void receiveValue(int valueOffset, byte newValue)
@ -353,8 +365,7 @@ void receiveValue(int valueOffset, byte newValue)
case veMapPage:
if (valueOffset < 256) //New value is part of the fuel map
{
fuelTable.values[15 - valueOffset / 16][valueOffset % 16] = newValue;
return;
fuelTable.values[15 - (valueOffset / 16)][valueOffset % 16] = newValue;
}
else
{
@ -367,10 +378,9 @@ void receiveValue(int valueOffset, byte newValue)
else
{
//Y Axis
valueOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order (Due to us using (0,0) in the top left rather than bottom right
fuelTable.axisY[valueOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
int tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order (Due to us using (0,0) in the top left rather than bottom right
fuelTable.axisY[tempOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
}
return;
}
break;
@ -386,8 +396,7 @@ void receiveValue(int valueOffset, byte newValue)
case ignMapPage: //Ignition settings page (Page 2)
if (valueOffset < 256) //New value is part of the ignition map
{
ignitionTable.values[15 - valueOffset / 16][valueOffset % 16] = newValue;
return;
ignitionTable.values[15 - (valueOffset / 16)][valueOffset % 16] = newValue;
}
else
{
@ -400,11 +409,11 @@ void receiveValue(int valueOffset, byte newValue)
else
{
//Y Axis
valueOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
ignitionTable.axisY[valueOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
int tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
ignitionTable.axisY[tempOffset] = (int)(newValue) * TABLE_LOAD_MULTIPLIER;
}
return;
}
break;
case ignSetPage:
pnt_configPage = &configPage2;
@ -418,8 +427,7 @@ void receiveValue(int valueOffset, byte newValue)
case afrMapPage: //Air/Fuel ratio target settings page
if (valueOffset < 256) //New value is part of the afr map
{
afrTable.values[15 - valueOffset / 16][valueOffset % 16] = newValue;
return;
afrTable.values[15 - (valueOffset / 16)][valueOffset % 16] = newValue;
}
else
{
@ -432,12 +440,12 @@ void receiveValue(int valueOffset, byte newValue)
else
{
//Y Axis
valueOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
afrTable.axisY[valueOffset] = int(newValue) * TABLE_LOAD_MULTIPLIER;
int tempOffset = 15 - (valueOffset - 272); //Need to do a translation to flip the order
afrTable.axisY[tempOffset] = int(newValue) * TABLE_LOAD_MULTIPLIER;
}
return;
}
break;
case afrSetPage:
pnt_configPage = &configPage3;
@ -456,57 +464,56 @@ void receiveValue(int valueOffset, byte newValue)
*((byte *)pnt_configPage + (byte)valueOffset) = newValue;
}
break;
case boostvvtPage: //Boost and VVT maps (8x8)
if (valueOffset < 64) //New value is part of the boost map
{
boostTable.values[7 - valueOffset / 8][valueOffset % 8] = newValue;
return;
boostTable.values[7 - (valueOffset / 8)][valueOffset % 8] = newValue;
}
else if (valueOffset < 72) //New value is on the X (RPM) axis of the boost table
{
boostTable.axisX[(valueOffset - 64)] = int(newValue) * TABLE_RPM_MULTIPLIER; //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
return;
}
else if (valueOffset < 80) //New value is on the Y (TPS) axis of the boost table
{
boostTable.axisY[(7 - (valueOffset - 72))] = int(newValue); //TABLE_LOAD_MULTIPLIER is NOT used for boost as it is TPS based (0-100)
return;
}
else if (valueOffset < 144) //New value is part of the vvt map
{
valueOffset = valueOffset - 80;
vvtTable.values[7 - valueOffset / 8][valueOffset % 8] = newValue;
return;
int tempOffset = valueOffset - 80;
vvtTable.values[7 - (tempOffset / 8)][tempOffset % 8] = newValue;
}
else if (valueOffset < 152) //New value is on the X (RPM) axis of the vvt table
{
valueOffset = valueOffset - 144;
vvtTable.axisX[valueOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
return;
int tempOffset = valueOffset - 144;
vvtTable.axisX[tempOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
}
else //New value is on the Y (Load) axis of the vvt table
{
valueOffset = valueOffset - 152;
vvtTable.axisY[(7 - valueOffset)] = int(newValue); //TABLE_LOAD_MULTIPLIER is NOT used for vvt as it is TPS based (0-100)
return;
int tempOffset = valueOffset - 152;
vvtTable.axisY[(7 - tempOffset)] = int(newValue); //TABLE_LOAD_MULTIPLIER is NOT used for vvt as it is TPS based (0-100)
}
case seqFuelPage:
if (valueOffset < 36) { trim1Table.values[5 - valueOffset / 6][valueOffset % 6] = newValue; } //Trim1 values
else if (valueOffset < 42) { trim1Table.axisX[(valueOffset - 36)] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the trim1 table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 48) { trim1Table.axisY[(5 - (valueOffset - 42))] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (TPS) axis of the boost table
//Trim table 2
else if (valueOffset < 84) { valueOffset = valueOffset - 48; trim2Table.values[5 - valueOffset / 6][valueOffset % 6] = newValue; } //New value is part of the trim2 map
else if (valueOffset < 90) { valueOffset = valueOffset - 84; trim2Table.axisX[valueOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 96) { valueOffset = valueOffset - 90; trim2Table.axisY[(5 - valueOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
//Trim table 3
else if (valueOffset < 132) { valueOffset = valueOffset - 96; trim3Table.values[5 - valueOffset / 6][valueOffset % 6] = newValue; } //New value is part of the trim2 map
else if (valueOffset < 138) { valueOffset = valueOffset - 132; trim3Table.axisX[valueOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 144) { valueOffset = valueOffset - 138; trim3Table.axisY[(5 - valueOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
//Trim table 4
else if (valueOffset < 180) { valueOffset = valueOffset - 144; trim4Table.values[5 - valueOffset / 6][valueOffset % 6] = newValue; } //New value is part of the trim2 map
else if (valueOffset < 186) { valueOffset = valueOffset - 180; trim4Table.axisX[valueOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. //The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 192) { valueOffset = valueOffset - 186; trim4Table.axisY[(5 - valueOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
break;
case seqFuelPage:
{
int tempOffset;
if (valueOffset < 36) { trim1Table.values[5 - (valueOffset / 6)][valueOffset % 6] = newValue; } //Trim1 values
else if (valueOffset < 42) { trim1Table.axisX[(valueOffset - 36)] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the trim1 table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 48) { trim1Table.axisY[(5 - (valueOffset - 42))] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (TPS) axis of the boost table
//Trim table 2
else if (valueOffset < 84) { tempOffset = valueOffset - 48; trim2Table.values[5 - (tempOffset / 6)][tempOffset % 6] = newValue; } //New value is part of the trim2 map
else if (valueOffset < 90) { tempOffset = valueOffset - 84; trim2Table.axisX[tempOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 96) { tempOffset = valueOffset - 90; trim2Table.axisY[(5 - tempOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
//Trim table 3
else if (valueOffset < 132) { tempOffset = valueOffset - 96; trim3Table.values[5 - (tempOffset / 6)][tempOffset % 6] = newValue; } //New value is part of the trim2 map
else if (valueOffset < 138) { tempOffset = valueOffset - 132; trim3Table.axisX[tempOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 144) { tempOffset = valueOffset - 138; trim3Table.axisY[(5 - tempOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
//Trim table 4
else if (valueOffset < 180) { tempOffset = valueOffset - 144; trim4Table.values[5 - (tempOffset / 6)][tempOffset % 6] = newValue; } //New value is part of the trim2 map
else if (valueOffset < 186) { tempOffset = valueOffset - 180; trim4Table.axisX[tempOffset] = int(newValue) * TABLE_RPM_MULTIPLIER; } //New value is on the X (RPM) axis of the table. The RPM values sent by TunerStudio are divided by 100, need to multiply it back by 100 to make it correct (TABLE_RPM_MULTIPLIER)
else if (valueOffset < 192) { tempOffset = valueOffset - 186; trim4Table.axisY[(5 - tempOffset)] = int(newValue) * TABLE_LOAD_MULTIPLIER; } //New value is on the Y (Load) axis of the table
}
break;
case canbusPage:
@ -534,6 +541,7 @@ void sendPage(bool useChar)
void* pnt_configPage;
struct table3D currentTable;
byte currentTitleIndex = 0;// This corresponds to the count up to the first char of a string in pageTitles
bool sendComplete = false; //Used to track whether all send operations are complete
switch (currentPage)
{
@ -549,12 +557,13 @@ void sendPage(bool useChar)
// currentTitleIndex = 27;
if (useChar)
{
uint16_t* pnt16_configPage;
// To Display Values from Config Page 1
// When casting to the __FlashStringHelper type Serial.println uses the same subroutine as when using the F macro
Serial.println((const __FlashStringHelper *)&pageTitles[27]);//27 is the index to the first char in the second sting in pageTitles
// The following loop displays in human readable form of all byte values in config page 1 up to but not including the first array.
// incrementing void pointers is cumbersome. Thus we have "pnt_configPage = (byte *)pnt_configPage + 1"
for (pnt_configPage = &configPage1; pnt_configPage < &configPage1.wueValues[0]; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
for (pnt_configPage = &configPage1; pnt_configPage < &configPage1.wueValues[0]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
for (byte x = 10; x; x--)// The x between the ';' has the same representation as the "x != 0" test or comparision
{
Serial.print(configPage1.wueValues[10 - x]);// This displays the values horizantially on the screen
@ -565,15 +574,16 @@ void sendPage(bool useChar)
Serial.println(*((byte *)pnt_configPage));// This displays all the byte values between the last array up to but not including the first unsigned int on config page 1
}
// The following loop displays four unsigned ints
for (pnt_configPage = &configPage1.inj1Ang; pnt_configPage < (unsigned int *)&configPage1.inj4Ang + 1; pnt_configPage = (unsigned int *)pnt_configPage + 1) Serial.println(*((unsigned int *)pnt_configPage));
for (pnt16_configPage = (uint16_t *)&configPage1.inj1Ang; pnt16_configPage < (uint16_t*)&configPage1.inj4Ang + 1; pnt16_configPage = (uint16_t*)pnt16_configPage + 1)
{ Serial.println(*((uint16_t *)pnt16_configPage)); }
// Following loop displays byte values between the unsigned ints
for (pnt_configPage = (unsigned int *)&configPage1.inj4Ang + 1; pnt_configPage < &configPage1.mapMax; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
for (pnt_configPage = (uint16_t *)&configPage1.inj4Ang + 1; pnt_configPage < &configPage1.mapMax; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
Serial.println(configPage1.mapMax);
// Following loop displays remaining byte values of the page
for (pnt_configPage = (unsigned int *)&configPage1.mapMax + 1; pnt_configPage < (byte *)&configPage1 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
return;
for (pnt_configPage = (uint16_t *)&configPage1.mapMax + 1; pnt_configPage < (byte *)&configPage1 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
sendComplete = true;
}
else pnt_configPage = &configPage1; //Create a pointer to Page 1 in memory
else { pnt_configPage = &configPage1; } //Create a pointer to Page 1 in memory
break;
}
@ -593,7 +603,7 @@ void sendPage(bool useChar)
Serial.println((const __FlashStringHelper *)&pageTitles[56]);
Serial.println(configPage2.triggerAngle);// configPsge2.triggerAngle is an int so just display it without complication
// Following loop displays byte values after that first int up to but not including the first array in config page 2
for (pnt_configPage = (int *)&configPage2 + 1; pnt_configPage < &configPage2.taeBins[0]; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
for (pnt_configPage = (int *)&configPage2 + 1; pnt_configPage < &configPage2.taeBins[0]; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
for (byte y = 2; y; y--)// Displaying two equal sized arrays
{
byte * currentVar;// A placeholder for each array
@ -604,9 +614,9 @@ void sendPage(bool useChar)
currentVar = configPage2.taeValues;
}
for (byte x = 4; x; x--)
for (byte j = 4; j; j--)
{
Serial.print(currentVar[4 - x]);
Serial.print(currentVar[4 - j]);
Serial.print(' ');
}
Serial.println();
@ -628,9 +638,9 @@ void sendPage(bool useChar)
{
Serial.println(*((byte *)pnt_configPage));// Displaying remaining byte values of the page
}
return;
sendComplete = true;
}
else pnt_configPage = &configPage2; //Create a pointer to Page 2 in memory
else { pnt_configPage = &configPage2; } //Create a pointer to Page 2 in memory
break;
}
@ -668,8 +678,9 @@ void sendPage(bool useChar)
for (byte y = 2; y; y--)// and again
{
byte* currentVar;
if (y == 2) currentVar = configPage3.airDenBins;
else currentVar = configPage3.airDenRates;
if (y == 2) { currentVar = configPage3.airDenBins; }
else { currentVar = configPage3.airDenRates; }
for (byte x = 9; x; x--)
{
Serial.print(currentVar[9 - x]);
@ -682,9 +693,9 @@ void sendPage(bool useChar)
{
Serial.println(*((byte *)pnt_configPage));
}
return;
sendComplete = true;
}
else pnt_configPage = &configPage3; //Create a pointer to Page 3 in memory
else { pnt_configPage = &configPage3; } //Create a pointer to Page 3 in memory
break;
}
@ -731,10 +742,10 @@ void sendPage(bool useChar)
Serial.println();
}
// Following loop is for remaining byte value of page
for (pnt_configPage = (byte *)&configPage4.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage4 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) Serial.println(*((byte *)pnt_configPage));
return;
for (pnt_configPage = (byte *)&configPage4.iacCrankBins[3] + 1; pnt_configPage < (byte *)&configPage4 + page_size; pnt_configPage = (byte *)pnt_configPage + 1) { Serial.println(*((byte *)pnt_configPage)); }
sendComplete = true;
}
else pnt_configPage = &configPage4; //Create a pointer to Page 4 in memory
else { pnt_configPage = &configPage4; } //Create a pointer to Page 4 in memory
break;
}
@ -751,15 +762,15 @@ void sendPage(bool useChar)
byte response[160]; //Bit hacky, but the size is: (8x8 + 8 + 8) + (8x8 + 8 + 8) = 160
//Boost table
for (int x = 0; x < 64; x++) { response[x] = boostTable.values[7 - x / 8][x % 8]; }
for (int x = 0; x < 64; x++) { response[x] = boostTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x] = byte(boostTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y] = byte(boostTable.axisY[7 - (y - 72)]); }
//VVT table
for (int x = 0; x < 64; x++) { response[x + 80] = vvtTable.values[7 - x / 8][x % 8]; }
for (int x = 0; x < 64; x++) { response[x + 80] = vvtTable.values[7 - (x / 8)][x % 8]; }
for (int x = 64; x < 72; x++) { response[x + 80] = byte(vvtTable.axisX[(x - 64)] / TABLE_RPM_MULTIPLIER); }
for (int y = 72; y < 80; y++) { response[y + 80] = byte(vvtTable.axisY[7 - (y - 72)]); }
Serial.write((byte *)&response, sizeof(response));
return;
sendComplete = true;
}
break;
}
@ -797,7 +808,7 @@ void sendPage(bool useChar)
}
Serial.println("");
}
return;
sendComplete = true;
//Do.... Something?
}
else
@ -806,23 +817,23 @@ void sendPage(bool useChar)
byte response[192]; //Bit hacky, but the size is: (6x6 + 6 + 6) * 4 = 192
//trim1 table
for (int x = 0; x < 36; x++) { response[x] = trim1Table.values[5 - x / 6][x % 6]; }
for (int x = 0; x < 36; x++) { response[x] = trim1Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x] = byte(trim1Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y] = byte(trim1Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim2 table
for (int x = 0; x < 36; x++) { response[x + 48] = trim2Table.values[5 - x / 6][x % 6]; }
for (int x = 0; x < 36; x++) { response[x + 48] = trim2Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 48] = byte(trim2Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 48] = byte(trim2Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim3 table
for (int x = 0; x < 36; x++) { response[x + 96] = trim3Table.values[5 - x / 6][x % 6]; }
for (int x = 0; x < 36; x++) { response[x + 96] = trim3Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 96] = byte(trim3Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 96] = byte(trim3Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
//trim4 table
for (int x = 0; x < 36; x++) { response[x + 144] = trim4Table.values[5 - x / 6][x % 6]; }
for (int x = 0; x < 36; x++) { response[x + 144] = trim4Table.values[5 - (x / 6)][x % 6]; }
for (int x = 36; x < 42; x++) { response[x + 144] = byte(trim4Table.axisX[(x - 36)] / TABLE_RPM_MULTIPLIER); }
for (int y = 42; y < 48; y++) { response[y + 144] = byte(trim4Table.axisY[5 - (y - 42)] / TABLE_LOAD_MULTIPLIER); }
Serial.write((byte *)&response, sizeof(response));
return;
sendComplete = true;
}
break;
}
@ -838,126 +849,129 @@ void sendPage(bool useChar)
{
Serial.println(*((byte *)pnt_configPage));// Displaying byte values of config page 3 up to but not including the first array
}
return;
sendComplete = true;
}
else pnt_configPage = &configPage10; //Create a pointer to Page 10 in memory
else { pnt_configPage = &configPage10; } //Create a pointer to Page 10 in memory
break;
}
default:
{
Serial.println(F("\nPage has not been implemented yet. Change to another page."));
return;
sendComplete = true;
break;
}
}
if (isMap)
if(!sendComplete)
{
if (useChar)
if (isMap)
{
do //This is a do while loop that kicks in for the boostvvtPage
if (useChar)
{
const char spaceChar = ' ';
/*while(pageTitles[currentTitleIndex])
do //This is a do while loop that kicks in for the boostvvtPage
{
Serial.print(pageTitles[currentTitleIndex]);
currentTitleIndex++;
}*/
Serial.println((const __FlashStringHelper *)&pageTitles[currentTitleIndex]);// F macro hack
Serial.println();
for (int y = 0; y < currentTable.ySize; y++)
{
byte axisY = byte(currentTable.axisY[y]);
if (axisY < 100)
const char spaceChar = ' ';
/*while(pageTitles[currentTitleIndex])
{
Serial.write(spaceChar);
if (axisY < 10)
Serial.print(pageTitles[currentTitleIndex]);
currentTitleIndex++;
}*/
Serial.println((const __FlashStringHelper *)&pageTitles[currentTitleIndex]);// F macro hack
Serial.println();
for (int y = 0; y < currentTable.ySize; y++)
{
byte axisY = byte(currentTable.axisY[y]);
if (axisY < 100)
{
Serial.write(spaceChar);
}
}
Serial.print(axisY);// Vertical Bins
Serial.write(spaceChar);
for (int x = 0; x < currentTable.xSize; x++)
{
byte value = currentTable.values[y][x];
if (value < 100)
{
Serial.write(spaceChar);
if (value < 10)
if (axisY < 10)
{
Serial.write(spaceChar);
}
}
Serial.print(value);
Serial.print(axisY);// Vertical Bins
Serial.write(spaceChar);
for (int i = 0; i < currentTable.xSize; i++)
{
byte value = currentTable.values[y][i];
if (value < 100)
{
Serial.write(spaceChar);
if (value < 10)
{
Serial.write(spaceChar);
}
}
Serial.print(value);
Serial.write(spaceChar);
}
Serial.println();
}
Serial.print(F(" "));
for (int x = 0; x < currentTable.xSize; x++)// Horizontal bins
{
byte axisX = byte(currentTable.axisX[x] / 100);
if (axisX < 100)
{
Serial.write(spaceChar);
if (axisX < 10)
{
Serial.write(spaceChar);
}
}
Serial.print(axisX);
Serial.write(spaceChar);
}
Serial.println();
}
Serial.print(F(" "));
for (int x = 0; x < currentTable.xSize; x++)// Horizontal bins
{
byte axisX = byte(currentTable.axisX[x] / 100);
if (axisX < 100)
if(currentTitleIndex == 121) //Check to see if on boostTable
{
Serial.write(spaceChar);
if (axisX < 10)
{
Serial.write(spaceChar);
}
currentTitleIndex = 132; //Change over to vvtTable mid display
currentTable = vvtTable;
}
Serial.print(axisX);
Serial.write(spaceChar);
}
Serial.println();
if(currentTitleIndex == 121) //Check to see if on boostTable
{
currentTitleIndex = 132; //Change over to vvtTable mid display
currentTable = vvtTable;
}
else currentTitleIndex = 0;
}while(currentTitleIndex == 132); //Should never loop unless going to display vvtTable
else currentTitleIndex = 0;
}while(currentTitleIndex == 132); //Should never loop unless going to display vvtTable
}
else
{
//Need to perform a translation of the values[yaxis][xaxis] into the MS expected format
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
byte response[MAP_PAGE_SIZE];
for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - (x / 16)][x % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
//loop();
for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
//loop();
for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
//loop();
Serial.write((byte *)&response, sizeof(response));
}
}
else
{
//Need to perform a translation of the values[yaxis][xaxis] into the MS expected format
//MS format has origin (0,0) in the bottom left corner, we use the top left for efficiency reasons
byte response[map_page_size];
/*if(useChar)
{
while(pageTitles[currentTitleIndex])
{
Serial.print(pageTitles[currentTitleIndex]);
currentTitleIndex++;
}
Serial.println();
for(byte x=0;x<page_size;x++) Serial.println(*((byte *)pnt_configPage + x));
}
else
{*/
//All other bytes can simply be copied from the config table
//byte response[npage_size[currentPage]];
for (byte x = 0; x < npage_size[currentPage]; x++)
{
//response[x] = *((byte *)pnt_configPage + x);
Serial.write(*((byte *)pnt_configPage + x)); //Each byte is simply the location in memory of the configPage + the offset + the variable number (x)
}
for (int x = 0; x < 256; x++) { response[x] = currentTable.values[15 - x / 16][x % 16]; } //This is slightly non-intuitive, but essentially just flips the table vertically (IE top line becomes the bottom line etc). Columns are unchanged. Every 16 loops, manually call loop() to avoid potential misses
//loop();
for (int x = 256; x < 272; x++) { response[x] = byte(currentTable.axisX[(x - 256)] / TABLE_RPM_MULTIPLIER); } //RPM Bins for VE table (Need to be dvidied by 100)
//loop();
for (int y = 272; y < 288; y++) { response[y] = byte(currentTable.axisY[15 - (y - 272)] / TABLE_LOAD_MULTIPLIER); } //MAP or TPS bins for VE table
//loop();
Serial.write((byte *)&response, sizeof(response));
}
}
else
{
/*if(useChar)
{
while(pageTitles[currentTitleIndex])
{
Serial.print(pageTitles[currentTitleIndex]);
currentTitleIndex++;
}
Serial.println();
for(byte x=0;x<page_size;x++) Serial.println(*((byte *)pnt_configPage + x));
}
else
{*/
//All other bytes can simply be copied from the config table
byte response[npage_size[currentPage]];
for (byte x = 0; x < npage_size[currentPage]; x++)
{
response[x] = *((byte *)pnt_configPage + x); //Each byte is simply the location in memory of the configPage + the offset + the variable number (x)
}
Serial.write((byte *)&response, npage_size[currentPage]);
// }
}
return;
//Serial.write((byte *)&response, npage_size[currentPage]);
// }
} //isMap
} //sendComplete
}
/*
@ -996,9 +1010,7 @@ void receiveCalibration(byte tableID)
break;
default:
return; //Should never get here, but if we do, just fail back to main loop
//pnt_TargetTable = (table2D *)&o2CalibrationTable;
//break;
break; //Should never get here, but if we do, just fail back to main loop
}
//1024 value pairs are sent. We have to receive them all, but only use every second one (We only store 512 calibratino table entries to save on EEPROM space)
@ -1069,33 +1081,33 @@ Send 256 tooth log entries
void sendToothLog(bool useChar)
{
//We need TOOTH_LOG_SIZE number of records to send to TunerStudio. If there aren't that many in the buffer then we just return and wait for the next call
if (toothHistoryIndex < TOOTH_LOG_SIZE) {
return; //This should no longer ever occur since the flagging system was put in place
}
unsigned int tempToothHistory[TOOTH_LOG_BUFFER]; //Create a temporary array that will contain a copy of what is in the main toothHistory array
//Copy the working history into the temporary buffer array. This is done so that, if the history loops whilst the values are being sent over serial, it doesn't affect the values
memcpy( (void*)tempToothHistory, (void*)toothHistory, sizeof(tempToothHistory) );
toothHistoryIndex = 0; //Reset the history index
//Loop only needs to go to half the buffer size
if (useChar)
if (toothHistoryIndex >= TOOTH_LOG_SIZE) //Sanity check. Flagging system means this should always be true
{
for (int x = 0; x < TOOTH_LOG_SIZE; x++)
unsigned int tempToothHistory[TOOTH_LOG_BUFFER]; //Create a temporary array that will contain a copy of what is in the main toothHistory array
//Copy the working history into the temporary buffer array. This is done so that, if the history loops whilst the values are being sent over serial, it doesn't affect the values
memcpy( (void*)tempToothHistory, (void*)toothHistory, sizeof(tempToothHistory) );
toothHistoryIndex = 0; //Reset the history index
//Loop only needs to go to half the buffer size
if (useChar)
{
Serial.println(tempToothHistory[x]);
for (int x = 0; x < TOOTH_LOG_SIZE; x++)
{
Serial.println(tempToothHistory[x]);
}
}
}
else
{
for (int x = 0; x < TOOTH_LOG_SIZE; x++)
else
{
Serial.write(highByte(tempToothHistory[x]));
Serial.write(lowByte(tempToothHistory[x]));
for (int x = 0; x < TOOTH_LOG_SIZE; x++)
{
Serial.write(highByte(tempToothHistory[x]));
Serial.write(lowByte(tempToothHistory[x]));
}
BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY);
}
BIT_CLEAR(currentStatus.squirt, BIT_SQUIRT_TOOTHLOG1READY);
toothLogRead = true;
}
toothLogRead = true;
}
void testComm()
@ -1125,10 +1137,10 @@ void commandButtons()
BIT_SET(currentStatus.testOutputs, 1);
break;
case 513: // cmd group is for injector1 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector1, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ digitalWrite(pinInjector1, HIGH); }
break;
case 514: // cmd group is for injector1 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector1, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ){digitalWrite(pinInjector1, LOW);}
break;
case 515: // cmd group is for injector1 50% dc actions
//for (byte dcloop = 0; dcloop < 11; dcloop++)
@ -1140,67 +1152,68 @@ void commandButtons()
//}
break;
case 516: // cmd group is for injector2 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector2, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ digitalWrite(pinInjector2, HIGH); }
break;
case 517: // cmd group is for injector2 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector2, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ digitalWrite(pinInjector2, LOW); }
break;
case 518: // cmd group is for injector2 50%dc actions
break;
case 519: // cmd group is for injector3 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector3, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinInjector3, HIGH); }
break;
case 520: // cmd group is for injector3 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector3, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinInjector3, LOW); }
break;
case 521: // cmd group is for injector3 50%dc actions
break;
case 522: // cmd group is for injector4 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector4, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ digitalWrite(pinInjector4, HIGH); }
break;
case 523: // cmd group is for injector4 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinInjector4, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ){ digitalWrite(pinInjector4, LOW); }
break;
case 524: // cmd group is for injector4 50% dc actions
break;
case 769: // cmd group is for spark1 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil1, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil1, HIGH); }
break;
case 770: // cmd group is for spark1 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil1, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil1, LOW); }
break;
case 771: // cmd group is for spark1 50%dc actions
break;
case 772: // cmd group is for spark2 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil2, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil2, HIGH); }
break;
case 773: // cmd group is for spark2 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil2, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil2, LOW); }
break;
case 774: // cmd group is for spark2 50%dc actions
break;
case 775: // cmd group is for spark3 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil3, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil3, HIGH); }
break;
case 776: // cmd group is for spark3 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil3, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil3, LOW); }
break;
case 777: // cmd group is for spark3 50%dc actions
break;
case 778: // cmd group is for spark4 on actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil4, HIGH);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil4, HIGH); }
break;
case 779: // cmd group is for spark4 off actions
if(BIT_CHECK(currentStatus.testOutputs, 1)){digitalWrite(pinCoil4, LOW);}
if( BIT_CHECK(currentStatus.testOutputs, 1) ) { digitalWrite(pinCoil4, LOW); }
break;
case 780: // cmd group is for spark4 50%dc actions
default:
break;
}
}

View File

@ -20,14 +20,14 @@ static inline byte correctionIATDensity(); //Inlet temp density correction
static inline byte correctionLaunch(); //Launch control correction
static inline bool correctionDFCO(); //Decelleration fuel cutoff
byte correctionsIgn(byte advance);
static inline byte correctionFixedTiming(byte);
static inline byte correctionCrankingFixedTiming(byte);
static inline byte correctionFlexTiming(byte);
static inline byte correctionIATretard(byte);
static inline byte correctionSoftRevLimit(byte);
static inline byte correctionSoftLaunch(byte);
static inline byte correctionSoftFlatShift(byte);
int8_t correctionsIgn(int8_t advance);
static inline int8_t correctionFixedTiming(int8_t);
static inline int8_t correctionCrankingFixedTiming(int8_t);
static inline int8_t correctionFlexTiming(int8_t);
static inline int8_t correctionIATretard(int8_t);
static inline int8_t correctionSoftRevLimit(int8_t);
static inline int8_t correctionSoftLaunch(int8_t);
static inline int8_t correctionSoftFlatShift(int8_t);
uint16_t correctionsDwell(uint16_t dwell);

View File

@ -74,7 +74,7 @@ byte correctionsFuel()
if (currentStatus.launchCorrection != 100) { sumCorrections = (sumCorrections * currentStatus.launchCorrection); activeCorrections++; }
bitWrite(currentStatus.squirt, BIT_SQUIRT_DFCO, correctionDFCO());
if ( bitRead(currentStatus.squirt, BIT_SQUIRT_DFCO) ) { sumCorrections = 0; }
if ( bitRead(currentStatus.squirt, BIT_SQUIRT_DFCO) == 1 ) { sumCorrections = 0; }
sumCorrections = sumCorrections / powint(100,activeCorrections);
@ -88,10 +88,21 @@ Uses a 2D enrichment table (WUETable) where the X axis is engine temp and the Y
*/
static inline byte correctionWUE()
{
byte WUEValue;
//Possibly reduce the frequency this runs at (Costs about 50 loops per second)
if (currentStatus.coolant > (WUETable.axisX[9] - CALIBRATION_TEMPERATURE_OFFSET)) { BIT_CLEAR(currentStatus.engine, BIT_ENGINE_WARMUP); return 100; } //This prevents us doing the 2D lookup if we're already up to temp
BIT_SET(currentStatus.engine, BIT_ENGINE_WARMUP);
return table2D_getValue(&WUETable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
if (currentStatus.coolant > (WUETable.axisX[9] - CALIBRATION_TEMPERATURE_OFFSET))
{
//This prevents us doing the 2D lookup if we're already up to temp
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_WARMUP);
WUEValue = 100;
}
else
{
BIT_SET(currentStatus.engine, BIT_ENGINE_WARMUP);
WUEValue = table2D_getValue(&WUETable, currentStatus.coolant + CALIBRATION_TEMPERATURE_OFFSET);
}
return WUEValue;
}
/*
@ -100,8 +111,9 @@ Additional fuel % to be added when the engine is cranking
*/
static inline byte correctionCranking()
{
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { return 100 + configPage1.crankingPct; }
else { return 100; }
byte crankingValue = 100;
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { crankingValue = 100 + configPage1.crankingPct; }
return crankingValue;
}
/*
@ -111,17 +123,21 @@ where an additional amount of fuel is added (Over and above the WUE amount)
*/
static inline byte correctionASE()
{
byte ASEValue;
//Two checks are requiredL:
//1) Is the negine run time less than the configured ase time
//2) Make sure we're not still cranking
if ( (currentStatus.runSecs < configPage1.aseCount) && !(BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK)) )
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ASE); //Mark ASE as active.
return 100 + configPage1.asePct;
ASEValue = 100 + configPage1.asePct;
}
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ASE); //Mark ASE as inactive.
return 100;
else
{
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ASE); //Mark ASE as inactive.
ASEValue = 100;
}
return ASEValue;
}
/*
@ -131,6 +147,7 @@ When the enrichment is turned on, it runs at that amount for a fixed period of t
*/
static inline byte correctionAccel()
{
byte accelValue = 100;
//First, check whether the accel. enrichment is already running
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_ACC) )
{
@ -140,29 +157,37 @@ static inline byte correctionAccel()
//Time to turn enrichment off
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_ACC);
currentStatus.TAEamount = 0;
return 100;
accelValue = 100;
}
else
{
//Enrichment still needs to keep running. Simply return the total TAE amount
accelValue = currentStatus.TAEamount;
}
//Enrichment still needs to keep running. Simply return the total TAE amount
return currentStatus.TAEamount;
}
//Check for deceleration (Deceleration adjustment not yet supported)
if (currentStatus.TPS < currentStatus.TPSlast) { return 100; }
//If TAE isn't currently turned on, need to check whether it needs to be turned on
int rateOfChange = ldiv(1000000, (currentStatus.TPS_time - currentStatus.TPSlast_time)).quot * (currentStatus.TPS - currentStatus.TPSlast); //This is the % per second that the TPS has moved
//currentStatus.tpsDOT = divs10(rateOfChange); //The TAE bins are divided by 10 in order to allow them to be stored in a byte.
currentStatus.tpsDOT = rateOfChange / 10;
if (rateOfChange > configPage1.tpsThresh)
else
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
currentStatus.TAEEndTime = micros() + ((unsigned long)configPage1.taeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
return 100 + table2D_getValue(&taeTable, currentStatus.tpsDOT);
//Check for deceleration (Deceleration adjustment not yet supported)
if (currentStatus.TPS < currentStatus.TPSlast)
{
accelValue = 100;
}
else
{
//If TAE isn't currently turned on, need to check whether it needs to be turned on
int rateOfChange = ldiv(1000000, (currentStatus.TPS_time - currentStatus.TPSlast_time)).quot * (currentStatus.TPS - currentStatus.TPSlast); //This is the % per second that the TPS has moved
currentStatus.tpsDOT = rateOfChange / 10; //The TAE bins are divided by 10 in order to allow them to be stored in a byte. Faster as this than divu10
if (rateOfChange > configPage1.tpsThresh)
{
BIT_SET(currentStatus.engine, BIT_ENGINE_ACC); //Mark accleration enrichment as active.
currentStatus.TAEEndTime = micros() + ((unsigned long)configPage1.taeTime * 10000); //Set the time in the future where the enrichment will be turned off. taeTime is stored as mS / 10, so multiply it by 100 to get it in uS
accelValue = 100 + table2D_getValue(&taeTable, currentStatus.tpsDOT);
}
}
}
//If we reach here then TAE is neither on, nor does it need to be turned on.
return 100;
return accelValue;
}
/*
@ -172,16 +197,17 @@ This function always returns either 100 or 0
static inline byte correctionFloodClear()
{
if(BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK))
byte floodValue = 100;
if( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) )
{
//Engine is currently cranking, check what the TPS is
if(currentStatus.TPS >= configPage2.floodClear)
{
//Engine is cranking and TPS is above threshold. Cut all fuel
return 0;
floodValue = 0;
}
}
return 100;
return floodValue;
}
/*
@ -190,8 +216,11 @@ Uses a 2D enrichment table (WUETable) where the X axis is engine temp and the Y
*/
static inline byte correctionBatVoltage()
{
if (currentStatus.battery10 > (injectorVCorrectionTable.axisX[5])) { return injectorVCorrectionTable.values[injectorVCorrectionTable.xSize-1]; } //This prevents us doing the 2D lookup if the voltage is above maximum
return table2D_getValue(&injectorVCorrectionTable, currentStatus.battery10);
byte batValue = 100;
if (currentStatus.battery10 > (injectorVCorrectionTable.axisX[5])) { batValue = injectorVCorrectionTable.values[injectorVCorrectionTable.xSize-1]; } //This prevents us doing the 2D lookup if the voltage is above maximum
else { batValue = table2D_getValue(&injectorVCorrectionTable, currentStatus.battery10); }
return batValue;
}
/*
@ -200,8 +229,11 @@ This corrects for changes in air density from movement of the temperature
*/
static inline byte correctionIATDensity()
{
if ( (currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET) > (IATDensityCorrectionTable.axisX[8])) { return IATDensityCorrectionTable.values[IATDensityCorrectionTable.xSize-1]; } //This prevents us doing the 2D lookup if the intake temp is above maximum
return table2D_getValue(&IATDensityCorrectionTable, currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); //currentStatus.IAT is the actual temperature, values in IATDensityCorrectionTable.axisX are temp+offset
byte IATValue = 100;
if ( (currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET) > (IATDensityCorrectionTable.axisX[8])) { IATValue = IATDensityCorrectionTable.values[IATDensityCorrectionTable.xSize-1]; } //This prevents us doing the 2D lookup if the intake temp is above maximum
else { IATValue = table2D_getValue(&IATDensityCorrectionTable, currentStatus.IAT + CALIBRATION_TEMPERATURE_OFFSET); }//currentStatus.IAT is the actual temperature, values in IATDensityCorrectionTable.axisX are temp+offset
return IATValue;
}
/*
@ -210,8 +242,10 @@ This simple check applies the extra fuel if we're currently launching
*/
static inline byte correctionLaunch()
{
if(currentStatus.launchingHard || currentStatus.launchingSoft) { return (100 + configPage3.lnchFuelAdd); }
else { return 100; }
byte launchValue = 100;
if(currentStatus.launchingHard || currentStatus.launchingSoft) { launchValue = (100 + configPage3.lnchFuelAdd); }
return launchValue;
}
/*
@ -219,9 +253,13 @@ static inline byte correctionLaunch()
*/
static inline bool correctionDFCO()
{
if ( !configPage2.dfcoEnabled ) { return false; } //If the DFCO option isn't turned on, always return false (off)
if ( bitRead(currentStatus.squirt, BIT_SQUIRT_DFCO) ) { return ( currentStatus.RPM > ( configPage2.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); }
else { return ( currentStatus.RPM > (unsigned int)( (configPage2.dfcoRPM * 10) + configPage2.dfcoHyster) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); }
bool DFCOValue = false;
if ( configPage2.dfcoEnabled == 1 )
{
if ( bitRead(currentStatus.squirt, BIT_SQUIRT_DFCO) == 1 ) { DFCOValue = ( currentStatus.RPM > ( configPage2.dfcoRPM * 10) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); }
else { DFCOValue = ( currentStatus.RPM > (unsigned int)( (configPage2.dfcoRPM * 10) + configPage2.dfcoHyster) ) && ( currentStatus.TPS < configPage2.dfcoTPSThresh ); }
}
return DFCOValue;
}
/*
@ -230,9 +268,13 @@ static inline bool correctionDFCO()
*/
static inline byte correctionFlex()
{
if(!configPage1.flexEnabled) { return 100; } //Check for flex being enabled
byte flexRange = configPage1.flexFuelHigh - configPage1.flexFuelLow;
return percentage(currentStatus.ethanolPct, flexRange) + 100;
byte flexValue = 100;
if(configPage1.flexEnabled == 1)
{
byte flexRange = configPage1.flexFuelHigh - configPage1.flexFuelLow;
flexValue = percentage(currentStatus.ethanolPct, flexRange) + 100;
}
return flexValue;
}
/*
@ -251,77 +293,81 @@ PID (Best suited to wideband sensors):
static inline byte correctionAFRClosedLoop()
{
if( (configPage3.egoType == 0)) { return 100; } //egoType of 0 means no O2 sensor
currentStatus.afrTarget = currentStatus.O2; //Catch all incase the below doesn't run. This prevents the Include AFR option from doing crazy things if the AFR target conditions aren't met. This value is changed again below if all conditions are met.
//Check the ignition count to see whether the next step is required
//if( (ignitionCount & (configPage3.egoCount - 1)) == 1 ) //This is the equivalent of ( (ignitionCount % configPage3.egoCount) == 0 ) but without the expensive modulus operation. ie It results in True every <egoCount> ignition loops. Note that it only works for power of two vlaues for egoCount
byte AFRValue = 100;
if( configPage3.egoType > 0 ) //egoType of 0 means no O2 sensor
{
//Determine whether the Y axis of the AFR target table tshould be MAP (Speed-Density) or TPS (Alpha-N)
byte yValue;
if (configPage1.algorithm == 0) { yValue = currentStatus.MAP; }
else { yValue = currentStatus.TPS; }
currentStatus.afrTarget = get3DTableValue(&afrTable, yValue, currentStatus.RPM); //Perform the target lookup
currentStatus.afrTarget = currentStatus.O2; //Catch all incase the below doesn't run. This prevents the Include AFR option from doing crazy things if the AFR target conditions aren't met. This value is changed again below if all conditions are met.
//Check all other requirements for closed loop adjustments
if( (currentStatus.coolant > (int)(configPage3.egoTemp - CALIBRATION_TEMPERATURE_OFFSET)) && (currentStatus.RPM > (unsigned int)(configPage3.egoRPM * 100)) && (currentStatus.TPS < configPage3.egoTPSMax) && (currentStatus.O2 < configPage3.ego_max) && (currentStatus.O2 > configPage3.ego_min) && (currentStatus.runSecs > configPage3.ego_sdelay) )
//Check the ignition count to see whether the next step is required
//This if statement is the equivalent of ( (ignitionCount % configPage3.egoCount) == 0 ) but without the expensive modulus operation. ie It results in True every <egoCount> ignition loops. Note that it only works for power of two vlaues for egoCount
//if( (ignitionCount & (configPage3.egoCount - 1)) == 1 )
{
//Check which algorithm is used, simple or PID
if (configPage3.egoAlgorithm == 0)
//Determine whether the Y axis of the AFR target table tshould be MAP (Speed-Density) or TPS (Alpha-N)
byte yValue;
if (configPage1.algorithm == 0) { yValue = currentStatus.MAP; }
else { yValue = currentStatus.TPS; }
currentStatus.afrTarget = get3DTableValue(&afrTable, yValue, currentStatus.RPM); //Perform the target lookup
//Check all other requirements for closed loop adjustments
if( (currentStatus.coolant > (int)(configPage3.egoTemp - CALIBRATION_TEMPERATURE_OFFSET)) && (currentStatus.RPM > (unsigned int)(configPage3.egoRPM * 100)) && (currentStatus.TPS < configPage3.egoTPSMax) && (currentStatus.O2 < configPage3.ego_max) && (currentStatus.O2 > configPage3.ego_min) && (currentStatus.runSecs > configPage3.ego_sdelay) )
{
//*************************************************************************************************************************************
//Simple algorithm
if(currentStatus.O2 > currentStatus.afrTarget)
//Check which algorithm is used, simple or PID
if (configPage3.egoAlgorithm == 0)
{
//Running lean
if(currentStatus.egoCorrection < (100 + configPage3.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
//*************************************************************************************************************************************
//Simple algorithm
if(currentStatus.O2 > currentStatus.afrTarget)
{
if(currentStatus.egoCorrection >= 100) { return (currentStatus.egoCorrection + 1); } //Increase the fueling by 1%
else { return 100; } //This means that the last reading had been rich, so simply return back to no adjustment (100%)
//Running lean
if(currentStatus.egoCorrection < (100 + configPage3.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
{
if(currentStatus.egoCorrection >= 100) { AFRValue = (currentStatus.egoCorrection + 1); } //Increase the fueling by 1%
else { AFRValue = 100; } //This means that the last reading had been rich, so simply return back to no adjustment (100%)
}
else { AFRValue = currentStatus.egoCorrection; } //Means we're at the maximum adjustment amount, so simply return then again
}
else { return currentStatus.egoCorrection; } //Means we're at the maximum adjustment amount, so simply return then again
else
//Running Rich
if(currentStatus.egoCorrection > (100 - configPage3.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
{
if(currentStatus.egoCorrection <= 100) { AFRValue = (currentStatus.egoCorrection - 1); } //Increase the fueling by 1%
else { AFRValue = 100; } //This means that the last reading had been lean, so simply return back to no adjustment (100%)
}
else { AFRValue = currentStatus.egoCorrection; } //Means we're at the maximum adjustment amount, so simply return then again
}
else
//Running Rich
if(currentStatus.egoCorrection > (100 - configPage3.egoLimit) ) //Fueling adjustment must be at most the egoLimit amount (up or down)
{
if(currentStatus.egoCorrection <= 100) { return (currentStatus.egoCorrection - 1); } //Increase the fueling by 1%
else { return 100; } //This means that the last reading had been lean, so simply return back to no adjustment (100%)
}
else { return currentStatus.egoCorrection; } //Means we're at the maximum adjustment amount, so simply return then again
}
else if(configPage3.egoAlgorithm == 2)
{
//*************************************************************************************************************************************
//PID algorithm
egoPID.SetOutputLimits((long)(-configPage3.egoLimit), (long)(configPage3.egoLimit)); //Set the limits again, just incase the user has changed them since the last loop. Note that these are sent to the PID library as (Eg:) -15 and +15
egoPID.SetTunings(configPage3.egoKP, configPage3.egoKI, configPage3.egoKD); //Set the PID values again, just incase the user has changed them since the last loop
PID_O2 = (long)(currentStatus.O2);
PID_AFRTarget = (long)(currentStatus.afrTarget);
else if(configPage3.egoAlgorithm == 2)
{
//*************************************************************************************************************************************
//PID algorithm
egoPID.SetOutputLimits((long)(-configPage3.egoLimit), (long)(configPage3.egoLimit)); //Set the limits again, just incase the user has changed them since the last loop. Note that these are sent to the PID library as (Eg:) -15 and +15
egoPID.SetTunings(configPage3.egoKP, configPage3.egoKI, configPage3.egoKD); //Set the PID values again, just incase the user has changed them since the last loop
PID_O2 = (long)(currentStatus.O2);
PID_AFRTarget = (long)(currentStatus.afrTarget);
egoPID.Compute();
//currentStatus.egoCorrection = 100 + PID_output;
return (100 + PID_output);
}
else { return 100; } // Occurs if the egoAlgorithm is set to 0 (No Correction)
egoPID.Compute();
//currentStatus.egoCorrection = 100 + PID_output;
AFRValue = 100 + PID_output;
}
else { AFRValue = 100; } // Occurs if the egoAlgorithm is set to 0 (No Correction)
}
}
} //Multi variable check
} //ignitionCount
} //egoType
return 100; //Catch all (Includes when AFR target = current AFR
return AFRValue; //Catch all (Includes when AFR target = current AFR
}
//******************************** IGNITION ADVANCE CORRECTIONS ********************************
byte correctionsIgn(byte advance)
int8_t correctionsIgn(int8_t base_advance)
{
advance = correctionFlexTiming(advance);
int8_t advance;
advance = correctionFlexTiming(base_advance);
advance = correctionIATretard(advance);
advance = correctionSoftRevLimit(advance);
advance = correctionSoftLaunch(advance);
advance = correctionSoftFlatShift(advance);
//Fixed timing check must go last
advance = correctionFixedTiming(advance);
advance = correctionCrankingFixedTiming(advance); //This overrrides the regular fixed timing, must come last
@ -329,84 +375,102 @@ byte correctionsIgn(byte advance)
return advance;
}
static inline byte correctionFixedTiming(byte advance)
static inline int8_t correctionFixedTiming(int8_t advance)
{
if (configPage2.FixAng != 0) { return configPage2.FixAng; } //Check whether the user has set a fixed timing angle
return advance;
byte ignFixValue = advance;
if (configPage2.FixAng != 0) { ignFixValue = configPage2.FixAng; } //Check whether the user has set a fixed timing angle
return ignFixValue;
}
static inline byte correctionCrankingFixedTiming(byte advance)
static inline int8_t correctionCrankingFixedTiming(int8_t advance)
{
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { return configPage2.CrankAng; } //Use the fixed cranking ignition angle
return advance;
byte ignCrankFixValue = advance;
if ( BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) ) { ignCrankFixValue = configPage2.CrankAng; } //Use the fixed cranking ignition angle
return ignCrankFixValue;
}
static inline byte correctionFlexTiming(byte advance)
static inline int8_t correctionFlexTiming(int8_t advance)
{
if(!configPage1.flexEnabled) { return advance; } //Check for flex being enabled
byte flexRange = configPage1.flexAdvHigh - configPage1.flexAdvLow;
byte ignFlexValue = advance;
if( configPage1.flexEnabled == 1 ) //Check for flex being enabled
{
byte flexRange = configPage1.flexAdvHigh - configPage1.flexAdvLow;
if (currentStatus.ethanolPct != 0) { currentStatus.flexIgnCorrection = percentage(currentStatus.ethanolPct, flexRange); }
else { currentStatus.flexIgnCorrection = 0; }
if (currentStatus.ethanolPct != 0) { currentStatus.flexIgnCorrection = percentage(currentStatus.ethanolPct, flexRange); }
else { currentStatus.flexIgnCorrection = 0; }
return advance + currentStatus.flexIgnCorrection;
ignFlexValue = advance + currentStatus.flexIgnCorrection;
}
return ignFlexValue;
}
static inline byte correctionIATretard(byte advance)
static inline int8_t correctionIATretard(int8_t advance)
{
byte ignIATValue = advance;
//Adjust the advance based on IAT. If the adjustment amount is greater than the current advance, just set advance to 0
byte advanceIATadjust = table2D_getValue(&IATRetardTable, currentStatus.IAT);
if (advanceIATadjust <= advance) { return (advance - advanceIATadjust); }
else { return 0; }
int8_t advanceIATadjust = table2D_getValue(&IATRetardTable, currentStatus.IAT);
int tempAdvance = (advance - advanceIATadjust);
if (tempAdvance >= -OFFSET_IGNITION) { ignIATValue = tempAdvance; }
else { ignIATValue = -OFFSET_IGNITION; }
return ignIATValue;
}
static inline byte correctionSoftRevLimit(byte advance)
static inline int8_t correctionSoftRevLimit(int8_t advance)
{
byte ignSoftRevValue = advance;
BIT_CLEAR(currentStatus.spark, BIT_SPARK_SFTLIM);
if (currentStatus.RPM > ((unsigned int)(configPage2.SoftRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_SFTLIM); return configPage2.SoftLimRetard; } //Softcut RPM limit (If we're above softcut limit, delay timing by configured number of degrees)
return advance;
if (currentStatus.RPM > ((unsigned int)(configPage2.SoftRevLim) * 100) ) { BIT_SET(currentStatus.spark, BIT_SPARK_SFTLIM); ignSoftRevValue = configPage2.SoftLimRetard; } //Softcut RPM limit (If we're above softcut limit, delay timing by configured number of degrees)
return ignSoftRevValue;
}
static inline byte correctionSoftLaunch(byte advance)
static inline int8_t correctionSoftLaunch(int8_t advance)
{
byte ignSoftLaunchValue = advance;
//SoftCut rev limit for 2-step launch control.
if (configPage3.launchEnabled && clutchTrigger && (currentStatus.clutchEngagedRPM < ((unsigned int)(configPage3.flatSArm) * 100)) && (currentStatus.RPM > ((unsigned int)(configPage3.lnchSoftLim) * 100)) )
{
currentStatus.launchingSoft = true;
BIT_SET(currentStatus.spark, BIT_SPARK_SLAUNCH);
return configPage3.lnchRetard;
ignSoftLaunchValue = configPage3.lnchRetard;
}
else
{
currentStatus.launchingSoft = false;
BIT_CLEAR(currentStatus.spark, BIT_SPARK_SLAUNCH);
}
currentStatus.launchingSoft = false;
BIT_CLEAR(currentStatus.spark, BIT_SPARK_SLAUNCH);
return advance;
return ignSoftLaunchValue;
}
static inline byte correctionSoftFlatShift(byte advance)
static inline int8_t correctionSoftFlatShift(int8_t advance)
{
byte ignSoftFlatValue = advance;
if(configPage3.flatSEnable && clutchTrigger && (currentStatus.clutchEngagedRPM > ((unsigned int)(configPage3.flatSArm) * 100)) && (currentStatus.RPM > (currentStatus.clutchEngagedRPM-configPage3.flatSSoftWin) ) )
{
BIT_SET(currentStatus.spark2, BIT_SPARK2_FLATSS);
return configPage3.flatSRetard;
ignSoftFlatValue = configPage3.flatSRetard;
}
else { BIT_CLEAR(currentStatus.spark2, BIT_SPARK2_FLATSS); }
BIT_CLEAR(currentStatus.spark2, BIT_SPARK2_FLATSS);
return advance;
return ignSoftFlatValue;
}
//******************************** DWELL CORRECTIONS ********************************
uint16_t correctionsDwell(uint16_t dwell)
{
uint16_t tempDwell = dwell;
//Pull battery voltage based dwell correction and apply if needed
currentStatus.dwellCorrection = table2D_getValue(&dwellVCorrectionTable, currentStatus.battery10);
if (currentStatus.dwellCorrection != 100) { dwell = divs100(dwell) * currentStatus.dwellCorrection; }
if (currentStatus.dwellCorrection != 100) { tempDwell = divs100(dwell) * currentStatus.dwellCorrection; }
//Dwell limiter
uint16_t dwellPerRevolution = dwell + (uint16_t)(configPage2.sparkDur * 100); //Spark duration is in mS*10. Multiple it by 100 to get spark duration in uS
byte pulsesPerRevolution = 1;
uint16_t dwellPerRevolution = tempDwell + (uint16_t)(configPage2.sparkDur * 100); //Spark duration is in mS*10. Multiple it by 100 to get spark duration in uS
int8_t pulsesPerRevolution = 1;
//Single channel spark mode is the only time there will be more than 1 pulse per revolution on any given output
if(configPage2.sparkMode == IGN_MODE_SINGLE && configPage1.nCylinders > 1) //No point in running this for 1 cylinder engines
if( (configPage2.sparkMode == IGN_MODE_SINGLE) && (configPage1.nCylinders > 1) ) //No point in running this for 1 cylinder engines
{
pulsesPerRevolution = (configPage1.nCylinders >> 1);
dwellPerRevolution = dwellPerRevolution * pulsesPerRevolution;
@ -415,7 +479,7 @@ uint16_t correctionsDwell(uint16_t dwell)
if(dwellPerRevolution > revolutionTime)
{
//Possibly need some method of reducing spark duration here as well, but this is a start
dwell = (revolutionTime / pulsesPerRevolution) - (configPage2.sparkDur * 100);
tempDwell = (revolutionTime / pulsesPerRevolution) - (configPage2.sparkDur * 100);
}
return dwell;
return tempDwell;
}

View File

@ -150,6 +150,11 @@ void triggerSec_missingTooth()
int getRPM_missingTooth()
{
if( currentStatus.RPM < (unsigned int)(configPage2.crankRPM * 100) )
{
if(configPage2.TrigSpeed) { crankingGetRPM(configPage2.triggerTeeth/2); } //Account for cam speed
else { return crankingGetRPM(configPage2.triggerTeeth); }
}
if(configPage2.TrigSpeed) { return (stdGetRPM() * 2); } //Account for cam speed
return stdGetRPM();
}
@ -298,7 +303,6 @@ void triggerSetup_BasicDistributor()
{
triggerActualTeeth = configPage1.nCylinders;
if(triggerActualTeeth == 0) { triggerActualTeeth = 1; }
//triggerToothAngle = 360 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
triggerToothAngle = 720 / triggerActualTeeth; //The number of degrees that passes from tooth to tooth
triggerFilterTime = 60000000L / MAX_RPM / configPage1.nCylinders; // Minimum time required between teeth
triggerFilterTime = triggerFilterTime / 2; //Safety margin
@ -366,10 +370,6 @@ int getCrankAngle_BasicDistributor(int timePerDegree)
tempToothLastToothTime = toothLastToothTime;
interrupts();
//int crankAngle = (tempToothCurrentCount - 1) * triggerToothAngle + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
//crankAngle += ldiv( (micros() - tempToothLastToothTime), timePerDegree).quot; //Estimate the number of degrees travelled since the last tooth
int crankAngle = (tempToothCurrentCount - 1) * triggerToothAngle + configPage2.triggerAngle; //Number of teeth that have passed since tooth 1, multiplied by the angle each tooth represents, plus the angle that tooth 1 is ATDC. This gives accuracy only to the nearest tooth.
//Estimate the number of degrees travelled since the last tooth}
long elapsedTime = micros() - tempToothLastToothTime;
@ -488,12 +488,24 @@ void triggerSetup_4G63()
toothLastToothTime = micros(); //Set a startup value here to avoid filter errors when starting
//Note that these angles are for every rising and falling edge
toothAngles[0] = 355; //Falling edge of tooth #1
toothAngles[1] = 105; //Rising edge of tooth #2
toothAngles[2] = 175; //Falling edge of tooth #2
toothAngles[3] = 285; //Rising edge of tooth #1
if(configPage1.nCylinders == 6)
{
// 70 / 50 for 6 cylinder applications
toothAngles[0] = 185; //
toothAngles[1] = 235; //
toothAngles[2] = 305; //
toothAngles[3] = 355; //
toothAngles[4] = 65; //
toothAngles[5] = 115; //
}
else
{
// 70 / 110 for 4 cylinder
toothAngles[0] = 355; //Falling edge of tooth #1
toothAngles[1] = 105; //Rising edge of tooth #2
toothAngles[2] = 175; //Falling edge of tooth #2
toothAngles[3] = 285; //Rising edge of tooth #1
}
/*
* https://forums.libreems.org/attachment.php?aid=34
toothAngles[0] = 715; //Falling edge of tooth #1
@ -529,14 +541,13 @@ void triggerPri_4G63()
toothLastToothTime = curTime;
toothCurrentCount++;
if(toothCurrentCount == 1 || toothCurrentCount > 4) //Trigger is on CHANGE, hence 4 pulses = 1 crank rev
if(toothCurrentCount == 1 || toothCurrentCount > configPage1.nCylinders) //Trigger is on CHANGE, hence 4 pulses = 1 crank rev
{
toothCurrentCount = 1; //Reset the counter
toothOneMinusOneTime = toothOneTime;
toothOneTime = curTime;
currentStatus.hasSync = true;
currentStatus.startRevolutions++; //Counter
//if ((startRevolutions & 15) == 1) { currentStatus.hasSync = false; } //Every 64 revolutions, force a resync with the cam
}
else if (!currentStatus.hasSync) { return; }
@ -544,25 +555,43 @@ void triggerPri_4G63()
{
if( toothCurrentCount == 1 ) { endCoil1Charge(); }
else if( toothCurrentCount == 3 ) { endCoil2Charge(); }
else if( toothCurrentCount == 5 ) { endCoil3Charge(); }
}
//Whilst this is an uneven tooth pattern, if the specific angle between the last 2 teeth is specified, 1st deriv prediction can be used
if(configPage2.triggerFilter == 1 || currentStatus.RPM < 1800)
if(configPage2.triggerFilter == 1 || currentStatus.RPM < 1400)
{
//Lite filter
if(toothCurrentCount == 1 || toothCurrentCount == 3) { triggerToothAngle = 70; triggerFilterTime = curGap; } //Trigger filter is set to whatever time it took to do 70 degrees (Next trigger is 110 degrees away)
else { triggerToothAngle = 110; triggerFilterTime = (curGap * 3) >> 3; } //Trigger filter is set to (110*3)/8=41.25=41 degrees (Next trigger is 70 degrees away).
if(toothCurrentCount == 1 || toothCurrentCount == 3 || toothCurrentCount == 5)
{
triggerToothAngle = 70;
triggerFilterTime = curGap; //Trigger filter is set to whatever time it took to do 70 degrees (Next trigger is 110 degrees away)
if(configPage1.nCylinders == 6)
{
triggerFilterTime = (curGap >> 2); //Trigger filter is set to (70/4)=17.5=17 degrees (Next trigger is 50 degrees away).
}
}
else
{
triggerToothAngle = 110;
triggerFilterTime = (curGap * 3) >> 3; //Trigger filter is set to (110*3)/8=41.25=41 degrees (Next trigger is 70 degrees away).
if(configPage1.nCylinders == 6)
{
triggerToothAngle = 50;
triggerFilterTime = (curGap * 3) >> 2; //Trigger filter is set to (50*3)/4=37.5=37 degrees (Next trigger is 70 degrees away).
}
}
}
else if(configPage2.triggerFilter == 2)
{
//Medium filter level
if(toothCurrentCount == 1 || toothCurrentCount == 3) { triggerToothAngle = 70; triggerFilterTime = (curGap * 5) >> 2 ; } //87.5 degrees with a target of 110
if(toothCurrentCount == 1 || toothCurrentCount == 3 || toothCurrentCount == 5) { triggerToothAngle = 70; triggerFilterTime = (curGap * 5) >> 2 ; } //87.5 degrees with a target of 110
else { triggerToothAngle = 110; triggerFilterTime = (curGap >> 1); } //55 degrees with a target of 70
}
else if (configPage2.triggerFilter == 3)
{
//Aggressive filter level
if(toothCurrentCount == 1 || toothCurrentCount == 3) { triggerToothAngle = 70; triggerFilterTime = (curGap * 11) >> 3 ; } //96.26 degrees with a target of 110
if(toothCurrentCount == 1 || toothCurrentCount == 3 || toothCurrentCount == 5) { triggerToothAngle = 70; triggerFilterTime = (curGap * 11) >> 3 ; } //96.26 degrees with a target of 110
else { triggerToothAngle = 110; triggerFilterTime = (curGap * 9) >> 5; } //61.87 degrees with a target of 70
}
else { triggerFilterTime = 0; } //trigger filter is turned off.
@ -586,7 +615,10 @@ void triggerSec_4G63()
toothLastSecToothTime = curTime2;
triggerSecFilterTime = curGap2 >> 1; //Basic 50% filter for the secondary reading
//triggerSecFilterTime = (curGap2 * 9) >> 5; //62.5%
//More aggressive options:
//62.5%:
//triggerSecFilterTime = (curGap2 * 9) >> 5;
//75%:
//triggerSecFilterTime = (curGap2 * 6) >> 3; //75%
if(BIT_CHECK(currentStatus.engine, BIT_ENGINE_CRANK) || !currentStatus.hasSync)
@ -605,12 +637,6 @@ void triggerSec_4G63()
if(READ_PRI_TRIGGER())// && (crankState == digitalRead(pinTrigger)))
{
toothCurrentCount = 4; //If the crank trigger is currently HIGH, it means we're on tooth #1
/* High-res mode
toothCurrentCount = 7; //If the crank trigger is currently HIGH, it means we're on the falling edge of the narrow crank tooth
toothLastMinusOneToothTime = toothLastToothTime;
toothLastToothTime = curTime;
*/
}
}
@ -628,15 +654,10 @@ int getRPM_4G63()
//if(currentStatus.startRevolutions < 2) { return 0; } //Need at least 2 full revolutions to prevent crazy initial rpm value
int tempToothAngle;
unsigned long toothTime;
if(toothLastToothTime == 0 || toothLastMinusOneToothTime == 0) { return; }
if(toothLastToothTime == 0 || toothLastMinusOneToothTime == 0) { return 0; }
noInterrupts();
tempToothAngle = triggerToothAngle;
/* High-res mode
if(toothCurrentCount == 1) { tempToothAngle = 70; }
else { tempToothAngle = toothAngles[toothCurrentCount-1] - toothAngles[toothCurrentCount-2]; }
*/
//revolutionTime = (toothOneTime - toothOneMinusOneTime); //The time in uS that one revolution would take at current speed (The time tooth 1 was last seen, minus the time it was seen prior to that)
toothTime = (toothLastToothTime - toothLastMinusOneToothTime); //Note that trigger tooth angle changes between 70 and 110 depending on the last tooth that was seen
interrupts();
toothTime = toothTime * 36;

View File

@ -23,7 +23,7 @@
//Handy bitsetting macros
#define BIT_SET(a,b) ((a) |= (1<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))
#define BIT_CHECK(var,pos) ((var) & (1<<(pos)))
#define BIT_CHECK(var,pos) !!((var) & (1<<(pos)))
#define MS_IN_MINUTE 60000
#define US_IN_MINUTE 60000000
@ -95,6 +95,7 @@
#define CALIBRATION_TABLE_SIZE 512
#define CALIBRATION_TEMPERATURE_OFFSET 40 // All temperature measurements are stored offset by 40 degrees. This is so we can use an unsigned byte (0-255) to represent temperature ranges from -40 to 215
#define OFFSET_FUELTRIM 127 //The fuel trim tables are offset by 128 to allow for -128 to +128 values
#define OFFSET_IGNITION 40 //Ignition values from the main spark table are offset 40 degrees downards to allow for negative spark timing
#define SERIAL_BUFFER_THRESHOLD 32 // When the serial buffer is filled to greater than this threshold value, the serial processing operations will be performed more urgently in order to avoid it overflowing. Serial buffer is 64 bytes long, so the threshold is set at half this as a reasonable figure
@ -108,7 +109,7 @@ const byte data_structure_version = 2; //This identifies the data structure when
const byte page_size = 64;
const int npage_size[11] = {0,288,64,288,64,288,64,64,160,192,128};
//const byte page10_size = 128;
const int map_page_size = 288;
#define MAP_PAGE_SIZE 288
struct table3D fuelTable; //16x16 fuel map
struct table3D ignitionTable; //16x16 ignition map
@ -225,7 +226,7 @@ struct statuses {
byte idleLoad; //Either the current steps or current duty cycle for the idle control.
int canin[9]; //16bit raw value of selected canin data for channel 1-8
uint8_t current_caninchannel = 0; //start off at channel 0
//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.
@ -239,8 +240,8 @@ struct statuses currentStatus; //The global status object
//This mostly covers off variables that are required for fuel
struct config1 {
byte unused1; //Cold cranking pulsewidth modifier. This is added to the fuel pulsewidth when cranking under a certain temp threshold (ms)
byte unused2; //Warm cranking pulsewidth modifier. This is added to the fuel pulsewidth when cranking (ms)
int8_t flexBoostLow; //Must be signed to allow for negatives
byte flexBoostHigh;
byte asePct; //Afterstart enrichment (%)
byte aseCount; //Afterstart enrichment cycles. This is the number of ignition cycles that the afterstart enrichment % lasts for
byte wueValues[10]; //Warm up enrichment array (10 bytes)
@ -296,7 +297,7 @@ struct config1 {
byte algorithm : 1; //"Speed Density", "Alpha-N"
byte baroCorr : 1;
byte injLayout : 2;
byte canEnable : 1; //is can interface enabled
byte unused2_38g : 1;
byte unused2_38h : 1;
byte primePulse;
@ -497,6 +498,7 @@ struct config4 {
//Page 10 of the config mostly deals with CANBUS control
//See ini file for further info (Config Page 10 in the ini)
struct config10 {
byte enable_canbus:2;
byte enable_candata_in:1;
byte caninput_sel[8];
uint16_t caninput_param_group[8];
@ -512,31 +514,10 @@ struct config10 {
byte unused10_48;
byte unused10_49;
byte enable_candata_out : 1;
byte unused10_51;
byte unused10_52;
byte unused10_53;
byte unused10_54;
byte unused10_55;
byte unused10_56;
byte unused10_57;
byte unused10_58;
byte unused10_59;
byte unused10_60;
byte unused10_61;
byte unused10_62;
byte unused10_63;
byte unused10_64;
byte unused10_65;
byte unused10_66;
byte unused10_67;
byte unused10_68;
byte unused10_69;
byte unused10_70;
byte unused10_71;
byte unused10_72;
byte unused10_73;
byte unused10_74;
byte unused10_75;
byte canoutput_sel[8];
uint16_t canoutput_param_group[8];
uint8_t canoutput_param_start_byte[8];
byte canoutput_param_num_bytes[8];
byte unused10_76;
byte unused10_77;
byte unused10_78;
@ -561,13 +542,10 @@ struct config10 {
byte unused10_97;
byte unused10_98;
byte unused10_99;
byte unused10_100;
byte unused10_101;
byte unused10_102;
byte unused10_103;
byte unused10_104;
byte unused10_105;
byte unused10_106;
byte speeduino_tsCanId:4; //speeduino TS canid (0-14)
uint16_t true_address; //speeduino 11bit can address
uint16_t realtime_base_address; //speeduino 11 bit realtime base address
uint16_t obd_address; //speeduino OBD diagnostic address
byte unused10_107;
byte unused10_108;
byte unused10_109;

View File

@ -45,6 +45,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "storage.h"
#include "scheduledIO.h"
#include <EEPROM.h>
#if defined (CORE_TEENSY)
#include <FlexCAN.h>
#endif
struct config1 configPage1;
struct config2 configPage2;
@ -150,10 +153,26 @@ void setup()
table3D_setSize(&trim4Table, 6);
loadConfig();
doUpdates(); //Check if any data items need updating (Occurs ith firmware updates)
Serial.begin(115200);
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
if (configPage1.canEnable) { Serial3.begin(115200); }
if (configPage10.enable_canbus == 1) { Serial3.begin(115200); }
#elif defined(CORE_STM32)
if (configPage10.enable_canbus == 1) { Serial2.begin(115200); }
else if (configPage10.enable_canbus == 2)
{
//enable local can interface
}
#elif defined(CORE_TEESNY)
if (configPage10.enable_canbus == 1) { Serial2.begin(115200); }
else if (configPage10.enable_canbus == 2)
{
//enable local can interface
FlexCAN CANbus0(2500000, 0); //setup can interface to 250k
static CAN_message_t txmsg,rxmsg;
CANbus0.begin();
}
#endif
//Repoint the 2D table structs to the config pages that were just loaded
@ -279,6 +298,8 @@ void setup()
triggerInterrupt = 3; break;
case 21:
triggerInterrupt = 2; break;
default:
triggerInterrupt = 0; break; //This should NEVER happen
}
#else
triggerInterrupt = pinTrigger;
@ -299,6 +320,8 @@ void setup()
triggerInterrupt2 = 3; break;
case 21:
triggerInterrupt2 = 2; break;
default:
triggerInterrupt2 = 0; break; //This should NEVER happen
}
#else
triggerInterrupt2 = pinTrigger2;
@ -514,6 +537,7 @@ void setup()
channel1InjEnabled = true;
break;
case 2:
channel1IgnDegrees = 0;
@ -534,6 +558,7 @@ void setup()
channel1InjEnabled = true;
channel2InjEnabled = true;
break;
case 3:
channel1IgnDegrees = 0;
@ -660,9 +685,9 @@ void setup()
channel5InjEnabled = true;
break;
case 6:
channel1IgnDegrees = 0;
channel2IgnDegrees = 120;
channel3IgnDegrees = 240;
channel1IgnDegrees = channel1InjDegrees = 0;
channel2IgnDegrees = channel2InjDegrees = 120;
channel3IgnDegrees = channel3InjDegrees = 240;
//For alternatiing injection, the squirt occurs at different times for each channel
/*
@ -682,10 +707,10 @@ void setup()
channel3InjEnabled = true;
break;
case 8:
channel1IgnDegrees = 0;
channel2IgnDegrees = 90;
channel3IgnDegrees = 180;
channel4IgnDegrees = 270;
channel1IgnDegrees = channel1InjDegrees = 0;
channel2IgnDegrees = channel2InjDegrees = 90;
channel3IgnDegrees = channel3InjDegrees = 180;
channel4IgnDegrees = channel3InjDegrees = 270;
//For alternatiing injection, the squirt occurs at different times for each channel
/*
@ -822,9 +847,10 @@ void loop()
command();
}
}
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
//if Can interface is enabled then check for serial3 requests.
if (configPage1.canEnable)
//if serial3 interface is enabled then check for serial3 requests.
if (configPage10.enable_canbus == 1)
{
if ( ((mainLoopCount & 31) == 1) or (Serial3.available() > SERIAL_BUFFER_THRESHOLD) )
{
@ -834,6 +860,43 @@ void loop()
}
}
}
#elif defined(CORE_STM32)
//if can or secondary serial interface is enabled then check for requests.
if (configPage10.enable_canbus == 1) //secondary serial interface enabled
{
if ( ((mainLoopCount & 31) == 1) or (Serial2.available() > SERIAL_BUFFER_THRESHOLD) )
{
if (Serial2.available() > 0)
{
canCommand();
}
}
}
else if (configPage10.enable_canbus == 2) // can module enabled
{
//check local can module
}
#elif defined(CORE_TEENSY)
//if can or secondary serial interface is enabled then check for requests.
if (configPage10.enable_canbus == 1) //secondary serial interface enabled
{
if ( ((mainLoopCount & 31) == 1) or (Serial2.available() > SERIAL_BUFFER_THRESHOLD) )
{
if (Serial2.available() > 0)
{
canCommand();
}
}
}
else if (configPage10.enable_canbus == 2) // can module enabled
{
//check local can module
// if ( ((mainLoopCount & 31) == 1) or (CANbus0.available())
// {
// CANbus0.read(rx_msg);
// }
}
#endif
// if (configPage1.displayType && (mainLoopCount & 255) == 1) { updateDisplay();} //Displays currently disabled
@ -865,6 +928,8 @@ void loop()
if (fpPrimed) { digitalWrite(pinFuelPump, LOW); } //Turn off the fuel pump, but only if the priming is complete
fuelPumpOn = false;
disableIdle(); //Turn off the idle PWM
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_CRANK); //Clear cranking bit (Can otherwise get stuck 'on' even with 0 rpm)
BIT_CLEAR(currentStatus.engine, BIT_ENGINE_WARMUP); //Same as above except for WUE
}
//Uncomment the following for testing
@ -935,7 +1000,7 @@ void loop()
readBat();
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) //ATmega2561 does not have Serial3
//if Can interface is enabled then check for serial3 requests.
if (configPage1.canEnable)
if (configPage10.enable_canbus == 1) // megas only support can via secondary serial
{
if (configPage10.enable_candata_in)
{
@ -956,6 +1021,34 @@ void loop()
}
}
}
#elif defined(CORE_STM32) || defined(CORE_TEENSY)
//if serial3io is enabled then check for serial3 requests.
if (configPage10.enable_candata_in)
{
if (configPage10.caninput_sel[currentStatus.current_caninchannel]) //if current input channel is enabled
{
if (configPage10.enable_canbus == 1) //can via secondary serial
{
sendCancommand(2,0,0,0,configPage10.caninput_param_group[currentStatus.current_caninchannel]); //send an R command for data from paramgroup[currentStatus.current_caninchannel]
}
else if (configPage10.enable_canbus == 2) // can via internal can module
{
sendCancommand(3,configPage10.speeduino_tsCanId,0,0,configPage10.caninput_param_group[currentStatus.current_caninchannel]); //send via localcanbus the command for data from paramgroup[currentStatus.current_caninchannel]
}
}
else
{
if (currentStatus.current_caninchannel <= 6)
{
currentStatus.current_caninchannel++; //step to next input channel if under 9
}
else
{
currentStatus.current_caninchannel = 0; //reset input channel back to 1
}
}
}
#endif
vvtControl();
idleControl(); //Perform any idle related actions. Even at higher frequencies, running 4x per second is sufficient.
@ -997,14 +1090,14 @@ void loop()
//Speed Density
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.MAP, currentStatus.RPM); //Perform lookup into fuel map for RPM vs MAP value
currentStatus.PW1 = PW_SD(req_fuel_uS, currentStatus.VE, currentStatus.MAP, currentStatus.corrections, inj_opentime_uS);
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM); //As above, but for ignition advance
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.MAP, currentStatus.RPM) - OFFSET_IGNITION; //As above, but for ignition advance
}
else
{
//Alpha-N
currentStatus.VE = get3DTableValue(&fuelTable, currentStatus.TPS, currentStatus.RPM); //Perform lookup into fuel map for RPM vs TPS value
currentStatus.PW1 = PW_AN(req_fuel_uS, currentStatus.VE, currentStatus.TPS, currentStatus.corrections, inj_opentime_uS); //Calculate pulsewidth using the Alpha-N algorithm (in uS)
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM); //As above, but for ignition advance
currentStatus.advance = get3DTableValue(&ignitionTable, currentStatus.TPS, currentStatus.RPM) - OFFSET_IGNITION; //As above, but for ignition advance
}
currentStatus.advance = correctionsIgn(currentStatus.advance);

View File

@ -56,6 +56,8 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
-----------------------------------------------------
*/
#define EEPROM_DATA_VERSION 0
#define EEPROM_CONFIG1_XSIZE 1
#define EEPROM_CONFIG1_YSIZE 2
#define EEPROM_CONFIG1_MAP 3
@ -78,13 +80,13 @@ Current layout of EEPROM data (Version 3) is as follows (All sizes are in bytes)
#define EEPROM_CONFIG6_START 999
#define EEPROM_CONFIG6_END 1063
#define EEPROM_CONFIG7_START 1063
#define EEPROM_CONFIG7_END 1127
#define EEPROM_CONFIG8_XSIZE1 1127
#define EEPROM_CONFIG7_END 1127
#define EEPROM_CONFIG8_XSIZE1 1127
#define EEPROM_CONFIG8_YSIZE1 1128
#define EEPROM_CONFIG8_MAP1 1129
#define EEPROM_CONFIG8_XBINS1 1193
#define EEPROM_CONFIG8_YBINS1 1201
#define EEPROM_CONFIG8_XSIZE2 1209
#define EEPROM_CONFIG8_XSIZE2 1209
#define EEPROM_CONFIG8_YSIZE2 1210
#define EEPROM_CONFIG8_MAP2 1211
#define EEPROM_CONFIG8_XBINS2 1275

View File

@ -24,9 +24,6 @@ void writeConfig()
//Create a pointer to the config page
byte* pnt_configPage;
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) - Page 1
| 16x16 table itself + the 16 values along each of the axis

34
speeduino/updates.ino Normal file
View File

@ -0,0 +1,34 @@
/*
* This routine is used for doing any data conversions that are required during firmware changes
* This prevents users getting difference reports in TS when such a data change occurs.
* It also can be used for setting good values when there are viarables that move locations in the ini
* When a user skips multiple firmware versions at a time, this will roll through the updates 1 at a time
*/
void doUpdates()
{
#define CURRENT_DATA_VERSION 3
//May 2017 firmware introduced a -40 offset on the ignition table. Update that table to +40
if(EEPROM.read(EEPROM_DATA_VERSION) == 2)
{
for(int x=0; x<16; x++)
{
for(int y=0; y<16; y++)
{
ignitionTable.values[x][y] = ignitionTable.values[x][y] + 40;
}
}
writeConfig();
EEPROM.write(EEPROM_DATA_VERSION, 3);
}
//Final check is always for 255 and 0 (Brand new arduino)
if(EEPROM.read(EEPROM_DATA_VERSION) == 0 || EEPROM.read(EEPROM_DATA_VERSION) == 255)
{
configPage10.true_address = 0x200;
EEPROM.write(EEPROM_DATA_VERSION, CURRENT_DATA_VERSION);
}
}