Drawing a Line that rotates around the Centre Axis on OLED Screen

You need to draw a line between two defined points.
You have a function that draws a line between two defined points.

How does that not work?

Hi AWOL, if I knew what I would work I wouldn't be on here trying to get some help. It's a bit like me expecting everyone to understand EDI (Electronic Data Interchange and the working of it - This is what I used to do before I retired) But I wasn't a programmer just a World Wide Trouble Shooter for the Software Operation and Function.

Takes years to learn, but soon forgotten too lol....

I keep paying around with the code but as I can't even get to load on to the arduino I cant see where its wrong, only the line where the Arduino Program stops.

display.Show(); //THIS NEEDS TO BE CHANGED AS IT DOESNT WORK
// do {
gauge(xx);
// }
while( u8g.nextPage() ); //THIS NEEDS TO BE CHANGED AS IT DOESNT WORK
}

I have tried

display.display(); //THIS NEEDS TO BE CHANGED AS IT DOESNT WORK
// do {
gauge(xx);
// }
while( display.display() ); //THIS NEEDS TO BE CHANGED AS IT DOESNT WORK
}

in the hope it might at least load but the error is

exit status 1
could not convert 'display.Adafruit_SSD1306::display()' from 'void' to 'bool'

display.Show();      //THIS NEEDS TO BE DELETED AS IT IS UNNECESSARY
while( display.display() );   //THIS NEEDS TO BE DELETED AS IT IS UNNECESSARY

Just call "gauge(45);"

What happens?

AWOL:
You need to draw a line between two defined points.
You have a function that draws a line between two defined points.

How does that not work?

I have the same question.. and Phil what was the graphics lib that you were using for your previous project (or is it still the same project) Hey but i found the book :smiley: a dutch version written by Max Voorburg

10 LET A=20
20 LET B=20
21 FOR C=15 TO 1 STEP -2
30 FOR X=0 TO 360 STEP 4
40 LET P=X*PI/180
50 PLOT A+C*COS P,B+C*SIN P
60 NEXT X
70 NEXT C

which draws 7 circles, anyway so

which draws 7 circles

...badly and inefficiently.

The Adafruit_SSD1306.h Library would write display.drawLine(20, 20, 20, 20, white) it doesn't understand xcenter, xcenter+arc*x1 etc.

Of course "it" understands those variables, if you have defined them in your program.

I would write something like:

  float x1=arc*sin(angle*M_PI/180.);              // needle TIP position, arc=needle length
  float y1=arc*cos(angle*M_PI/180.);
  display.drawLine(xcenter, ycenter, xcenter+x1, ycenter-y1,white);

But if you don't understand any of this notation, then you will either have to learn it, or try a different approach completely.

What I'm trying to say is..

Why do I try? No one EVER understands what I'm trying to say.

Look, you said you said it was an Adafruit screen. And, you're not all that comfortable with coding. It would be simpler to use the adafruit call and push the problem into the math. Instead of trying to port someone else's code, of unknown orignins, to work with the adafruit base code. This pushes your problem in to the code world. Where you don't really want to be.

Found this for you..

Hope this helps, I'll shut up now..

-jim lee

Hi Deva_Rishi,

Same project! it's the final part of the Scope I would like to add. I couldn't find any reference online to making a line rotate so didn't know where to even start on it. but I did find the code I added on my first post on this Subject, but this uses the wrong Library u8glib. I could load and run this, so I stripped out all the code I didn't need from it and managed to get the Line to go a full 360 Degrees as in the code I downloaded from the internet it only moved back and forth from the centre 180 degrees.

But then when trying to convert to use the Adafruit_ssd1306 Library my problems started as some of the code wasn't recognised and I didn't have a clue how to change it to work so I could incorporate it with the rest of my code (and your of course)

I see the code you have written above but where would it go?

Many thanks Phil

I see the code you have written above but where would it go?

It's BASIC (and bad BASIC at that) - it doesn't go anywhere near an Arduino.

AWOL:
...badly and inefficiently.

I was quite happy with it at the time... 35 years ago...

1 Like

Deva_Rishi:
I was quite happy with it at the time... 35 years ago...

I think Mr Bresenham was around 35 years ago.

Hi People, well with your help we have got it working, well sort of!!!

I have managed to delete what I think is the unneeded code and uploaded it and hey presto I have a rotating Line, but if I remove the display.clearDisplay I get a filled circle as the line doesn't clear from behind.I cant use clearDisplay as it clears the screen of other things running.

Will play again tomorrow, but any suggestions on how to run without using clearDisplay would be appreciated.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 12

Adafruit_SSD1306 display(OLED_RESET);

int xmax=64;             // max length x-axis
int ymax=32;             // max length y-axis
int xcenter=xmax/2;      // center of x-axis
int ycenter=ymax/2;      // center of y-axis
int arc=ymax/4;                                                              
int p, w, m,a=10;        // a= Needle Speed
int xx=0;    

// ------------------------------------------------- void gauge() ------------------------------------------
void gauge(uint8_t angle) {

  // Draw the Needle
 
    float x1=sin(2*angle*2*3.14/100);              // needle position
    float y1=cos(2*angle*2*3.14/100);
    display.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1, WHITE);
    display.display();

  }

// ------------------------------------------------- void setup() ------------------------------------------
void setup(void) {
  
    Serial.begin(9600);
    while ( !Serial );
    randomSeed(analogRead(A0));  // read froam A0 then it makes sense to do an analogRead
 
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)  
    display.clearDisplay();     // clears the screen and buffer ** DO NOT REMOVE **

  }

// ------------------------------------------------- void loop() ------------------------------------------

void loop(void) {

    p+=a;     
    m = map(p,0,1023,0,100);      // map needle movement

// Show Needle
    xx = m;                       // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max

// Picture Loop

    display.display();     
    gauge(xx);  
    display.clearDisplay();
  }

Try drawing the line in white, then a short while later in black.
But only if the input value has changed.

Hi AWOL, just thought of that after I posted, and I have done it.... Removed a few more bits of the code as I didn't think they were needed to run the Dial and it still works.

If you could just check through this now and see if it's OK

Thanks for all your help

Regards Phil

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 12

Adafruit_SSD1306 display(OLED_RESET);

int xmax=64;             // max length x-axis
int ymax=32;             // max length y-axis
int xcenter=xmax/2;      // center of x-axis
int ycenter=ymax/2;      // center of y-axis
int arc=ymax/4;                                                              
int p, m,a=30;        // a= Needle Speed
int xx=0;    

// ------------------------------------------------- void gauge() ------------------------------------------
void radar(uint8_t angle) {

  // Draw the Needle
 
    float x1=sin(2*angle*2*3.14/100);              // needle position
    float y1=cos(2*angle*2*3.14/100);
    display.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1, WHITE);
    display.display();
    display.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1, BLACK);
    display.display();
  }

// ------------------------------------------------- void setup() ------------------------------------------
void setup() {
  
    Serial.begin(9600);
    while ( !Serial );
    randomSeed(analogRead(A0));  // read froam A0 then it makes sense to do an analogRead
 
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)  
    display.clearDisplay();     // clears the screen and buffer ** DO NOT REMOVE **

  }

// ------------------------------------------------- void loop() ------------------------------------------

void loop() {

    p+=a;     
    m = map(p,0,1023,0,100);      // map needle movement

// Show Needle
    xx = m;                       // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max

// Picture Loop

    display.display();     
    radar(xx);  
//    display.clearDisplay();
  }

no this is not quite correct, what you should do is store the old needle value in a variable as suchint xx=0, oldx=0,oldy=0; and then blot the old position out just before you draw the new one

void radar(uint8_t angle) {

    float x1=sin(2*angle*2*3.14/100);              // needle position
    float y1=cos(2*angle*2*3.14/100);    // a more accurate calculation would be "cos(DEG_TO_RAD*angle)"

    display.drawLine(xcenter, ycenter, xcenter+oldx, ycenter-oldy, BLACK);  // overdraw the old line

    oldx=arc*x1;  // calculate the new values and store them
    oldy=arc*y1;  // variable names are now not complete explanatory since we use them for the new drawing 
                        // as well, but this is the least calculations

    display.drawLine(xcenter, ycenter, xcenter+oldx, ycenter-oldy, WHITE);  // draw the new line
    display.display();    // display the new image
    
    display.display();
  }

Hi Deva_Rishi,

I have put it all together and its working fine.

THANKS YOU EVER SO MUCH FOR YOUR HELP.

All the best regards Phil

If you want to speed it up then make a sketch print out your circle coordinates, save them to PROGMEM and instead of the calculation code just fetch coordinates from PROGMEM (program memory in flash) and draw. It will be faster.