Jump to content
The simFlight Network Forums

FSUIPC v3.999z8 Offset data conversion Lazarus/Delphi


Recommended Posts

Hello developers (and Pete offcourse!),

 

I'm currently busy programming for FSUIPC via Lazarus/Delphi. I'm building a program which is able to read and change radio frequencies from FSUIPC, and will eventually be controllable via Arduino.

 

Currently the program doesn't work and it states an error about the offset is not an integer..., but it did work in the past (most of the time some frequencies work, and other don't). It seems to be a data-conversion issue, which seems to be different every time I start FS. I know that the offset-data is in BCD format. Can anyone please help me out with the conversion?

procedure TFormMain.FormCreate(Sender: TObject);
var
   dwResult : DWORD;
begin
  // Verbinding maken met FSUIPC
  if FSUIPC_Open(SIM_Any, dwResult) then begin
    // Status wanneer verbonden tonen
    Lbl_FSUIPC_Conn_status.Caption := 'Connected'
  end else begin
    // Status wanneer niet verbonden tonen
    Lbl_FSUIPC_Conn_status.Caption := 'Not connected'
  end;
end;

procedure TFormMain.TimerRefreshDataTimer(Sender: TObject);
var
  dwResult : DWORD;
  int_COMM1_Active_FS_frequency, int2_COMM1_Active_FS_frequency, int_NAV1_Active_FS_frequency, int2_NAV1_Active_FS_frequency, int_COMM1_Standby_FS_frequency, int2_COMM1_Standby_FS_frequency, int_NAV1_Standby_FS_frequency, int2_NAV1_Standby_FS_frequency: integer;
  str_COMM1_Active_FS_frequency, str_NAV1_Active_FS_frequency, str_COMM1_Standby_FS_frequency, str_NAV1_Standby_FS_frequency : string;
begin
  // COMM1 Active uit FS lezen
  if FSUIPC_Read($034E, 2, @int_COMM1_Active_FS_frequency, dwResult) then begin
    // "Read" voltooid, dan:
    if FSUIPC_Process(dwResult) then begin
      // "Process" wanneer voltooid, dan:
      str_COMM1_Active_FS_frequency := IntToHex(int_COMM1_Active_FS_frequency,1);
      int2_COMM1_Active_FS_frequency := StrToInt(str_COMM1_Active_FS_frequency);
      int2_COMM1_Active_FS_frequency := 10000 + int2_COMM1_Active_FS_frequency;
      Lbl_COMM1_Active_frequency.Caption := IntToStr(int2_COMM1_Active_FS_frequency);
    end
  end;
  // NAV1 uit FS lezen
  if FSUIPC_Read($0350, 2, @int_NAV1_Active_FS_frequency, dwResult) then begin
    // "Read" voltooid, dan:
    if FSUIPC_Process(dwResult) then begin
      // "Process" wanneer voltooid, dan:
      str_NAV1_Active_FS_frequency := IntToHex(int_NAV1_Active_FS_frequency,1);
      int2_NAV1_Active_FS_frequency := StrToInt(str_NAV1_Active_FS_frequency);
      int2_NAV1_Active_FS_frequency := 10000 + int2_NAV1_Active_FS_frequency;
      Lbl_NAV1_Active_frequency.Caption := IntToStr(int2_NAV1_Active_FS_frequency);
    end
  end;
    // COMM1 Standby uit FS lezen
  // COMM1 Standby uit FS lezen
  if FSUIPC_Read($311A, 2, @int_COMM1_Standby_FS_frequency, dwResult) then begin
    // "Read" voltooid, dan:
    if FSUIPC_Process(dwResult) then begin
      // "Process" wanneer voltooid, dan:
      str_COMM1_Standby_FS_frequency := IntToHex(int_COMM1_Standby_FS_frequency,1);
      int2_COMM1_Standby_FS_frequency := StrToInt(str_COMM1_Standby_FS_frequency);
      int2_COMM1_Standby_FS_frequency := 10000 + int2_COMM1_Standby_FS_frequency;
      Lbl_COMM1_Standby_frequency.Caption := IntToStr(int2_COMM1_Standby_FS_frequency);
    end
  end;
  // NAV1 Standby uit FS lezen
  if FSUIPC_Read($311E, 2, @int_NAV1_Standby_FS_frequency, dwResult) then begin
    // "Read" voltooid, dan:
    if FSUIPC_Process(dwResult) then begin
      // "Process" wanneer voltooid, dan:
      str_NAV1_Standby_FS_frequency := IntToHex(int_NAV1_Standby_FS_frequency,1);
      int2_NAV1_Standby_FS_frequency := StrToInt(str_NAV1_Standby_FS_frequency);
      int2_NAV1_Standby_FS_frequency := 10000 + int2_NAV1_Standby_FS_frequency;
      Lbl_NAV1_Standby_frequency.Caption := IntToStr(int2_NAV1_Standby_FS_frequency);
    end
  end;
end;

I hope you can help me with my problem!

 

Jesse

Link to comment
Share on other sites

Currently the program doesn't work and it states an error about the offset is not an integer..., but it did work in the past (most of the time some frequencies work, and other don't). It seems to be a data-conversion issue, which seems to be different every time I start FS. I know that the offset-data is in BCD format. Can anyone please help me out with the conversion?

 

Sorry, but I am not familiar with Lazarus Delphi. But doesn't is come with a Debugger? Have you tried checking WHERE it is failing, i.e. which line? Without such basic detail I don't expect anyone could help.

 

There are certainly no error messages like that from FSUIPC, so it is all to do with the language and the library functions you are using!

 

Pete

Link to comment
Share on other sites

  • 2 weeks later...

I understand that you don't have all the information that you need to solve my problem.

To be more precise, the data coming from offsets 034E, 0350, 311A and 311E is, following the manual, in BCD-format. Now I try to store that data as string, then I try to convert that to a integer to gain the posibillity to edit the value further on in my program. So the conversion from the raw data from FSUIPC to the integer in my program is not working. I see they can make a raw- to calculated data conversion in the  FSUIPC data monitor I bought, so for me, it seems possible. Can anyone please help me how I should do it?

 

Thanks in advance,

 

Jesse

Link to comment
Share on other sites

I understand that you don't have all the information that you need to solve my problem.

To be more precise, the data coming from offsets 034E, 0350, 311A and 311E is, following the manual, in BCD-format. Now I try to store that data as string, then I try to convert that to a integer to gain the posibillity to edit the value further on in my program. So the conversion from the raw data from FSUIPC to the integer in my program is not working.

 

These values should be read as integers in any case -- they are 16-bit short unsigned integers! It would never work reading them as "strings"! Strings are numbers of ASCII characters, one character to an 8-bit byte! How do you think 4 hexadecimal digits can fit as 4 characters into a 16-bit value?

 

BCD means Binary-Coded Decimal. The "Binary" part of that is the key. The value is a decimal value, but coded in such a way that each 4 bits contains one of the decimal digits you want!

 

For example, the hexadecimal value 0x1895, has the decimal integer value 6293 but represents the frequency 118.95 (the first 1 is assumed). So you just read it and split off each group of 4 bits in turn. You can do that either by logical shifts and "Ands", or by repeated division by 16, taking the remainders each time.

 

If you want the frequency as a string for display, use a formatting command to show it as hexadecimal. In C, using the standard library, that would be

 

char result[7];

sprinf(result, "1%02X.%02X", value/256, value%256);

 

The result of this in the example 0x1895 would be "118.95". I split the upper 8 bits from the lower so I could insert the decimal point.

 

Pete

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.