Introduction: SiPEED Maixduino First Camera Test Arduino Sketch

As a continuation of my previous post Arduino Framework Blink Tests With SiPEED Maixduino, this post will present an Arduino sketch to test capturing images with the attached camera to display them to the attached LCD. The goal is that simple.

I would assume PlatformIO project MaixduinoExperiments setup as mentioned in my previous post Arduino Framework Blink Tests With SiPEED Maixduino, and add yet another sketch to it -- camtest/camtest.ino.

The Maixduino board should support two common variants of cameras, OV2640 and GC0328. The sketch here can be targeted for both variants. However, since I only have GC0328, I only tested the sketch with GC0328.

Step 1: The Sketch

To src of MaixduinoExperiments, add camtest/camtest.ino

#define CAMERA_IS_GC0328

#if defined (CAMERA_IS_GC0328)
  #include "Maixduino_GC0328.h"
  class MaixduinoCamera: public Maixduino_GC0328 {
  public:
    MaixduinoCamera(): Maixduino_GC0328(FRAMESIZE_QVGA, PIXFORMAT_RGB565) {
    }
    // spelling mistake of Camera class ... should have been called setRotation
    void setRotaion(uint8_t rotation) {
      Maixduino_GC0328::setRotation(rotation);
    }
  };
  MaixduinoCamera camera;
#else
  #include <Sipeed_OV2640.h>
  Sipeed_OV2640 camera(FRAMESIZE_QVGA, PIXFORMAT_RGB565);
#endif

#include <Sipeed_ST7789.h>
SPIClass spi_(SPI0); // MUST be SPI0 for Maix series on board LCD
Sipeed_ST7789 lcd(320, 240, spi_);

bool camera_initialized;
void setup() {
  Serial.begin(115200);

  lcd.begin(15000000, COLOR_LIGHTGREY);
  lcd.setTextColor(COLOR_GREEN);
  lcd.setTextSize(2);

  camera_initialized = camera.begin();
  camera.run(true);
}

int  frame_count = 0;
long start_ms = -1;
void loop() {
  if (!camera_initialized) {
    Serial.println("failed to initialize camera");
    delay(1000);
    return;
  }
  if (start_ms == -1) {
    start_ms = millis();
  }
  uint8_t* img = camera.snapshot();
  if (img == NULL) {
    Serial.println("snap fail");
    return;
  }
  frame_count += 1;
  long total_ms = millis() - start_ms;
  float fps = 1000.0 / ((float) total_ms / (float) frame_count);

  if ((frame_count % 10) == 0) {
    // print FPS to serial every 10 frames
    Serial.printf("FPS: %0.2f\n", fps);
  }

  lcd.drawImage(0, 0, camera.width(), camera.height(), (uint16_t*) img);

  lcd.setCursor(0, 0);
  lcd.printf("FPS: %d", (int) fps);
}

If your camera is not GC0328, please comment out the macro CAMERA_IS_GC0328 in the above sketch.

//#define CAMERA_IS_GC0328

If your camera is GC0328, actually, things are a bit messier, since you will need an additional library Maixduino_GC0328 (Maixduino_GC0328.h). Moreover, since there is a name mismatch between the class Maixduino_GC0328 and the base class Camera, a hack is needed -- one way to remedy the issue is to override the class Maixduino_GC0328 as done in the above sketch.

  #include "Maixduino_GC0328.h"
  class MaixduinoCamera: public Maixduino_GC0328 {
  public:
    MaixduinoCamera(): Maixduino_GC0328(FRAMESIZE_QVGA, PIXFORMAT_RGB565) {
    }
    // spelling mistake of Camera class ... should have been called setRotation
    void setRotaion(uint8_t rotation) {
      Maixduino_GC0328::setRotation(rotation);
    }
  };
  MaixduinoCamera camera;

The entry point main.cpp should be like

#include <Arduino.h>
#include "camtest/camtest.ino

Step 2: Building the Sketch

If your camera is GC0328, you will need to modify platformio.ini adding an additional dependency

[env:maixduino]
platform = kendryte210
platform_packages =
  platformio/framework-maixduino@^0.3.9
board = sipeed-maixduino
framework = arduino
lib_deps =
    https://github.com/adafruit/Adafruit_NeoPixel#1.11.1
    https://github.com/trevorwslee/Arduino-DumbDisplay
    ; for GC0328 Camera
    https://github.com/fukuen/Maixduino_GC0328
monitor_speed = 115200
monitor_port = COM12
upload_port = COM12

Build it, upload it, and see it working.

Step 3: Enjoy!

Peace be with you. May God bless you! Jesus loves you!