1

I'm trying to stream the data coming from my I2C MMA8452Q accelerometer to an Adafruit-based SSD1351 OLED RGB display that uses SPI via an Arduino UNO.

When I run example code for the accelerometer I can see it outputting data to the serial monitor, and when I run my code for the screen using a joystick as test input it graphs the values nicely.

When I try and build in the I2C example code into my code for the display, the moment I include to the code to read the values from the accelerometer, the program runs setup and then goes blank after that. When I block out the sensor read and swap in the joystick reads it works fine again.

I've been staring at all kinds of forum posts about using SPI and I2C simultaneously but I haven't really found any with a straightforward solution or they use a very different board.

#include <Adafruit_SSD1351.h>
#include <SparkFun_MMA8452Q.h>
#include <SPI.h>
#include <Wire.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 128 // Change this to 96 for 1.27" OLED.
// You can use any (4 or) 5 pins 
#define SCLK_PIN 2 // not using this as I've got it setup 
#define MOSI_PIN 3 // on the hardware SPI pins as per the text below
#define DC_PIN 4
#define CS_PIN 5
#define RST_PIN 6 // not in use
#define joy_XPin A1
#define joy_YPin A0
// Color definitions
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0 
#define WHITE 0xFFFF
// Option 1: use any pins but a little slower
// Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN); 
// Option 2: must use the hardware SPI pins 
// (for UNO thats sclk = 13 and sid(which is SDA on my display) = 11) and pin 10 must be 
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);
MMA8452Q accel; // intialise sensor - SDA/SCL connected to A4/A5 pins as per example code
#define graphLength 32
int joy_X, joy_Y;
int tilt_X, tilt_Y;
int graphY[graphLength] = {0};
int graphX[graphLength] = {0};
void setup() {
 Serial.begin(9600);
 tft.begin();
 Wire.begin();
 
 tft.fillScreen(BLACK);
 
 tft.setCursor(10,64);
 tft.setTextColor(WHITE);
 tft.println("Welcome, have fun");
 delay(2000);
 tft.fillScreen(BLACK);
}
void loop() {
 // scaled inputs to be smaller and offset to be in the middle of the screen
 joy_X = (analogRead(joy_XPin) / 32)+48; 
 joy_Y = (analogRead(joy_YPin) / 32)+48;
 // when this block is included everything breaks
 // this is the code to read the accelerometer input so I'm pretty sure the issue is here.
 /*
 if(accel.available()){
 tilt_X = accel.getCalculatedX() * 10;
 tilt_Y = accel.getCalculatedY()* 10;
 }
 */
 graphY[graphLength - 1] = tilt_X; // swap tilt_X/Y with joy_X/Y to graph joystick inputs
 graphX[graphLength - 1] = tilt_Y;
 for(int i = 0; i <= (graphLength - 1); i++){ // invokes undefined behaviour but it works for now
 tft.drawPixel(i,graphY[i],RED); 
 tft.drawPixel(i,graphX[i],BLUE);
 }
 
 delay(5);
 graphShiftAlong();
}
// Just functions to clear the things I've drawn on the display rather than trying to wipe the whole display each time.
void clearPixel(uint16_t x, uint16_t y){
 tft.drawPixel(x, y, BLACK);
}
void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color){
 int x1,y1,x2,y2;
 w = w/2;
 h = h/2;
 
 x1 = x - w;
 y1 = y - h;
 x2 = x + w;
 y2 = y + h;
 
 tft.drawLine(x1,y1,x1,y2,color); // top left to bottom left
 tft.drawLine(x1,y1,x2,y1,color); // top left to top right
 tft.drawLine(x2,y1,x2,y2,color); // top right to bottom right
 tft.drawLine(x2,y2,x1,y2,color); // bottom right to bottom left
}
void clearRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h){
 drawRect(x,y,w,h,BLACK);
}
// Sets the 'old' data to be drawn as black and redraws it one pixel offset
// Compiler gives me red text but not errors so I'm running with it for now
void graphShiftAlong(){
 for(int i = 0; i <= (graphLength - 1); i++){
 tft.drawPixel(i,graphY[i],BLACK);
 tft.drawPixel(i,graphX[i],BLACK);
 graphX[i] = graphX[i+1];
 graphY[i] = graphY[i+1];
 }
}

The example code I'm using for the sensor is here:

 Library for the MMA8452Q
 By: Jim Lindblom and Andrea DeVore
 SparkFun Electronics
 Do you like this library? Help support SparkFun. Buy a board!
 https://www.sparkfun.com/products/14587
 This sketch uses the SparkFun_MMA8452Q library to initialize
 the accelerometer and stream calcuated x, y, z, acceleration
 values from it (in g units).
 Hardware hookup:
 Arduino --------------- MMA8452Q Breakout
 3.3V --------------- 3.3V
 GND --------------- GND
 SDA (A4) --\/330 Ohm\/-- SDA
 SCL (A5) --\/330 Ohm\/-- SCL
 The MMA8452Q is a 3.3V max sensor, so you'll need to do some
 level-shifting between the Arduino and the breakout. Series
 resistors on the SDA and SCL lines should do the trick.
 License: This code is public domain, but if you see me
 (or any other SparkFun employee) at the local, and you've
 found our code helpful, please buy us a round (Beerware
 license).
 Distributed as is; no warrenty given.
*/
#include <Wire.h> // Must include Wire library for I2C
#include "SparkFun_MMA8452Q.h" // Click here to get the library: http://librarymanager/All#SparkFun_MMA8452Q
MMA8452Q accel; // create instance of the MMA8452 class
void setup() {
 Serial.begin(9600);
 Serial.println("MMA8452Q Basic Reading Code!");
 Wire.begin();
 if (accel.begin() == false) {
 Serial.println("Not Connected. Please check connections and read the hookup guide.");
 while (1);
 }
}
void loop() {
 if (accel.available()) { // Wait for new data from accelerometer
 // Acceleration of x, y, and z directions in g units
 Serial.print(accel.getCalculatedX(), 3);
 Serial.print("\t");
 Serial.print(accel.getCalculatedY(), 3);
 Serial.print("\t");
 Serial.print(accel.getCalculatedZ(), 3);
 Serial.println();
 }
}
asked Jul 1, 2021 at 2:32

1 Answer 1

1

Your SPI is not setup for the Arduino UNO. Check another example for SPI and you will be using pins 11 and 13, this is mandatory and 8,9,10 or any three and there is a definition statement for these 3 pins - look at the example for your display. For I2C do you have pullup resistors on both I2C lines 4.7k up to 10k? These are required. Good luck

answered Jul 2, 2021 at 13:43
1
  • Sorry I should have clarified a bit more than what is in the code, I am using pins 11 and 13 for SPI, ignoring the setup defined early in the code. There are two declaration statements for the display - one uses any combination of pins for the display and the other uses 11 and 13 plus the other three. As for the pullup resistors, no I haven't put those in. However I did think that if the sensor worked when its own example code was run (even without the resistors) that it should run in conjunction with the display. Or is there some interference I am missing? Commented Jul 3, 2021 at 0:22

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.