#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
////////////////////
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
/////////////////
void setup()
{
Serial.begin(115200);
///////////////////
u8g2.begin();
//////////////////
Serial.println(F("Initialize MPU6050"));
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println(F("Could not find a valid MPU6050 sensor, check wiring!"));
delay(500);
}
}
void loop()
{
// Read normalized values
Vector normAccel = mpu.readNormalizeAccel();
// Calculate Pitch & Roll
int pitch = -(atan2(normAccel.XAxis, sqrt(normAccel.YAxis*normAccel.YAxis + normAccel.ZAxis*normAccel.ZAxis))*180.0)/M_PI;
int roll = (atan2(normAccel.YAxis, normAccel.ZAxis)*180.0)/M_PI;
u8g2.clearBuffer();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_pxplusibmvga9_tf);
u8g2.setCursor(0, 12);
u8g2.print(F("x="));
u8g2.print(roll);
u8g2.print(char(176));
u8g2.setCursor(0, 26);
u8g2.print(F("y="));
u8g2.print(pitch);
u8g2.print(char(176));
u8g2.drawVLine(64, 4, 25);
u8g2.setCursor(66, 12);
u8g2.drawRFrame(2,47,122,12,6);
u8g2.drawFilledEllipse( map(pitch, -100, 100, 0, 122), 52, 7, 5, U8G2_DRAW_ALL);
if (pitch==0){
u8g2.setFont(u8g2_font_pxplusibmvga9_tf);
u8g2.setCursor(59,63);
u8g2.print("flat");
}
}
while ( u8g2.nextPage() );
}
Errors
` Sketch uses 16322 bytes (53%) of program storage space. Maximum is 30720 bytes.
Global variables use 1830 bytes (89%) of dynamic memory, leaving 218 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.`
This is not an error but a warning. The 128x64 pixel OLED display code uses more than half of the available RAM of the Nano for the display buffer. You have to be extremely careful with the remaining memory but just try the sketch, it might run without problems.
PS: You still have one print without the F() macro.
But, its not showing results in OLED display
Does it show anything in the display?
If the answer is no, you may want to try to use the smaller version of the display (128x32) as it uses half of the buffer memory.
Many such display libraries allocate memory for their buffers. That would probably fail since your available RAM is so low.
I suspect that you will need something with more memory.
At first it showed the results for fraction of seconds then turned off .But now nothing displays .but display is ok I checked for another code
Any suggestions to reduce the memory usage in my code
You might be able to write your own display library using only those features you want and excluding those you do not want.
The u8g2 library is a hog for memory. I use the u8g2 library on an ESP32 using color displays but the ESP32 has loads of ram for such. Instead, you might want to try using a library that has less baggage like this one Adafruit SSD1306 - Arduino Reference from Adafruit to drive the display.
Thank you I will try it
What is a first page and next page function?
Did you get the Adafruit example working?
Yeah it works fine.
To update values repeatedly what conditions I should have in my while
Did you get the Adafruit library example to work?
Yes..It works fine
That is meant to be used when using a page buffer with the display, but the code is using the constructor for a full buffer. The proper constructor will significantly decrease the buffer size.
Note the adafruit library does not allocate the buffer until runtime, so the ram shown by the compiler is misleading.
Have you tried changing the constructor for the display:
#include <U8g2lib.h>
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
Ok thanks for information
I am using adafruit library due to low memory availablity
The link to Adafruit_SSD1306/Adafruit_SSD1306.h at master · adafruit/Adafruit_SSD1306 (github.com)
I do not find that the Adafruit library has a display.firstPage() method.
Here is the entire Adafruit_SSD1306/Adafruit_SSD1306.h at master · adafruit/Adafruit_SSD1306 (github.com) file.
/*!
* @file Adafruit_SSD1306.h
*
* This is part of for Adafruit's SSD1306 library for monochrome
* OLED displays: http://www.adafruit.com/category/63_98
*
* These displays use I2C or SPI to communicate. I2C requires 2 pins
* (SCL+SDA) and optionally a RESET pin. SPI requires 4 pins (MOSI, SCK,
* select, data/command) and optionally a reset pin. Hardware SPI or
* 'bitbang' software SPI are both supported.
*
* 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, with
* contributions from the open source community.
*
* BSD license, all text above, and the splash screen header file,
* must be included in any redistribution.
*
*/
#ifndef _Adafruit_SSD1306_H_
#define _Adafruit_SSD1306_H_
// ONE of the following three lines must be #defined:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen
#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
//#define SSD1306_96_16 ///< DEPRECATED: old way to specify 96x16 screen
// This establishes the screen dimensions in old Adafruit_SSD1306 sketches
// (NEW CODE SHOULD IGNORE THIS, USE THE CONSTRUCTORS THAT ACCEPT WIDTH
// AND HEIGHT ARGUMENTS).
// Uncomment to disable Adafruit splash logo
//#define SSD1306_NO_SPLASH
#if defined(ARDUINO_STM32_FEATHER)
typedef class HardwareSPI SPIClass;
#endif
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
#if defined(__AVR__)
typedef volatile uint8_t PortReg;
typedef uint8_t PortMask;
#define HAVE_PORTREG
#elif defined(__SAM3X8E__)
typedef volatile RwReg PortReg;
typedef uint32_t PortMask;
#define HAVE_PORTREG
#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) && \
!defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_RP2040)
typedef volatile uint32_t PortReg;
typedef uint32_t PortMask;
#define HAVE_PORTREG
#endif
/// The following "raw" color names are kept for backwards client compatability
/// They can be disabled by predefining this macro before including the Adafruit
/// header client code will then need to be modified to use the scoped enum
/// values directly
#ifndef NO_ADAFRUIT_SSD1306_COLOR_COMPATIBILITY
#define BLACK SSD1306_BLACK ///< Draw 'off' pixels
#define WHITE SSD1306_WHITE ///< Draw 'on' pixels
#define INVERSE SSD1306_INVERSE ///< Invert pixels
#endif
/// fit into the SSD1306_ naming scheme
#define SSD1306_BLACK 0 ///< Draw 'off' pixels
#define SSD1306_WHITE 1 ///< Draw 'on' pixels
#define SSD1306_INVERSE 2 ///< Invert pixels
#define SSD1306_MEMORYMODE 0x20 ///< See datasheet
#define SSD1306_COLUMNADDR 0x21 ///< See datasheet
#define SSD1306_PAGEADDR 0x22 ///< See datasheet
#define SSD1306_SETCONTRAST 0x81 ///< See datasheet
#define SSD1306_CHARGEPUMP 0x8D ///< See datasheet
#define SSD1306_SEGREMAP 0xA0 ///< See datasheet
#define SSD1306_DISPLAYALLON_RESUME 0xA4 ///< See datasheet
#define SSD1306_DISPLAYALLON 0xA5 ///< Not currently used
#define SSD1306_NORMALDISPLAY 0xA6 ///< See datasheet
#define SSD1306_INVERTDISPLAY 0xA7 ///< See datasheet
#define SSD1306_SETMULTIPLEX 0xA8 ///< See datasheet
#define SSD1306_DISPLAYOFF 0xAE ///< See datasheet
#define SSD1306_DISPLAYON 0xAF ///< See datasheet
#define SSD1306_COMSCANINC 0xC0 ///< Not currently used
#define SSD1306_COMSCANDEC 0xC8 ///< See datasheet
#define SSD1306_SETDISPLAYOFFSET 0xD3 ///< See datasheet
#define SSD1306_SETDISPLAYCLOCKDIV 0xD5 ///< See datasheet
#define SSD1306_SETPRECHARGE 0xD9 ///< See datasheet
#define SSD1306_SETCOMPINS 0xDA ///< See datasheet
#define SSD1306_SETVCOMDETECT 0xDB ///< See datasheet
#define SSD1306_SETLOWCOLUMN 0x00 ///< Not currently used
#define SSD1306_SETHIGHCOLUMN 0x10 ///< Not currently used
#define SSD1306_SETSTARTLINE 0x40 ///< See datasheet
#define SSD1306_EXTERNALVCC 0x01 ///< External display voltage source
#define SSD1306_SWITCHCAPVCC 0x02 ///< Gen. display voltage from 3.3V
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26 ///< Init rt scroll
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27 ///< Init left scroll
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29 ///< Init diag scroll
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A ///< Init diag scroll
#define SSD1306_DEACTIVATE_SCROLL 0x2E ///< Stop scroll
#define SSD1306_ACTIVATE_SCROLL 0x2F ///< Start scroll
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3 ///< Set scroll range
// Deprecated size stuff for backwards compatibility with old sketches
#if defined SSD1306_128_64
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_64 defined
#define SSD1306_LCDHEIGHT 64 ///< DEPRECATED: height w/SSD1306_128_64 defined
#endif
#if defined SSD1306_128_32
#define SSD1306_LCDWIDTH 128 ///< DEPRECATED: width w/SSD1306_128_32 defined
#define SSD1306_LCDHEIGHT 32 ///< DEPRECATED: height w/SSD1306_128_32 defined
#endif
#if defined SSD1306_96_16
#define SSD1306_LCDWIDTH 96 ///< DEPRECATED: width w/SSD1306_96_16 defined
#define SSD1306_LCDHEIGHT 16 ///< DEPRECATED: height w/SSD1306_96_16 defined
#endif
/*!
@brief Class that stores state and functions for interacting with
SSD1306 OLED displays.
*/
class Adafruit_SSD1306 : public Adafruit_GFX {
public:
// NEW CONSTRUCTORS -- recommended for new projects
Adafruit_SSD1306(uint8_t w, uint8_t h, TwoWire *twi = &Wire,
int8_t rst_pin = -1, uint32_t clkDuring = 400000UL,
uint32_t clkAfter = 100000UL);
Adafruit_SSD1306(uint8_t w, uint8_t h, int8_t mosi_pin, int8_t sclk_pin,
int8_t dc_pin, int8_t rst_pin, int8_t cs_pin);
Adafruit_SSD1306(uint8_t w, uint8_t h, SPIClass *spi, int8_t dc_pin,
int8_t rst_pin, int8_t cs_pin, uint32_t bitrate = 8000000UL);
// DEPRECATED CONSTRUCTORS - for back compatibility, avoid in new projects
Adafruit_SSD1306(int8_t mosi_pin, int8_t sclk_pin, int8_t dc_pin,
int8_t rst_pin, int8_t cs_pin);
Adafruit_SSD1306(int8_t dc_pin, int8_t rst_pin, int8_t cs_pin);
Adafruit_SSD1306(int8_t rst_pin = -1);
~Adafruit_SSD1306(void);
bool begin(uint8_t switchvcc = SSD1306_SWITCHCAPVCC, uint8_t i2caddr = 0,
bool reset = true, bool periphBegin = true);
void display(void);
void clearDisplay(void);
void invertDisplay(bool i);
void dim(bool dim);
void drawPixel(int16_t x, int16_t y, uint16_t color);
virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
void startscrollright(uint8_t start, uint8_t stop);
void startscrollleft(uint8_t start, uint8_t stop);
void startscrolldiagright(uint8_t start, uint8_t stop);
void startscrolldiagleft(uint8_t start, uint8_t stop);
void stopscroll(void);
void ssd1306_command(uint8_t c);
bool getPixel(int16_t x, int16_t y);
uint8_t *getBuffer(void);
protected:
inline void SPIwrite(uint8_t d) __attribute__((always_inline));
void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color);
void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color);
void ssd1306_command1(uint8_t c);
void ssd1306_commandList(const uint8_t *c, uint8_t n);
SPIClass *spi; ///< Initialized during construction when using SPI. See
///< SPI.cpp, SPI.h
TwoWire *wire; ///< Initialized during construction when using I2C. See
///< Wire.cpp, Wire.h
uint8_t *buffer; ///< Buffer data used for display buffer. Allocated when
///< begin method is called.
int8_t i2caddr; ///< I2C address initialized when begin method is called.
int8_t vccstate; ///< VCC selection, set by begin method.
int8_t page_end; ///< not used
int8_t mosiPin; ///< (Master Out Slave In) set when using SPI set during
///< construction.
int8_t clkPin; ///< (Clock Pin) set when using SPI set during construction.
int8_t dcPin; ///< (Data Pin) set when using SPI set during construction.
int8_t
csPin; ///< (Chip Select Pin) set when using SPI set during construction.
int8_t rstPin; ///< Display reset pin assignment. Set during construction.
#ifdef HAVE_PORTREG
PortReg *mosiPort, *clkPort, *dcPort, *csPort;
PortMask mosiPinMask, clkPinMask, dcPinMask, csPinMask;
#endif
#if ARDUINO >= 157
uint32_t wireClk; ///< Wire speed for SSD1306 transfers
uint32_t restoreClk; ///< Wire speed following SSD1306 transfers
#endif
uint8_t contrast; ///< normal contrast setting for this device
#if defined(SPI_HAS_TRANSACTION)
protected:
// Allow sub-class to change
SPISettings spiSettings;
#endif
};
#endif // _Adafruit_SSD1306_H_
Can you point out to me where in the Adafruit library that .fisrtPage() method is located?
As far as I know, the Adafruit library does not support a paged display buffer. firstPage() and nextPage() are specific to the U8g2 library, and will need to be changed for the Aafruit library.
You should not even be using firstPage() and nextPage() while using a full buffer with U8g2 - those are intended for a paged buffer (see my previous post about the constructor to see how to declare a paged buffer).
NOTE - You DO NOT save any RAM by using the Adafruit library instead of U8g2 with a full buffer - both libraries will need 1024 bytes of RAM for a 128x64 display. The U8g2 library allocates the buffer at compile time, while the Adafruit library allocates the buffer at runtime, so the compiler does not show the buffer memory for the Adafruit library in the dynamic memory usage.