RS-232 Communication with MS1/Extra

Only for use with the MS1 Extra code (MS1 - 68H908 based microprocessors)

By Philip Ringwood (daxtojeiro), James Murray (jsmcortina) and Ken Culver (muythaibxr)


Before you start any hardware mods please read this entire manual and the Software Manual, available HERE.

For other MS1 Extra Manuals please see HERE

Warning for
E-Bay buyers!!
Please see the Official Suppliers list before buying through E-Bay.
This is there for your protection.

Please Note:

All of these instructions / diagrams are to be used at your own risk, like most things there is more than one way to do the same thing, what we have tried to do is to offer a method that we have tested or that others have tested for us. No warranty expressed or implied.

Use at your own risk.


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 valu
e
   byteArray(2) = Asc("W") ' write cmd
   byteArray(3) = 0        ' position in page
   byteArray(4) = 99       ' value
   DataOut = byteArray
   MSComm1.Output = DataOut