Arduinoでクルマのエンジンが動く？　オープンソースECU Speeduino (8)ソースコードのデータ

#Speeduinoソースコードのデータを読み解く
[前回記事 (7)ソースコードの構造](https://qiita.com/covao/items/171bd38e4f190692e62e)
Speeduinoのソースコードで定義している信号やパラメータを解読します。:smiling_imp:

##データ型
###数値型
[FPU(Floating Point Unit)](https://ja.wikipedia.org/wiki/FPU)のないマイコンで処理するため、
処理時間やメモリ消費量なども考慮して、整数型のみ使用しています。:sunglasses:

|型|サイズ(byte)|
|:--|--:|
|bool|1||
|byte|1||
|uint8_t|1|
|int8_t|1|
|uint16_t|2|
|int16_t|2|
|uint32_t|4|
|int32_t|4|

###ビットフィールド
1ビットのフラグや数bitで表す値を構造体ビットフィールドで表現している場合があります。
パラメータ定義[globals.h](https://github.com/noisymime/speeduino/blob/201810/speeduino/globals.h#L782)などで使用しています。

ビットフィールドの例

```ruby:globals.h
struct config10 {
  byte crankingEnrichBins[4];
  byte crankingEnrichValues[4];

  byte rotaryType : 2;
  byte stagingEnabled : 1;
  byte stagingMode : 1;
  byte EMAPPin : 4;

  byte rotarySplitValues[8];
  byte rotarySplitBins[8];

```

### テーブル、マップ
テーブル、マップのデータ型と処理関数が定義されています。

- テーブルの例
![image.png](https://qiita-image-store.s3.amazonaws.com/0/329764/df33fd10-48d6-5e25-d359-e452fb3efded.png)

- マップの例
![image.png](https://qiita-image-store.s3.amazonaws.com/0/329764/be468dfc-7c34-bfbb-7501-e96cdeb2075a.png)

- テーブルセット関数　テーブルデータのサイズを指定し、メモリを動的に確保します。
- テーブルルックアップ関数　格子点データを基に補間計算を行い、出力値を算出します。
 
 
|型|テーブルセット関数|テーブルルックアップ関数|
|:--|:--|:--|
|[table2D](https://github.com/noisymime/speeduino/blob/201810/speeduino/table.h#L14)|              [table2D_setSize](https://github.com/noisymime/speeduino/blob/201810/speeduino/table.ino#L14)|[table2D_getValue](https://github.com/noisymime/speeduino/blob/201810/speeduino/table.ino#L57)|
|[table3D](https://github.com/noisymime/speeduino/blob/201810/speeduino/table.h#L36)|[table3D_setSize](https://github.com/noisymime/speeduino/blob/201810/speeduino/table.ino#L36)|[get3DTableValue](https://github.com/noisymime/speeduino/blob/201810/speeduino/table.ino#L221)|


テーブルデータは、[globals.h](https://github.com/noisymime/speeduino/blob/201810/speeduino/globals.h#L215)で定義しています。


```ruby:globals.h

struct table3D fuelTable; //16x16 fuel map
struct table3D ignitionTable; //16x16 ignition map
struct table3D afrTable; //16x16 afr target map
struct table3D stagingTable; //8x8 fuel staging table
struct table3D boostTable; //8x8 boost map
struct table3D vvtTable; //8x8 vvt map
struct table3D trim1Table; //6x6 Fuel trim 1 map
struct table3D trim2Table; //6x6 Fuel trim 2 map
struct table3D trim3Table; //6x6 Fuel trim 3 map
struct table3D trim4Table; //6x6 Fuel trim 4 map
struct table2D taeTable; //4 bin TPS Acceleration Enrichment map (2D)
struct table2D WUETable; //10 bin Warm Up Enrichment map (2D)
struct table2D crankingEnrichTable; //4 bin cranking Enrichment map (2D)
struct table2D dwellVCorrectionTable; //6 bin dwell voltage correction (2D)
struct table2D injectorVCorrectionTable; //6 bin injector voltage correction (2D)
struct table2D IATDensityCorrectionTable; //9 bin inlet air temperature density correction (2D)
struct table2D IATRetardTable; //6 bin ignition adjustment based on inlet air temperature  (2D)
struct table2D rotarySplitTable; //8 bin ignition split curve for rotary leading/trailing  (2D)
struct table2D flexFuelTable;  //6 bin flex fuel correction table for fuel adjustments (2D)
struct table2D flexAdvTable;   //6 bin flex fuel correction table for timing advance (2D)
struct table2D flexBoostTable; //6 bin flex fuel correction table for boost adjustments (2D)
struct table2D knockWindowStartTable;
struct table2D knockWindowDurationTable;
```


##ステータス変数
Tunerstudioでモニター可能な信号として、globals.hに[status](https://github.com/noisymime/speeduino/blob/201810/speeduino/globals.h#L329)構造体が定義されています。

- ステータス変数の例

|変数|型|意味|単位|
|:--|:--|:--|:--|
|currentStatus.RPM|uint16_t|回転数|rpm|
|currentStatus.TPS|byte |スロットルセンサ|%|
|currentStatus.VE|byte|体積効率|%|
|currentStatus.advance|int8_t|点火タイミング|deg|
|currentStatus.PW1|uint16_t|インジェクタパルス幅|us|

##パラメータ
- globals.hにパラメータ構造体[configxx](https://github.com/noisymime/speeduino/blob/201810/speeduino/globals.h#L429)が定義されています。
- パラメータ値の初期値は、ソースコードに定義されていません。:hushed:
- データは、EEPROMに値が記憶され、起動時に読み込まれます。
- TunerStudioでアクセスを行うため、ページ単位で管理されています。
- TunerStudioでパラメータをセットし、EEPROMに書き込みます。

- パラメータ変数の例

|変数|型|意味|
|:--|:--|:--|:--|
|[configPage2.tpsMin](https://github.com/noisymime/speeduino/blob/201810/speeduino/globals.h#L498)|byte|TPS A/D値Min|
|[configPage2.tpsMax](https://github.com/noisymime/speeduino/blob/201810/speeduino/globals.h#L499)|byte|TPS A/D値Max|

EEPROMアクセス関数

|関数|内容|
|:--|:--|
|[writeConfig()](https://github.com/noisymime/speeduino/blob/201810/speeduino/storage.ino#L32)|EEROM書き込み|
|[loadConfig()](https://github.com/noisymime/speeduino/blob/201810/speeduino/storage.ino#L393)|EEPROM読み出し|

##TunerStudio　データ定義
ステータス変数、パラメータはTunerStudioの下記ファイルにも定義されています。
ファイルを編集することで、TunerStudioに変数を修正や追加をすることもできます。:smiling_imp:

###[speeduino.ini](https://github.com/noisymime/speeduino/blob/201810/reference/speeduino.ini)
パラメータ定義 Page1-10
TunerStudioで設定するデータ名、データ型、スケールが定義されています。


パラメータの項目

|設定項目|意味|
|:--|:--|
|name|パラメータ名|
|bits/scalar/array|データ種類(ビット、スカラー、配列）|
|type|データ型(U08,U16等)|
|offset|オフセット（先頭から何バイト目かを示す）|
|bits|ビット（何ビット目かを示す）|
|shape|配列のサイズ|
|units|単位|
|scale|物理値変換のスケール|
|translate|物理値変換のオフセット|
|lo|最小値|
|hi|最大値|
|digits||

```ruby:speeduino.ini
page = 1
   ;  name       = bits,   type,    offset, bits
   ;  name       = array,  type,    offset, shape, units,     scale, translate,    lo,      hi, digits
   ;  name       = scalar, type,    offset,        units,     scale, translate,    lo,      hi, digits
      veTable    = array,  U08,       0, [16x16],"%",          1.0,      0.0,   0.0,   255.0,      0
      rpmBins    = array,  U08,     256, [  16], "RPM",      100.0,      0.0,   100.0, 25500.0,      0
      fuelLoadBins = array,  U08,   272, [  16], { bitStringValue(algorithmUnits ,  algorithm) },        2.0,      0.0,   0.0,   {fuelLoadMax},      0
      ;fuelLoadBins = array,  U08,   272, [  16], { bitStringValue(algorithmUnits ,  algorithm) },        2.0,      0.0,   0.0,   { arrayValue(rpmBins , algorithm) },      0



;--------------------------------------------------
;Start Page 2
;Page 2 is all general settings (Previously part of page 1)
;--------------------------------------------------
page = 2
      unused2-1     = scalar, S08,       0,         "kPa",      1.0,       0.0,   -127,    127,       0
      unused2-2     = 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
      crankingPct   = scalar, U08,      14,         "%",        1.0,       0.0,   0.0,    255,       0
      pinLayout     = bits,   U08,      15, [0:7],  "Speeduino v0.1", "Speeduino v0.2", "Speeduino v0.3", "Speeduino v0.4", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NA6 MX5 PNP", "Turtana PCB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Plazomat I/O 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "Daz V6 Shield 0.1", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "NO2C", "UA4C", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "dvjcodec Teensy RevA", "dvjcodec Teensy RevB", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID", "INVALID"
      tachoPin      = bits,   U08,      16, [0:5],  "Board Default", "1", "2", "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"
      tachoDiv      = bits,   U08,      16, [6:7],  "Normal", "Half", "INVALID", "INVALID"
      unused2-17    = scalar, U08,      17,         "ms",       0.1,       0.0,   0.0,    25.5,      1
      unused2-18    = scalar, U08,      18,         "ms",       0.1,       0.0,   0.0,    25.5,      1
      tpsThresh     = scalar, U08,      19,         "%/s",      1.0,       0.0,   0.0,    255,       0
      taeTime       = scalar, U08,      20,         "ms",        10,       0.0,   0.0,    2550,      0
```

ステータス変数
https://github.com/noisymime/speeduino/blob/201810/reference/speeduino.ini#L3118

```ruby:speeduino.ini
;-------------------------------------------------------------------------------

[OutputChannels]
   ; The number of bytes MegaTune or TunerStudio should expect as a result
   ; of sending the "A" command to Speeduino is determined
   ; by the value of ochBlockSize, so be very careful when
   ; you change it.

   ochGetCommand    = "r\$tsCanId\x30%2o%2c"
   ochBlockSize     =  90

   secl             = scalar, U08,  0, "sec",    1.000, 0.000
   status1          = scalar, U08,  1, "bits",   1.000, 0.000
    inj1Status       = bits,    U08,    1, [0:0]
    inj2Status       = bits,    U08,    1, [1:1]
    inj3Status       = bits,    U08,    1, [2:2]
    inj4Status       = bits,    U08,    1, [3:3]
    DFCOOn           = bits,    U08,    1, [4:4]
    boostCutFuel     = bits,    U08,    1, [5:5]
    toothLog1Ready   = bits,    U08,    1, [6:6]
    toothLog2Ready   = bits,    U08,    1, [7:7]
   engine           = scalar, U08,  2, "bits",   1.000, 0.000
    running          = bits,    U08,    2, [0:0]
    crank            = bits,    U08,    2, [1:1]
    ase              = bits,    U08,    2, [2:2]
    warmup           = bits,    U08,    2, [3:3]
    tpsaccaen        = bits,    U08,    2, [4:4]
    tpsaccden        = bits,    U08,    2, [5:5]
    mapaccaen        = bits,    U08,    2, [6:6]
    mapaccden        = bits,    U08,    2, [7:7]
   dwell	          = scalar,   U08,    3, "ms",     0.100, 0.000
   map              = scalar,   U16,      4, "kpa",    1.000, 0.000
```
###[Speeduino base tune.msq](https://github.com/noisymime/speeduino/blob/201810/reference/Base%20Tunes/Speeduino%20base%20tune.msq)



TunerStudioのパラメータ値が記述されています。

```ruby:Speeduino_base_tune.msq
<?xml version="1.0" encoding="ISO-8859-1"?>
<msq xmlns="http://www.msefi.com/:msq">
<bibliography author="TunerStudio MS(Beta) 3.0.60.33 - EFI Analytics, Inc." tuneComment="" writeDate="Thu Nov 15 22:10:26 AEDT 2018"/>
<versionInfo fileFormat="5.0" firmwareInfo="Speeduino+2018.8" nPages="10" signature="speeduino 201810"/>
<page>
<pcVariable name="tsCanId">"CAN ID 0"</pcVariable>
<pcVariable cols="1" digits="0" name="algorithmLimits" rows="8">
         511.0 
         100.0 
         511.0 
         511.0 
         100.0 
         100.0 
         100.0 
         100.0 
      </pcVariable>
<pcVariable digits="0" name="fuelLoadMax">255.0</pcVariable>
<pcVariable digits="0" name="ignLoadMax">255.0</pcVariable>
</page>
<page number="0" size="288">
<constant cols="16" digits="0" name="veTable" rows="16" units="%">
         39.0 39.0 39.0 39.0 39.0 38.0 37.0 36.0 35.0 34.0 33.0 33.0 33.0 33.0 33.0 33.0 
         40.0 40.0 41.0 42.0 42.0 41.0 40.0 39.0 39.0 39.0 39.0 39.0 40.0 40.0 40.0 40.0 
         40.0 42.0 43.0 46.0 46.0 45.0 44.0 43.0 42.0 42.0 43.0 43.0 43.0 44.0 44.0 44.0 
         42.0 45.0 47.0 51.0 51.0 49.0 48.0 47.0 46.0 46.0 46.0 47.0 47.0 47.0 48.0 48.0 
         44.0 49.0 52.0 56.0 55.0 54.0 52.0 51.0 50.0 50.0 50.0 50.0 51.0 51.0 51.0 52.0 
         48.0 54.0 58.0 61.0 59.0 58.0 56.0 55.0 54.0 53.0 54.0 54.0 54.0 55.0 55.0 55.0 
         54.0 61.0 64.0 66.0 64.0 62.0 61.0 59.0 58.0 57.0 57.0 58.0 58.0 59.0 59.0 59.0 
         60.0 67.0 70.0 70.0 68.0 67.0 65.0 63.0 62.0 61.0 61.0 61.0 62.0 63.0 63.0 63.0 
         67.0 74.0 76.0 75.0 73.0 71.0 69.0 68.0 66.0 64.0 65.0 65.0 66.0 66.0 67.0 67.0 
         74.0 80.0 81.0 79.0 77.0 75.0 73.0 72.0 70.0 68.0 68.0 69.0 69.0 70.0 70.0 71.0 
         81.0 85.0 86.0 84.0 82.0 80.0 78.0 76.0 74.0 72.0 72.0 72.0 73.0 74.0 74.0 74.0 
         87.0 91.0 91.0 88.0 86.0 84.0 82.0 80.0 78.0 76.0 76.0 76.0 77.0 78.0 78.0 78.0 
         93.0 93.0 93.0 93.0 93.0 90.0 88.0 86.0 84.0 83.0 83.0 83.0 84.0 85.0 85.0 86.0 
         93.0 93.0 93.0 93.0 93.0 92.0 90.0 88.0 86.0 86.0 86.0 87.0 88.0 89.0 89.0 90.0 
         93.0 93.0 93.0 93.0 93.0 93.0 93.0 90.0 90.0 90.0 90.0 91.0 92.0 93.0 93.0 93.0 
         93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 93.0 95.0 
      </constant>
<constant cols="1" digits="0" name="rpmBins" rows="16" units="RPM">
         500.0 
         700.0 
         900.0 
         1400.0 
         2000.0 
         2800.0 
         3600.0 
         4500.0 
         5200.0 
         5500.0 
         5800.0 
         6200.0 
         6500.0 
         6800.0 
         6900.0 
         7000.0 
      </constant>
<constant cols="1" digits="0" name="fuelLoadBins" rows="16" units="kPa">
         16.0 
         26.0 
         30.0 
         36.0 
         40.0 
         46.0 
         50.0 
         56.0 
         60.0 
         66.0 
         70.0 
         76.0 
         86.0 
         90.0 
         96.0 
         100.0 
      </constant>
</page>
```

##参考
- [TunerStudio Manual](http://www.tunerstudio.com/index.php/manuals)

##最後に
次回は、SpeeduinoのArduinoMega単体でプログラムの動作を確認するため、デバッグモードの追加を行う予定です。