Post Go back to editing

Question about CN0359 Conductivity Measurement System

Hi,
I'm re-programming the CN0359 board as per my requirements. I have been able to do some basic changes in the source code provided on analog wiki and download it on my board. Now, I want to proceed to the next step and have some basic questions as I'm rather new to this.

1. Is there a way I can store the a fixed number of conductivity results (e.g. first 50) in a file or array on the ADuCM360 processor's memory itself, and then read to the computer using RS-485 afterwards?
1b. A follow up question is, if the data can indeed be stored, will it be retained after the system is turned off?
2. Currently the system converts the ADC measurements and displays the conductivity readings continuously. Is there a way I can reduce the periodicity at which it is stored and displayed (e.g. measure conductivity every 30s or so)?

I would greatly appreciate if you could help me with my questions or point me to the right reference material.

Thanks,

  • Hi SckrPK,

    1. Yes, this is possible using the on-chip flash controller which gives you 128kb of memory. Another reference design has done this which is the CN0409 where calibration values are stored in flash and retained. In fact, it is used and supported by the CN0359 source. The device settings and measurement constants are stored in flash (cell constant, excitation frequency, temperature coefficients, etc.)

    b. Yes, they are retained even without power

    2. This is not directly supported by the software. The display of conductivity measurement is set after completing measurements for the four channels. You can check this on the last lines of the on_adc0 function. The on_adc0 function is called by the ADC interrupt handler which fires it periodically with the sampling pwm signals.

    The software was written such that the ADC will continuously sample. You can observe that in adc.cpp there is only a start_adc0 function (enabling the ADC), which is called upon initialization, and there is no method to disable it.

    Best Regards,

    Nikko

  • Thanks Nikko.

    Regarding the first question : Could you provide the reference code for CN0409 where the data is stored in flash. With 128kb of memory available, how many readings can I expect to store?

    Regarding the second question : I don't necessarily want to disable the ADC. It can run in continuous mode and produce outputs, I just want to be able to store the conductivity measurements every few seconds. How can I achieve that? Currently I'm doing something like below in order to add the delay between displaying successive readings, but I'm not sure if it's the right way to do it

    void ADC0_Int_Handler(void)
    {
    adc0_result = pADI_ADC0->DAT;

    timer t;
    t.time = 1000;
    t.timer_app.argc = 0;
    t.timer_app.fun = on_adc0_gp;
    t.timer_app.argv = new char*;
    new_timer(t);

    // app msg;
    // msg.argc = 0;
    // msg.fun = on_adc0;
    // ts_post_message(msg);
    }

    int on_adc0_gp(int argc, char *argv[])
    {
    // beep(100, 100, 100);
    app msg;
    msg.argc = 0;
    msg.fun = on_adc0;
    ts_post_message(msg);
    }

    Any help on this and and example source code would be great.

    Thanks again,

  • Hi SckrPK,

    1. You can use examples from the CN0359 source code: Here is a function which edits the cell constant value stored in flash: 

    2. You won't be able to use the entire 128kb since it is already being used. The best way to answer this is through testing

    3. It is not advisable to do this in the ADC interrupt handler. A better way will be to start the timer after initialization and use the timer interrupt handler to store the current conductivity. I think  or  can add to this.

    Best Regards,

    Nikko

  • Thanks Nikko. I'm revisiting this after some time but thanks a lot for the pointers. 

    I agree I don't want to modify with the ADC interrupt handler. When you say start timer after initialization, are you referring to the void CHomeDialog::OnCreat(void) in HomeDialog.cpp?

    After looking into it a little bit more, I think I want to peform store the value of the conductivity variable calculated in HomeDialog.cpp in a file. I tried unsuccessfully doing an fwrite to a file with the conductivity value in void CHomeDialog::OnConductivity(void) in HomeDialog.cpp. I have copied the section of HomeDialog.cpp file where I want to perform a write. See my comment in blue.

    void CHomeDialog::OnConductivity(void)
    {
    adc_file adc;
    decltype(flash_file::cell_const) k;
    decltype(flash_file::temp_coef) conf;

    fseek(p_flash, (int) (&p_flash_file->cell_const) - (int) (p_flash_file), SEEK_SET);
    fread(&k, sizeof(flash_file::cell_const), 1, p_flash);

    fseek(p_flash, (int) (&p_flash_file->temp_coef) - (int) (p_flash_file), SEEK_SET);
    fread(&conf, sizeof(flash_file::temp_coef), 1, p_flash);

    rewind(p_adc);
    fread(&adc, sizeof(adc_file), 1, p_adc);

    conductivity = (k * (adc.p_curt - adc.n_curt) / (adc.p_volt - adc.n_volt))
    * (100 / (100 + conf * (temperature - 25)));

    //Store 10 consecutive conductivity readings every 10 seconds in a new or existing file and display them on the LCD

     if (!(isfinite(conductivity) && conductivity >= 1e-24 && conductivity < 1e27))
     {
     beep(100);
     }

    OnDraw();
    }

    Do you have a sample code that can do something similar? How can I achieve this? I 

    Can I achieve this without having to define a new file? When I tried to define a new FILE in devices.cpp and insert the following code I seem to be going into a constant beep interrupt as soon as I power up the board. Below is what I tried in devices.cpp file (lines 84,85; I've commented them for now)

    81: p_adc = fopen("adc", "rb");
    82: setvbuf(p_adc, nullptr, _IOFBF, sizeof(adc_file));

    84: p_cond = fopen("cond", "rb");
    85: setvbuf(p_cond, nullptr, _IOFBF, sizeof(cond_file));

    87: encoder_open();

    Lastly, I have also defined a new function in cmd_poll.cpp to read the conductivity values via RS485. For now I am reusing the existing poll function that refers to the existing flash files. But eventually I want to be able to poll the file where I'm storing the conductivity values

    int cmd_condonly (int argc, char *argv[])
    {
    int i = 0;
    if (argc != 1)
    {
    printf("%s: error, syntax: ADDRESS %s\n\n", argv[0], argv[0]);
    }
    else
    {
    flash_file * p_flash_file;

    decltype(p_flash_file->temp_coef) temp_coef;
    fseek(p_flash, (int) (&p_flash_file->temp_coef) - (int) (p_flash_file), SEEK_SET);
    fread(&temp_coef, sizeof(flash_file::temp_coef), 1, p_flash);

    decltype(p_flash_file->cell_const) cell_const;
    fseek(p_flash, (int) (&p_flash_file->cell_const) - (int) (p_flash_file), SEEK_SET);
    fread(&cell_const, sizeof(flash_file::cell_const), 1, p_flash);

    adc_file adc;

    // while(i<4) {
    rewind(p_adc);
    fread(&adc, sizeof(adc_file), 1, p_adc);
    float conductivity = (cell_const * (adc.p_curt - adc.n_curt) / (adc.p_volt - adc.n_volt))
    * (100 / (100 + temp_coef * (adc.temp - 25)));
    printf("%e\n", conductivity);
    fflush(stdout);
    i++;
    // }
    }

    Any help with this is highly appreciated

    Thanks,

  • Hi,

    Since I couldn't successfully define a new file, I tried updating the struct flash_file in flash.h to add slots for storing conductivity readings.

    struct flash_file
    {
    int baud_rate = 115200;
    int rs485_address = 30;
    float voltage = 1.f;
    float frequency = 100.f;
    float temp_coef = 2.f;
    float cell_const = 1.f;
    float setup = 10.f;
    float hold = 1.f;
    int lcd_uc1601s_br = 3;
    int lcd_uc1601s_pm = 104;
    int lcd_uc1601s_tc = 2;
    float conductivity0 = 0;
    float conductivity1 = 0;
    float conductivity2 = 0;
    float conductivity3 = 0;
    }const default_setting;

    I'm then adding below commands in HOmeDialog.cpp to write these values based on a local count

    fseek(p_flash, (int) (&p_flash_file->conductivity0) - (int) (p_flash_file), SEEK_SET);
    fwrite(&gpcond1, sizeof(flash_file::conductivity0), 1, p_flash); fflush(p_flash);

    I could read these over RS-485 but only some manually forced values and not the actual conductivity results for some reason

    I'm sure there is a more elegant way to do this. Can you help me with this or suggest some example codes?

    Thanks,