Page 1 of 1

Maple Mini ArduCam-Mini-2MP

Posted: Sun Oct 25, 2020 9:06 am
by Lethal Raptor
Hi Guys, I'm hoping somewhere here can help me get setup with using the ArduCam-Mini-2MP (OV2640) Camera with a Maple Mini. I have had it working successfully on an Arduino Nano but now I want to try something a bit faster. I'm not sure on the correct pins to use on the maple as there are two I2C's and two SPI's?

Thanks!

Re: Maple Mini ArduCam-Mini-2MP

Posted: Sun Oct 25, 2020 11:03 am
by stevestrong
viewtopic.php?f=2&t=301
Which core do you intend to use?
Which pinout do you plan?
Why do you need SPI?
You can use any I2C interface.

Re: Maple Mini ArduCam-Mini-2MP

Posted: Sun Oct 25, 2020 9:44 pm
by Lethal Raptor
Which core do you intend to use? : Not sure if this is correct answer, but this is the number on the chip - STM32F103CBT6
Which pinout do you plan? : Not sure what I need. So far I've connected like this :
  • (ArduCam to Maple Mini)
  • VCC to VCC
  • GND to GND
  • CS to PIN7 (which I now see is SPI1 SS - could this be an issue if I've declared PIN7 as an OUTPUT?)
  • MOSI to MOSI (SPI1)
  • MISO to MISO (SPI1)
  • SCK to SCK (SPI1)
  • SDA to SDA (I2C1)
  • SCL to SCL (I2C1)
Why do you need SPI? : Example code shows that SPI is used
You can use any I2C interface. : Isn't this the Wire class?

Below is the code I've uploaded to the board. It has been modified to automatically capture and send the frame to the PC continuously. I am using a windows app to receive the data which works for the Arduino Nano.

Using the Maple Mini it shows me the error message "SPI Interface Error". Which I'm guessing is I'm using the wrong pins.

The Nano only has one SPI and one I2C, but I've seen other Arduino boards (like the Maple Mini) that have two SPI and two I2C interfaces, which I thought were accessed like Wire1 and Wire2 or SPI1 and SPI2. (I'm not positive though). Question is, how can I be sure that in the Maple Mini, that the code SPI.begin() and Wire.begin() directly relate to the pins for I2C1 and SPI1? I can't find any class declarations like Wire1 and Wire2.

Code: Select all

// The demo sketch will do the following tasks:
// 1. Set the camera to JPEG output mode.
// 2. Read data from Serial port and deal with it
// 3. If receive 0x00-0x08,the resolution will be changed.
// 4. If receive 0x10,camera will capture a JPEG photo and buffer the image to FIFO.Then write datas to Serial port.
// 5. If receive 0x20,camera will capture JPEG photo and write datas continuously.Stop when receive 0x21.
// 6. If receive 0x30,camera will capture a BMP  photo and buffer the image to FIFO.Then write datas to Serial port.
// 7. If receive 0x11 ,set camera to JPEG output mode.
// 8. If receive 0x31 ,set camera to BMP  output mode.

#include <Wire.h>
#include <OV2640.h>
#include <SPI.h>

#define OV2640_MINI_2MP

#define BMPIMAGEOFFSET 66
const char bmp_header[BMPIMAGEOFFSET] PROGMEM =
{
  0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00,
  0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00,
  0x00, 0x00
};

// set pin 7 as the slave select for the digital pot:
const int CS = 7;
bool is_header = false;
int mode = 0;
uint8_t start_capture = 0;

ArduCAM myCAM(OV2640, CS);

void setup() {

    // put your setup code here, to run once:
    uint8_t vid, pid;
    uint8_t temp;

    Wire.begin();
    Serial.begin(115200);
    // Serial.begin(921600);

    Serial.println("ArduCAM Start!");
    // set the CS as an output:
    pinMode(CS, OUTPUT);
    digitalWrite(CS, HIGH);

    // initialize SPI:
    SPI.begin();

    //Reset the CPLD
    myCAM.write_reg(0x07, 0x80);
    delay(100);
    myCAM.write_reg(0x07, 0x00);
    delay(100);

    while (1) {
        //Check if the ArduCAM SPI bus is OK
        myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
        temp = myCAM.read_reg(ARDUCHIP_TEST1);
        if (temp != 0x55) {
            Serial.println("SPI Interface Error!");
            delay(1000); continue;
        }
        else {
            Serial.println("SPI Interface OK."); break;
        }
    }

    while (1) {
        //Check if the camera module type is OV2640
        myCAM.wrSensorReg8_8(0xff, 0x01);
        myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
        myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
        if ((vid != 0x26) && ((pid != 0x41) || (pid != 0x42))) {
            Serial.println("Can't find OV2640 module!");
            delay(1000);
            continue;
        }
        else {
            Serial.println("OV2640 Has Been Detected.");
            break;
        }
    }

    //Change to JPEG capture mode and initialize the OV5642 module
    myCAM.set_format(JPEG);
    myCAM.InitCAM();
    myCAM.OV2640_set_JPEG_size(OV2640_320x240);

    delay(1000);

    myCAM.clear_fifo_flag();
}

void loop() {
    while (1) {
        digitalWrite(33, HIGH);
        delay(1000);
        digitalWrite(33, LOW);

        mode = 2;
        start_capture = 2;

        uint8_t temp = 0xff, temp_last = 0;

        while (1)
        {
            if (start_capture == 2)
            {
                myCAM.flush_fifo();
                myCAM.clear_fifo_flag();
                //Start capture
                myCAM.start_capture();
                start_capture = 0;
            }

            if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))//if the capture has completed
            {
                uint32_t length = 0;
                length = myCAM.read_fifo_length();// buffer length
                if ((length >= MAX_FIFO_SIZE) | (length == 0))
                {
                    myCAM.clear_fifo_flag();
                    start_capture = 2;
                    continue;
                }
                myCAM.CS_LOW();
                myCAM.set_fifo_burst();//Set fifo burst mode
                temp = SPI.transfer(0x00);
                length--;
                while (length--)
                {
                    temp_last = temp;
                    temp = SPI.transfer(0x00);
                    if (is_header == true)
                    {
                        Serial.write(temp);
                    }
                    else if ((temp == 0xD8) & (temp_last == 0xFF))
                    {
                        is_header = true;
                        Serial.write(temp_last);
                        Serial.write(temp);
                    }
                    if ((temp == 0xD9) && (temp_last == 0xFF)) //If find the end ,break while,
                        break;
                    delayMicroseconds(15);
                }
                myCAM.CS_HIGH();
                myCAM.clear_fifo_flag();
                start_capture = 2;
                is_header = false;
            }

        }
    }
}
I have also noted these definitions in ArduCam.h for various types of chips. (Here is the one for the Nano)

Code: Select all

#if defined (__AVR__)
#define cbi(reg, bitmask) *reg &= ~bitmask
#define sbi(reg, bitmask) *reg |= bitmask
#define pulse_high(reg, bitmask) sbi(reg, bitmask); cbi(reg, bitmask);
#define pulse_low(reg, bitmask) cbi(reg, bitmask); sbi(reg, bitmask);
#define cport(port, data) port &= data
#define sport(port, data) port |= data
#define swap(type, i, j) {type t = i; i = j; j = t;}
#define fontbyte(x) pgm_read_byte(&cfont.font[x])  
#define regtype volatile uint8_t
#define regsize uint8_t
#endif
This is what I have defined for the Maple Mini but they are more guess work than anything else. The below definitions were the only ones used by ArduCam so I didn't bother trying to convert the others.

Code: Select all

#ifdef __STM32F1__//these values may not be correct
#define cbi(reg, bitmask) *reg &= ~bitmask
#define sbi(reg, bitmask) *reg |= bitmask
#define regtype volatile uint32_t
#define regsize uint32_t
#endif

Re: Maple Mini ArduCam-Mini-2MP

Posted: Sun Oct 25, 2020 11:50 pm
by mrburnette
NOT ARDUINO ... for basic connections
https://github.com/ArduCAM/STM32
Brief Introduction
- This program is a demo of how to use ArduCAM Mini camera on STM32 f103C8T6/ f103ZET6 .etc platform.
- This demo was made for ArduCAM_Mini_2MP. ArduCAM_Mini_5MP_Plus. It needs to be used in combination with PC software.
- It support signal capture
- It can take photo continuously as video streaming.
Ray

PS: I have many of these and they work OK: https://www.amazon.com/AiTrip-ESP32-CAM ... B07WCFGMTF

Re: Maple Mini ArduCam-Mini-2MP

Posted: Mon Oct 26, 2020 8:48 am
by Lethal Raptor
Thanks! I'll have a good read and see if I can get it going.

Re: Maple Mini ArduCam-Mini-2MP

Posted: Sun Nov 01, 2020 4:27 pm
by ag123
arducam apparently made life somewhat easier by interfacing ov2640 and present a SPI interface.
https://www.arducam.com/product/arducam ... 7-arduino/
it is quite possible to interface ov2640 directly from stm32 with some of the 'parallel' gpio techniques and i2c for scci but that may be quite a lot harder than arducam. direct interfacing is more hardcore and takes more entrenched firmware development be it stm32duino or otherwise.
using usb-serial is probably easier to interface with a desktop. otherwise if one attempt usb video or usb ptp
there would be additional challenges implementing the usb protocol driver
https://en.wikipedia.org/wiki/USB#Device_classes
and the default usb full speed 12 mbps may give some additional bandwidth challenges, but literally it may not even be possible to reach usb full speed 12 mbps due to various other overheads on the mcu io and video processing side. it is possibly feasible to do on the fly video compression and usb transmit on an F4 mcu, but would be a challenge on a blue pill stm32f103c8

if arducam simply does SPI for the images, the hard part is probably to interface the arducam over SPI that'd be the thing to figure out in stm32duino (either cores). apparently reading the specs, one may even be able to hack together a usb-serial-spi-arducam interface and commands can be funneled directly from a desktop app.

Re: Maple Mini ArduCam-Mini-2MP

Posted: Sun Nov 01, 2020 6:56 pm
by zoomx
Maybe you can borrow code from the ESP32-cam that uses ov2640 too.