Adding state ?

Dear Members,

I can use a simple timer in :

https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v15.0.0%2Fnrf_dev_simple_timer_example.html

I want to add another state

in timeout handler I added :

void timeout_handler(void * p_context)

    case APP_STATE_SINGLE_SHOT_ANT_HRM:
                                             if (--m_state_transit_counter != 0)
                                 {
                                        if (--m_toggle_led_counter == 0)
                                        {
                                                m_toggle_led_counter = TOGGLE_LED_COUNTER;
                                                bsp_board_led_invert(BSP_BOARD_LED_0);
                                        }

                                        err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT,
                                                                                     timeout_handler,
                                                                                     TIMEOUT_VALUE,
                                                                                     NULL);
                                        APP_ERROR_CHECK(err_code);
                                }
                                else
                                {
                                        state_machine_state_change(APP_STATE_REPEATED_ANT_HRM);
                                }                
            break;

but the code doesn't go to this state...

Any clues ? thanks

  • Hello, 

    Thanks for your query.

    I would like to know few more information about function for executing the state entry action. Which state it is when you say adding a new state - 

    state_machine_state_change (APP_STATE_REPEATED_ANT_HRM) or the case APP_STATE_SINGLE_SHOT_ANT_HRM? I

    Best Regards,

    Kazi Afroza Sultana

  • Hi Kazi,

    Thanks for the reply,

    I'm talking about both states,

    Here's the case :

    /**@brief Function for executing the state entry action.
     */
    static __INLINE void state_entry_action_execute(void) //originally 20Jan22 Rixtronix LAB
    //void state_entry_action_execute(void)	
    {
        switch (m_state)
        {
            case APP_STATE_SINGLE_SHOT:
                led_and_timer_control(BSP_BOARD_LED_0, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
    				    //start GPS from state machine, Rixtronix LAB 17 Jan 2022
    				   	//ANT_HRM_flag_timer =0;
    						
    				    GPS_flag_timer=1;
    				   
    				    
    					 
                break;
    
            case APP_STATE_REPEATED:
                //led_and_timer_control(BSP_BOARD_LED_1, APP_SIMPLE_TIMER_MODE_REPEATED); //originally 14Jan22 Rixtronix LAB
    				    led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_REPEATED);
    				    //led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
    				   //NRF_LOG_INFO("APP_STATE_REPEATED");
    				     GPS_flag_timer=0;
    					   
    				    
    				    
    					 
    				    //led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
                break;
    				
    				case APP_STATE_SINGLE_SHOT_ANT_HRM: 
    					   led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT); 
    				     //NRF_LOG_INFO("APP_STATE_SINGLE_SHOT_ANT_HRM");
    				     	
                 ANT_HRM_flag_timer =1;					
                break;
    				case APP_STATE_REPEATED_ANT_HRM:
    					    led_and_timer_control(BSP_BOARD_LED_0, APP_SIMPLE_TIMER_MODE_REPEATED); 
    					    ANT_HRM_flag_timer =0;					
    					   break;
            default:
                APP_ERROR_HANDLER(m_state);
                break;
        }
    }
    
    
    void timeout_handler(void * p_context)
    {
        switch (m_state)
        {
            uint32_t err_code;
    
            case APP_STATE_SINGLE_SHOT:
                if (--m_state_transit_counter != 0)
                {
                    if (--m_toggle_led_counter == 0)
                    {
                        m_toggle_led_counter = TOGGLE_LED_COUNTER;
                        bsp_board_led_invert(BSP_BOARD_LED_0);
                    }
    
                    err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT,
                                           timeout_handler,
                                           TIMEOUT_VALUE,
                                           NULL);
                    APP_ERROR_CHECK(err_code);
                }
                else
                {
                    state_machine_state_change(APP_STATE_REPEATED);
                }
                break;
    
            case APP_STATE_REPEATED:
                if (--m_state_transit_counter != 0)
                {
                    if (--m_toggle_led_counter == 0)
                    {
                        m_toggle_led_counter = TOGGLE_LED_COUNTER;
                       // bsp_board_led_invert(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    									  bsp_board_led_invert(BSP_BOARD_LED_2);
                    }
                }
                else
                {
                    bsp_board_led_on(BSP_BOARD_LED_0);
                    //bsp_board_led_on(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    							  bsp_board_led_on(BSP_BOARD_LED_2);
    							  
    
                    //err_code = app_simple_timer_stop();
                   // APP_ERROR_CHECK(err_code);
    
                    nrf_delay_ms(GENERIC_DELAY_TIME);
    
                    //state_machine_state_change(APP_STATE_SINGLE_SHOT); //originally 20Jan22
    							  state_machine_state_change(APP_STATE_SINGLE_SHOT_ANT_HRM);
                }
                break;
    						
    			case APP_STATE_SINGLE_SHOT_ANT_HRM: 
    											 if (--m_state_transit_counter != 0)
    								 {
    										if (--m_toggle_led_counter == 0)
    										{
    												m_toggle_led_counter = TOGGLE_LED_COUNTER;
    												bsp_board_led_invert(BSP_BOARD_LED_0);
    										}
    
    										err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT,
    																					 timeout_handler,
    																					 TIMEOUT_VALUE,
    																					 NULL);
    										APP_ERROR_CHECK(err_code);
    								}
    								else
    								{
    										state_machine_state_change(APP_STATE_REPEATED_ANT_HRM);
    								}				
                break;
    								
    			 case APP_STATE_REPEATED_ANT_HRM:			
    								 if (--m_state_transit_counter != 0)
    							{
    									if (--m_toggle_led_counter == 0)
    									{
    											m_toggle_led_counter = TOGGLE_LED_COUNTER;
    										 // bsp_board_led_invert(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    											bsp_board_led_invert(BSP_BOARD_LED_2);
    									}
    							}
    							else
    							{
    									bsp_board_led_on(BSP_BOARD_LED_0);
    									//bsp_board_led_on(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    									bsp_board_led_on(BSP_BOARD_LED_2);
    									
    
    									err_code = app_simple_timer_stop();
    									APP_ERROR_CHECK(err_code);
    
    									nrf_delay_ms(GENERIC_DELAY_TIME);
    
    									//state_machine_state_change(APP_STATE_SINGLE_SHOT); //originally 20Jan22
    									state_machine_state_change(APP_STATE_SINGLE_SHOT);//return to turn on GPS 20Jan22 Rixtronix LAB
    							}   				 
    				    break;
    
            default:
                APP_ERROR_HANDLER(m_state);
                break;
        }
    }
    
    

    It never goes to state 3 and 4, what do I miss here ?

    Any clues ?

    Thanks

  • Hello, 

    I have tested this (adding your extra state state_machine_state_change (APP_STATE_SINGLE_SHOT_ANT_HRM) and state_machine_state_change(APP_STATE_REPEATED_ANT_HRM) ) with the attached code and all states (LED1, LED2, LED3 and LED4)  are reached. Could you please check whether all LEDs blink?

     

    /**
     * Copyright (c) 2014 - 2021, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /**@file
     * @defgroup nrf_dev_simple_timer_example_main.c
     * @{
     * @ingroup nrf_dev_simple_timer_example
     * @brief Timer example application main file.
     *
     * This file contains the source code for a sample application using timer library.
     * For a more detailed description of the functionality, see the SDK documentation.
     */
    
    #include "app_simple_timer.h"
    #include <stdio.h>
    #include "boards.h"
    #include "app_error.h"
    #include "nrf_delay.h"
    
    #define TIMEOUT_VALUE                    50000                          /**< 50 mseconds timer time-out value. */
    #define TOGGLE_LED_COUNTER               (500 / (TIMEOUT_VALUE / 1000)) /**< Interval for toggling a LED. Yields to 500 mseconds. */
    #define STATE_TRANSIT_COUNTER_INIT_VALUE (4 * TOGGLE_LED_COUNTER)       /**< Initial value for the state transition counter.  */
    #define GENERIC_DELAY_TIME               1000                           /**< Generic delay time used by application. */
    
    volatile uint8_t GPS_flag_timer=0;
    volatile uint8_t ANT_HRM_flag_timer=0;
    
    /**@brief Application states. */
    typedef enum
    {
        APP_STATE_SINGLE_SHOT,                                              /**< Application state where single shot timer mode is tested. */
        APP_STATE_REPEATED,                                                 /**< Application state where repeated timer mode is tested. */
        APP_STATE_SINGLE_SHOT_ANT_HRM,
        APP_STATE_REPEATED_ANT_HRM
    } state_t;
    
    static volatile uint32_t m_state_transit_counter = 0;                            /**< State transition counter variable. */
    static volatile uint32_t m_toggle_led_counter    = 0;                            /**< Led toggling counter variable. */
    static volatile state_t  m_state;                                                /**< Current application state. */
    
    void timeout_handler(void * p_context);
    
    
    void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
    {
        bsp_board_leds_off();
    
        for (;;)
        {
            nrf_delay_ms(GENERIC_DELAY_TIME);
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            bsp_board_led_invert(BSP_BOARD_LED_1);
            bsp_board_led_invert(BSP_BOARD_LED_2);
            bsp_board_led_invert(BSP_BOARD_LED_3);
    
        }
    }
    
    
    /**@brief Function for toggling a LED and starting a timer.
     *
     * @param[in] led_id     ID of the LED to toggle.
     * @param[in] timer_mode Timer mode @ref timer_mode_t.
     */
    static void led_and_timer_control(uint32_t led_id, app_simple_timer_mode_t timer_mode)
    {
        uint32_t err_code;
    
        bsp_board_led_invert(led_id);
    
        m_state_transit_counter = STATE_TRANSIT_COUNTER_INIT_VALUE;
        m_toggle_led_counter    = TOGGLE_LED_COUNTER;
    
        err_code = app_simple_timer_start(timer_mode, timeout_handler, TIMEOUT_VALUE, NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for executing the state entry action.
     */
    static __INLINE void state_entry_action_execute(void) //originally 20Jan22 Rixtronix LAB
    //void state_entry_action_execute(void)	
    {
        switch (m_state)
        {
            case APP_STATE_SINGLE_SHOT:
                led_and_timer_control(BSP_BOARD_LED_0, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
    				    //start GPS from state machine, Rixtronix LAB 17 Jan 2022
    				   	//ANT_HRM_flag_timer =0;
    						
    				    GPS_flag_timer=1;
    				   
    				    
    					 
                break;
    
            case APP_STATE_REPEATED:
                //led_and_timer_control(BSP_BOARD_LED_1, APP_SIMPLE_TIMER_MODE_REPEATED); //originally 14Jan22 Rixtronix LAB
    				    led_and_timer_control(BSP_BOARD_LED_1, APP_SIMPLE_TIMER_MODE_REPEATED);
    				    //led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
    				   //NRF_LOG_INFO("APP_STATE_REPEATED");
    				     GPS_flag_timer=0;
    					   
    				    
    				    
    					 
    				    //led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT);
                break;
    				
    				case APP_STATE_SINGLE_SHOT_ANT_HRM: 
    					   led_and_timer_control(BSP_BOARD_LED_2, APP_SIMPLE_TIMER_MODE_SINGLE_SHOT); 
    				     //NRF_LOG_INFO("APP_STATE_SINGLE_SHOT_ANT_HRM");
    				     	
                 ANT_HRM_flag_timer =1;					
                break;
    				case APP_STATE_REPEATED_ANT_HRM:
    					    led_and_timer_control(BSP_BOARD_LED_3, APP_SIMPLE_TIMER_MODE_REPEATED); 
    					    ANT_HRM_flag_timer =0;					
    					   break;
            default:
                APP_ERROR_HANDLER(m_state);
                break;
        }
    }
    
    
    /**@brief Function for changing the state of the state machine.
     *
     * @param[in] new_state  State to which the state machine transitions.
     */
    static void state_machine_state_change(state_t new_state)
    {
        m_state = new_state;
        state_entry_action_execute();
    }
    
    
    
    
    
    void timeout_handler(void * p_context)
    {
        switch (m_state)
        {
            uint32_t err_code;
    
            case APP_STATE_SINGLE_SHOT:
                if (--m_state_transit_counter != 0)
                {
                    if (--m_toggle_led_counter == 0)
                    {
                        m_toggle_led_counter = TOGGLE_LED_COUNTER;
                        bsp_board_led_invert(BSP_BOARD_LED_0);
                    }
    
                    err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT,
                                           timeout_handler,
                                           TIMEOUT_VALUE,
                                           NULL);
                    APP_ERROR_CHECK(err_code);
                }
                else
                {
                    state_machine_state_change(APP_STATE_REPEATED);
                }
                break;
    
            case APP_STATE_REPEATED:
                if (--m_state_transit_counter != 0)
                {
                    if (--m_toggle_led_counter == 0)
                    {
                        m_toggle_led_counter = TOGGLE_LED_COUNTER;
                       // bsp_board_led_invert(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    									  bsp_board_led_invert(BSP_BOARD_LED_1);
                    }
                }
                else
                {
                    bsp_board_led_on(BSP_BOARD_LED_0);
                    //bsp_board_led_on(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    							  bsp_board_led_on(BSP_BOARD_LED_1);
    							  
    
                    //err_code = app_simple_timer_stop();
                   // APP_ERROR_CHECK(err_code);
    
                    nrf_delay_ms(GENERIC_DELAY_TIME);
    
                    //state_machine_state_change(APP_STATE_SINGLE_SHOT); //originally 20Jan22
    							  state_machine_state_change(APP_STATE_SINGLE_SHOT_ANT_HRM);
                }
                break;
    						
    			case APP_STATE_SINGLE_SHOT_ANT_HRM: 
    											 if (--m_state_transit_counter != 0)
    								 {
    										if (--m_toggle_led_counter == 0)
    										{
    												m_toggle_led_counter = TOGGLE_LED_COUNTER;
    												bsp_board_led_invert(BSP_BOARD_LED_2);
    										}
    
    										err_code = app_simple_timer_start(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT,
    																					 timeout_handler,
    																					 TIMEOUT_VALUE,
    																					 NULL);
    										APP_ERROR_CHECK(err_code);
    								}
    								else
    								{
    										state_machine_state_change(APP_STATE_REPEATED_ANT_HRM);
    								}				
                break;
    								
    			 case APP_STATE_REPEATED_ANT_HRM:			
    								 if (--m_state_transit_counter != 0)
    							{
    									if (--m_toggle_led_counter == 0)
    									{
    											m_toggle_led_counter = TOGGLE_LED_COUNTER;
    										 // bsp_board_led_invert(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    											bsp_board_led_invert(BSP_BOARD_LED_3);
    									}
    							}
    							else
    							{
    									bsp_board_led_on(BSP_BOARD_LED_0);
    									//bsp_board_led_on(BSP_BOARD_LED_1);//originally 14Jan22 Rixtronix LAB
    									bsp_board_led_on(BSP_BOARD_LED_1);
                                        bsp_board_led_on(BSP_BOARD_LED_2);
                                        bsp_board_led_on(BSP_BOARD_LED_3);
    									
    
    									err_code = app_simple_timer_stop();
    									APP_ERROR_CHECK(err_code);
    
    									nrf_delay_ms(GENERIC_DELAY_TIME);
    
    									//state_machine_state_change(APP_STATE_SINGLE_SHOT); //originally 20Jan22
    									state_machine_state_change(APP_STATE_SINGLE_SHOT);//return to turn on GPS 20Jan22 Rixtronix LAB
    							}   				 
    				    break;
    
            default:
                APP_ERROR_HANDLER(m_state);
                break;
        }
    }
    
    /**@brief Function for the Power Management.
     */
    static void power_manage(void)
    {
        // Use directly __WFE and __SEV macros since the SoftDevice is not available.
    
        // Wait for event.
        __WFE();
    
        // Clear Event Register.
        __SEV();
        __WFE();
    }
    
    
    int main(void)
    {
        uint32_t err_code = app_simple_timer_init();
        APP_ERROR_CHECK(err_code);
    
        bsp_board_init(BSP_INIT_LEDS);
        bsp_board_led_on(BSP_BOARD_LED_0);
        bsp_board_led_on(BSP_BOARD_LED_1);
        bsp_board_led_on(BSP_BOARD_LED_2);
        bsp_board_led_on(BSP_BOARD_LED_3);
    
        nrf_delay_ms(GENERIC_DELAY_TIME);
    
        state_machine_state_change(APP_STATE_SINGLE_SHOT);
    
        for (;;)
        {
            power_manage();
        }
    }
    

    Please check and let us know the output.

    Have a nice weekend.

    Best Regards,

    Kazi Afroza Sultana

  • Hi Kazi,

    Thanks for the reply,

    It works ok without softdevice , but when I use softdevice,

    It works one round LED1->2->3-> then error, all LEDs blinking.

    How can I debug it ?

    DEBUG -DEBUG_NRF on preprocessor and other ways ?

    Thanks

  • on ANT HRM event :

    void ant_hrm_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
    {
        ant_hrm_profile_t * p_profile = ( ant_hrm_profile_t *)p_context;
        if (p_ant_evt->channel == p_profile->channel_number)
        {
            switch (p_ant_evt->event)
            {
                case EVENT_RX:
    							
                    if (p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID
                     || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID
                     || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID)
                    {  //originally
    													//use timer for displaying message 24 December 2021 Rixtronix LAB, stop GPS,BSC,BSP activity.
    												//GPS_flag_timer =0;	//stop GPS Activity avoid crash 30Dec21
    										//if ((ANT_HRM_flag_timer==1)&&(GPS_flag_timer==0))
    										
    											 
    											 //GPS_flag_timer =0;
    									if (ANT_HRM_flag_timer ==1)
    											{
    													//nrf_gpio_pin_set(16);
    													disp_message_decode(p_profile, p_ant_evt->message.ANT_MESSAGE_aucPayload);
    												//	ANT_HRM_flag_timer =0;
    												  //GPS_flag_timer=1;
    													//nrf_gpio_pin_clear(16);
    														// GPS_flag_timer =1;
    															 //set flag for UART READ 15 December 2021 Rixtronix LAB		
    														//GPS_UART1_Flag=1;
    												//set flag for ANT HRM SENSOR 24 December 2021 Rixtronix LAB		
    								
    											}		
    										
                    }//originally

    Any clues ?

Related