Workbench add precompiled .a lib to user app

Hi all, I guess it’s time to get some help as I’m stuck with this project again :man_facepalming:t3:

long story short, I’m working with environmental sensor from Renesas/IDT ZMOD4510 after a long wait for approval, back to 2020 for use of their product firmware I realized that the examples available where for win belong with their evaluation kit so I abandoned the project but now they extend their examples even for Arduinos boards and provide the firmware for many ARM’s based devices including Cortex M4 which Boron is based. The problem is that some of required libs are precompiled and they are .a type file rather than .h I try all which I could but no luck

The project structure looks good as compile do not complain about any #incude some.h files
I set in library.properties

precompiled=true

Also in Makefile I added this:


export LDFLAGS = -L./home/arek/Particle_workbench/ZMOD4510/ePaper_airquality/lib/Renesas_ZMOD4510_OAQ_2nd/src/ -lliboaq_2nd_gen


I have all required files in place but still no luck :face_with_raised_eyebrow:

I’m able to get compile this for different Arduino’s board but not for Boron

What I miss here ?? and this is even possible to add precompiled libs to user app space ?

Some configuration details:




Thank you all in advance for any advice

Best,
Arek

Really nobody ???
@nrobinson2000 @rickkas7 @ScruffR @m_m @peekay123
could you guys please help a with this I really wanted to run this ZMOD on Boron
Even the answer “yes it’s possible” “no is not possible” will be appreciated
thanks in Advance,

It’s not currently possible.

You might be able to modify the user.mk in the Device OS tree that Workbench uses, but this has the unfortunate side effect of putting the library in every user app you compile.

The problem is that there’s no place in the user makefile you can insert the correct LDFLAGS and have it work as expected.

1 Like

Thank you so much @rickkas7 :+1:

I got it working on Boron ! :smile: belong with my crappie looking DIY pcb but the good thing is that is running :muscle:
Conclusion:

nothing is impossible they are only things which are very unlikely :stuck_out_tongue_winking_eye:



@dreamER, perhaps you could share how you got it working?

I guess yeah … but I feel that I forced square shaped object into round hole :man_facepalming:t3: it’s s not elegant at all.
I used example for Arduino provided by Renesas/IDT mixed with Born functionality
Added :
LIBS += oaq_2nd_gen
LIB_DIRS +=$(APPDIR)/lib/Renesas_ZMOD4510_OAQ_2nd/src/M4f/arm-none-eabi-gcc
To
/.particle/toolchains/deviceOS/2.0.1/modules/boron/user-part makefile

Also the name of the .a lib in project lib directory starts with lib I mean liboaq_2nd_gen not like in makefile where’s just oaq_2nd_gen

In meantime I realized that Boron is Cortex M4f :man_shrugging:t3: It’s important

Just wondering if there is any relation between library.properties and makefile ? I mean can makefile read values from library.properties somehow :thinking:

EDIT:

here is full ino for boron:

/*******************************************************************************
 * Copyright (c) 2022 Renesas Electronics Corporation
 * All Rights Reserved.
 *
 * This code is proprietary to Renesas, and is license pursuant to the terms and
 * conditions that may be accessed at:
 * https://www.renesas.com/eu/en/document/msc/renesas-software-license-terms-gas-sensor-software
 *
 ******************************************************************************/

/**
 * @file    oaq_2nd_gen.ino
 * @brief   This is an Arduino example for the ZMOD4510 gas sensor using the oaq_2nd_gen library.
 * @version 4.0.0
 * @author Renesas Electronics Corporation
 */

#include "Particle.h"
#include <zmod4510_config_oaq2.h>
#include <zmod4xxx.h>
#include <zmod4xxx_hal.h>
#include <oaq_2nd_gen.h>

void error_handle();


zmod4xxx_dev_t dev;

/* Sensor specific variables */
uint8_t zmod4xxx_status;
uint8_t prod_data[ZMOD4510_PROD_DATA_LEN];
uint8_t adc_result[ZMOD4510_ADC_DATA_LEN] = { 0 };
uint8_t track_number[ZMOD4XXX_LEN_TRACKING];
oaq_2nd_gen_handle_t algo_handle;
oaq_2nd_gen_results_t algo_results;
oaq_2nd_gen_inputs_t algo_input;


//SYSTEM_THREAD(ENABLED);




FuelGauge fuel;
CellularSignal sig;


float strengthVal = 0.0;
float strengthPercentage = 0.0;
float qualityVal = 0.0;
float qualityPercentage = 0.0;
float bat = 0.0;
float charg = 0.0;
unsigned long interval = 0;
int ledPin = D7;
int rat = 0;
bool ledState = false;
bool isVarmOk = true;

char bat_sig_data[] = "{\"charg\":%.2f,\"batV\":%.2f,\"rat\":%d,\"strghVal\":%.2f,\"qualVal\":%.2f,\"qualProc\":%.2f,\"strghProc\":%.2f,\"O3ppb\":%.2f,\"fast_AQI\":%d,\"EPA_AQI\":%d,\"isVarm\":%i,\"isError\":%d}";
char bat_template[sizeof(bat_sig_data) + 64];


int SysRes(String comand){
    int colonPos = comand.indexOf(":") ;
    if (colonPos < 0) return -1 ;                 // syntax error not found
    String command = comand.substring(0,colonPos) ;
    String argument = comand.substring(colonPos+1) ;
    
     if (command.equalsIgnoreCase("reset")){
        System.reset();
        return 0;
    } else {
        return -2 ;                         // command not found
    }
}

void toggleLed() 
{
  ledState = !ledState;
  digitalWrite(ledPin, ledState);
  delay(50);
  ledState = !ledState;
  digitalWrite(ledPin, ledState);
}

void setup()
{
  Serial.begin(9600);


    isVarmOk = true;
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, ledState);
    
    sig = Cellular.RSSI();
    rat = sig.getAccessTechnology();
    strengthVal = sig.getStrengthValue();
    strengthPercentage = sig.getStrength();
    qualityVal = sig.getQualityValue();
    qualityPercentage = sig.getQuality();
    bat = fuel.getVCell();
    charg = fuel.getSoC();   
    
    
   
    Particle.function("reset",SysRes); 
    //Particle.variable("status", msg); 
    Particle.variable("bat_sig_data", bat_template) ;

    int8_t lib_ret;
    zmod4xxx_err api_ret;

    delay(1000);

    Serial.println(F("Starting the Sensor!"));
    
    api_ret = init_hardware(&dev);
   
    
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F(" during init hardware, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }
    
    dev.i2c_addr =  ZMOD4510_I2C_ADDR;
    dev.pid = ZMOD4510_PID;
    dev.init_conf = &zmod_oaq2_sensor_cfg[INIT];
    dev.meas_conf = &zmod_oaq2_sensor_cfg[MEASUREMENT];
    dev.prod_data = prod_data;

    api_ret = zmod4xxx_read_sensor_info(&dev);
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(
            F(" during reading sensor information, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }

    

    api_ret = zmod4xxx_read_tracking_number(&dev, track_number);
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F(" during preparation of the sensor, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }
    Serial.print(F("Sensor tracking number: x0000"));
    for (uint8_t i = 0; i < sizeof(track_number); i++) {
        Serial.print(track_number[i], HEX);
    }
    Serial.println("");
    Serial.print(F("Sensor trimming data:"));
    for (uint8_t i = 0; i < sizeof(prod_data); i++) {
        Serial.print(prod_data[i]);
    }
    Serial.println("");

     api_ret = zmod4xxx_prepare_sensor(&dev);
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F(" during preparation of the sensor, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }

    
    lib_ret = init_oaq_2nd_gen(&algo_handle);
    if (lib_ret) {
        Serial.println(F("Error "));
        Serial.print(lib_ret);
        Serial.println(F(" during initializing algorithm, exiting program!"));
        error_handle();
    }
    snprintf(bat_template, sizeof(bat_template), bat_sig_data, charg, bat
                                , rat
                                , strengthVal
                                , qualityVal
                                , qualityPercentage
                                , strengthPercentage
                                , 0.0
                                , 0
                                , 0
                                , isVarmOk
                                , api_ret);
    
    
}

void loop()
{
  
  if (millis() - interval > 2000) {
    interval = millis();
    toggleLed();
    
    sig = Cellular.RSSI();
    rat = sig.getAccessTechnology();
    strengthVal = sig.getStrengthValue();
    strengthPercentage = sig.getStrength();
    qualityVal = sig.getQualityValue();
    qualityPercentage = sig.getQuality();
    bat = fuel.getVCell();
    charg = fuel.getSoC();  
    
    
   
    int8_t lib_ret;
    zmod4xxx_err api_ret;
    
    api_ret = zmod4xxx_start_measurement(&dev);
     
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F(" during starting measurement, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }

    dev.delay_ms(ZMOD4510_OAQ2_SAMPLE_TIME);

     api_ret = zmod4xxx_read_status(&dev, &zmod4xxx_status);
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F(" during read of sensor status, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }

   if (zmod4xxx_status & STATUS_SEQUENCER_RUNNING_MASK) {
       
        api_ret = zmod4xxx_check_error_event(&dev);
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        switch (api_ret) {
        case ERROR_POR_EVENT:
            Serial.print(F("Error "));
            Serial.print(api_ret);
            Serial.println(F("Measurement completion fault. Unexpected sensor reset.\n"));
            break;
        case ZMOD4XXX_OK:
            Serial.print(F("Error "));
            Serial.print(api_ret);
            Serial.println(F("Measurement completion fault. Wrong sensor setup.\n"));
            break;
        default:
            Serial.print(F("Error "));
            Serial.print(api_ret);
            Serial.println(F("Error during reading status register "));
            break;
        }
         error_handle();
    }

    api_ret = zmod4xxx_read_adc_result(&dev, adc_result);
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F("Error %d during read of ADC results, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }

    
    api_ret = zmod4xxx_check_error_event(&dev);
    if (api_ret) {
        Serial.print(F("Error "));
        Serial.print(api_ret);
        Serial.println(F("during reading status register, exiting program!\n"));
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, -9.99, -9.99
                                , -999
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -9.99
                                , -999
                                , -999
                                , false
                                , api_ret);
        error_handle();
    }


    algo_input.adc_result = adc_result;
    
    algo_input.humidity_pct = 50.0;
    algo_input.temperature_degc = 20.0;

     lib_ret =  calc_oaq_2nd_gen(&algo_handle, &dev, &algo_input, &algo_results);
     if ((lib_ret != OAQ_2ND_GEN_OK) && (lib_ret != OAQ_2ND_GEN_STABILIZATION)) {
        Serial.println(F("Error when calculating algorithm, exiting program!"));
    } else {
        
        Serial.println("*********** Measurements ***********");
        for (int i = 0; i < 8; i++) {
            Serial.print(" Rmox[");
            Serial.print(i);
            Serial.print("] = ");
            Serial.print(algo_results.rmox[i] / 1e3);
            Serial.println(" kOhm");
        }
        Serial.print(" O3_conc_ppb = ");
        Serial.println(algo_results.O3_conc_ppb);
        Serial.print(" Fast AQI = ");
        Serial.println(algo_results.FAST_AQI);
        Serial.print(" EPA AQI = ");
        Serial.println(algo_results.EPA_AQI);


        if (lib_ret == OAQ_2ND_GEN_STABILIZATION) {
            Serial.println(F(" Warm-Up! \n"));
            isVarmOk = true;
        } else {
            Serial.println(F(" Valid! \n"));
            isVarmOk = false;
        }
        snprintf(bat_template, sizeof(bat_template), bat_sig_data, charg, bat
                                , rat
                                , strengthVal
                                , qualityVal
                                , qualityPercentage
                                , strengthPercentage
                                , algo_results.O3_conc_ppb
                                , algo_results.FAST_AQI
                                , algo_results.EPA_AQI
                                , isVarmOk
                                , api_ret); 
        Serial.printf(" all_data: %s\n",bat_template);
        Serial.println(" ");
    }
   
  }
  
}


void error_handle()
{
    int count = 0;
    while (1){
        Serial.print("Error ");
       delay(1000);
       Particle.process();
       count++;
       if(count>=30){
        count = 0;
        System.reset();
       }
    }
}

also i changed: #define ZMOD4510_OAQ2_SAMPLE_TIME (2000U) to 200U as I’m using milis() but for some reason ZMOD doesn’t want to work without any delay.

and the last one in: zmod4xxx_hal.h

#ifndef _ZMOD4XXX_HAL_H_
#define _ZMOD4XXX_HAL_H_

#ifdef HICOM
#include "hal_hicom.h"
#elif defined RL78
#include "hal_rl78.h"
//#elif defined ARDUINO
//#include "hal_arduino.h"
#elif defined RASPI
#include "hal_raspi.h"
#elif defined PARTICLE
#include "hal_arduino.h"
#endif
1 Like

One more thing, as this was my initial inspiration , couple weeks ago

when this statement will become true ?
also I’ll like to repeat my previous question:

Best,
Arek

That’s not what that’s referring to. It’s providing a better user interface in Workbench for selecting a library to add like the Web IDE, rather than having to type in the name.

There is no schedule for that to be added. There’s an even better library search feature in the docs, and then you can easily copy and paste the name.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.