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

Hi, I am trying to Draw a Line that will rotate 360 Degrees around the Centre Axis of my Small 64x32 OLED Screen (Like a Radar Needle)

I can do Lines, Circles, Rectangles etc but this one is really frustrating me. i have searched here and the internet but not found any answers or examples to play with.

The only code I have found is this but is for the U8glib.h Library and the rest of my Program used the Adafruit_SSD1306.h

I have tried with NO Success in trying to convert this to work with the Adafruit_SSD1306.h library.

#include "U8glib.h"

U8GLIB_SSD1306_64X48 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Res = 12
                                                // For OLED display with SH1106 driver. If you use another display,
                                                // then please check the u8glib documentation and website at
                                                // https://github.com/olikraus/u8glib

int xmax=64;                                   // max length x-axis
int ymax=48;                                    // 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;    // Needle Speed
u8g_uint_t xx=0;

#define u8g_logo_width 64
#define u8g_logo_height 48

void draw(void) {
}

// ------------------------------------------------- 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);
  u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);

}

// ------------------------------------------------- void setup() ------------------------------------------
void setup(void) {

}

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

void loop(void) {

   p+=a;     

//  w = map(p,0,1023,0,90);                      // map it between 0 and 100

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

  // show needle and dial
  xx = m;                                      // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
  if (xx-360){                                   // positie correctie
    xx=xx+0;
  }
  else {
   xx=xx-45;
  }

 // // picture loop
 {
   u8g.firstPage(); 
   do {             
    gauge(xx);
  }
  while( u8g.nextPage() );
 }
}

Any help would be Very Much Appreciated

I have tried with NO Success in trying to convert this to work with the Adafruit_SSD1306.h library.

The code you posted is (in approach) correct, although the numbers associated with the cos() and sin() angle terms don't make much sense.

This would make sense, with (0,0) being in the upper left corner and Y increasing downwards:

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

For informed help, you need to post the code that you tried and either post the associated error messages, or clearly explain what went wrong.

Hi jremington, thanks for the info but I still need it all to Run using the Adafruit_SSD1306.h library. The Library I want to use doesn't use this code "drawline(xcenter, ycenter, xcenter+arcx1, ycenter-arcy1);" ir errors.

I need to be able to run the Code I Posted with the Adafruit_SSD1306.h library.

Many Thanks

I can do Lines, Circles, Rectangles etc

Simply replace the call to drawline() in reply #1, with a call to the line function in the desired library.

  // draw the needle
  float x1=sin(2*angle*2*3.14/100);              // needle position
  float y1=cos(2*angle*2*3.14/100);

If you table pre-calculated int coordinates, you can fetch them in less than a microsecond.
I wonder how many 100 micros those 2 lines take to execute? Maybe less than a 16000 cycle milli anyway. Do the sin() and cos() functions run series calculations to 6 places? Maybe not!

Wow, is that even English? I'm a total novice at programming the Arduino, I have NO programming Skills at all and don't understand cos sin etc. I'm more of a copy and paste guy who then changes bits in the code to see what it does and what it alters.

For instance this bit of the code

{
u8g.firstPage();
do {
gauge(xx);
}
while( u8g.nextPage() );
}
}

The Adafruit_SSD1306.h library does not understand fistPage or nextPage.

All i really need is for someone to convert the code I supplied which uses the U8glib.h Library to code that will work with the Adafruit_SSD1306.h library. I can then play around with the code and see what it does.

Thanks

 {
   u8g.firstPage(); 
   do {             
    gauge(xx);
  }
  while( u8g.nextPage() );
 }
}

Do you understand what that code does, and why?
Does your library use that kind of mechanism?

Hi jremington, I have tried that but there are other commands in the Code that the Adafruit_SSD1306.h library does not understand like

u8g.firstPage();

u8g.nextPage();

u8g.drawLine(xcenter, ycenter, xcenter+arcx1, ycenter-arcy1);

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

it doesn't understand xcenter, xcenter+arc*x1 etc.

Those are simply variables.
Why do you think the library doesn't understand them?

Hi AWOL, As i have said I'm no programmer but I assume it like a page refresh, but the Library is not mine its Adafruit's SSD1306 general Library, as to if can do what the U8glib.h Library does I would have no idea, sorry

IF the Adafruit Library can't do this then I need some help with what code I need to Draw a Line that Rotates 360 Degrees from the Center Axis.

If I change the rest of the code to what I think the Adafruit_ssd1306 would use I get error on those lines as well as u8g.drawLine(xcenter, ycenter, xcenter+arcx1, ycenter-arcy1);

I have no idea how to change it so it will load on the Arduino and display

Many Thanks

Perhaps if you posted the code you're having problems with, and the errors you're seeing, we could help you.

Hi AWOL,

The whole code is on my First Post on this Subject, But here it is.

#include "U8glib.h"

U8GLIB_SSD1306_64X48 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9, Res = 12
                                                // For OLED display with SH1106 driver. If you use another display,
                                                // then please check the u8glib documentation and website at
                                                // https://github.com/olikraus/u8glib

int xmax=64;                                   // max length x-axis
int ymax=48;                                    // 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;    // Needle Speed
u8g_uint_t xx=0;

#define u8g_logo_width 64
#define u8g_logo_height 48

void draw(void) {
}

// ------------------------------------------------- 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);
  u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);

}

// ------------------------------------------------- void setup() ------------------------------------------
void setup(void) {

}

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

void loop(void) {

   p+=a;     

  w = map(p,0,1023,0,90);                      // map it between 0 and 100

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

  // show needle and dial
  xx = m;                                      // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
  if (xx-360){                                   // positie correctie
    xx=xx+0;
  }
  else {
   xx=xx-45;
  }

 // // picture loop
 {
   u8g.firstPage(); 
   do {             
    gauge(xx);
  }
  while( u8g.nextPage() );
 }
}

Many thanks Phil

No, the code with the Adafruit library, and the errors you say you're seeing.

Are your end points along a circle? Like a radar? Then its just calculate those end points along the edge of the circle and leave the initial x,y as your center point.

void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,uint16_t color)

There's some formula for a circle with radius r in the math world. I remeber coming across it about 30 years ago.

-jim lee

Hi AWOL, I deleted it as it didn't work I can re do and Post here so Hopefully the errors can be corrected.

Many thanks

I'm with the guys that are saying that any library that does a drawline(x1,y1,x2,y); will be able to do the job is you calculate the x & y coords. Now i haven't done this in over 30 years... how do we draw the circle again ? i'm gonna grab my zx81 book..

Hi AWOL, here is the code with the Adafruit_ssd1306.h Library, but there are still a lot of U8glib.h Library references for the functions as I have no idea what they should be.

#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=48;                                    // 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;    // Needle Speed
u8g_uint_t xx=0;    //THIS NEEDS TO BE CHANGED AS IT DOESNT WORK

void draw(void) {
}

// ------------------------------------------------- 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);
  u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1);
     //THE LINE ABOVE NEEDS TO BE CHANGED AS IT DOESNT WORK
}

// ------------------------------------------------- void setup() ------------------------------------------
void setup(void) {

}

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

void loop(void) {

   p+=a;     

//  w = map(p,0,1023,0,90);                      // map it between 0 and 100

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

  // show needle and dial
  xx = m;                                      // 135 = zero position, 180 = just before middle, 0 = middle, 45 = max
  if (xx-360){                                   // positie correctie
    xx=xx+0;
  }
  else {
   xx=xx-45;
  }

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

Hi Deva_Rishi, Z81, Spectrum, Basic Coding Language if I remember Correctly and yes well over 30 Years ago lol

//THIS NEEDS TO BE DELETED AS IT DOESNT WORK
   do {

Hi jimLee, i get the void Adafruit_GFX::writeLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1,uint16_t color)
I can draw normal lines OK and ones that move up and down or possibly left to right, but not round in an Arc.

But the line in question drawLine(xcenter, ycenter, xcenter+arcx1, ycenter-arcy1); has the xcenter+arc*x1

This just doesn't work.

Thanks