-
-
Save brianbri6/671a8ab96d0f52e6d60182e9eba4723b to your computer and use it in GitHub Desktop.
Chevy Volt / Opel Ampera SHVCS DTC Clearing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* This is an experimental script which I used to successfully clear the "Service High Voltage Charging System" message which can occur due to a loss of isolation. | |
* Previously I had to pay frequently to access the expensive SPS programming system to clear this code whilst attempting to resolve the underlying cause. | |
* This script was generated by a tool I developed to analyse J2534 log files. | |
* This could work for other cars but I can't comment on success. Please do not run this unless you understand the consequences! | |
* I intend to convert to a version that will work with ELM327 once I learn how these work. | |
* The program requires the J2534-Sharp library as a dependency. | |
* https://github.com/BrianHumlicek/J2534-Sharp | |
*/ | |
using System; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using SAE.J2534; | |
namespace J5234Examples | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Device device1; | |
Channel channel1; | |
int filter1; | |
int filter2; | |
// Change this line is using something different to the VXDIAG VCX Nano! | |
string DllFileName = APIFactory.GetAPIinfo().First(api => api.Name.Contains("VXDIAG")).Filename; | |
API API = APIFactory.GetAPI(DllFileName); | |
Console.WriteLine("PTOpen"); | |
device1 = API.GetDevice(); | |
Console.WriteLine("PTReadVersion"); | |
Console.WriteLine(device1.FirmwareVersion); | |
Console.WriteLine("PTConnect"); | |
// 6 = ISO15765 | |
channel1 = device1.GetChannel((Protocol)6, (Baud)500000, 0); | |
Console.WriteLine("PTIoctl"); | |
// 32768 = CAN_MIXED_FORMAT | |
channel1.SetConfig(new[] { new SConfig((Parameter)32768, 1) }); | |
Console.WriteLine("PTStartMsgFilter"); | |
filter1 = channel1.StartMsgFilter(new MessageFilter() { FilterType = (Filter)3, Mask = new byte[] { 0xff, 0xff, 0xff, 0xff }, Pattern = new byte[] { 0x00, 0x00, 0x07, 0xec }, FlowControl = new byte[] { 0x00, 0x00, 0x07, 0xe4 } }); | |
Console.WriteLine("PTStartMsgFilter"); | |
filter2 = channel1.StartMsgFilter(new MessageFilter() { FilterType = (Filter)1, Mask = new byte[] { 0xff, 0xff, 0xff, 0xff }, Pattern = new byte[] { 0x00, 0x00, 0x05, 0xec }, FlowControl = null }); | |
Console.WriteLine("Pause"); | |
Console.WriteLine("Sleep(2000)\n"); | |
Thread.Sleep(2000); | |
Console.WriteLine("PTWriteMsgs"); | |
Console.WriteLine(">>> 00 00 07 e4 27 01"); | |
// 64 = ISO15765_FRAME_PAD | |
channel1.SendMessages(new[] { new Message(new byte[] { 0x00, 0x00, 0x07, 0xe4, 0x27, 0x01 }, (TxFlag)64) }); | |
Console.WriteLine("ReadBlock"); | |
ReadUntilMessage(channel1, new byte[] { 0x00, 0x00, 0x07, 0xec, 0x67, 0x01, 0x58, 0xe3 }, 1500); | |
Console.WriteLine("PTWriteMsgs"); | |
Console.WriteLine(">>> 00 00 07 e4 27 02 75 6c"); | |
// 64 = ISO15765_FRAME_PAD | |
channel1.SendMessages(new[] { new Message(new byte[] { 0x00, 0x00, 0x07, 0xe4, 0x27, 0x02, 0x75, 0x6c }, (TxFlag)64) }); | |
Console.WriteLine("ReadBlock"); | |
ReadUntilMessage(channel1, new byte[] { 0x00, 0x00, 0x07, 0xec, 0x67, 0x02 }, 1500); | |
Console.WriteLine("PTWriteMsgs"); | |
Console.WriteLine(">>> 00 00 07 e4 ae fc 02 00 00 46 00"); | |
// 64 = ISO15765_FRAME_PAD | |
channel1.SendMessages(new[] { new Message(new byte[] { 0x00, 0x00, 0x07, 0xe4, 0xae, 0xfc, 0x02, 0x00, 0x00, 0x46, 0x00 }, (TxFlag)64) }); | |
Console.WriteLine("ReadBlock"); | |
ReadUntilMessage(channel1, new byte[] { 0x00, 0x00, 0x07, 0xec, 0xee, 0xfc }, 1500); | |
Console.WriteLine("PTWriteMsgs"); | |
Console.WriteLine(">>> 00 00 07 e4 ae fc 02 00 00 49 00"); | |
// 64 = ISO15765_FRAME_PAD | |
channel1.SendMessages(new[] { new Message(new byte[] { 0x00, 0x00, 0x07, 0xe4, 0xae, 0xfc, 0x02, 0x00, 0x00, 0x49, 0x00 }, (TxFlag)64) }); | |
Console.WriteLine("ReadBlock"); | |
ReadUntilMessage(channel1, new byte[] { 0x00, 0x00, 0x07, 0xec, 0xee, 0xfc }, 7000); | |
Console.WriteLine("Pause"); | |
Console.WriteLine("Sleep(2000)\n"); | |
Thread.Sleep(2000); | |
Console.WriteLine("PTStopMsgFilter"); | |
channel1.StopMsgFilter(filter1); | |
Console.WriteLine("PTStopMsgFilter"); | |
channel1.StopMsgFilter(filter2); | |
Console.WriteLine("PTDisconnect"); | |
channel1.Dispose(); | |
Console.WriteLine("PTClose"); | |
device1.Dispose(); | |
} | |
static void ReadUntilMessage(Channel c, byte[] message, int timeout) | |
{ | |
var attempts = 5; | |
Console.WriteLine("ReadUntilMessage: " + BytesToHexString(message)); | |
while (true) | |
{ | |
var results = c.GetMessages(1, timeout); | |
PrintBytes(results); | |
if (results.Result == ResultCode.BUFFER_EMPTY) | |
{ | |
Console.WriteLine("Waiting for message..."); | |
attempts--; | |
if (attempts == 0) return; | |
continue; | |
} | |
if (results.Messages.Length == 1) | |
{ | |
if (results.Messages[0].Data.SequenceEqual(message)) | |
{ | |
Console.WriteLine("FOUND\n"); | |
return; | |
} | |
} | |
} | |
} | |
static string BytesToHexString(byte[] bytes) | |
{ | |
StringBuilder builder = new StringBuilder(); | |
for (int i = 0; i < bytes.Length; i++) | |
{ | |
builder.Append(bytes[i].ToString("x2")); | |
} | |
return builder.ToString(); | |
} | |
static void PrintBytes(GetMessageResults results) | |
{ | |
StringBuilder builder = new StringBuilder(); | |
foreach (var msg in results.Messages) | |
{ | |
for (int i = 0; i < msg.Data.Length; i++) | |
{ | |
builder.Append(msg.Data[i].ToString("x2")); | |
} | |
builder.Append("\n"); | |
} | |
Console.WriteLine(builder.ToString()); | |
} | |
} | |
} |
What do i need for this to work if you have used it ?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Please can you give me info on how to use this please?