Hi,
I want to display data, from my LIS3DH accelaration Sensor, on a SH1106 1.3" OLED display.
They both use I2C.
I have run both example codes, which worked fine.
Now I have tried combining these, by copying single lines over.
But as soon, as the second I2C conecction is used, it stops working.
Here I added the the LIS3DH example code into the one from the display. Only the lines 18-37, 101-136 and 153-156 are from the LIS3DH example.
/*********************************************************************
This is an example for our Monochrome OLEDs based on SH110X drivers
This example is for a 128x64 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
i2c SH1106 modified by Rupert Hirst 12/09/21
*********************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LIS3DH.h>
#include <Adafruit_Sensor.h>
// Used for software SPI
#define LIS3DH_CLK 13
#define LIS3DH_MISO 12
#define LIS3DH_MOSI 11
// Used for hardware & software SPI
#define LIS3DH_CS 10
// software SPI
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS, LIS3DH_MOSI, LIS3DH_MISO, LIS3DH_CLK);
// hardware SPI
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS);
// Low Power 5Khz data rate needs faster SPI, and calling setPerformanceMode & setDataRate
//Adafruit_LIS3DH lis = Adafruit_LIS3DH(LIS3DH_CS, 2000000);
// I2C
Adafruit_LIS3DH lis = Adafruit_LIS3DH();
//#include <SPI.h>
//#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>
/* Uncomment the initialize the I2C address , uncomment only one, If you get a totally blank screen try the other*/
#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's
//#define i2c_Address 0x3d //initialize with the I2C addr 0x3D Typically Adafruit OLED's
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // QT-PY / XIAO
Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH 16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000
};
void setup() {
Serial.begin(9600);
// Show image buffer on the display hardware.
// Since the buffer is intialized with an Adafruit splashscreen
// internally, this will display the splashscreen.
delay(250); // wait for the OLED to power up
display.begin(i2c_Address, true); // Address 0x3C default
//display.setContrast (0); // dim display
display.display();
delay(2000);
// Clear the buffer.
display.clearDisplay();
Serial.println("LIS3DH test!");
if (! lis.begin(0x18)) { // change this to 0x19 for alternative i2c address
Serial.println("Couldnt start");
while (1) yield();
}
Serial.println("LIS3DH found!");
// lis.setRange(LIS3DH_RANGE_4_G); // 2, 4, 8 or 16 G!
//Serial.print("Range = "); Serial.print(2 << lis.getRange());
// Serial.println("G");
/*
// lis.setPerformanceMode(LIS3DH_MODE_LOW_POWER);
Serial.print("Performance mode set to: ");
switch (lis.getPerformanceMode()) {
case LIS3DH_MODE_NORMAL: Serial.println("Normal 10bit"); break;
case LIS3DH_MODE_LOW_POWER: Serial.println("Low Power 8bit"); break;
case LIS3DH_MODE_HIGH_RESOLUTION: Serial.println("High Resolution 12bit"); break;
}
// lis.setDataRate(LIS3DH_DATARATE_50_HZ);
Serial.print("Data rate set to: ");
switch (lis.getDataRate()) {
case LIS3DH_DATARATE_1_HZ: Serial.println("1 Hz"); break;
case LIS3DH_DATARATE_10_HZ: Serial.println("10 Hz"); break;
case LIS3DH_DATARATE_25_HZ: Serial.println("25 Hz"); break;
case LIS3DH_DATARATE_50_HZ: Serial.println("50 Hz"); break;
case LIS3DH_DATARATE_100_HZ: Serial.println("100 Hz"); break;
case LIS3DH_DATARATE_200_HZ: Serial.println("200 Hz"); break;
case LIS3DH_DATARATE_400_HZ: Serial.println("400 Hz"); break;
case LIS3DH_DATARATE_POWERDOWN: Serial.println("Powered Down"); break;
case LIS3DH_DATARATE_LOWPOWER_5KHZ: Serial.println("5 Khz Low Power"); break;
case LIS3DH_DATARATE_LOWPOWER_1K6HZ: Serial.println("1.6 Khz Low Power"); break;
}
*/
// draw a single pixel
display.drawPixel(10, 10, SH110X_WHITE);
// Show the display buffer on the hardware.
// NOTE: You _must_ call display after making any drawing commands
// to make them visible on the display hardware!
display.display();
delay(2000);
display.clearDisplay();
// draw many lines
testdrawline();
display.display();
delay(2000);
display.clearDisplay();
lis.read();
Serial.print("X: "); Serial.print(lis.x);
Serial.print(" \tY: "); Serial.print(lis.y);
Serial.print(" \tZ: "); Serial.print(lis.z);
/* Or....get a new sensor event, normalized */
// draw rectangles
testdrawrect();
display.display();
delay(2000);
display.clearDisplay();
// draw multiple rectangles
testfillrect();
display.display();
delay(2000);
display.clearDisplay();
// draw mulitple circles
testdrawcircle();
display.display();
delay(2000);
display.clearDisplay();
// draw a SH110X_WHITE circle, 10 pixel radius
display.fillCircle(display.width() / 2, display.height() / 2, 10, SH110X_WHITE);
display.display();
delay(2000);
display.clearDisplay();
testdrawroundrect();
delay(2000);
display.clearDisplay();
testfillroundrect();
delay(2000);
display.clearDisplay();
testdrawtriangle();
delay(2000);
display.clearDisplay();
testfilltriangle();
delay(2000);
display.clearDisplay();
// draw the first ~12 characters in the font
testdrawchar();
display.display();
delay(2000);
display.clearDisplay();
// text display tests
display.setTextSize(1);
display.setTextColor(SH110X_WHITE);
display.setCursor(0, 0);
display.println("Failure is always an option");
display.setTextColor(SH110X_BLACK, SH110X_WHITE); // 'inverted' text
display.println(3.141592);
display.setTextSize(2);
display.setTextColor(SH110X_WHITE);
display.print("0x"); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
display.clearDisplay();
// miniature bitmap display
display.drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
display.display();
delay(1);
// invert the display
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
display.clearDisplay();
// draw a bitmap icon and 'animate' movement
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
}
void loop() {
}
void testdrawbitmap(const uint8_t *bitmap, uint8_t w, uint8_t h) {
uint8_t icons[NUMFLAKES][3];
// initialize
for (uint8_t f = 0; f < NUMFLAKES; f++) {
icons[f][XPOS] = random(display.width());
icons[f][YPOS] = 0;
icons[f][DELTAY] = random(5) + 1;
Serial.print("x: ");
Serial.print(icons[f][XPOS], DEC);
Serial.print(" y: ");
Serial.print(icons[f][YPOS], DEC);
Serial.print(" dy: ");
Serial.println(icons[f][DELTAY], DEC);
}
while (1) {
// draw each icon
for (uint8_t f = 0; f < NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SH110X_WHITE);
}
display.display();
delay(200);
// then erase it + move it
for (uint8_t f = 0; f < NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SH110X_BLACK);
// move it
icons[f][YPOS] += icons[f][DELTAY];
// if its gone, reinit
if (icons[f][YPOS] > display.height()) {
icons[f][XPOS] = random(display.width());
icons[f][YPOS] = 0;
icons[f][DELTAY] = random(5) + 1;
}
}
}
}
void testdrawchar(void) {
display.setTextSize(1);
display.setTextColor(SH110X_WHITE);
display.setCursor(0, 0);
for (uint8_t i = 0; i < 168; i++) {
if (i == '\n') continue;
display.write(i);
if ((i > 0) && (i % 21 == 0))
display.println();
}
display.display();
delay(1);
}
void testdrawcircle(void) {
for (int16_t i = 0; i < display.height(); i += 2) {
display.drawCircle(display.width() / 2, display.height() / 2, i, SH110X_WHITE);
display.display();
delay(1);
}
}
void testfillrect(void) {
uint8_t color = 1;
for (int16_t i = 0; i < display.height() / 2; i += 3) {
// alternate colors
display.fillRect(i, i, display.width() - i * 2, display.height() - i * 2, color % 2);
display.display();
delay(1);
color++;
}
}
void testdrawtriangle(void) {
for (int16_t i = 0; i < min(display.width(), display.height()) / 2; i += 5) {
display.drawTriangle(display.width() / 2, display.height() / 2 - i,
display.width() / 2 - i, display.height() / 2 + i,
display.width() / 2 + i, display.height() / 2 + i, SH110X_WHITE);
display.display();
delay(1);
}
}
void testfilltriangle(void) {
uint8_t color = SH110X_WHITE;
for (int16_t i = min(display.width(), display.height()) / 2; i > 0; i -= 5) {
display.fillTriangle(display.width() / 2, display.height() / 2 - i,
display.width() / 2 - i, display.height() / 2 + i,
display.width() / 2 + i, display.height() / 2 + i, SH110X_WHITE);
if (color == SH110X_WHITE) color = SH110X_BLACK;
else color = SH110X_WHITE;
display.display();
delay(1);
}
}
void testdrawroundrect(void) {
for (int16_t i = 0; i < display.height() / 2 - 2; i += 2) {
display.drawRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i, display.height() / 4, SH110X_WHITE);
display.display();
delay(1);
}
}
void testfillroundrect(void) {
uint8_t color = SH110X_WHITE;
for (int16_t i = 0; i < display.height() / 2 - 2; i += 2) {
display.fillRoundRect(i, i, display.width() - 2 * i, display.height() - 2 * i, display.height() / 4, color);
if (color == SH110X_WHITE) color = SH110X_BLACK;
else color = SH110X_WHITE;
display.display();
delay(1);
}
}
void testdrawrect(void) {
for (int16_t i = 0; i < display.height() / 2; i += 2) {
display.drawRect(i, i, display.width() - 2 * i, display.height() - 2 * i, SH110X_WHITE);
display.display();
delay(1);
}
}
void testdrawline() {
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, 0, i, display.height() - 1, SH110X_WHITE);
display.display();
delay(1);
}
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(0, 0, display.width() - 1, i, SH110X_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(0, display.height() - 1, i, 0, SH110X_WHITE);
display.display();
delay(1);
}
for (int16_t i = display.height() - 1; i >= 0; i -= 4) {
display.drawLine(0, display.height() - 1, display.width() - 1, i, SH110X_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for (int16_t i = display.width() - 1; i >= 0; i -= 4) {
display.drawLine(display.width() - 1, display.height() - 1, i, 0, SH110X_WHITE);
display.display();
delay(1);
}
for (int16_t i = display.height() - 1; i >= 0; i -= 4) {
display.drawLine(display.width() - 1, display.height() - 1, 0, i, SH110X_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for (int16_t i = 0; i < display.height(); i += 4) {
display.drawLine(display.width() - 1, 0, 0, i, SH110X_WHITE);
display.display();
delay(1);
}
for (int16_t i = 0; i < display.width(); i += 4) {
display.drawLine(display.width() - 1, 0, i, display.height() - 1, SH110X_WHITE);
display.display();
delay(1);
}
delay(250);
}