Recent

Author Topic: Single array to extended array  (Read 6307 times)

CM630

  • Hero Member
  • *****
  • Posts: 1743
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Single array to extended array
« on: November 16, 2012, 02:58:39 pm »
I did a procedure in which I have an 2D extended array (array of array of extended).
For some reason the procedure crashes when I use it.
So I made array of array of single.
The problem is that a 1D array of extended (array of extended) has to take one of the columns of the 2D array:
I did Array1D:= Array2D[index] but I get
Error: Incompatible type: got dynamic array of single, expected dynamic array of extended.
Array1D:= Extended(Array2D[index]);
Does it mean, that I shall cast every element of the array separately?

If it matters, the 1D array is a part of a record.
Лазар 4,8 32 bit (sometimes 64 bit); FPC3,2,2

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Single array to extended array
« Reply #1 on: November 16, 2012, 03:08:05 pm »
Quote
I did Array1D:= Array2D[index] but I get
Error: Incompatible type: got dynamic array of single, expected dynamic array of extended.
Array1D:= Extended(Array2D[index]);
Does it mean, that I shall cast every element of the array separately?

You cannot cast this way.
Retyping single to extended will cause non-sense. (Single is 4B, Extended is 10B)
The same with array of single.

2D array of extended should work.
Post here original code of 2D extended array, lets look why it crashed.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

CM630

  • Hero Member
  • *****
  • Posts: 1743
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Single array to extended array
« Reply #2 on: November 16, 2012, 03:33:40 pm »
Here is the source, I do not know if it can be useful, since it uses
http://www.mccdaq.com/daq-software/universal-library.aspx.

Code: [Select]
type
DaqRecord= Record
  Values: array of Extended;
  dt:   Extended;
  Count:  Integer;
end;   

DAQArray= array of DAQRecord; 

.
.
.

function TfrmMain.TakeWave():DAQArray;
var
  DaqData: DTMSArray;
  i,j: integer;
  index: integer=0;
  ChannelCount: integer;
  CurrentSample: integer=0;
  ChannelValue: array of array of Extended;
  EngUnits: Single;
begin
   {declare Revision Level}
   RevLevel := CURRENTREVNUM;
   ULStat := cbDeclareRevision(RevLevel);
   {set up internal error handling for the Universal Library}
   ErrReporting := PRINTALL;       {set Universal Library to print all errors}
   ErrHandling := STOPALL;         {set Universal Library to stop on errors}
   ULStat := cbErrHandling(ErrReporting, ErrHandling);

 Rate:=spRate.Value;
 BoardNum:= spDeviceNum.Value;
 LowChan:= spChanMin.Value;
 HighChan:= spChanMax.Value; //WORKS FINE IF LowChan=0 and HighChan=0, but crashes if HighChan>0
 Count:= spSampleCount.Value;

 ChannelCount:=spChanMax.Value- spChanMin.Value+1;
 {set up a buffer in Windows to contain the data}
 MemHandle := cbWinBufAlloc (Count*ChannelCount);
 SetLength(ADData, spSampleCount.Value * ChannelCount);
 Rate:= spRate.Value ;
 ULStat:= cbAInScan(BoardNum, LowChan,HighChan, Count, Rate, Range, MemHandle, 0);
 If ULStat <> 0 then exit;
 ULStat := cbWinBufToArray (MemHandle, ADData[0], FirstPoint, Count);
 If ULStat <> 0 then exit;
 SetLength(ChannelValue,ChannelCount,Count);
 SetLength(DaqData,ChannelCount);

 for i:= 0 to Length(ADData)-1 do
 begin
   for j:= 0 to ChannelCount-1 do
   begin
     ULStat := cbToEngUnits (BoardNum, Range, ADData[index+j], EngUnits);
     ChannelValue[j,CurrentSample]:=  Extended(EngUnits);
   end;
   index:= index+ ChannelCount ;
   CurrentSample:=CurrentSample+1;
 end;

  for i:=0 to ChannelCount-1 do
  begin
       DaqData[i].Count:=Count;
       DaqData[i].dt:=1/(rate* ChannelCount);
       for j:= 0 to trunc(Count/ChannelCount)-1 do
         DaqData[i].Values:= ChannelValue[i];
  end;
  ULStat := cbWinBufFree (MemHandle);
  Result:= DaqData;
end;

Here are some other vars and constants:
Code: [Select]
var
   ULStat:                Integer;
   MemHandle:             Integer;
   ErrReporting:          Integer;
   ErrHandling:           Integer;
   Rate:                  LongInt;
   ADData:                array of Word;
   Revlevel:              Single;
   DataValue:             Single;

 const
   BoardNum:              Integer = 0;
   Count:                 Integer = 600;
   FirstPoint:            LongInt = 0;
   TargetRate:            LongInt = 1000;
   LowChan:               Integer = 0;
   HighChan:              Integer = 1;
   Range:                 LongInt = BIP10VOLTS;
   Options:               Integer = CONVERTDATA;

If the function is run it crashed when it comes to the END;
As written in the comments, if LowChan=0 and HighChan=0, everything is okay, but it crashes if HighChan>0
« Last Edit: November 16, 2012, 03:36:46 pm by paskal »
Лазар 4,8 32 bit (sometimes 64 bit); FPC3,2,2

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Single array to extended array
« Reply #3 on: November 16, 2012, 06:00:28 pm »
Definitely, this line causes error:
Code: [Select]
     ChannelValue[j,CurrentSample]:=  Extended(EngUnits);
As I mentioned above, you cannot retype single to extended. Single is 4 bytes and extended is 10 bytes.
Compiler tries do read 10 bytes but only 4 bytes are accessible. This may cause non-sense values, access violation or unexpected state.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: Single array to extended array
« Reply #4 on: November 16, 2012, 06:40:36 pm »
It should be ok i think, by small test app i tried. Same way that you can convert single to double, and byte to single, etc.

You can just write this too:
Code: [Select]
ChannelValue[j,CurrentSample]:=EngUnits;
Other than that, i don't see why you should use extended type if original data comes as single. You're just using much more memory.

Blaazen

  • Hero Member
  • *****
  • Posts: 3241
  • POKE 54296,15
    • Eye-Candy Controls
Re: Single array to extended array
« Reply #5 on: November 16, 2012, 07:02:58 pm »
Hmm, I see now.
Now I think it crashes on bad indexing of "CurrentSample"
Code: [Select]
     ChannelValue[j,CurrentSample]:=  Extended(EngUnits);
   end;
   index:= index+ ChannelCount ;
   CurrentSample:=CurrentSample+1;
 end;
When I replaced the last line:
Code: [Select]
   CurrentSample:=0; //CurrentSample+1;
it did not crash.
But I run modified code, I had to comment many lines because code is incomplete.
Lazarus 2.3.0 (rev main-2_3-2863...) FPC 3.3.1 x86_64-linux-qt Chakra, Qt 4.8.7/5.13.2, Plasma 5.17.3
Lazarus 1.8.2 r57369 FPC 3.0.4 i386-win32-win32/win64 Wine 3.21

Try Eye-Candy Controls: https://sourceforge.net/projects/eccontrols/files/

CM630

  • Hero Member
  • *****
  • Posts: 1743
  • Не съм сигурен, че те разбирам.
    • http://sourceforge.net/u/cm630/profile/
Re: Single array to extended array
« Reply #6 on: November 19, 2012, 07:39:24 am »
It should be ok i think, by small test app i tried. Same way that you can convert single to double, and byte to single, etc.

You can just write this too:
Code: [Select]
ChannelValue[j,CurrentSample]:=EngUnits;
I tried with ChannelValue[j,CurrentSample]:=  EngUnits; and since it crashed, I tried ChannelValue[j,CurrentSample]:=  Extended(EngUnits);

Other than that, i don't see why you should use extended type if original data comes as single. You're just using much more memory.
The idea of DAQData is to be as a general format, for using with different data acquisition devices (DAQ) or files.
While I do not expect to have a DAQ with more than 24 or let's say 32 bits resolution, some files some files use 8 bytes per sample, used in a strange way, so that I am not sure that even  extended vars will be sufficient in some cases.

Hmm, I see now.
Now I think it crashes on bad indexing of "CurrentSample"
Code: [Select]
     ChannelValue[j,CurrentSample]:=  Extended(EngUnits);
   end;
   index:= index+ ChannelCount ;
   CurrentSample:=CurrentSample+1;
 end;
When I replaced the last line:
Code: [Select]
   CurrentSample:=0; //CurrentSample+1;
it did not crash.
But I run modified code, I had to comment many lines because code is incomplete.
Shall I understand that the app crashed for you, too, before changing that line?
The idea of that piece of code is that I have for example four measurement channels, but all data comes from the DAQ in a single array. Data for each channel comes serially- one sample from channel 1, one form channel 2, one form channel 3, one from channel 4 and again - channel 1;2;3;4.

EDIT: It is really an indexing problem, the bug is here:
for i:= 0 to Length(ADData)-1 do
It should be something like:
for i:= 0 to  trunc(Length(ADData)/ChannelCount-1) do //TODO: to make sure that Length(ADData) is dividable by ChannelCount.
I still have some bug around, but I'll handle it later.

Still I do not (and probably I won't) understand why the compiler does not crash during the cycle, but at a later stage and why it does it with single precision values only.
Thanks for the help!
« Last Edit: November 19, 2012, 08:10:00 am by paskal »
Лазар 4,8 32 bit (sometimes 64 bit); FPC3,2,2

 

TinyPortal © 2005-2018