Tuesday, March 14, 2017

Arducam too unstable to be useful

The costly Arducam Mini 5Mpixel camera module.
Warning, read before you buy, I do not recommend it!
After weeks of fighting I came to the conclusion that the Arducam ecosystem is useless, and even counter-productive to me -- while its original goal was obviously the opposite.

These camera are sold to provide pictures to Arduinos and other microcontrollers. The Arduino does not have enough memory, so these boards embeds enough processing power (FPGA?) and on-board memory to bufferize it and allow for serialized data to be stored and then transferred on demand. This way, the Arduino can store on an SD, or send it over GSM as I needed.

Now, the hardware may be nice and promising, but the software is really bad in my opinion.

This is strange to me as the Arducam is a wellknown project, and it is costly: I paid 43€ on watterott for example!

But it did not help me work faster, on the contrary. I really had all kinds of problems with the software, trying to interface both on a Uno or on a Mega.

The examples are half-baked, the API code source and the entire library is bloated with tens of variants of boards (28MB zipped just for the Arduinos!). Even the links to source code examples on some product page are broken. All in all, I consider that this somehow expensive camera is barely usable as it produces way too often invalid JPEG streams.

I found it impossible to find reliable, or even to fix samples from the huge library (namely, it is 100+MB unpacked without git overhead, so if you want to keep up to date or to help... well, it has to be your main job -- but you will get no funding for it).

It simply never worked reliably enough for me and my project: getting a 5Mpixel shot and sending it over GSM to a server, period. Seems simple, eh?

You feel like you are close enough to keep on
trying to cicumvent the issues, in vain (in my case).

Worse, it is half baked enough so you keep thinking you are "close enough to a solution (tm)". But I am about to cancel the whole project because I already sent literally hundreds of hours trying to make the whole reliable enough for a stand alone, remote, reliable system. It would be the first I time I would have done so.
1200 lines of messy un-commented code.
The monolithic API is bloated with many #define,
which reminds me of the Marlin 3D printing firmware

Annoyingly, the sheer size of the monolithic library, and the broken examples seems to deter anyone to help them on github. For example, Sumotoy has had a promising, lightweight, independent fork on github to help alleviate some of the issues, but it is getting quite old and it never was merged back in the official library: his readme is really revealing on the issue with the Arducam software stack.

Issues with the chronic, broken, unstable Arducam API

So what is this huge sensor-specific Arduino library for? The outer layers should make the capture of a frame safe and homogeneous across the Arducam product family imho. But it does not.

Just an example: the author has a weird view of his products, e.g. he says that the produced JPEGs are "fine" .... as long as you remove the spurious bytes in front of the JPEG start marker with a hex editor (!).

"No, my product is good, you just forgot to fix it"... LOL, this is a strange business :D
Obviously I had fixed the spurious bytes at the start, and also at the end in my case, long ago by reading the expected JPEG begin and end markers (FFD8 ... FFD9).

I would be OK with the hack, but I am less confident as it is anyhow risky without us knowing how the Arducam encodes its data (proprietary code, see below). I do not think it embeds a thumbnail, but I will never have warranty on this.

Also, due to unknown circumstances (mostly the state of the camera or hardware context, etc), the thing may refuse to talk at all. Sometimes the camera is not recognized, probably locked in an unknown internal state, and I found no way I can reset it without re-powering it and extra hardware.

It also kept on returning wrong FIFO buffer sizes (usually it is too short which is bad as I need to know the size to send it over GSM). Timing may be the issue but I was not able to solve them (the documentation is lacking here and the samples have no comments at all, as much as the library actually).

Or it behaves weirdly (as Sumotoy says, "the SPI doesn't play nice with other SPI devices").

What eventually made me write this little review/rant is that it just started to freeze when I set control bits trying to capture an image (this should precisely be the job of the API, by the way). It was working before, so may be the cam is dead (since I have to switch it off/on regularly so it will be recognized with a higher probability).

The "ArduChip" is proprietary, closed-source (source)
Too bad it is precisely what makes the Arducam unreliable in my opinion..
The broken, inconsistent API examples and the monstrous library only adds to the pain.
I do not recommend this product when you expect it to make your life easier :/
I suspect all these issues come from the way the library is (un)structured, and because of the closed source component of the Arducam: "the ArduChip uses ArduCAM proprietary third generation camera controller technology which handles the complex camera, memory and user interface hardware timing and provides a user friendly SPI interface.". Hence I suspect the embedded code is probably very hacky itself, given hos the outer library is.

In any case, the Arducam is hostile. It is not friendly at all, with examples full of switches and hardware calls, that depends on the kind of Arducam you bought.

What is an API for then? In addition, it is not reliable and nobody can help because of the way the library is (non-)structured.

Conclusion: I do not recommend the Arducam at all

All in all I just cannot trust nor recommend this product, sorry.

I would better have worked low-level with the Omivision sensor datasheet and a dumb, naked camera board, with a more powerful STM32F micro-controller, for example. I wrongly expected the Arducam to help me alleviate this work, but now I regret NOT being able to do this work and only fight with the library instead.