32-bit to 64-bit, Maestro

I’m having some trouble with an app that controls a Maestro. It worked in Windows XP 32-bit. In Windows 7 64-bit the app can still connect but it’s like the commands aren’t being received. Here is a snippet of code that I suspect, my suspicion is that the 0xA7 and 0x03 don’t have the same value in the 64-bit environment … this is pure speculation as I have no idea.

                    else if (bit8.Equals("1") & outFlag != "Checkered Flag")
                    {
                        outFlag = "Checkered Flag";
                        SP.Write(new byte[] { 0xA7, 0X03 }, 0, 2);
                        Console.WriteLine("Checkered Flag - " + Convert.ToString(lapdistpct));
                    }

SP.Write is sending the command to change subroutines on the Maestro. This is what I suspect no longer works. Is the coding different between 32-bit and 64-bit? Any help, advice, or direction would be fantastic.

Hello.

What language is this? Is it C#?

The expression “else if (bit8.Equals(“1”) & outFlag != “Checkered Flag”)” looks very suspect to me. Are you sure you didn’t mean && instead of &?

Could you simplify your code down to the simplest possible thing that should work but doesn’t, and post it in its entirety here? It should just open the serial port and send a single command.

–David

Thanks for the response David. I appreciate the help. Yes, it is C#. Here is the full, was working in XP, code. Now in 64-bit Windows the app runs, but it’s like the Maestro isn’t getting the serial commands. I didn’t know if that was a result of the Hex values behaving differently in Windows 7 64-bit.

This app interfaces with the iRacing software API. I read the flag conditions from the API and tell the Maestro when to jump into and out of subroutines to control the LEDs. Here is a youtube video of what it is: http://www.youtube.com/watch?v=HpXlL0OYhrU&feature=plcp

Should I be able to send decimal values instead of hex? Like SP.Write(new byte[] { 167,8 }, 0, 2); Instead of SP.Write(new byte[] { 0xA7, 0x08 }, 0, 2);

I know that the flag logic is working because the console app is still running and it displays the current flag in text. The only thing that is missing is the lights changing. The console app is working as expected.

Also … I know the code is rough. I’m not a great coder. I pieced it together with the knowledge I had. Thanks again.

using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using iRSDKSharp;
using Pololu.UsbWrapper;
using Pololu.Usc;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
        Begin:
            Console.WriteLine("CautionLights v1.0 -- written by Steve Nuzum Jr. - " + DateTime.Now);
            SerialPort SP = new SerialPort("COM4", 300, Parity.None, 8);
            iRacingSDK sdk = new iRacingSDK();
            string outFlag = "No Flag";
            string ontrackflag = "No";
            int SessionState;
            int intSessionLaps;
            int intMidwayLap = -99;
            int SessionFlags;
            string txtSessionFlags;
            string hexValue;
            decimal[] position = new decimal[64];
            decimal[] lappct = new decimal[64];
            decimal[] laps = new decimal[64];
            decimal lapdistpct = Convert.ToDecimal(sdk.GetData("LapDistPct"));
            int lap = Convert.ToInt16(sdk.GetData("Lap"));
            decimal myposition = Convert.ToDecimal(lap) + lapdistpct;
            int[] laps1 = (int[])sdk.GetData("CarIdxLap");
            float[] lappct1 = (float[])sdk.GetData("CarIdxLapDistPct");
            string byteSessionFlags = Convert.ToString(sdk.GetData("SessionFlags"));
            int gotDataOutput = 0;
            int currentSessionState = 0;
            Int16 intvalue;
            int newUpdate = 0;
            int lastUpdate = 0;
            bool ParseResult;
            String ParseAttempt;

            SP.Open();

            while (!sdk.IsConnected())
            {
                sdk.Startup();
                Thread.Sleep(10000);
            }

            while (sdk.IsConnected())
            {
                if (gotDataOutput.Equals(0))
                {
                    Console.WriteLine("Track Name: " + YamlParser.Parse(sdk.GetSessionInfo(), "WeekendInfo:TrackName:"));
                    Console.WriteLine("Event Type: " + YamlParser.Parse(sdk.GetSessionInfo(), "WeekendInfo:EventType:"));
                    Console.WriteLine("Session Type: " + YamlParser.Parse(sdk.GetSessionInfo(), "SessionInfo:SessionType:"));
                    Console.WriteLine("Start Type: " + YamlParser.Parse(sdk.GetSessionInfo(), "WeekendInfo:WeekendOptions:StandingStart:"));
                    Console.WriteLine("Session ID: " + YamlParser.Parse(sdk.GetSessionInfo(), "WeekendInfo:SessionID:"));
                    Console.WriteLine("Sub Session ID: " + YamlParser.Parse(sdk.GetSessionInfo(), "WeekendInfo:SubSessionID:"));
                    gotDataOutput = 1;
                }

                if (Convert.ToInt16(sdk.GetData("Lap")) > lap)
                {
                    Console.WriteLine("Lap: " + Convert.ToString(sdk.GetData("Lap")));
                }

                lapdistpct = Convert.ToDecimal(sdk.GetData("LapDistPct"));
                lap = Convert.ToInt16(sdk.GetData("Lap"));
                myposition = Convert.ToDecimal(lap) + lapdistpct;
                laps1 = (int[])sdk.GetData("CarIdxLap");
                lappct1 = (float[])sdk.GetData("CarIdxLapDistPct");
                byteSessionFlags = Convert.ToString(sdk.GetData("SessionFlags"));
                SessionState = Convert.ToInt16(sdk.GetData("SessionState"));
                int currentSessionNumber = sdk.GetData(“SessionNum”);

                if (lappct1 != null)
                {
                    for (int x = 0; x < lappct1.Length; x++)
                    {
                        lappct[x] = Convert.ToDecimal(lappct1[x]);
                    }
                }

                if (laps1 != null)
                {
                    for (int x = 0; x < laps1.Length; x++)
                    {
                        laps[x] = Convert.ToDecimal(laps1[x]);
                    }
                }

                if (laps != null & lappct != null)
                {
                    for (int a = 0; a < 64; a++)
                    {
                        position[a] = laps[a] + lappct[a];
                    }
                }

                var yournumber = (from nbr in position where nbr < 1000 select nbr).Max();
                int leaderpct = Array.IndexOf(position, yournumber);

                bool ontrack = Convert.ToBoolean(sdk.GetData("IsOnTrack"));

                //if (sdh.sessionInfoUpdate.Equals(true))
                //{
                //Console.WriteLine("We should see something next, get session info");
                /******* OLD GET INFO STUFF **********\
                if (info == null || lap.Equals(1))
                {
                    result = "0";
                    info = sdk.GetSessionInfo();
                    Console.WriteLine("Got the info");
                    String sessionType = YamlParser.Parse(sdk.GetSessionInfo(), "SessionInfo:SessionType:");
                    Console.WriteLine("SESSION TYPE:" + sessionType);

                    if (info == null)
                    {
                        start = -1;
                        result = "-1";
                        Console.WriteLine("we set the result to -1");
                    }
                    else
                    {
                        start = info.IndexOf("SessionLaps");
                        gotinfo = "Yes";
                        if (info.Length > 500)
                            result = info.Substring((start + 13), 3);
                        Console.WriteLine("We got the session info: " + Convert.ToString(result));
                        Console.WriteLine(sdk.GetData("SessionState"));
                    }
                
                    if (result == "unl" || result == null)
                    {
                        Console.WriteLine(result);
                        result = "-99";
                        intSessionLaps = 0;
                        Console.WriteLine("We set the result to -99");
                    }
                    else
                    {
                        intSessionLaps = Convert.ToInt32(result);
                        intMidwayLap = intSessionLaps / 2;
                        Console.WriteLine(Convert.ToString(intMidwayLap) + " - midwaylap");
                        Console.WriteLine(Convert.ToString(intSessionLaps) + " - Sessionlaps");
                    }
                }
                */

                //********** NEW GET INFO STUFF ***********//
                    newUpdate = sdk.Header.SessionInfoUpdate;
                    Console.WriteLine("New Update Value: " + newUpdate);
                    String sessionType = YamlParser.Parse(sdk.GetSessionInfo(), "SessionInfo:Sessions:SessionNum:{0}SessionType:", currentSessionNumber);
                    //Console.WriteLine("Session Type: " + sessionType);
                    //Console.WriteLine(SessionState);

                    if (((currentSessionState != SessionState) & ontrack & (newUpdate != lastUpdate)) || lap.Equals(1))
                    {
                        lastUpdate = newUpdate;
                        Console.WriteLine("Session State change from: " + 
                            Convert.ToString(currentSessionState) + " to " + Convert.ToString(SessionState));
                        currentSessionState = SessionState;
                        ParseAttempt = YamlParser.Parse(sdk.GetSessionInfo(), "SessionInfo:Sessions:SessionNum:{0}SessionLaps:", currentSessionNumber);
                        Console.WriteLine(ParseAttempt);
                        ParseResult = Int16.TryParse(ParseAttempt, out intvalue);
                        Console.WriteLine(ParseResult);
                        if (ParseResult)
                        {
//                          Console.WriteLine("BEAT THE PARSER");
//                          Console.WriteLine("Session State: " + SessionState);
                            intSessionLaps = Convert.ToInt16(YamlParser.Parse(sdk.GetSessionInfo(), "SessionInfo:Sessions:SessionNum:{0}SessionLaps:", currentSessionNumber));
                            intMidwayLap = intSessionLaps / 2;
                            Console.WriteLine("Midway lap: " + Convert.ToString(intMidwayLap));
                            Console.WriteLine("Session Laps: " + Convert.ToString(intSessionLaps));
                        }
                        else
                        {
                            Console.WriteLine("Unlimited Lap Session State");
                        }
                    }
                // ********** END NEW GET INFO STUFF ********** //

                if (ontrack == false & ontrackflag != "No")
                {
                    SP.Write(new byte[] { 0XA7, 0x04 }, 0, 2);
                    Thread.Sleep(1000);
                    outFlag = "In Garage";
                    ontrackflag = "No";
                    Console.WriteLine("In Garage");
                }
                else if (sdk.IsConnected() & ontrack)
                {
                    Thread.Sleep(750);
                    SessionFlags = Convert.ToInt32(sdk.GetData("SessionFlags"));
                    txtSessionFlags = Convert.ToString(SessionFlags);
                    hexValue = SessionFlags.ToString("X");
                    ontrackflag = "Yes";

                    string bit1 = "0";
                    string bit2 = "0";
                    string bit3 = "0";
                    string bit4 = "0";
                    string bit5 = "0";
                    string bit6 = "0";
                    string bit7 = "0";
                    string bit8 = "0";

                    if (hexValue.Length > 0)
                        bit1 = hexValue.Substring(0, 1);
                    if (hexValue.Length > 1)
                        bit2 = hexValue.Substring(1, 1);
                    if (hexValue.Length > 2)
                        bit3 = hexValue.Substring(2, 1);
                    if (hexValue.Length > 3)
                        bit4 = hexValue.Substring(3, 1);
                    if (hexValue.Length > 4)
                        bit5 = hexValue.Substring(4, 1);
                    if (hexValue.Length > 5)
                        bit6 = hexValue.Substring(5, 1);
                    if (hexValue.Length > 6)
                        bit7 = hexValue.Substring(6, 1);
                    if (hexValue.Length > 7)
                        bit8 = hexValue.Substring(7, 1);

                    if ((bit5.Equals("4") || bit5.Equals("8")) & (outFlag != "Caution Flag"))
                    {
                        outFlag = "Caution Flag";
                        SP.Write(new byte[] { 0xA7, 0X05 }, 0, 2);
                        Console.WriteLine("Caution Flag - " + Convert.ToString(lapdistpct));
                    }
                    else if (outFlag != "Blue Flag" & (lap > 0) & ((lapdistpct * 100) - (lappct[leaderpct] * 100) < 8) & ((lapdistpct * 100) - (lappct[leaderpct] * 100) > 0))
                    {
                        outFlag = "Blue Flag";
                        SP.Write(new byte[] { 0xA7, 0x08 }, 0, 2);
                        Console.WriteLine("Blue Flag - " + Convert.ToString(lapdistpct));
                    }
                    else if (bit8.Equals("1") & outFlag != "Checkered Flag")
                    {
                        outFlag = "Checkered Flag";
                        SP.Write(new byte[] { 0xA7, 0X03 }, 0, 2);
                        Console.WriteLine("Checkered Flag - " + Convert.ToString(lapdistpct));
                    }
                    else if (bit8.Equals("2") & outFlag != "White Flag")
                    {
                        outFlag = "White Flag";
                        SP.Write(new byte[] { 0xA7, 0X02 }, 0, 2);
                        Console.WriteLine("White Flag - " + Convert.ToString(lapdistpct));
                    }
                    else if (bit4.Equals("2") || bit4.Equals("5") & (outFlag != "Black Flag" & outFlag != "Black Flag Repair"))
                    {
                        outFlag = "Black Flag";
                        SP.Write(new byte[] { 0XA7, 0X06 }, 0, 2);
                        Console.WriteLine("Black Flag - " + Convert.ToString(lapdistpct));
                    }
                    else if (bit3.Equals("1") & (outFlag != "Black Flag Repair" & outFlag != "Black Flag"))
                    {
                        outFlag = "Black Flag Repair";
                        SP.Write(new byte[] { 0XA7, 0X09 }, 0, 2);
                        Console.WriteLine("Black Flag Repair - " + Convert.ToString(lapdistpct));
                    }
                    else if (bit8.Equals("4") & outFlag != "Green Flag Waving")
                    {
                        outFlag = "Green Flag Waving";
                        SP.Write(new byte[] { 0xA7, 0X01 }, 0, 2);
                        Console.WriteLine("Green Flag Waving - " + Convert.ToString(lapdistpct));
                    }
                    else if (bit1.Equals("1") & bit4.Equals("4") & bit3.Equals("0") & bit8.Equals("0") & (outFlag != "Green Flag") &
                        (bit8 != "4") & lap != intMidwayLap & (((lapdistpct * 100) - (lappct[leaderpct] * 100) > 8) || ((lapdistpct * 100) - (lappct[leaderpct] * 100) < 1))
                        & bit5 != ("4") & bit5 != ("8") & (lap > 0)) 
                    {
                        outFlag = "Green Flag";
                        SP.Write(new byte[] { 0xA7, 0X00 }, 0, 2);
                        Console.WriteLine("Green Flag - " + Convert.ToString(lapdistpct));
                    }
                    else if (outFlag != "Half Way Flag" & lap.Equals(intMidwayLap))
                    {
                            outFlag = "Half Way Flag";
                            SP.Write(new byte[] { 0xA7, 0X07 }, 0, 2);
                            Console.WriteLine("Half Way Flag - " + Convert.ToString(lapdistpct));
                    }
                }
                else
                {
                    sdk.Startup();
                }
            }

            SP.Write(new byte[] { 0XA7, 0x04 }, 0, 2);
            Thread.Sleep(500);
            SP.Write(new byte[] { 0XA4 }, 0, 1);
            SP.Close();
            sdk.Shutdown();

            if (!sdk.IsConnected())
            {
                goto Begin;
            }
            }
    }
}

It probably is not.

You cannot actually send decimal values OR hex values. You are sending bytes to the Maestro. Every byte is a series of 8 bits, with no preference for any particular kind of representation. Whether you write the byte in hex or decimal in your C# source code, it is only the value of the byte that actually matters. Both of the ways you wrote your command are equivalent.

Your code is complicated and has many code paths. It is possible that you might be sending some command that contradicts the 0xA7 0x08 a couple milliseconds later. Maybe you are accidentally sending the 0xA7 0x08 command over and over again, forcing the Maestro to keep restarting the script so that the script never actually makes any progress. To rule out all of these possibilities, you should simplify your code to the simplest thing that should work but doesn’t.

–David

I think Visual Studio lets you select between “Any CPU”, “x86”, and “x64” when compiling. If this really is a 32-bit/64-bit issue, maybe selecting the right option there would solve your problem.

–David