Project shift from nrF52833 to nrF52840

Hi,

Im currently planning to move a project i did in nrF52833DK to nrF52840DK.

My project uses the thread protocol. and relevant DHT11 files.

So i directly added the DHT11 files and replaced the main.c  file with a main.c file of my own in the cli folder of examples in the sdk folder.  "C:\nrf_dk(test)\nrf5_sdk_for_thread_and_zigbee_v4.2.0_af27f76\examples\myprojects\cli"

when i did this and ran the ses file from pca10056, there were no errors and I deployed it in the nrF25840.

But the board is not responding as intended.It is supposed to send prompts in Putty but it isnt working.

this is the output we are gettinng from the debug terminal.

"

<info> app_timer: RTC: initialized.
<info> app: Thread version : OPENTHREAD/20191113-00534-gc6a258e3; NRF52840; Apr 5 2020 21:51:18
<info> app: Network name : OpenThread
<info> app: State changed! Flags: 0x00038200 Current role: 0  "

Can you please help?

thanks!

  • /**
     * Copyright (c) 2017 - 2022, 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 cli_example_main main.c
     * @{
     * @ingroup cli_example
     * @brief An example presenting OpenThread CLI.
     *
     */
    #include "app_scheduler.h"
    #include "app_timer.h"
    #include "bsp_thread.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_delay.h"
    #include "thread_utils.h"
    #include <openthread/cli.h>
    #include <openthread/thread.h>
    #include <openthread/udp.h>
    #include "dht11.h"
    #include "bsp.h"
    
    #include "nrfx_saadc.h"
    #include "nrf_saadc.h"
    
    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "nrf.h"
    #include "nrf_drv_saadc.h"
    #include "nrf_drv_ppi.h"
    #include "nrf_drv_timer.h"
    #include "boards.h"
    #include "app_util_platform.h"
    #include "nrf_pwr_mgmt.h"
    
    bool run = true;
    #define SCHED_QUEUE_SIZE      32                              /**< Maximum number of events in the scheduler queue. */
    #define SCHED_EVENT_DATA_SIZE APP_TIMER_SCHED_EVENT_DATA_SIZE /**< Maximum app_scheduler event size. */
    
    #define SAADC_CHANNEL1 0
    #define SAADC_CHANNEL2 1
    #define SAADC_CHANNEL3 2
    char mystr[10] = "";
    
    static void bsp_event_handler(bsp_event_t event);
    APP_TIMER_DEF(m_our_char_timer_id);
    
    /***************************************************************************************************
     * @section State
     **************************************************************************************************/
     // ... (previous code remains unchanged)
    
    #include "nrf_nvmc.h"
    
    // Non-volatile memory address for storing power-fail flag
    #define POWER_FAIL_FLAG_ADDR    (NRF_UICR->CUSTOMER[0])
    
    // Power-fail flag value
    #define POWER_FAIL_FLAG_VALUE   0xA5A5A5A5
    
    static void timer_start_on_power_restore(void)
    {
        if (POWER_FAIL_FLAG_ADDR == POWER_FAIL_FLAG_VALUE)
        {
            // Power failure occurred, start the timer
            timer_start();
    
            // Clear the flag in non-volatile memory
            nrf_nvmc_write_word(POWER_FAIL_FLAG_ADDR, 0);
        }
    }
    
    
    
       
    
    
    void saadc_callback(nrf_drv_saadc_evt_t const * p_event)
    {
    }
    
    void saadc_init(void)
    {
        ret_code_t err_code;
        nrf_saadc_channel_config_t channel1_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
    
        nrf_saadc_channel_config_t channel2_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN1);
    
        nrf_saadc_channel_config_t channel3_config =
            NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN2);
    
        err_code = nrf_drv_saadc_init(NULL, saadc_callback);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(0, &channel1_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(1, &channel2_config);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_drv_saadc_channel_init(2, &channel3_config);
        APP_ERROR_CHECK(err_code);
    }
    
    nrf_saadc_value_t sample1;
    nrf_saadc_value_t sample2;
    nrf_saadc_value_t sample3;
    
    void read_rain(int *samp1, int *samp2, int *samp3)
    {
        nrf_saadc_value_t sample1;
        nrf_saadc_value_t sample2;
        nrf_saadc_value_t sample3;
    
        nrfx_saadc_sample_convert(SAADC_CHANNEL1, &sample1);
        nrfx_saadc_sample_convert(SAADC_CHANNEL2, &sample2);
        nrfx_saadc_sample_convert(SAADC_CHANNEL3, &sample3);
    
        *samp1 = sample1;
        *samp2 = sample2;
        *samp3 = sample3;
    }
    
    uint16_t temp = 0;
    void temp_humid_sense()
    {
        uint16_t temperature, humidity;
        DHTxx_ErrorCode dhtErrCode;
        int i = 2;
        while (i > 0)
        {
            dhtErrCode = DHTxx_Read(&temperature, &humidity);
            if (dhtErrCode == DHT11_OK)
            {
                break;
            }
            else
            {
                i--;
            }
        }
        char myhum[10];
        temp = temperature;
        sprintf(mystr, "%d", temperature);
    
        sprintf(myhum, "%d", humidity);
        strcat(mystr, ":");
        strcat(mystr, myhum);
        strcat(mystr, ":n4");
    }
    
    static void thread_state_changed_callback(uint32_t flags, void *p_context)
    {
        NRF_LOG_INFO("State changed! Flags: 0x%08x Current role: %d\r\n",
                     flags, otThreadGetDeviceRole(p_context));
    }
    
    /***************************************************************************************************
     *  @section Initialization
     **************************************************************************************************/
    
    /**@brief Function for initializing the Application Timer Module.
     */
    static void timer_init(void)
    {
        uint32_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for initializing the LEDs.
     */
    static void leds_init(void)
    {
        LEDS_CONFIGURE(LEDS_MASK);
        LEDS_OFF(LEDS_MASK);
    }
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for initializing the Thread Stack.
     */
    static void thread_instance_init(void)
    {
        thread_configuration_t thread_configuration =
        {
            .radio_mode = THREAD_RADIO_MODE_RX_ON_WHEN_IDLE,
            .autocommissioning = true,
            .autostart_disable = false,
        };
    
        thread_init(&thread_configuration);
        thread_cli_init();
        thread_state_changed_callback_set(thread_state_changed_callback);
    
        uint32_t err_code = bsp_thread_init(thread_ot_instance_get());
        APP_ERROR_CHECK(err_code);
    }
    
    /**@brief Function for deinitializing the Thread Stack.
     *
     */
    
    /**@brief Function for initializing scheduler module.
     */
    static void scheduler_init(void)
    {
        APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    }
    
    /***************************************************************************************************
     * @section Main
     **************************************************************************************************/
    int count = 0;
    bool udp = true;
    void allCommands()
    {
        char command2[] = "udp open\n";
        otCliConsoleInputLine(command2, strlen(command2));
        char command3[] = "udp bind :: 1234\n";
        otCliConsoleInputLine(command3, strlen(command3));
        udp = false;
    }
    
    void udp_send()
    {
        char myrain[10];
        char command2[] = "udp send fdde:ad00:beef:0:9367:4f3:953:18d3 1234 ";
        sprintf(myrain, "%i:%i:%i:", sample1, sample2, sample3);
        strcat(command2, myrain);
        strcat(command2, ":n4");
        sprintf(command2, "%s\n", command2);
    
        otCliOutput(command2, strlen(command2));
        otCliConsoleInputLine(command2, strlen(command2));
    }
    
    static void timer_timeout_handler(void *p_context)
    {
    
        NRF_LOG_FLUSH();
        if (udp)
            allCommands();
        read_rain(&sample1, &sample2, &sample3);
        udp_send();
        temp_humid_sense();
      
        NRF_LOG_FLUSH();
    
    }
    
    void timer_start()
    {
        ret_code_t err_code;
        err_code = app_timer_start(m_our_char_timer_id, APP_TIMER_TICKS(5000), NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    void timer_stop()
    {
        ret_code_t err_code;
        app_timer_stop(m_our_char_timer_id);
        APP_ERROR_CHECK(err_code);
    }
    
    static void bsp_event_handler(bsp_event_t event)
    {
        switch (event)
        {
        case BSP_EVENT_KEY_0:
            timer_start();
            break;
        case BSP_EVENT_KEY_1:
            timer_stop();
            break;
        default:
            timer_start();
            return; // no implementation needed
        }
    }
    
    int main(int argc, char *argv[])
    {
        log_init();
        saadc_init();
        scheduler_init();
        timer_init();
        leds_init();
        uint32_t err_code = bsp_init(BSP_INIT_BUTTONS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
        thread_instance_init();
        app_timer_create(&m_our_char_timer_id, APP_TIMER_MODE_REPEATED, timer_timeout_handler);
        timer_start();
        timer_stop();
    
        while (true)
        {
            // Process Thread stack and application scheduler events
            thread_process();
            app_sched_execute();
    
            // Process logs or put the device into low-power sleep mode if idle
            if (NRF_LOG_PROCESS() == false)
            {
                // Enter low-power sleep mode (System ON Sleep) to conserve power during idle periods
                // The device will wake up when the timer expires or when an interrupt occurs
                __WFE(); // Wait for Event
                __SEV(); // Signal Event (to clear the pending event)
                __WFE(); // Wait for Event (again, to truly enter sleep)
            }
        }
         // Check if power failure occurred during the last run
        if (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk)
        {
            // Power-fail recovery: Set the flag in non-volatile memory
            nrf_nvmc_write_word(POWER_FAIL_FLAG_ADDR, POWER_FAIL_FLAG_VALUE);
    
            // Clear the reset reason register
            NRF_POWER->RESETREAS = POWER_RESETREAS_RESETPIN_Msk;
        }
        else
        {
            // Reset the flag since it is not a power-fail recovery
            nrf_nvmc_write_word(POWER_FAIL_FLAG_ADDR, 0);
        }
    
        // Start the timer after power-on/reset
        timer_start_on_power_restore();
    
    }
    
    
    #include "nrf_delay.h"
    #include "dht11.h"
    #include "nrf_gpio.h"
    
    #include "SEGGER_RTT.h"
    #include "SEGGER_RTT_Conf.h"
    static void Data_SetInput()
    {
            nrf_gpio_cfg_input(DHT11_PIN, NRF_GPIO_PIN_PULLUP);
    }
    
    static uint32_t Data_GetVal()
    {
    	return nrf_gpio_pin_read(DHT11_PIN);
    }
    
    static void Data_SetOutput()
    {
            nrf_gpio_cfg_output(DHT11_PIN);
            nrf_gpio_pin_set(DHT11_PIN);
    }
    
    static void Data_ClrVal()
    {
            nrf_gpio_pin_clear(DHT11_PIN);
    }
    
    void DelayUSec(int usec)
    {
           nrf_delay_us(usec);
    }
    
    void DelayMSec(int msec)
    {
          nrf_delay_ms(msec);
    }
    
    DHTxx_ErrorCode DHTxx_Read (uint16_t *temperatureCentigrade, uint16_t *humidityCentipercent)
    {
      int cntr;
      int loopBits;
      uint8_t buffer[5];
      int i;
      int data;
    
      /* init buffer */
      for(i=0;i<sizeof(buffer); i++) {
        buffer[i] = 0;
      }
    
      /* set to input and check if the signal gets pulled up */
      Data_SetInput();
      DelayUSec(50);
      if(Data_GetVal()==0) {
        return DHT11_NO_PULLUP;
      }
    
      /* send start signal */
      Data_SetOutput();
      Data_ClrVal();
      DelayMSec(20); /* keep signal low for at least 18 ms */
      Data_SetInput();
      DelayUSec(50);
    
      /* check for acknowledge signal */
      if (Data_GetVal()!=0) { /* signal must be pulled low by the sensor */
        return DHT11_NO_ACK_0;
      }
      /* wait max 100 us for the ack signal from the sensor */
      cntr = 18;
      while(Data_GetVal()==0) { /* wait until signal goes up */
    	DelayUSec(5);
        if (--cntr==0) {
          return DHT11_NO_ACK_1; /* signal should be up for the ACK here */
        }
      }
      /* wait until it goes down again, end of ack sequence */
      cntr = 18;
      while(Data_GetVal()!=0) { /* wait until signal goes down */
    	DelayUSec(5);
        if (--cntr==0) {
          return DHT11_NO_ACK_0; /* signal should be down to zero again here */
        }
      }
      /* now read the 40 bit data */
      i = 0;
      data = 0;
      loopBits = 40;
      do {
        cntr = 11; /* wait max 55 us */
        while(Data_GetVal()==0) {
          DelayUSec(5);
          if (--cntr==0) {
            return DHT11_NO_DATA_0;
          }
        }
        cntr = 15; /* wait max 75 us */
        while(Data_GetVal()!=0) {
          DelayUSec(5);
          if (--cntr==0) {
            return DHT11_NO_DATA_1;
          }
        }
        data <<= 1; /* next data bit */
        if (cntr<10) { /* data signal high > 30 us ==> data bit 1 */
          data |= 1;
        }
        if ((loopBits&0x7)==1) { /* next byte */
          buffer[i] = data;
          i++;
          data = 0;
        }
      } while(--loopBits!=0);
    
      /* now we have the 40 bit (5 bytes) data:
       * byte 1: humidity integer data
       * byte 2: humidity decimal data (not used for DTH11, always zero)
       * byte 3: temperature integer data
       * byte 4: temperature fractional data (not used for DTH11, always zero)
       * byte 5: checksum, the sum of byte 1 + 2 + 3 + 4
       */
      /* test CRC */
      if ((uint8_t)(buffer[0]+buffer[1]+buffer[2]+buffer[3])!=buffer[4]) {
        return DHT11_BAD_CRC;
      }
    
      /* store data values for caller */
      *humidityCentipercent = ((int)buffer[0])*100+buffer[1];
      *temperatureCentigrade = ((int)buffer[2])*100+buffer[3];
    
      return DHT11_OK;
    }
    
    dht11.h

    these are the files i added in the cli folder.

  • Hi,

    The nRF5 SDK for Thread and ZigBee has been deprecated:

    "Note: The nRF5 SDK for Thread and Zigbee is deprecated and will not be upgraded. The OpenThread stack that is part of this SDK contains a known vulnerability (see the SA-2023-234 Security Advisory v1.1 on the Security Advisories page for details.) For new projects, use the nRF Connect SDK."

    If you are upgrading your project, concider using the nRF Connect SDK instead.

    Regards,
    Sigurd Hellesvik

  • Hello, 

    Considering this change, do you have any suggestions on the process we should take to make this transition, considering the two codes I have shared here. 

    Thanks! 

  • The nRF5 SDK and the nRF Connect SDK are quite different, so converting projects from one to the other is not really possible.

    The best procedure is to start over again for the nRF Connect SDK.
    However, your code does not seem too large, so I think that is a reasonable approach.

    The largest downside, I would say is that the learning curve for getting into the nRF Connect SDK is quite steep, so you will have to spend a bit of time learning this. However, we have made https://academy.nordicsemi.com/ for a set of good and free courses which you can take to get started. I suggest that you start with the Fundamentals one here to get started.

    One good upside for your project is that the nRF Connect SDK has drivers for the DHT sensor, and a sample which you can test it with, which should make the sensor part of your project quick to implement.
    Also, the nRF Connect SDK lets you build one project for multiple different boards, so you can use the same project for both the nRF52833 and the nRF52840, with just different build commands, making the change a lot easier.
    Of course, the nRF Connect SDK has good Thread support as well, and you can see both our docs and samples for this.

Related