m5stack / TimerCam-arduino

TimerCam Arduino Library
MIT License
46 stars 26 forks source link

Camera Init Fail when TimerCAM is initialized with enableRTC = true #16

Open OndrejBakan opened 10 months ago

OndrejBakan commented 10 months ago

Describe the bug

I tried to use the http_post.ino example, but I changed initialization to TimerCAM.begin(true) to enable RTC for deepsleep between camera pictures.

The code won't get past this:

20:16:57.789 -> E (472) i2c: i2c driver install error
20:16:57.789 -> E (473) camera: sccb init err
20:16:57.789 -> E (473) camera: Camera probe failed with error 0xffffffff(ESP_FAIL)
20:16:57.789 -> Camera Init Fail

I also tried to initialize camera in the wakeup.ino example and I got a same error.

To reproduce

Initialize TimerCAM with RTC enabled - TimerCAM.begin(true) and then try to initialize camera with TimerCAM.Camera.begin().

Expected behavior

TimerCAM would succesfully initialize with both, Camera and RTC available.

Screenshots

No response

Environment

Additional context

No response

Issue checklist

akita11 commented 9 months ago

I'm also facing the same problem...

akita11 commented 9 months ago

I'm reading the library source codes:

akita11 commented 9 months ago

This results as follows, with I2C initializaion error...

E (10300) i2c: i2c driver install error
[ 10326][E][esp32-hal-i2c.c:92] i2cInit(): i2c_driver_install failed
[ 10330][E][Wire.cpp:526] write(): NULL TX buffer pointer
[ 10335][E][Wire.cpp:526] write(): NULL TX buffer pointer
[ 10340][E][Wire.cpp:448] endTransmission(): NULL TX buffer pointer](url)
akita11 commented 9 months ago

I'm reading source codes. TimerCAM.begin() calls esp_camera_init() with "sccb_i2c_port = 0" in config, while TimerCAM.Rtc.begin() uses Wire1. These means SCCB and RTC use different I2C units.

felmue commented 9 months ago

Hello @akita11

sccb_i2c_port from config is only used if pin_sccb_sda is -1 see comment here and implemenation here. In my understanding sccb_i2c_port could be used if RTC and camera use the same I2C bus - which is not the case here.

Which port the camera uses is determined by CONFIG_SCCB_HARDWARE_I2C_PORT1 see here.

Now when I change the I2C bus the RTC is using from Wire1 to Wire (see here) the camera gets initialized properly. (Which leads me to assume that CONFIG_SCCB_HARDWARE_I2C_PORT1 must be set.)

Thanks Felix

akita11 commented 9 months ago

@felmue Thank you for your advise. I'm trying with changing begin() in RTC8563_Class.cpp to use Wire from Wire1. No debug message comes on monitoring serial port... seems go be hang-up?

For CONFIG_SCCB_HARDWARE_I2C_PORT1, it is used in esp32-camera/driver/sccb.c. How to set CONFIG_SCCB_HARDWARE_I2C_PORT1? In my user program?

Thanks!

felmue commented 9 months ago

Hello @akita11

which example did you try? I tested with http_post.ino and capture.ino; changing TimerCAM.begin() to TimerCAM.begin(true).

I don't think you can modify CONFIG_SCCB_HARDWARE_I2C_PORT1 in the user program. It's defined in sdkconfig (see here) for the arduino-esp32 / framework-arduinoesp32 library build, which is then used as precompiled library. See here.

If you want to build arduino-esp32 / framework-arduino32 library yourself then have a look here.

Thanks Felix

akita11 commented 9 months ago

Hi, @felmue , thank you for your advise. I'm trying "capture" sample with changing TimerCAM.begin(true), and Wire1->Wire in RTC8563_Class.cpp on PlatformIO, not ArduinoIDE, and actually camera works. By adding some codes as follows, capturing 1000 frames followed by going to sleep and wake after 5sec. OK to capture, going to sleep, but doesn't wake after 5sec. I'll continue to investigate.

void setup() {
    TimerCAM.begin(true);
    if (!TimerCAM.Camera.begin()) {
        Serial.println("Camera Init Fail");
        return;
    }
    Serial.println("Camera Init Success");
    TimerCAM.Camera.sensor->set_pixformat(TimerCAM.Camera.sensor,
                                          PIXFORMAT_JPEG);
    TimerCAM.Camera.sensor->set_framesize(TimerCAM.Camera.sensor,
                                          FRAMESIZE_QVGA);

    TimerCAM.Camera.sensor->set_vflip(TimerCAM.Camera.sensor, 1);
    TimerCAM.Camera.sensor->set_hmirror(TimerCAM.Camera.sensor, 0);
    for (int i = 0; i < 1000; i++)
    if (TimerCAM.Camera.get()) {
        Serial.printf("%d pic size: %d\n", i, TimerCAM.Camera.fb->len);
        TimerCAM.Camera.free();
    }
    printf("going to sleep for 5 sec\n");
    TimerCAM.Power.timerSleep(5);
}
raduprv commented 7 months ago

I am having the same issue, but a bit different. My program works like so: It starts the camera, wifi, etc. It takes a picture, sends it by ftp, and at the very end of the program I have: TimerCAM.begin(true); TimerCAM.Power.timerSleep(5);

Then I get: 01:26:39.360 -> 5138 01:26:39.360 -> E (5123) i2c: i2c driver install error

Any solutions to this problem? The Timer Camera board is useless without this feature...

raduprv commented 7 months ago

Ok, I made some progress. I used esp_camera_deinit(); after I was done with the camera, and then did the sleep thing. I got no errors, but the device never wakes up...

raduprv commented 7 months ago

Ok, so for the camera to wake, you must use an external battery AND remove it from the USB port.

OndrejBakan commented 7 months ago

Ok, so for the camera to wake, you must use an external battery AND remove it from the USB port.

I think you need to do it like here: https://github.com/m5stack/TimerCam-arduino/blob/0.0.3/examples/wakeup/wakeup.ino

They set up the external wake up in setup function, then in the end of the loop disconnect the battery, setup the esp's builtin deepsleep and start it.

raduprv commented 7 months ago

That's the old way. The most recent way is https://github.com/m5stack/TimerCam-arduino/blob/master/examples/wakeup/wakeup.ino

akita11 commented 7 months ago

Finally I succeeded to capture -> sleep -> wake by followings (on PlatformIO):

akita11 commented 7 months ago

I've made pull-request on this fix.

jjurg commented 2 months ago

Debugging the camera after deepsleep too.

Does anyone know if TimerCAM.Power.timerSleep(5); does deepsleep or sleep wirh higher power consumption?

akita11 commented 2 months ago

It goes deepsleep.

vollukas commented 1 week ago

Finally I succeeded to capture -> sleep -> wake by followings (on PlatformIO):

  • change "Wire1"->"Wire" at begin() in RTC8563_Class.cpp, located at .pio/libdeps/m5stack-timer-cam/Timer-CAM/src/utility/
  • initialize using TimerCAM.begin(true)
  • go to sleep by TimerCAM.Power.timerSleep(5), for waking up after 5 seconds Note that wake-up works only with battery operation, no USB connection. Device reset -> poewr on by button -> start operation.

Hell yeah that works! And I'm happy they approved your PR! But it is not in latest release from 2023 :/ I added it manually and it did the trick! Thank you sooooo much!! I'm so happy 😄