its been 4 days need help :( COS\ SIN for meter needle

every demo or link I can find does this a different way with too many code other bits added making it hard to work out. http://www.helixsoft.nl/articles/circle/sincos.htm

so i have been trying to make a SIMPLE needle\Line that responds to a mapped analogRead that's defines the pos. of x1 and y1 on a 128x64 screen.

display.drawLine(64, 64, x1, y1, WHITE);

the closest I have got is

z = map(analogRead(0), 0, 1024, 0, 6);

int x, y; int length = 128; float angle = z;

// calculate x, y from a vector with known length and angle x = length * cos (angle); y = length * sin (angle);

display.drawLine(64, 50, x, y, WHITE);

issue is the needle length is no defined the start and finish points are not defined

but it does move and respond to my POT input smooth and to ratio.

any help will be appreciated. thanks

angle is in radians. half circle is PI. a full circle is 2*PI. map not to 6 but to 2 * PI. max analogRead is 1023

https://en.wikipedia.org/wiki/Sine#Unit_circle_definition

But I would add a lookup. Sin/cos is pretty beefy stuff for a micro (at least the 8-bit ones) to calculate all the time.

thanks, kinda get what cos\sin is about. the issue is implementing it into code with the 128x64 screen and half or full circle.

is the code im using right or ?

also does not help with the start and end point, and needle length

THe principle of the code is almost right. You now only calculate the end position relative to the origin (0,0). Aka, add the starting point of the line to it:

const byte XStart = 64;
const byte YStart = 50;

xEnd = length * cos (angle) + XStart;
yEnd = length * sin (angle) + YStart;
display.drawLine(XStart, YStart, xEnd,  yEnd, WHITE);

And if you want to optimize it, drop the cos and sin and replace it with a lookup table.

it is not smooth because you map it to only 7 values. map it to angle. float a = (PI/1024) * analogRead

thanks I think im getting close, but can you dumb it down for me a bit more?

what is? xEnd YEnd

is this the needle length? or line length total?

basically I would like the line to start left to right 180deg of the screen, but control the needle length wipe.

basically an arc

right now I can get the line to 360, but the start and points are not the right places and the length to long.

thanks

Ah, yeah, missed the map part, sorry!

[edit] Saw my mistake, I edited my last post. Because I made the variable XStart it was stupid to call the end just x so renamed it to xEnd (aka x position of the end of the line) but forgot change it in the draw().

thanks I was using something else I found, which I didn't post to keep the question simple. which is regarding the start- end point and needle length.

what I was using":

float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }

for

float z = mapfloat(analogRead(0), 0, 1024, 0.0, 6.28);

but your code is much more simple:

float z = (PI/1024) * analogRead(0);

which maps 0,1023 to 0.0,3.14

(y)

Juraj: it is not smooth because you map it to only 7 values. map it to angle. float a = (PI/1024) * analogRead

OK... so almost there its working! but its arcing along the bottom of the screen not the top and the length of the needle\line is the full length (to long)

main code:

void loop() {

display.clearDisplay();

float z = (PI/1023) * analogRead(0);

int x, y; int length = 128; float angle = z; x = length * cos (angle); y = length * sin (angle);

const byte XStart = 64; const byte YStart = 50; float xEnd; float yEnd;

xEnd = length * cos (angle) + XStart; yEnd = length * sin (angle) + YStart; display.drawLine(XStart, YStart, xEnd, yEnd, WHITE);

Please start using code tags! ;)

But why are you calling something z and put it into a more logical angle later on...

And quick question (because it differs between libraries, what is the origin of your screen? Is it the left bottom (like we use to see in graphs) or the top left? This will matter quite a bit for the math involved :D

Adafruit_SSD1306 display

currently with the code, the arc is upside down

“But why are you calling something z and put it into a more logical angle later on…”
do you mean why don’t I call it something else? or the code is wrong?
it was just “Z” for testing.

I noticed changing that value . Z will make the line length shorty (y)

so now its just the upside down thing to fix :slight_smile:

void loop() {

display.clearDisplay(); 
  float z = (PI/1023) * analogRead(0);

    int x, y;
    int length = 25;
    float angle = z;

const byte XStart = 64;
const byte YStart = 30;

x = length * cos (angle) + XStart;
y = length * sin (angle) + YStart;
display.drawLine(XStart, YStart, x, y, WHITE);

Even when you you just want to test it, isn't it a lot more logical to call it what it is? Calling it BigYellowElephant would be as logical as z ;)

Also, don't let us look up the answers, just answer all questions asked... That library probably has it's origin left top. So to get the upper part of the circle it would be:

void loop() {
  //probably even more logical as 
  const byte XStart = 64;
  const byte YStart = 50;
  const byte Length = 128;
  const byte ReadPin = A0;
  
  display.clearDisplay();

  float angle = (PI/1023) * analogRead(ReadPin);
  byte xEnd = length * cos (angle) + XStart;
  byte yEnd = YStart - length * sin (angle);
  
  display.drawLine(XStart, YStart, xEnd, yEnd, WHITE);
}

Also took the liberty to make it more readable ;)

numbers and text are the right way around just this arc is upside down?

0 is top left 128 top right 64 is bottom left 0 is top left

already confused with using cos and sin, with understanding X0 Y0 X1 Y1 mapping and just found out there are different screens orientated in library's.

I have a math disability .

thanks

Fixed my code, did it the wrong way around.

Thing is, in math drawings of a sin cos circle the origin is in the middle and a positive y means up. But on the display a positive y means going down the screen. So in order to make the line go up, you need to make the change from the origin negative.

thanks that's working! :) is there a way to reverse the angle value\calc? its running as, right to left

0-1023, 3.14-0.00.

how would I saw the start,end points

septillion: Fixed my code, did it the wrong way around.

Thing is, in math drawings of a sin cos circle the origin is in the middle and a positive y means up. But on the display a positive y means going down the screen. So in order to make the line go up, you need to make the change from the origin negative.

Code:





```
void loopcolor=#000000[/color] {

const byte XStart = 64;
 const byte YStart = 50;
 const byte Length = 128;
 const byte ReadPin = A0;

display.clearDisplaycolor=#000000[/color];

int value = analogReadcolor=#000000[/color];
 float angle = PI * value / 1023;
 byte xEnd = XStart - length * cos color=#000000[/color];  // <----- Mirror result around the y axis
 byte yEnd = YStart - length * sin color=#000000[/color];

display.drawLine(XStart, YStart, xEnd, yEnd, WHITE);
}
```

|

Or:

Code:





```
void loopcolor=#000000[/color] {

const byte XStart = 64;
  const byte YStart = 50;
  const byte Length = 128;
  const byte ReadPin = A0;

display.clearDisplaycolor=#000000[/color];

int value = analogReadcolor=#000000[/color];
  value = 1023 - value;  // <-------- maps 1023 → 0, and 0 → 1023   
  float angle = PI * value / 1023;
  byte xEnd = length * cos color=#000000[/color] + XStart;
  byte yEnd = YStart - length * sin color=#000000[/color];

display.drawLine(XStart, YStart, xEnd, yEnd, WHITE);
}
```

|

g43q654wutrjh:
I have a math disability .

Never too late to do something about that! :slight_smile:

Programming is a lot af applied mathematics.

Pieter

hahah thanks.. .I just figured it out and was going to edit

byte x1 = x0 - length * cos (angle);

so if anyone wants the full working code:

<Adafruit_SSD1306.h> SPI 128x64 screen

must read:

void loop() {

display.clearDisplay(); 

float angle  = (PI/1023) * analogRead(0);     // map analog in 0,1023, to 0.00,3.14
int length = 50;                                          // line height Ratio of Screen 0-64
const byte x0 = 64;                                    // x0 Line Start 0-128
const byte y0 = 63;                                    // y0 Line Start 0-64

byte x1 = x0 - length * cos (angle);
byte y1 = y0 - length * sin (angle);

display.drawLine(x0, y0, x1, y1, WHITE); // write to screen
display.display();  
}

this code does not inc. the SETUP and library details.
but you can get them from a TEST or EXAMPLE code (get that working then modify)

thanks all who helped, the COS\SIN code can be hard to understand.

(y)

Why call them confusing x0 and x1 again :/ And the constness of length...

But note, sin and cos are terrible slow. Fine if it's quick enough but don't look weird if your loop() turns out to be slow.