Cannot get OLED working with Encoders/Motor

I am building a test project that uses a dc motor with a quadrature encoder using encoder.h and a rotary encoder using rotaryencoder.h and an Adafruit OLED display. I cannot seem to figure out how to get the display function to work on my arduino mini pro showing both the motor and the rotary position. I have a version working just showing the rotary position but no motor included. My programming knowledge is limited but I am teaching myself as I go so please be gentle.... Any help would be appreciated. My goal is to get the OLED display to show the motor position and rotary position at the time its being moved. My display is I2C which I know can cause some problems with time but hopefully it isnt the one problem here.

My code:

// PID motor position control.
// Thanks to Brett Beauregard for his nice PID library http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
#include <Encoder.h>
#include <RotaryEncoder.h>

//#include <PinChangeInt.h>
#include <PID_v1.h>
#include <stdio.h>
#include <digitalWriteFast.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
Encoder myEnc(3, 4);
//#define encodPinA1      3                       // Quadrature encoder A pin
//#define encodPinB1      4                       // Quadrature encoder B pin
#define M1              5                      // PWM outputs to L298N H-Bridge motor driver module
#define M2              6
RotaryEncoder encoder2(A2, A3);

#define OLED_RESET 8
Adafruit_SSD1306 display(OLED_RESET);

#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 };

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

double kp = 4 , ki = 1.5 , kd = 0.2;             // modify for optimal performance
double input = 0, output = 0, setpoint = 0;
long temp;

PID myPID(&input, &output, &setpoint, kp, ki, kd, DIRECT);  // if motor will only run at full speed try 'REVERSE' instead of 'DIRECT'

unsigned int pos = 0;

unsigned int tick = 0;
unsigned int mark = 0;
volatile long encoderPos = 0;

void draw();

void setup() {
  Serial.begin (115200);                              // for debugging
  Serial.println("SimplePollRotator example for the RotaryEncoder library.");
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done
    // Show image buffer on the display hardware.
  // Since the buffer is initialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(1000);

  // Clear the buffer.
  display.clearDisplay();
  // text display tests
  tick = pos;
  mark = encoderPos;

    pinModeFast(5, OUTPUT); //Initiates Motor Channel A pin
    pinModeFast(6, OUTPUT); //Initiates Brake Channel A pin
    input = myEnc.read();
    setpoint = 0;
    TCCR0A = _BV(COM0A1) | _BV(COM0B1) | _BV(WGM00); 
    TCCR0B = _BV(CS00);
    myPID.SetMode(AUTOMATIC);
    myPID.SetSampleTime(1);
    myPID.SetOutputLimits(-255, 255);

}

void draw() {
  int enc = tick;
  int mtr = mark;
  String e = String(enc);
  while(e.length() < 3)
   e = String('0') + e;
 String m = String(mtr);
 while(m.length() < 3)
  m = String('0') + m;
  display.clearDisplay();
  display.setFont(NULL);
  display.setCursor(0,0);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("Enc:"); display.println(e);
  display.print("Motor:"); display.println(m);
  display.display();
}

void enc() {
    encoder2.tick();
  int newPos = encoder2.getPosition();
  setpoint = newPos * 4;              // modify to fit motor and encoder characteristics, rotary encoder connected
  
  if (pos != newPos) {
    pos = newPos;
    tick = pos;
  }
}

void motorposition() {
  input = myEnc.read();                                // data from encoder
  if (input != encoderPos)
  {
    encoderPos = input;
    mark = encoderPos;
  }
  
}

void loop() {
display.clearDisplay();
enc();
motorposition();
draw();
  myPID.Compute();                                    // calculate new output
  pwmOut(output);                                     // drive L298N H-Bridge module

}


void pwmOut(int out) {                                // to H-Bridge board
  if (out > 0) {
    analogWrite(M1, out);                             // drive motor CW
    analogWrite(M2, 0);
  }
  else {
    analogWrite(M1, 0);
    analogWrite(M2, abs(out));                        // drive motor CCW
  }
}

All those libraries you're using are going to trip over each other. Ditch some/most/all of them and write the code yourself. You'll never learn to program if all you do is patch together other peoples' code.

Hi,
Have you got code that just uses the OLED display, to prove you are controlling it?

What display are you using?

Thanks.. Tom... :slight_smile:

Tom,

Yes I programmed one that just shows the OLED displaying the rotary encoder turns live. Its an I2C 128x32 OLED from Amazon.

/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x32 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
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RotaryEncoder.h>
//#include <Encoder.h>
RotaryEncoder encoder(A2, A3);
//Encoder myEnc(3, 4);
#define OLED_RESET 8
Adafruit_SSD1306 display(OLED_RESET);

#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 };

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
unsigned int pos = 0;
unsigned int tick = 0;


void draw();


void setup()   {                
  Serial.begin(9600);

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(1000);

  // Clear the buffer.
  display.clearDisplay();
  tick = pos;

}


void draw() {
  int enc = tick;
  String e = String(enc);
  while(e.length() < 3)
    e = String('0') + e;
  display.clearDisplay();
  display.setFont(NULL);
  display.setCursor(0,0);
  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.print("POS: "); display.print(e);
  display.display();
}

void loop() {
  encoder.tick();
  int newPos = encoder.getPosition();
  if (pos != newPos) {
    Serial.print(newPos);
    Serial.println();
    pos = newPos;
    tick = pos;
     draw();
  }
 
}