Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Turning camera off in nrf52-ble-image-transfer-demo for nRF52840 Dongle

Hello everyone, I'd like to implement the nrf52-ble-image-transfer-demo for nRF52840 Dongle. The normal code already plays well. However, since I am aiming for a low-power application, I need to somehow put the camera in sleep mode while it is not used. Since I've found no such code or method, I simply turn it off completely using MOSFET. This worked well for the big nRF52840. I simply introduced a camera_init_new() function to initialize the camera before every Take Picture command. The only problem here I have is that I need to put in a delay after the camera init, I think this is due to the fact that the camera needs some time to initialize. 

However, this does not work for the Donlge. The whole thing simply crashes as soon as I send the take picture command. Funny though that after it crashes it performs some kind of reset, meaning that I get automatically disconnected and can connect again.

Anyone an idea where the problem might be?

  • Hi,

    Did you build the application for the pca10059, or did you run the pca10056 build on the dongle? Did you make any other modifications to the example to get it running on the Dongle? Do you use the same GPIOs (if not, which GPIOs do you use?), did you disable UART, etc?

    The reset behavior is typically due to an error/assert in the application, where the default behavior is to do a soft reset in the error handler. 

    Do you have debug capabilities on your dongle? I.e., do you use a debugger to program the dongle, or do you use the bootloader solution that comes with the dongle to program it over the USB port?

    Best regards,
    Jørgen

  • Hi Jørgen,

    I made all the modifications necessary to run the normal example on the Donlge. Like disabling UART, change the application to be build for pca10059, changed the GPIOs as well like so:

    #elif defined(BOARD_PCA10059)
    m_camera_init.pinScl = 32;
    m_camera_init.pinSda = 24;
    m_camera_init.pinSck = 22;
    m_camera_init.pinMiso = 20;
    m_camera_init.pinMosi = 17;
    m_camera_init.pinCsn = 15;

    The Image demo example does run without problems, only when I introduce the code which disables the camera via MOSFET does it crush. However, the same does not happen on the normal nrf52840. The GPIO I use for the gate of the MOSFET is pin 1.10 (I address it in the code with 32+10).

    I do not have any debug capabilities, how could I using the Dongle? I use the bootloader solution with nRF programmer over the USB port.

    Thanks for your help!

    Paul

  • Paul M. said:
    The Image demo example does run without problems, only when I introduce the code which disables the camera via MOSFET does it crush. However, the same does not happen on the normal nrf52840. The GPIO I use for the gate of the MOSFET is pin 1.10 (I address it in the code with 32+10).

    What exactly does this function do? Can you post the code?

    Paul M. said:
    I do not have any debug capabilities, how could I using the Dongle?

    You can solder a 10-pin debug header on the back of the dongle (e.g. this), and use a cable between this and the debug output (P19) port of a nRF52xxx DK. Alternatively, you can solder headers/pins to the SWDCLK/SWDIO pads close to the USB port on the dongle and connect these to the P20 SWD debug output pins on the DK to debug the application. It is also possible to use a TC2050 cable from Tag-Connect.

    We highly recommend adding debug capabilities if you are planning to develop applications for the dongle. If not, it is very hard for us to help you with any issues. The dongle is mainly intended for use with out development tools/precompiled applications.

    For more details, see the nRF52840 Dongle programming tutorial.

  • The code (for nRF 52840, not dongle) would be: first, at the beginning of the main and before the initialization, I clear the pin for the gate of my p-channel MOSFET:

    nrf_gpio_cfg_output(32 + 8);
    nrf_gpio_pin_clear(32 + 8);

    so that the camera is powered. Then, after the initialization and before the advertising_start function, i set the pin again so that the camera is shut down and does not drain current anymore:

    nrf_gpio_pin_set(32 + 8);

    advertising_start();

    In the for-loop, when the take picture command comes in, I clear the gate pin again so that the camera is powered again, call the camera_init_new() function to initialize the camera again, and proceed with the code. 

    switch(new_command)
    {

    case APP_CMD_SINGLE_CAPTURE:
    nrf_gpio_pin_clear(32 + 8);
    nrf_delay_ms(4);
    camera_init_new();
    nrf_delay_ms(500);
    if(arducam_mini_2mp_bytesAvailable() == 0)
    {

    NRF_LOG_INFO("Starting capture...");
    arducam_mini_2mp_startSingleCapture();
    image_size = arducam_mini_2mp_bytesAvailable();
    NRF_LOG_INFO("Capture complete: size %i bytes", (int)(image_size));
    ble_its_img_info_t image_info;
    image_info.file_size_bytes = image_size;

    ble_its_img_info_send(&m_its, &image_info);

    }

    At the end of the image transfer loop, I check if the arducam_mini_2mp_bytesAvailable() == 0 to set the gate pin again to shut the camera down.

    I use the altered camera_init_new() function instead of the camera_init() function because the code did not work with using the normal camera_init() function. I do not know completely yet, but I assume this is due to the camera_init() function also initializing the necessary Pins of the nRF, which can't be initialized more than once. So these were the changes I made in the camera_init() function: instead of calling the arducam_mini_2mp_open(&m_camera_init) function, i introduced the arducam_mini_2mp_open_new(&m_camera_init) function, where I left everything the same except for removing the arducam_spiRegisterCallback(spiCallback); function:

    void arducam_mini_2mp_open_new(arducam_mini_2mp_init_t *config)
    {
    // put your setup code here, to run once:
    uint8_t vid, pid;
    uint8_t temp;
    arducam_new_init(OV2640, config->pinScl, config->pinSda, config->pinCsn, config->pinMosi, config->pinMiso, config->pinSck);

    //nrfSystem.registerError(LS_DEBUG, "ARDUCAM", 0, "Camera Start");

    //arducam_spiRegisterCallback(spiCallback);

    //Check if the ArduCAM SPI bus is OK
    arducam_write_reg(ARDUCHIP_TEST1, 0x55);
    temp = arducam_read_reg(ARDUCHIP_TEST1);
    //Serial.println(temp);
    if (temp != 0x55)
    {
    //nrfSystem.registerError(LS_ERROR, "ARDUCAM", 0, "SPI interface non responsive");
    while(1);
    }
    //Check if the camera module type is OV2640
    arducam_wrSensorReg8_8(0xff, 0x01);
    arducam_rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
    arducam_rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
    if ((vid != 0x26) || (pid != 0x42))
    {
    //nrfSystem.registerError(LS_ERROR, "ARDUCAM", 0, "TWI interface non responsive");
    }
    else
    {
    //nrfSystem.registerError(LS_DEBUG, "ARDUCAM", 0, "OV2640 module detected");
    }

    arducam_set_format(JPEG);
    arducam_InitCAM();
    //arducam_OV2640_set_JPEG_size(OV2640_160x120);
    nrf_delay_ms(10);
    arducam_clear_fifo_flag();
    }

    Also, after calling the camera_init_new() function I need to go into a delay for ca 500 ms. I do not know why, since the necessary delays needed for the camera to initialize are already put in the camera_init() and camera_init_new() function, but that was something I determined by trying. 

    So, this code does work on the nRF52840, however, it does not on the Dongle (of course after adjusting the pin numbers). 

  • Furthermore, how do I debug using the SWDCLK/SWDIO? I already connected them to the P20 SWD of the DK, but what other steps must I take? I have read the discussion Program the pca10059 with pca10056 that the D- and D+ must be cut. Are those the SB3 and SB4 bridges? What else must I do? Do I still need to plug the dongle into the USB port for power, and must the DK also be connected to my pc? 

    Thanks in andvance!

Related