This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

undefined reference twi error

Hi,

I hope you can help me. I get an error while compiling. I merge "twi sensor" example from sdk to the "ble app uart" example from sdk. So I customize the sdk_config to enable twi. In addition to that, I add all missing nRF_Drivers to make it work. While compiling, I get the following output:

1> "C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/as" --traditional-format -I../../../config -I../../../../../../components -I../../../../../../components/ble/ble_advertising -I../../../../../../components/ble/ble_dtm -I../../../../../../components/ble/ble_link_ctx_manager -I../../../../../../components/ble/ble_racp -I../../../../../../components/ble/ble_services/ble_ancs_c -I../../../../../../components/ble/ble_services/ble_ans_c -I../../../../../../components/ble/ble_services/ble_bas -I../../../../../../components/ble/ble_services/ble_bas_c -I../../../../../../components/ble/ble_services/ble_cscs -I../../../../../../components/ble/ble_services/ble_cts_c -I../../../../../../components/ble/ble_services/ble_dfu -I../../../../../../components/ble/ble_services/ble_dis -I../../../../../../components/ble/ble_services/ble_gls -I../../../../../../components/ble/ble_services/ble_hids -I../../../../../../components/ble/ble_services/ble_hrs -I../../../../../../components/ble/ble_services/ble_hrs_c -I../../../../../../components/ble/ble_services/ble_hts -I../../../../../../components/ble/ble_services/ble_ias -I../../../../../../components/ble/ble_services/ble_ias_c -I../../../../../../components/ble/ble_services/ble_lbs -I../../../../../../components/ble/ble_services/ble_lbs_c -I../../../../../../components/ble/ble_services/ble_lls -I../../../../../../components/ble/ble_services/ble_nus -I../../../../../../components/ble/ble_services/ble_nus_c -I../../../../../../components/ble/ble_services/ble_rscs -I../../../../../../components/ble/ble_services/ble_rscs_c -I../../../../../../components/ble/ble_services/ble_tps -I../../../../../../components/ble/common -I../../../../../../components/ble/nrf_ble_gatt -I../../../../../../components/ble/nrf_ble_qwr -I../../../../../../components/ble/peer_manager -I../../../../../../components/boards -I../../../../../../components/libraries/atomic -I../../../../../../components/libraries/atomic_fifo -I../../../../../../components/libraries/atomic_flags -I../../../../../../components/libraries/balloc -I../../../../../../components/libraries/bootloader/ble_dfu -I../../../../../../components/libraries/bsp -I../../../../../../components/libraries/button -I../../../../../../components/libraries/cli -I../../../../../../components/libraries/crc16 -I../../../../../../components/libraries/crc32 -I../../../../../../components/libraries/crypto -I../../../../../../components/libraries/csense -I../../../../../../components/libraries/csense_drv -I../../../../../../components/libraries/delay -I../../../../../../components/libraries/ecc -I../../../../../../components/libraries/experimental_section_vars -I../../../../../../components/libraries/experimental_task_manager -I../../../../../../components/libraries/fds -I../../../../../../components/libraries/fifo -I../../../../../../components/libraries/fstorage -I../../../../../../components/libraries/gfx -I../../../../../../components/libraries/gpiote -I../../../../../../components/libraries/hardfault -I../../../../../../components/libraries/hci -I../../../../../../components/libraries/led_softblink -I../../../../../../components/libraries/log -I../../../../../../components/libraries/log/src -I../../../../../../components/libraries/low_power_pwm -I../../../../../../components/libraries/mem_manager -I../../../../../../components/libraries/memobj -I../../../../../../components/libraries/mpu -I../../../../../../components/libraries/mutex -I../../../../../../components/libraries/pwm -I../../../../../../components/libraries/pwr_mgmt -I../../../../../../components/libraries/queue -I../../../../../../components/libraries/ringbuf -I../../../../../../components/libraries/scheduler -I../../../../../../components/libraries/sdcard -I../../../../../../components/libraries/slip -I../../../../../../components/libraries/sortlist -I../../../../../../components/libraries/spi_mngr -I../../../../../../components/libraries/stack_guard -I../../../../../../components/libraries/strerror -I../../../../../../components/libraries/svc -I../../../../../../components/libraries/timer -I../../../../../../components/libraries/twi_mngr -I../../../../../../components/libraries/twi_sensor -I../../../../../../components/libraries/uart -I../../../../../../components/libraries/usbd -I../../../../../../components/libraries/usbd/class/audio -I../../../../../../components/libraries/usbd/class/cdc -I../../../../../../components/libraries/usbd/class/cdc/acm -I../../../../../../components/libraries/usbd/class/hid -I../../../../../../components/libraries/usbd/class/hid/generic -I../../../../../../components/libraries/usbd/class/hid/kbd -I../../../../../../components/libraries/usbd/class/hid/mouse -I../../../../../../components/libraries/usbd/class/msc -I../../../../../../components/libraries/util -I../../../../../../components/nfc/ndef/conn_hand_parser -I../../../../../../components/nfc/ndef/conn_hand_parser/ac_rec_parser -I../../../../../../components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser -I../../../../../../components/nfc/ndef/conn_hand_parser/le_oob_rec_parser -I../../../../../../components/nfc/ndef/connection_handover/ac_rec -I../../../../../../components/nfc/ndef/connection_handover/ble_oob_advdata -I../../../../../../components/nfc/ndef/connection_handover/ble_pair_lib -I../../../../../../components/nfc/ndef/connection_handover/ble_pair_msg -I../../../../../../components/nfc/ndef/connection_handover/common -I../../../../../../components/nfc/ndef/connection_handover/ep_oob_rec -I../../../../../../components/nfc/ndef/connection_handover/hs_rec -I../../../../../../components/nfc/ndef/connection_handover/le_oob_rec -I../../../../../../components/nfc/ndef/generic/message -I../../../../../../components/nfc/ndef/generic/record -I../../../../../../components/nfc/ndef/launchapp -I../../../../../../components/nfc/ndef/parser/message -I../../../../../../components/nfc/ndef/parser/record -I../../../../../../components/nfc/ndef/text -I../../../../../../components/nfc/ndef/uri -I../../../../../../components/nfc/platform -I../../../../../../components/nfc/t2t_lib -I../../../../../../components/nfc/t2t_parser -I../../../../../../components/nfc/t4t_lib -I../../../../../../components/nfc/t4t_parser/apdu -I../../../../../../components/nfc/t4t_parser/cc_file -I../../../../../../components/nfc/t4t_parser/hl_detection_procedure -I../../../../../../components/nfc/t4t_parser/tlv -I../../../../../../components/softdevice/common -I../../../../../../components/softdevice/s140/headers -I../../../../../../components/softdevice/s140/headers/nrf52 -I../../../../../../components/toolchain/cmsis/include -I../../../../../../external/fprintf -I../../../../../../external/segger_rtt -I../../../../../../external/utf_converter -I../../../../../../integration/nrfx -I../../../../../../integration/nrfx/legacy -I../../../../../../modules/nrfx -I../../../../../../modules/nrfx/drivers/include -I../../../../../../modules/nrfx/hal -I../../../../../../modules/nrfx/mdk -I../config -mcpu=cortex-m4 -mlittle-endian -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb "C:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/main.asm" -o "Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o"
1> rm "C:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/main.asm"
1> Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o (28.06.2020 20:58:16) is newer than Output/Debug/Exe/ble_app_uart_pca10100_s140.elf (28.06.2020 20:57:32).
1> Linking ble_app_uart_pca10100_s140.elf
1> "C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld" -X --omagic -eReset_Handler --defsym=__vfprintf=__vfprintf_long --defsym=__vfscanf=__vfscanf_long -EL --gc-sections "-TC:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/ble_app_uart_pca10100_s140.ld" -Map Output/Debug/Exe/ble_app_uart_pca10100_s140.map -u_vectors -o Output/Debug/Exe/ble_app_uart_pca10100_s140.elf --emit-relocs --start-group "@C:/Users/hp/Desktop/Firmware Entwicklung/nRF5SDK160098a08e2.zip/examples/ble_peripheral/ble_app_uart/pca10100/s140/ses/Output/ble_app_uart_pca10100_s140 Debug/Obj/ble_app_uart_pca10100_s140.ind" --end-group
1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld: Output/ble_app_uart_pca10100_s140 Debug/Obj/nrf_drv_twi.o: in function `nrf_drv_twi_init':
1> C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\integration\nrfx\legacy/nrf_drv_twi.c:186: undefined reference to `nrfx_twi_init'
1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld: Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o: in function `nrf_drv_twi_enable':
1> C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\examples\ble_peripheral\ble_app_uart\pca10100\s140\ses/../../../../../../integration/nrfx/legacy/nrf_drv_twi.h:513: undefined reference to `nrfx_twim_enable'
1> C:/Program Files/SEGGER/SEGGER Embedded Studio for ARM 4.50/gcc/arm-none-eabi/bin/ld: Output/ble_app_uart_pca10100_s140 Debug/Obj/main.o: in function `nrf_drv_twi_tx':
1> C:\Users\hp\Desktop\Firmware Entwicklung\nRF5SDK160098a08e2.zip\examples\ble_peripheral\ble_app_uart\pca10100\s140\ses/../../../../../../integration/nrfx/legacy/nrf_drv_twi.h:544: undefined reference to `nrfx_twim_tx'
Build failed

But I don´t know what I´m making wrong.

Could you help me with that?

Thanks in advance

Parents
  • Hello,

    Which SDK are you using?
    If you are using the newer versions in which nrf_drv_* is legacy, you will notice that they are forwarding macros to the new nrfx_ drivers.
    Therefore, you will need to also add the nrfx_ drivers to your project for the TWI functionality to work. Namely, it seems you are missing nrfx_twim.c. You can see from the error codes that the problem is nrf_drv_twi_* making calls to undefined "nrfx_twim_*" functions.
    I would also recommend you that you work directly with the nrfx_ drivers, instead of using the legacy layers - this will decrease future work in which you will have to port your code to the nrfx_ drivers, since nrf_drv is already legacy.

    For future reference, it would be beneficial if you were specific when saying that you have added "all missing nRF_drivers to make it work" - which drivers have you added, and which changes have you made to sdk_config?

    Please let me know if this does not resolve your problem, or if anything regarding the nrfx_* vs. nrf_drv_* drivers should be unclear.

    Best regards,
    Karl

  • Hi,

    I´m using SDK 16.

    Namely, it seems you are missing nrfx_twim.c.

    I don´t think so. I added it in the folder "nRF_Drivers as shown in screenshot attached.

    I have added the twi drivers in the BLE Uart example, to make TWI work (the same drivers are used in TWI Sensor example of SDK):

    - nrfx_twim.c

    - nrf_drv_twi.c

    In addition to that, I customized sdk_config. In general I enabled all TWI options. Nothing special I think. I attached the sdk_config if it would help you for analyzing.

    53234.sdk_config.h

    Another thing is, that the application is compiling well in "release" build configuration, but not in "debug" configuration. But when I compile in "release", the BLE application doesn´t work.

    Because of nrfx_twim.c is already in my driver folder the problem exists furthermore. Is there something else I could try? Thanks in advance.

    Simon

  • Hello Simon,

    simon1516 said:

    I debugged this and debug terminal shows me, that the error is here: app_timer2.c:559 --> (ASSERT(timeout_handler);)

    I´m not really sure, what to insert in the "app_timer_create" for timeout_handler. I read that there is a function coming in, which is executed when the timer is expired. Could you please give me an example for this?

    You may not provide NULL as the event_handler argument here, this is the reason why it ASSERTS. Are you familiar with using ASSERT?
    If you are unsure what you should provide as arguments to a function, or how to use a function, please see the functions API Refernce.
    In this case, from the app_timer_create API Reference you can see that the third argument is the event_handler, which is the function to be called when the timer expires.
    In your case, you may therefore do a TWIM transfer for each expiration, for example.

    An example for an event_handler function is for instance the saadc_event_handler from the SAADC example.
    This is the function that is called every time the SAADC generates an event - which then is used to handle those events.
    So, when a DONE event is generated, the saadc_event_handler is the function that process the samples that are collected.
    Or, in your case, the timers event handler is the function you would like to call every time the timer expires.

    simon1516 said:
    I´m doing this actually with one read with 14 bytes. This works fine :-)

    Great, I am glad to hear that!
    In that case, adding a 500 us delay before the transfer should not increase your power consumption too much.

    simon1516 said:
    I disabled deferred logging. Now there are no longer errors with this, so this works too :-)

    Great! Just keep in mind that this adds some processing time to each NRF_LOG_* line in your function. So, if you have a function with a lot of debugging write-outs you it will take much longer to complete with DEFERRED LOGGING set to 0.

    simon1516 said:

    To this error again: Disabling the deffered logging solves that there are no longer the messages "Logs dropped ()". But the main problem was not solved. I debugged again. And the code stops every time after exactly three minutes, because it is calling "static void sleep_mode_enter(void)"  and "err_code = sd_power_system_off();"

    Exactly three minutes, this is the time, the system is advertising for BLE devices! If I connect with nRF connect Mobile App to the nRF Chip, the TWIM doesn´t stop. The transmission is working until BLE connection is closed. So after advertising, the chip is calling the sleep mode was the explanation here.

    Like it works is okay, because TWIM just has to send data if a BLE connection is established. I just want to give you feedback for this.

    Good catch, I am happy to hear that you were able to identify the root of the behavior! This is exactly the time that your device is advertising.
    You may disable this feature, but it is a very good power-saving feature. What it does is make the device sleep if it has been without a connection for too long - conserving power by reducing RADIO ON time.
    In your situation, it sounds like you should keep this feature, if you only need to be awake when in a connection.
    Thank you for the feedback on this, I too am curious to hear about the problems resolve.

    simon1516 said:
    Have a nice weekend, I hope we can solve my Timer issue together.

    Thank you Simon, I did indeed have a nice weekend! I hope yours was as well.

    I think we are close to solving the Timer issue. I look forward to hearing if my comments above were helpful in resolving it!

    Best regards,
    Karl

  • Hi Karl,

    I´m sorry for late reply.

    You may not provide NULL as the event_handler argument here, this is the reason why it ASSERTS. Are you familiar with using ASSERT?

    No, not really. I don´t know for what this is for.

    _______________________________________________

    If you are unsure what you should provide as arguments to a function, or how to use a function, please see the functions API Refernce.

    Okay, I get it. I did it the same way like provided by the SAADC example. So now, every time the timer expires, my "sensor_data_read" function should be called. This is, what I would like to have.

    Unfortunaly, it doesn´t work completely. I tried to start my timer in the main loop. While compiling I get a warning. Could you tell me, what is the reason for this?

    I commented out my "read_sensor_data" function because it is called automatically by expiration of the time (i hope so :-) ).

    I think there is something wrong with the definition of my timer_id. As described in the nordic InfoCenter, I declared this variable as a static. Do I have to pay attention to something other?

    Thanks in Advance,

    Simon

  • Hello Simon,

    simon1516 said:
    I´m sorry for late reply.

    Do not worry about this at all, it is no problem.

    simon1516 said:
    No, not really. I don´t know for what this is for.

    Using ASSERTs in your code is a very helpful tool when debugging, to make sure certain conditions are always fulfilled before executing code.
    Here is a brief explanation. In this case, the ASSERT tells us that you did not provide the function with the required parameters, and it therefore can not continue.

    simon1516 said:

    Okay, I get it. I did it the same way like provided by the SAADC example. So now, every time the timer expires, my "sensor_data_read" function should be called. This is, what I would like to have.

    Unfortunaly, it doesn´t work completely. I tried to start my timer in the main loop. While compiling I get a warning. Could you tell me, what is the reason for this?

    Please tell me what the warning said - there is no way for me to see this from your included picture. What are you trying to do in your static const my_timer_id = 3; line?
    If you are attempting to declare a timer instance, you will need to use the _TIMER_INSTANCE macro. You can see this being done in line 72 of the SAADC example.

    simon1516 said:
    I commented out my "read_sensor_data" function because it is called automatically by expiration of the time (i hope so :-) ).

    Cool, lets get this timer configuration out of the way, so we may see if it works!

    simon1516 said:
    I think there is something wrong with the definition of my timer_id. As described in the nordic InfoCenter, I declared this variable as a static. Do I have to pay attention to something other?

    Yes, as I mentioned above you will need to use the INSTANCE macro. If you are uncertain about how something like this should be done, the fastest way to find out is to check a similar example and see how it is implemented there! :) 
    You will also need to make sure that the timer is enabled in your sdk_config file ( but since you did not receive a compiler error I think it already is ).
    Also here you may check the sdk_config file of the example, to see that it matches up on the particular functionality you are interested in using.

    Best regards,
    Karl

  • Hi Karl,

    I am a Little bit confused.

    If you are attempting to declare a timer instance, you will need to use the _TIMER_INSTANCE macro. You can see this being done in line 72 of the SAADC example.

    Okay, but in this example it seems that there is a library "nrf_drv_timer.h" is used. But I already use "app_timer.h". So I don´t think that I need both, or not? If I include additional the "nrf_drv_timer.h" I get errors with my NRFX_Timer driver. I think in this example an other Driver is used, can this be?

    If you are attempting to declare a timer instance, you will need to use the _TIMER_INSTANCE macro. You can see this being done in line 72 of the SAADC example.

    I think for this I have to enable a few things in sdk_config, but I also use app_timer in my project for other Things.

    So do I have to include the new library (as shown in example) or can I just work with my app_timer library?

    Thanks in Advance.

    Kind regards

    Simon

  • Hello Simon,

    simon1516 said:
    I am a Little bit confused.
    simon1516 said:
    Okay, but in this example it seems that there is a library "nrf_drv_timer.h" is used. But I already use "app_timer.h". So I don´t think that I need both, or not? If I include additional the "nrf_drv_timer.h" I get errors with my NRFX_Timer driver. I think in this example an other Driver is used, can this be?

    I am sorry for any confusion I might have caused here, my mistake. I thought you were using the TIMER driver directly. If you are using the app_timer library, you will not need ot use the _TIMER_INSTANCE macro, but you will need to use the APP_TIMER_DEF macro instead.
    If you are using the app_timer library, then you do not need to use the TIMER peripheral drivers directly - the app_timer library handles this for you.

    simon1516 said:
    So do I have to include the new library (as shown in example) or can I just work with my app_timer library?

    I am sorry about my confusion here, I thought you intended to use the TIMER driver, not the app_timer library. You may just use the app_timer library as you already are, no need to worry about the TIMER driver.

    Best regards,
    Karl

Reply
  • Hello Simon,

    simon1516 said:
    I am a Little bit confused.
    simon1516 said:
    Okay, but in this example it seems that there is a library "nrf_drv_timer.h" is used. But I already use "app_timer.h". So I don´t think that I need both, or not? If I include additional the "nrf_drv_timer.h" I get errors with my NRFX_Timer driver. I think in this example an other Driver is used, can this be?

    I am sorry for any confusion I might have caused here, my mistake. I thought you were using the TIMER driver directly. If you are using the app_timer library, you will not need ot use the _TIMER_INSTANCE macro, but you will need to use the APP_TIMER_DEF macro instead.
    If you are using the app_timer library, then you do not need to use the TIMER peripheral drivers directly - the app_timer library handles this for you.

    simon1516 said:
    So do I have to include the new library (as shown in example) or can I just work with my app_timer library?

    I am sorry about my confusion here, I thought you intended to use the TIMER driver, not the app_timer library. You may just use the app_timer library as you already are, no need to worry about the TIMER driver.

    Best regards,
    Karl

Children
  • Hi Karl,

    so now I just use my app_timer.h library but someting went wrong in my implementation.

    For creating my timers I do the following:

    /**@brief Function for initializing the timer module.
     */
    static void timers_init(void)
    {
    
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
        APP_TIMER_DEF(my_timer_id);
        err_code=app_timer_create(&my_timer_id,APP_TIMER_MODE_REPEATED, read_sensor_data);
        APP_ERROR_CHECK(err_code);
    }

    But when I try to start the timer in my main function, then I get an error because "my_timer_id" is not declared in here:

    Could you explain me how to declare this const?

    If I say "#define my_timer_id 3" for example I get an error because of integer value is not possible here.

    Is there an example of using this app_timer? I didn´t find much using this app_timer :-/

    Thanks in advance

    Kind regards

    Simon

  • Hello Simon,

    You can see the necessary steps for using the application timer library in its documentation. It seems to me that you are close to making it work, you will just need to move your APP_TIMER_DEF, and possibly also enable the timers in the sdk_config file.

    simon1516 said:
    But when I try to start the timer in my main function, then I get an error because "my_timer_id" is not declared in here:

    You should move your APP_TIMER_DEF to the top of your file - right next to your #define's.
    Could you also verify for me that APP_TIMER_ENABLED, TIMER_ENABLED, and NRFX_TIMER_ENABLED is defined to 1 in the sdk_config? You will also need to have the particular timer instance ENABLE set to 1 ( seem to me like you are using timer instance 3 ).

    Hope this helps! :) 

    Best regards,
    Karl

  • Hi Karl,

    I am here again with new findings:

    __________________________________

    you will just need to move your APP_TIMER_DEF, and possibly also enable the timers in the sdk_config file

    Thats it. After moving "APP_TIMER_DEF(my_timer_id);" to the top of main.c the compilation works fine. But how can there be an ID (Integer Value) for my timer? I just give it the name my_timer_id. Do I have to give an ID at all? If I trying to do that, I get an error:

    __________________________________

    Could you also verify for me that APP_TIMER_ENABLED, TIMER_ENABLED, and NRFX_TIMER_ENABLED is defined to 1 in the sdk_config? You will also need to have the particular timer instance ENABLE set to 1 ( seem to me like you are using timer instance 3 ).

    Everything is set to "1".

    NRFX_TIMER0_ENABLED to NRFX_TIMER4_ENABLED is set to 1.

    __________________________________

    If I don´t define the "#define my_timer_id 3" the compiling works fine. Then the main loop is running. But after the expiration of the timer (#define TWIM_transmission_time          APP_TIMER_TICKS(10000)) the code stucks with NRF_BUSY error. It´s the same error like posted on 24. August 2020 7:54 p.m. (although I didn´t change anything on this function since then). So the behaviour is confusing a little bit.

    In my main loop is not much code.

    This works:

            nrf_delay_ms(20);
           // ret_code_t err_code = app_timer_start(my_timer_id, TWIM_transmission_time, NULL);
           // APP_ERROR_CHECK(err_code);
            read_sensor_data();

    This doesn´t work:

            nrf_delay_ms(20);
            ret_code_t err_code = app_timer_start(my_timer_id, TWIM_transmission_time, NULL);
            APP_ERROR_CHECK(err_code);
          //  read_sensor_data();

    Where is the difference? The only difference is, that in first example the function "read _sensor_data()"  is called automatically and in the second example the function "read _sensor_data()"  is called by expiration of the timer. Because of that, I don´t think there is someting wrong with my function rather someting with the timer procedure...

    __________________________________

    So, I hope you see something that I don´t see, which I can fix :-)

    Kind regards

    Simon

  • Hello Simon, 

    simon1516 said:
    Thats it. After moving "APP_TIMER_DEF(my_timer_id);" to the top of main.c the compilation works fine.
    simon1516 said:
    But how can there be an ID (Integer Value) for my timer? I just give it the name my_timer_id. Do I have to give an ID at all? If I trying to do that, I get an error:

    You do not need to give your timer an integer ID, no. The APP_TIMER_DEF creates an instance with that name. So, what you would do is basically:

    APP_TIMER_DEF(m_twi_timer);
    ..
    err_code = app_timer_init();
    ..
    err_code = app_timer_create(&m_twi_timer, APP_TIMER_MODE_SINGLE_SHOT, twi_timer_handler);
    APP_ERROR_CHECK(err_code);
    ..
    err_code = app_timer_start(m_twi_timer, TWI_TRANSMISSION_DELAY, NULL);
    APP_ERROR_CHECK(err_code);
    ..
    

    If you would like to see the source of the compiler error you are getting here, go to the definition of APP_TIMER_DEF and see what argument it expects, vs. the integer "3" you provided.

    simon1516 said:

    Everything is set to "1".

    NRFX_TIMER0_ENABLED to NRFX_TIMER4_ENABLED is set to 1.

    Thank you for confirming this.

    simon1516 said:
    APP_TIMER_TICKS(10000)

     This is a 10,000 ms delay, i.e 10 s. Is this the intended delay?

    simon1516 said:
    the code stucks with NRF_BUSY error

    Which function is returning this error code, nrfx_twim_xfer? And, what do you mean by "stuck", does the device reset?

    simon1516 said:
    Where is the difference? The only difference is, that in first example the function "read _sensor_data()"  is called automatically and in the second example the function "read _sensor_data()"  is called by expiration of the timer.

    The difference is that the CPU is free to continue with other tasks in the meantime, while the timer is running. In your current setup, this means that the CPU will run for 10 seconds while the timer is still running. The question then becomes, what are you doing in these 10 seconds? If the code above is your entire main loop then the CPU will immediately enter the loop again, and try to start the timer again in the next loop iteration. From the 

    app_timer_start

    documentation we see that this function call is ignored if the timer is already started.
    What you should instead do is therefore to either go to sleep, or perform some other task.
    Could you show the entire contents of your current main function?

    Best regards,
    Karl

  • If you would like a more fully-fledged tutorial on the app_timer, then I highly recommend taking a look at this one written by my colleague.
    The tutorial is a bit old, but the general approach and theory still holds true for the app_timer in the newest SDK.

    Best regards,
    Karl

Related