Good afternoon,
A newbie question I have been unable to resolve at all. I have the following setup:
- ESP32 DevKit v1.
- BNO08x (GY-BNO08x).
- 128*64 OLED monitor. The monitor only works in SPI mode.
- Button for zeroing.
=====
My connections are done as follows:
OLED – ESP32:
CS – D5
DC – D2
RES – D15
SDA – D23
SCL – D18
VCC – 3V3
GND – GND
BN08X – ESP32:
VCC – 3V3
GND – GND
SCL/SCK/RX – D18
SDA/MISO/TX – D19
ADDR/MOSI – D23
CS – D13
INT – D14
RST – D25
PS1 – GND
PS0 – GND
Button – ESP32:
Connector 1 – GND
Connector 2 – D32
=====
My code is the following:
#include <SPI.h>
#include <Wire.h>
#include <U8g2lib.h>
#include <Adafruit_BNO08x.h>
#include <esp_now.h>
#include <WiFi.h>
#define OLED_CS 5
#define OLED_DC 2
#define OLED_RST 15
// OLED display (U8g2 library)
U8G2_SSD1309_128X64_NONAME2_F_4W_HW_SPI u8g2(U8G2_R0, OLED_CS, OLED_DC, OLED_RST);
#define BUTTON_PIN 32
// BNO08x pins
#define BNO08X_CS 13
#define BNO08X_INT 14
#define BNO08X_RST 25
Adafruit_BNO08x bno08x(BNO08X_RST); // Only reset pin passed here
sh2_SensorValue_t sensorValue;
float localYaw = 0;
float remoteYaw = 0;
float zeroOffset = 0;
typedef struct struct_message {
float yaw;
} struct_message;
struct_message incomingData;
// ESP-NOW callback
void OnDataRecv(const esp_now_recv_info_t *info, const uint8_t *incomingDataRaw, int len) {
memcpy(&incomingData, incomingDataRaw, sizeof(incomingData));
remoteYaw = incomingData.yaw;
}
void setup() {
Serial.begin(115200);
delay(100);
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Initialize OLED
u8g2.begin();
u8g2.enableUTF8Print();
Serial.println(F("OLED ready"));
// Reset BNO08x
pinMode(BNO08X_RST, OUTPUT);
digitalWrite(BNO08X_RST, LOW);
delay(10);
digitalWrite(BNO08X_RST, HIGH);
delay(10);
// Initialize BNO08x with SPI
if (!bno08x.begin_SPI(BNO08X_CS, BNO08X_INT, &SPI, BNO08X_RST)) {
Serial.println("Failed to find BNO08X chip");
while (1);
}
Serial.println("BNO08X ready");
bno08x.enableReport(SH2_ROTATION_VECTOR);
// Initialize ESP-NOW
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
esp_now_register_recv_cb(OnDataRecv);
}
void loop() {
if (bno08x.getSensorEvent(&sensorValue)) {
if (sensorValue.sensorId == SH2_ROTATION_VECTOR) {
float w = sensorValue.un.rotationVector.real;
float x = sensorValue.un.rotationVector.i;
float y = sensorValue.un.rotationVector.j;
float z = sensorValue.un.rotationVector.k;
localYaw = atan2(2.0f * (w * z + x * y),
1.0f - 2.0f * (y * y + z * z));
localYaw *= 180.0 / PI;
if (localYaw < 0) localYaw += 360.0;
}
}
// Button sets relative zero
if (digitalRead(BUTTON_PIN) == LOW) {
zeroOffset = localYaw - remoteYaw;
}
float relativeAngle = localYaw - remoteYaw - zeroOffset;
if (relativeAngle < 0) relativeAngle += 360.0;
if (relativeAngle > 360.0) relativeAngle -= 360.0;
// Display on OLED
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.setCursor(0, 20);
u8g2.print("Rotation angle:");
u8g2.setCursor(0, 40);
u8g2.print(relativeAngle, 1);
u8g2.print("°");
u8g2.sendBuffer();
delay(50);
}
=====
What results from it. The OLED monitor is working and communicates with ESP32 effectively. BNO08x can never be found. My previous code was based on I2C mode, and the result was just the same (OLED visible, BNO08x not detected). Then, I've decided to switch to SPI mode (so that the OLED and BNO08x would communicate in the same mode).
Serial monitor output:
ets Jul 29 2019 12:21:46
rst:0x1 (POWERON_RESET),boot:0x12 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4888
load:0x40078000,len:16516
load:0x40080400,len:4
load:0x40080404,len:3476
entry 0x400805b4
Attempting to initialize BNO08X over SPI...
BNO08X not found!
=====
The soldering is solid. Voltage everywhere is around 3.23 to 3.25 V. There are built-in resistors on SCL/SDA pins of BNO08x (I've tried soldering external resistors additionally, but this yielded no result).
I've run multiple tests in Arduino IDE, BNO08x is never detected in either I2C or SPI (which I adhere to now).
Any advice on what may be wrong and how to make things work?