Overview
MegaSquirt 1 comes with an RS-232
port that allows loading new firmware and the operation of such software
applications as TunerStudio. With a program such as Hyperterminal you
can send some rudimentary commands to MegaSquirt 1 (MS1) as is shown
in the assembly manual. With a programming language you can do more
sophisticated communication to retrieve data from MS1 or modify the
tables. The only requirement is that you have a programming language
such as C or Visual Basic and a method to send or receive strings
and data (an array of bytes) with RS232 (also referred to as COM1,
COM2 etc)
In this section I'll explain some of the commands for
MS1/Extra and demonstrate how to use Visual Basic 6.0 to use these
commands. I'll also show you how to read the msns-extra.ini
file to get more information on how to use the 'raw' data from MS1/Extra.
A VB 6.0 example program is available for download. It shows how to
download real time variables, and tables.
Basic Commands for MS1/Extra
Communications is established when the PC communications
program sends a command character - the particular character sets
the mode:
"A" = MS1 sends the
real time variables as an array of 22 bytes
"B" = MS1 jump to flash
burner routine and burn VE/constant values in RAM into flash
"C" = Test communications
- echo back SECL (timer, 0 to 255) as a byte
"P"+<page> =
MS1 loads page of data from Flash to RAM
"R" = MS1 sends the
real time variables as an array of 39 bytes
"S" = Signature - MS1
sends an identifier string (this is not the version)
"T" = Revision - MS1
sends the code version as a string
"V" = MS1 sends the
VE table and/or constants as an array of bytes
"W"+<offset>+<newbyte>
= MS1 receives new table or constant byte value and stores in 'offset'
location
"X"+<offset>+<count>+<newbyte>+<newbyte>....
MS1 receives series of new data bytes
These commands are the fundamental commands to perform
most functions that you find in TunerStudio. To use the command, send
a single letter (string) to MS1 and read the response from MS1 in
the input buffer. Some of the commands are followed by a single byte
or an array of bytes. For example "P" might be used to select
a specific table before using the 'V' command to read an array of
constants or a table.
Simple
communications with VB 6.0
Microsoft VB 6.0 (and Microsoft Excel) has the capability
to easily communicate with RS232 using the Microsoft COMM object.
To use the Microsoft COMM object it must be setup to the same communication
properties as MS1. First open VB using a form and then place the MS
COMM object on the form. It will be named MSCOMM1. Place a command
button on the form and copy or type in this code.
Private
Sub Command1_click ()
' Buffer to hold input string
Dim Version As Variant
' Use COM1.
MSComm1.CommPort = 1
' 9600 baud, no parity, 8 data, and 1 stop bit.
MSComm1.Settings = "9600,N,8,1"
' Tell the control to read entire buffer
' when Input is used.
MSComm1.InputLen = 0
'
Tell the control to get input as string
MSComm1.InputMode = comInputModeText
' Open the port.
MSComm1.PortOpen = True
' Send the get version command to MS
MSComm1.Output = "T"
' Wait for data to come back to the serial port.
Do
DoEvents
Loop Until MSComm1.InBufferCount > 10
' Read the response in the serial port.
Version = MSComm1.Input
' Close the serial port.
MSComm1.PortOpen = False
End Sub
With RS232 connected to the correct port and MS1 powered
up you will receive the version string from MS1 when clicking the
command button. Download VB 6.0 example
that demonstrates many of the above commands as well as reconstructing
tables.
"A"
&"R" command
The "A" command will return the real time variables
as an array of 22 bytes. The "R" command will return additional
data in an array of 39 bytes. Each byte represents a variable in MS1.
The variable names and properties for each byte are described in the
msn-extra.ini file shipped with each version of MS1/Extra. The "A"
command is the Megaview compatability mode. Once issued the "A"
command returns the right number of zeros to keep megaview happy.
* variable requires two bytes
Variable Name |
location (index) |
Units |
Description |
secl |
0 |
sec |
clock counter that continuously counts from 0 to 255 |
squirt |
1 |
bits |
Bit Description when high
0 inj1 squirt 1 inj2
squirt 2 scheduled to squirt
3 squirting 4 injector
2 (sched2) 5 squirting injector
2 6 boost control Off |
engine |
2 |
bits |
Engine current status
Bit Description when high
0 running
1 cranking
2 after start enrichment
(ASE)
3 in warmup
4 in TPS acceleration
mode
5 in deceleration mode
6 in MAP acceleration
mode
7 idle on |
baroADC |
3 |
ADC |
MAP value used for baro correction |
mapADC |
4 |
ADC |
Current MAP value |
matADC |
5 |
ADC |
Manifold air temperature |
cltADC |
6 |
ADC |
Coolant temperature |
tpsADC |
7 |
ADC |
Throttle position |
batADC |
8 |
ADC |
Battery voltage |
egoADC |
9 |
ADC |
Exhaust gas oxygen sensor |
egoCorrection |
10 |
% |
Exhaust gas correction |
airCorrection |
11 |
% |
Gair |
warmupEnrich |
12 |
% |
Warmup enrichment |
rpm100 |
13 |
r100 |
rpm divided by 100 |
pulsewidth1 |
14 |
ms |
Pulse width, divide by 10 to get ms |
accelEnrich |
15 |
ms |
|
baroCorrection |
16 |
% |
Barometer Lookup Correction |
gammaEnrich |
17 |
% |
Total Gamma Enrichments |
veCurr1 |
18 |
% |
Current VE value in use (table 1) |
pulsewidth2 |
19 |
ms |
Pulse width, divide by 10 to get ms |
veCurr2 |
20 |
% |
|
idleDC |
21 |
% |
|
iTime* |
22 |
s |
The interval Time - i.e. time between decoder triggers. It is
used for the "hi-res" rpm calculation.
( ctimeCommH in msns-extra.h file) This is the middle (H) byte
of a 3 byte value X:H:L |
iTime* |
23 |
s |
The interval Time - i.e. time between decoder triggers. It is
used for the "hi-res" rpm calculation.
( ctimeCommH in msns-extra.h file) This is the lower byte (L)
of a 3 byte value X:H:L |
advance |
24 |
deg |
raw ignition advance value. Multiply by actual = raw*0.352-10 |
afrTarget |
25 |
ADC |
Raw ADC target that MS is trying to reach from the target
table or switch point 255 = 5V |
fuelADC |
26 |
ADC |
Raw ADC from X7 (second O2 or fuel pressure or VSS sensor) |
egtADC |
27 |
ADC |
Raw ADC from X6 If Exhaust gas temp. then temp in
ºF = egtADC*7.15625
ºC = egtADC*3.90625 if VSS Volts = egtADC*0.019 |
CltIatAngle |
28 |
deg |
Spark Angle added or removed for IAT CLT temp. Angle
= raw value*0.352 (Angle < 45 Angle : -90 + Angle) |
KnockAngle |
29 |
deg |
Spark Angle removed due to Knock System |
egoCorrection2 |
30 |
% |
Same as egocorrection, but this is for second O2 sensor
|
porta |
31 |
bits |
Bit Description when high
0 Fuel Pump On
1 Fidle/Spark On
2 Output 2 On (X5)
3 Output 1/Boost Cont On (X4)
4 NOS/w Inj Pulsing On (X3)
5 Fan/w Inj On (X2)
6 Flyback
7 Flyback |
portb |
32 |
bits |
ADC inputs
Bit Description when high
0 MAP
1 MAT 2 CLT
3 TPS 4 BAT
5 EGO 6 "X7"
spare, EGO2, fuel pressure or 2nd MAP 7 "X6"
spare, EGT |
portc |
33 |
bits |
Bit Description
0 Squirt
LED or coil a 1 Accel LED or coil b
or HEI7 bypass 2 Fan/Output 4/coil
c On 3 multiplexed shift or coil
e 4 light outputs or 2nd trig
input |
portd |
34 |
bits |
Bit Description
0 unused or coil d
1 NOS/Tables Off
2 No Knock (low = knocked)
3 Launch Off
4 Inj1
5 Inj2 or used for X2 Electric
fan output |
stackL |
35 |
byte |
CPU stack |
tpsLast |
36 |
|
TPS/MAP last value for MT Accel Wizard, so we have last
and current values to give a gauge of dot (delta) |
iTimeX |
37 |
s |
The interval Time - i.e. time between decoder triggers. It is
used for the "hi-res" rpm calculation.
This is the highest byte (X) of a 3 byte value X:H:L |
bcdc |
38 |
% |
|
The data returned is 'raw' data as stored in MS1. To obtain maximum
resolution and at the same time use as little as possible memory space
the variables are scaled to best fit into the available memory. This
means that most variables will not be recognizable until they are
scaled to some user readable form. The scaling is dependent on the
chosen hardware or other options. The scaling is documented in the
file msns-extra.ini
As an example lets assume we have send the string "A" and
received an array of 22 bytes. We want to know the exhaust gas oxygen
sensor value. We read egoADC as a value of 142. This is the unscaled
'raw' value. To get the scaling we have to use the file msns-extra.ini
Open msns-extra.ini (found along with the firmware) and search
for egoADC. The first instance will be the listing of the above table.
Do another Find and you'll find this:
egoVoltage = { egoADC /
255.0 * 5.0 } ; EGO sensor voltage.
To find the voltage input to MS1/Extra Voltage = (egoADC/255)
* 5 or stated differently; the ego input voltage to MS1/Extra
is represented by 0-255 for the voltage range of 0-5V.
Let's use another example. Suppose we want to know the MAP value
in kPa. The raw value is mapADC. Do a Find in the msns-extra.ini file.
The first instance is in a line like this;
mapADCGauge = mapADC, "MAP ADC", "",
0, 255, -1, -1, 256, 256, 0, 0
This uses mapADC variable to set up a gauge to read the raw value.
Another Find and we get the table that gives the location of the
variable (as above).
Another Find and we see this:
#if MPXH6300A
; barometer = { table(baroADC, "kpafactor4250.inc") }
barometer = { (baroADC + 1.53) * 1.213675 }
map = { (mapADC + 1.53) * 1.213675 }
#elif MPXH6400A
; barometer = { table(baroADC, "kpafactor4250.inc") }
barometer = { (baroADC + 2.147) * 1.6197783 }
map = { (mapADC + 2.147) * 1.6197783 }
#elif MPX4250
barometer = { table(baroADC, "kpafactor4250.inc") }
map = { table(mapADC, "kpafactor4250.inc") } ; Manifold
pressure in kPa.
#else
barometer = { table(baroADC, "kpafactor4115.inc") }
map = { table(mapADC, "kpafactor4115.inc") }
These four paragraphs define how to compute the variable barometer
and map from the raw data. Each paragraph is for a different MAP sensor.
Let's look at the paragraph for the MPX4250 on the line
#elif MPX4250
Below the if statement we see;
map = { table(mapADC,
"kpafactor4250.inc") }
This means we can compute the variable map from
the variable mapADC (raw data) by using a table contained
in the file kpafactor4250.inc Lets assume that the
raw data is 76. When we look in the file we find this line:
KPA ADC Volts
DB 83T ; 76 -
1.490
76 is the raw ADC value. TunerStudio will interpret the raw value for
76 as a MAP value of 83kPa
VB 6.0 example:
Dim
Data As Variant
' Send command to MS as text
MSComm1.InputMode = comInputModeBinary
'
Send the commands to get a page
MSComm1.Output = "A"
'
wait 200 ms
delay 200
Data
= MSComm1.Input ' grab data from comm port.
"B" command
Burns all values of current page in the RAM to the ROM for permanent
storage. Values of current page are lost if the page is changed before
sending Burn command.
"C" command
Returns a byte of the counter (0-255) SECL. Read the counter like
this in VB
Dim DataIn As Variant
With MSComm1
.InputMode = comInputModeBinary
.Output = "C"
DataIn = .Input
End With
"S" & "T"
command
"S" returns the signature string and "T" returns
the version string. The signature indicates the last revision to the
msns-extra.ini file, and the version indicates the last revision of
the MS1/Extra firmware. Read version as shown
above in VB
"P" command
This command must be accompanied with a byte that selects
a page to load data from Flash to RAM. The table below lists the byte
to send for each pa ge. Search the file msns-extra.ini with "page
=" for the variables, tables and scaling of a page.
Page |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
byte value |
1 |
2 |
3 |
0 |
4 |
5 |
6 |
7 |
8 |
For a programming example, see the "V" and
"W" command below
"V"
command
Use the "V" command to read a page
of data after setting the page with the "P"command. The
"V" command will return an array of bytes that contain tables
and other variables. The table definition and variables are contained
in the msns-extra.ini file. Some commonly used tables are repeated
here for convenience. Some bytes may be zero for MegaView compatibility.
Table/variable name |
veBins1 |
veBins2 |
advTable1 |
advTable2 |
veBins3 |
afrBins1 |
afrBins2
(for ve3) |
Page (index) |
1(1) |
2(2) |
3(3) |
5(4) |
6(5) |
7(6) |
7(6) |
offset, start index |
0 |
0 |
0 |
0 |
0 |
0 |
80 |
size |
[12x12] |
[12x12] |
[12x12] |
[12x12] |
[12x12] |
[8x8] |
[8x8] |
For scaling and more details,
see the msns-extra.ini file. Pages are somewhat
different than variables outlined above in the "A" command,
but the concept is the same. Here is a line with headings from the
target AFR table 1 (afrBins1) on 'page' 7:
Variable
index <------- scale ------>
name type, size, offset, shape,
units, multipl. offset lo, hi, digits
afrBins1 = array, U08, 0, [8x8], "AFR",
0.0392, 255.0, 10.0,20.0, 1
The type is either array, bits, or scalar where
an array is multiple bytes of data (e.g. tables) bits is a byte where
each bit may have a True/False meaning, and scalar is a single number.
The size indicates the memory size. U08 is an unsigned
8 bit number, U16 is an unsigned 16 bit number and will require two
bytes of data.
Shape tells you the number of dimensions to the
array. A [12x12] shape indicates a two dimensional array such as a
VE table. A [12] is a one dimensional array such as the x or y axis
table data for MAP and rpm. The tables start on the lower left going
from left to right and up. See the example VB program for creating
a table.
Units are the human readable units. ADC means the
value from the analog to digital converter before they are scaled.
ADC units typically represent 0-5V max using 0-255
The scaling is done with a multiplier
and an offset (translate) to get to user units (in
the above example e AFR) use this formula:
userValue = (msValue + translate) * multiplier.
The lo and hi value
indicate the range of the values. In this example for an input of
0-5V (Innovate 0-5V LC-1) the user units will range from an AFR of
10 to 20. The scaling values will be different for different sensor
settings. Do a search of the variable in the msns-extra.ini file for
details.
The digits indicates the number of useful digits
after the decimal point.
This snippet of code demonstrates how to set up page1 and then read
the table and constants from that page into an array.
Dim
DataOut As Variant
Dim byteArray(2) As Byte
'
Send command to MS as array of bytes
MSComm1.InputMode = comInputModeBinary
byteArray(0)
= Asc("P")
byteArray(1) = 1
byteArray(2) = Asc("V")
DataOut = byteArray
'
Send the commands to get a page of data
MSComm1.Output = DataOut
delay 100 ' delay 100 ms
DataIn = MSComm1.Input ' grab data from comm port.
"W" command
Use the "W" command to change one byte on the currently
set page. To change one byte first set the page with the "P"
command, and then send the character "W" followed first
by the location of the byte on the page, and then the byte value.
In this VB 6.0 example, first we put the commands, start position,
byte position and the byte value in a byte array. We then sent the
byte array. The bottom left value of the table will change to 99 in
RAM.
Dim
DataOut As Variant
Dim byteArray(4) As Byte
MSComm1.InputMode
= comInputModeBinary
'
Set the page of table 1
byteArray(0) = Asc("P")
byteArray(1) = 1
' The start position
of
' table and the table value
byteArray(2) = Asc("W") '
write cmd
byteArray(3) = 0 '
position in page
byteArray(4) = 99 '
value
DataOut = byteArray
MSComm1.Output = DataOut