Plot a rolling graph?

I'm trying to do something like this guy

He's plotting some readings from a ultrasound sensor. It's rolling but and the plot will move around according to the distance of the object from the sensor.

I'm using a SSD1309 display. So my display is a bit bigger.

I think my question is: What is going on here?

  int i;
  for (i = 0; i < 127; i++) {
    display.drawLine(i, 64 - distances[i], (i + 1), 64 - distances[i + 1], WHITE);
    distances[i] = distances[i + 1];
  }
  distances[127] = distance;

When I put this in, it crashes the Arduino. Is the for loop just drawing the initial plot? The author tries to explain it but seems like he just rolls over quickly through it.
What's the easiest way to do a rolling graph?
My code is here:


#include <Arduino.h>
#include <U8x8lib.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif

U8G2_SSD1309_128X64_NONAME2_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8);  

const int trigPin = 6;
const int echoPin = 7;

float duration, distance;
int distances[128];

void setup() {
  u8g2.begin();

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);
}

void loop(void) {
  u8g2.clearBuffer();					// clear the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = (duration*.0343)/2;      // reports in centimeters

  Serial.print("Distance: ");
  Serial.println(distance);

  u8g2.setCursor(0,10);
  u8g2.print("Distance: " ); u8g2.print(distance,2); u8g2.print(" cm");

  drawline();
  u8g2.sendBuffer();					// transfer internal memory to the display
  u8g2.display();

  delay(1000);
}

void drawline(){
  int i;
  for (i = 0; i < 127; i++) {
    u8g2.drawLine(i, 64 - distances[i], (i + 1), 64 - distances[i + 1]);
    distances[i] = distances[i + 1];
  }

  distances[127] = distance;
}

Please post all the code. The crash is probably caused by something in the part you did not post.

Is the for loop just drawing the initial plot?

No, see the next statement after the drawLine statement, which performs the "rolling".

Thanks. I just updated. Please take a look.

  1. Counting through the 128 columns in the OLED
  2. Drawing line segments from THIS pixel at (i, 64-d[i] to NEXT pixel at (i+1, 64 -d[i+1], in color WHITE
  3. move to NEXT pixel

I do not see a way to have a measurement of "i + 1" until "i" is known.

I doubt "distances[127] = distance;" is correct.

Here is a sample of how I plot on a serial device...

#define trigPin 12
#define echoPin 13
#define width  100 // adjust for screen width
#define speed  100 // adjust for speed of graph

long duration;
int distance;

void setup() {
  Serial.begin(115200);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  // create trigger pulse
  digitalWrite(trigPin, LOW);         // turn off pulses
  delayMicroseconds(2);               // pause before transmitting
  digitalWrite(trigPin, HIGH);        // transmit pulses...
  delayMicroseconds(10);              // ...for 10 microseconds
  digitalWrite(trigPin, LOW);         // turn off pulses
  duration = pulseIn(echoPin, HIGH);  // time the echo
  for (int i = 0; i < (duration / (3 * width)) + 1; i++) { // create graph of echo
    Serial.print("*");
  }
  Serial.println();
  delay(speed);
}

The loop function takes care of that. The "distances" data array is initialized to zeros, but after 128 iterations of loop(), it will be filled with presumably valid data.

The code is correct but the first 127 plots (after program startup) will have mostly zero entries.

So why am I crashing? I wish the Arduino would tell me if it turned out in the for loop or output a crash report to the IDE

Who knows? You forgot to describe the symptoms of the crash. Explain what you expected the program to do and what it did instead. Describe or post examples of the output.

Why did you switch to U8G2? Maybe you've configured it incorrectly.

The project is supposed to work as above in the link. The Arduino plots the output of the ultrasonic sensor.

I started with u8x8 because I've used it in the past. Then I realized I can't draw lines plus the sample code in the like uses u8g2 library.

By crashing I mean the Arduino stops responding. No lights. Nothing on the serial output. Lcd is dark. I can comment out the drawline function and it works again.

A simulation of your sketch results in compile errors stating the functions you call do not exist. Is it possible you are using a non-standard U8g library?

sketch.ino: In function 'void loop()':
sketch.ino:27:8: error: 'class U8X8_SSD1306_128X64_NONAME_HW_I2C' has no member named 'clearBuffer'; did you mean 'clearLine'?
   u8g2.clearBuffer();     // clear the internal memory
        ^~~~~~~~~~~
        clearLine
sketch.ino:46:8: error: 'class U8X8_SSD1306_128X64_NONAME_HW_I2C' has no member named 'sendBuffer'
   u8g2.sendBuffer();     // transfer internal memory to the display
        ^~~~~~~~~~
sketch.ino: In function 'void drawline()':
sketch.ino:55:10: error: 'class U8X8_SSD1306_128X64_NONAME_HW_I2C' has no member named 'drawLine'; did you mean 'drawTile'?
     u8g2.drawLine(i, 64 - distances[i], (i + 1), 64 - distances[i + 1]);
          ^~~~~~~~
          drawTile

Error during build: exit status 1

Whoa! How'd you run a simulation? I can run a verify on the Arduino IDE and it passes.

Is that my code? I'm using u8g2, not u8x8 ssd1306.

How long after the program starts, and what does it do before it stops responding?

Try the original code, with the Adafruit library. I don't use U8xx and can't offer advice regarding it.

@traderjoe

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.