-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I2C bus not working for PI PICO-W #27
Comments
I have not messed with the PI PICO-W can you tell me how the i2c code needs to access the i2c bus |
Not sure if your question is relating to just this ISSUE, or in part also if relation to the ISSUE #26, where I noted the lack of DEFINES in the PI PICO-W build. My code fragment test above demonstrated that your "Simple_Wire.h" library when used in isolation works just fine with the default I2C pins (GP4, GP5 [pins 6,7 on board]). I do not understand what is causing the code to fail when the global mpu object is defined at the top of the file. I have modified my code fragment and include it below, where I have a few #defines to control where the Simple_Wire object is created and used, and also added conrtrol of the onboard LED to try to observe execution and effects. Read the comments at the top of the fragment for brief results summary. ========================================// Code to test Simple_Wire.cpp/h #define DOWAY 3 #include "Simple_Wire.h" #if DOWAY == 3 void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); // USB so baud is ignored #if WAITUSB == 1 Serial.println(F("MyTest_I2C:Start:")); #if DOWAY == 1 // Try to scan I2C on Pico board, see what we can find. } void loop() { #if DOWAY == 3 delay(2000); // wait 2 seconds }======================================== Also I did not say before, but from the Arduino IDE, various tab settings are: Arduino 1.8.19 Tools - Board - Raspberry PI RP2040 Boards (2.5.2) ================= Also my INO file is in a directory with the following files: Simple_Wire.cpp, Simple_Wire.h <- YOUR FILES FROM GITHUB Have done it this way to try to be clear what files were being used, as have had issues in past with all the MPU_6050 libraries that I have been testing/trying while trying to find one that works with any accuracy, I have found at times that Arduino IDE finds multiple same named libraries and either warns or builds with the WRONG library. Obviously the IDE is also including a whole set of other files from who knows where, hopefully ALL from "earlephilhower's" board support. ============= NOTE: for DOWAY=3 and WAITUSB=0, the code builds, but does not appear to manage to run as far as Setup(), as the LED does not turn on. This is what makes me think that there is some issue with the placement of objects outside of Setup() or Loop(), i.e. at the top of the file, but I do not know what that is, but suspect it is either some issue with the "earlephilhower/arduino-pico" support for RP2040 based targets, or an Arduino include/library issue. I would also note that the behaviour of this simple code is slightly different to the behaviour with your full MPU library, there the code was atleast running, but without functional I2C, but I guess there the "SimpleWire" object was inside the MPU object, so must have modified the code behaviour somehow letting it run and get into Setup() and then Loop(). Hope that this info may be of some help in identifying what is going wrong. |
Something I have found in a post from 2014, so may not be appropriate. Quote:Quite a lot of things happen before setup() is called. Many people think that main() is the first bit of code called, but that is not correct. The first bit of code is called "crt0" (C RunTime stage 0). This performs:
On the Arduino main() then does a number of functions, including setting up the timers for millis(), PWM, etc, and configuring such things as interrupts and ADC. It basically gets the system ready for you - all things you would normally be doing manually in a less abstracted system. (check out the init() function in wiring.c) Then and only then does setup() get called. Point 3 in the list above is the one that catches most people out. If you have a global object with code in the constructor that does things with peripherals that aren't configured until main() has run then you can have all sorts of strange things happening or just plain not working right. That is why most classes have a .begin() member function to do all the configuration instead of doing it in the constructor. ====== A brief look at your code, and I see that for "Simple_MPU6050::Simple_MPU6050(uint8_t DMPMode)" this does very little, so is probably OK on point 3. But for "Simple_Wire::Simple_Wire()", this calls "Wire.begin()", so may explain my problem with the test code I posted earlier today which does not run if I set "DOWAY = 3", as this would fall foul of point 3, as calling "begin" on Wire before main() and setup() are called. My CPP is a bit rusty, but from Simple_MPU6050.h (line 63) looks like Simple_MPU6050 class inherits from "Simple_Wire" class, which I presume will call the "Simple_Wire" constructor when Simple_MPU6050 is declared before setup(), which in turn will cause Wire.begin() to be called at line 28 of "Simple_Wire.h" Then if that is true it could manifest in different ways depending on the target board. I also note in Simple_Wire.h there are two constructor versions: But only the first appears to exist. ====== Not sure if what I have highlighted above is true or significant to the primary problem of I2C not working with your original code. Still not sure about how to go about specifying the GPIO pins (or BUS 0 or 1), that should be used during setup of the hardware, as can not see what potential methods may be exposed via the class inheritance. [NOTE: I am not sure what is controlling the formatting of this post, but there appears to be some auto formatting going on in the quoted text, which I can't see how to tame it]. |
|
I have been testing on an ESP32 C3 and am facing similar issues I may have code worthy of posting shortly. This is a hobby and I appreciate all the help Thanks. |
uploaded changes including yours Thank you! |
Hi, just got round to trying the changes, but hit a snag. I took both your libraries and placed them in the directories: C:\Users.....\Documents\Arduino\libraries\Simple_Wire Opened a new example (Simple_MPU6050_Example) from the list of examples for your library. If I use board target as Arduino UNO But if I Select board target as Raspberry PI PICO-W ++++ As for the error. =-======== I have been trying to untangle the wire/twowire classes to try to work out what needs to change.
So this suggests either a change in SimpleWire.cpp around lines 28-38 to a another custom compiler test, and use the Also it may be worth considering what if the user needs a slower clock speed (due to having longer cables which will not run at higher rates, possibly need to pass clock in through the top level begin() somehow. |
I think I have worked out a fix for the compiler error, though leaves a few questions. In Simple_Wire.cpp, at about line 54, I added the EXTRA test variant "#elif defined(ARDUINO_ARCH_RP2040)" and removed the "ARDUINO_ARCH_RP2040" from the final elif test variant. Not sure this is the cleanest method, but it appears to work. =-========= Another thing I needed to do for my PICO-W target, was edit the example code to change the to specify my pins (using the default of 4,5), found there are defs of PIN_WIRE0_SDA, PIN_WIRE0_SCL, but not sure if they are specific to the RP2040 targets, or if they are ARDUINO defines. In Simple_Wire.h -> void begin(int sdaPin = 0, int sclPin = 1); Hopefully that will put this to bed. |
This issue is still open, I am not sure if it has been fully addressed, but judging by the recent Issue #28, I suspect that my last post in the issue is still waiting a final fix. Which would hopefully sort out both issues #27 and #28 so both can be closed. But hopefully the info in this issue (Posted on Sept 21 2022) will be sufficient to allow other users to fix it for themselves in the short term, as I know that these libraries were provided as a hobby rather than a fully supported release, and the issue appears to be target specific. |
I am unable to work on projects that involve using the pi Pico-w, because, unfortunately, I don't have access to this device at the moment. I would greatly appreciate any assistance from the community in making this a viable option for my code. If anyone has experience with the pi Pico-w or any suggestions on how to make my code work with it, I would be grateful for your input. Thank you in advance for your help and support! |
Trying to build/run example code (Simple_MPU6050_Example or Simple_MPU6050_Basic_Example and probably the others) for PI PICO-W code compiles and downloads to target, but I2C is not working.
Serial output reports that detected MPU6050 at 0x68, with WHOAmI=0x00
Does this regardless of what is connected, even when nothing connected.
After a brief test using a new project and just the Simple_Wire.cpp/h and using the following code:
======
#include "Simple_Wire.h"
void setup() {
Serial.begin(115200);
while (!Serial);
Serial.println(F("MyTest_I2C:Start:"));
Simple_Wire myWire;
// scan I2C on Pico board, see what we can find.
Serial.println(F("try call I2C_Scanner()"));
myWire.I2C_Scanner();
}
void loop() {
// put your main code here, to run repeatedly:
}
======
Code correctly identifies when DMP6050 (GY-521) is connected or missing.
Proving that the I2C is working.
====
Further exploration resulted in observation that in you example code, you generally have:
"Simple_MPU6050 mpu;" at the top of the file before setup() or loop().
In my case defining the global "mpu" object before the setup() and initial creation of the Serial.begin() appears to kill I2C.
I am guessing that there is some code race condition preventing I2C setup, or breaking it if Serial.begin() comes after the mpu creation.
I managed to find a HACK that works for my PI PICO-W, but probably is not the correct solution.
I changed the "Simple_MPU6050 mpu;" to "Simple_MPU6050 *mpu;", as a pointer.
Changed ALL "mpu." to "mpu->"
Then in Setup() after the Serial.begin() I added:
"
Simple_MPU6050 myMpu;
mpu = &myMpu;
"
This delayed the creation of the mpu object until after the Serial monitor setup.
BUT this then kills code in loop(), so code in loop() then has to be moved inside setup() at the end in a WHILE loop, otherwise exiting setup() destroys the "mpu" object, but the pointer still points to something.
Another thing I could not work out is how to select different pins for the I2C bus, as Simple_MPU6050 and Simple_Wire classes do not appear to expose a method to allow user selection of alternate I2C pins during creation of the mpu object.
The text was updated successfully, but these errors were encountered: