Arducam on Electron (e-series) using Wire1 and B0 pin for CS


Hello, all!

I’m needing some guidance on an Arducam OV5642 using Wire1 and B0 for CS. I was able to successfully get the cam working using wire and A2 (Standard with the Library), but now having issues getting the cam to spin up on Wire1.

I went into the arduCAM.h file and changed the A2(hard coded) pin to B0 and in arduCAM.cpp changed every instance of Wire to Wire1.

I should note - A2 using Wire1 does work, however I need the pin to be B0 as I already have my PCB’s in hand and trying not to go through another round of revision.

Am I missing something? Could the issue be B0 is not an analog to digital pin?

Help on this issue is greatly appreciated!


That won’t be an issue as all the pins can be used as digital IO.

Have you checked the level on B0 it it is at all doing what you’d expect?

Have you got the code to look at?

BTW, I2C won’t require a chip-select, so where does the need come from other than SPI?
Consequently: Which SPI interface are you using?
Are you providing the correct CS pin to SPIx.begin()?
When not explicitly providing the alternative CS pin A2 is assumed and pinMode() won’t be set for the alternative pin (unless you do explicitly yourself).


Very much appreciate your help, sir! Thank you. I’m actually receiving a Hard Fault SOS. Maybe I2C??

Figured this wouldn’t be an issue. But thought I’d ask just to make sure I wasn’t crazy (well…maybe a little).

Not sure if I understand. I checked the continuity on my board and everything checks out.

Sure do! For brevity sake I’ve truncated.

I’m using the standard one - Just SPI. And yes, Wire1 was changed so I contributed the underlying issue to that, but I understand now that this shouldn’t effect anything (as long as I changed every instance of Wire to Wire1 - and I did!).

Yes, Adding B0 to SPI.begin()

Correct, I understand that SPI.begin(X) will turn the pin to OUTPUT and select HIGH. Are there extended settings that “begin” changes as well?


Actually probing the level on the pin during operation - e.g. via oscilloscope or even an LED should do the trick.

Yes and no :wink:
Of course it will do all the stuff that enables the HW SPI interface internally, but nothing that would differentiate between A2 and B0.

You should try to pin point the instruction that effectively causes the SOS+1.

  #define pinLO(_pin) (PIN_MAP[_pin].gpio_peripheral->BSRRH = PIN_MAP[_pin].gpio_pin)
  #define pinHI(_pin) (PIN_MAP[_pin].gpio_peripheral->BSRRL = PIN_MAP[_pin].gpio_pin)
  #define cbi(_pin, bit)                 pinLO(B0)
  #define sbi(_pin, bit)                 pinHI(B0)

I’d define these macros differently.

  #define pinLO(_pin)    pinResetFast(_pin)
  #define pinHI(_pin)    pinSetFast(_pin)
  #define cbi(_pin, bit) pinLO(_pin)    
  #define sbi(_pin, bit) pinHI(_pin)  

Not sure if needed in the library but your code seems to not define pulse_high() nor pulse_low().

However, since you are already altering code in the library, you may as well remove all the non-applicable code from it to make it easier to debug.
All these #ifdefs don’t help following the actual flow.

If in fact everything works with Wire1, SPI and A2 and only changing A2 to B0 causes your issues, I’d focus on ArduCAM::ArduCAM(byte model ,int CS) and all the local variables impacted by CS (i.e. P_CS and B_CS) whether they actually get initialised correctly.


Will give it a shot.

I tried your solution and received an error for volatile uint32_t. However, this portion of the lib does in fact get me past a hard fault. only when i change to this

//#define pinLO(_pin) (PIN_MAP[_pin].gpio_peripheral->BSRRH = PIN_MAP[_pin].gpio_pin)
 // #define pinHI(_pin) (PIN_MAP[_pin].gpio_peripheral->BSRRL = PIN_MAP[_pin].gpio_pin)
  #define cbi(_pin, bit)                 digitalWrite(_pin, LOW)
  #define sbi(_pin, bit)                 digitalWrite(_pin, HIGH)

I know this is wrong though…

I would totally agree but i fear that would just get me deeper in the pit.

Ill start there and see what I come up with. Thank you! I think you pointed me in a direction i havent tried! Novice here…


What was the exact error message?
What device OS version are you targeting - pinSetFast(_pin) (sbi(_pin, _bit)) and pinResetFast(_pin) (cbi(_pin, _bit)) should be available for almost every “newer” version.


“Invalid conversion from ‘volatile unit32_t* {aka volatile long unsigned int*}’ to pin_t”
Error for 7 of the same

1.4.0 Latest


That suggests that the wrong #ifdef branch is used.
The reason why P_CS is defined as volatile uin32_t* stems from the fact that on AVRs sbi()/cbi() directly touch the port - we don’t do that here ;-).
You could work around this in multiple ways (type casting, changing the definition, going with another #ifdef, removing the non-applicable portions, …).

Changing the definition would look like this

 #define cbi(_port, _pin)   pinLO(_pin)
 #define sbi(_port, _pin)   pinHI(_pin)

(the original naming of the “parameters” was misleading)

But I’d go - as said before - with removing the non-applicable portions.


Thank you for your time! I’m going to start stripping this down and see where it leads!


As this solution was a great contribution to troubleshoot my issue, it wasn’t the cause. However, after stripping the lib of all the unnecessary #ifdef’s I have a better understanding of what is actually going on. Thank you for pointing me in that direction.

I was able to narrow the issue down to voltage on SCL and SDA (causing the board to reboot… Back to Wire :(…).

I have the e-series dev board and the voltage output is 3.3v and the camera works using Wire1 and B0. After that, I started to look for differences between the dev board and my pcb (should have done this earlier - my bad!). My PCB’s are outputting 5V on SCL and SDA, this is weird as there is nothing different between them. No line crossings, bad connections etc…

As far as the E-Series chips go there aren’t any differentiators between them. They both say v0.0.0.

Any thoughts? Should I open a new thread on this?


Solved. Thank you for you time. Voltage on camera apparently cant be 5V even though it says it can be.