B4R Question How to pass array of double from Inline-C to B4R ?

peacemaker

Expert
Licensed User
Longtime User
If we have arrays:

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Dim FreqX(20), MagX(20), RmsX As Double
    Dim FreqY(20), MagY(20), RmsY As Double
    Dim FreqZ(20), MagZ(20), RmsZ As Double
End Sub

How to fill them from Inline-C ?


C++:
struct PeakInfo {
  double frequency;
  double amplitude;
  double rms;
};
....

    for (int i = 0; i < MAX_PEAKS; i++) {
        b4r_espmpu6050_fft::_freqx->data[i] = peaksX[i].frequency;
        b4r_espmpu6050_fft::_magx->data[i] = peaksX[i].amplitude;
       
        b4r_espmpu6050_fft::_freqy->data[i] = peaksY[i].frequency;
        b4r_espmpu6050_fft::_magy->data[i] = peaksY[i].amplitude;
       
        b4r_espmpu6050_fft::_freqz->data[i] = peaksZ[i].frequency;
        b4r_espmpu6050_fft::_magz->data[i] = peaksZ[i].amplitude;
    }

This code does not allow it with error:
\b4r_espmpu6050_fft.cpp:282:47: error: 'void*' is not a pointer-to-object type
282 | b4r_espmpu6050_fft::_freqx->data = peaksX.frequency;
 
Solution
SOLVED:
C++:
/**
 * Universal sub to pass doubles array to B4R.
 *
 * @param b4rArrayPtr - B4R array pointer(ex, b4r_espmpu6050_fft::_freqx).
 * @param sourceData  - double source array (ex, peaksX[i].frequency).
 * @param dataCount   - qty to copy.
 * @param startIndex  - Start target index in B4R's array (0 by default).
 */
void PassDoubleArrayToB4R(B4R::Array* b4rArrayPtr, const double* sourceData, int dataCount, int startIndex = 0) {
    if (b4rArrayPtr == nullptr) {
        Serial.println("Error1: B4R::Array is not inited");
        return;
    }
    if (b4rArrayPtr->data == nullptr) {
        Serial.println("Error2: B4R::Array data is null");
        return;
    }

    float* targetArray = (float*)b4rArrayPtr->data;
    int...

peacemaker

Expert
Licensed User
Longtime User
C++:
void PassDoubleArrayToB4R(B4R::Array* b4rArrayPtr, const double* sourceData, int dataCount, int startIndex = 0) {
    if (b4rArrayPtr == nullptr) {
        Serial.println("Error1: B4R::Array is not inited");
        return;
    }
    if (b4rArrayPtr->data == nullptr) {
        Serial.println("Error2: B4R::Array data is null");
        return;
    }

    double* targetArray = (double*)b4rArrayPtr->data;
    int availableSpace = b4rArrayPtr->length - startIndex;

    // Copy with bounds check
    int elementsToCopy = (dataCount < availableSpace) ? dataCount : availableSpace;
    for (int i = 0; i < elementsToCopy; i++) {
        targetArray[startIndex + i] = sourceData[i];
    }
}

Usage:
    // axle X
    double passing[MAX_PEAKS];
    for (int i = 0; i < MAX_PEAKS; i++) passing[i] = 0;
    for (int i = 0; i < peakCountX; i++) passing[i] = peaksX[i].frequency;
    PassDoubleArrayToB4R(b4r_espmpu6050_fft::_freqx, passing, peakCountX);
    
    for (int i = 0; i < MAX_PEAKS; i++) passing[i] = 0;
    for (int i = 0; i < peakCountX; i++) passing[i] = peaksX[i].amplitude;
    PassDoubleArrayToB4R(b4r_espmpu6050_fft::_magx, passing, peakCountX);

Such sub helps to pass the data, but ... it's wrongly interpreted as the doubles... :(
 
Upvote 0

peacemaker

Expert
Licensed User
Longtime User
SOLVED:
C++:
/**
 * Universal sub to pass doubles array to B4R.
 *
 * @param b4rArrayPtr - B4R array pointer(ex, b4r_espmpu6050_fft::_freqx).
 * @param sourceData  - double source array (ex, peaksX[i].frequency).
 * @param dataCount   - qty to copy.
 * @param startIndex  - Start target index in B4R's array (0 by default).
 */
void PassDoubleArrayToB4R(B4R::Array* b4rArrayPtr, const double* sourceData, int dataCount, int startIndex = 0) {
    if (b4rArrayPtr == nullptr) {
        Serial.println("Error1: B4R::Array is not inited");
        return;
    }
    if (b4rArrayPtr->data == nullptr) {
        Serial.println("Error2: B4R::Array data is null");
        return;
    }

    float* targetArray = (float*)b4rArrayPtr->data;
    int availableSpace = b4rArrayPtr->length - startIndex;

    // Copy with bounds check
    int elementsToCopy = (dataCount < availableSpace) ? dataCount : availableSpace;
    for (int i = 0; i < elementsToCopy; i++) {
        targetArray[startIndex + i] = sourceData[i];
    }
}

Key is:
    float* targetArray = (float*)b4rArrayPtr->data;
 
Last edited:
Upvote 1
Solution
Top