Sine Wave - recurring break in waveform pattern?

New to this forum, so let me know if I'm doing something incorrectly. I am using code to create a sine wave and it is working fine and showing up on serial plotter. But as you can see in the attached image, there is a break in the sine wave where it fails to go to negative cycle and seems to restart. It's not a problem, but I'd like to understand this.

//  y(t) = A sin (wt + p)
//  where A = Amplitude, w = angular frequency, t = time, p = phase

void setup() {
  // put your setup code here, to run once:

  Serial.begin(4800);

}

  
void loop() {
  // put your main code here, to run repeatedly:


  for (int t=0; t<360; t++) {
    
  float y1 = 1 * sin( (30.00/180 * t) + 0);
  Serial.print(y1);
  Serial.print(" ");
  Serial.println(" ");
  delay(5);
  }
}

Please post the test code.
Read the forum guidelines to see how to properly post code and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

The loop function loops (it is called repeatedly by the hidden main program), which means it starts over after the "for" loop contained within it terminates.

You don't actually need that "for" loop.

1 Like

Thanks - code posted.

That makes sense - thank you. Also, I will experiment without the for loop.

The sine function expects an angle in radians, you are giving it in degrees. That may explain the discontinuity.

1 Like

you get the discontinuity when t = 359 and then t = 0

convert your degrees into radian (180° ➜ PI radians)

//  y(t) = A sin (wt + p)
//  where A = Amplitude, w = angular frequency, t = time, p = phase

unsigned long t = 0;

void setup() {
  Serial.begin(115200);
}

void loop() {
  float y1 = 1 * sin(180.0 / M_PI * t++ + 0);
  Serial.println(y1);
  delay(5);
}

image

1 Like
//  y(t) = A sin (wt + p)
//  where A = Amplitude, w = angular frequency, t = time, p = phase

#define Phase 0
#define Amp 2

void setup() {
  Serial.begin(115200);
}

void loop() {
  static float t = 0.0;
  t = t + 5.0;
  Serial.println(Amp * sin(PI * (t + Phase) / 180.0), 2);
  delay(10);
}

1 Like

Perhaps add a modulo here.

I learned this from a tutorial and it got me started using sine wave gen and serial plotter, but I can see that I need to better understand the math and rewrite the code which I will be doing soon - you guys are really giving me an education! Also, I see you are all using a baud rate of 115200 - what is the thinking behind selecting a suitable baud rate? Thanks.

I understand the modulo operator from my C programming, but can you explain how including that would work and improve the function?

that's how fast you send the data from the Arduino to whatever is on the other side of the Serial port
there is no reason to go super slow...

t will overflow eventually, something like the following makes sure t stays within the range [0.0, 360.0].

t = fmod(t + 5.0, 360);

Or if t is an integer:

t = (t + 1) % 360;
1 Like

Produces 9½ cycles causing the bump. Changing to

for (int t = 0; t < 340; t++) {

Produces 9 full cycles, so they join perfectly when the for loop re-starts.

However, better to work with radians as the sin() function expects for input.

image

1 Like

I got this code from a tutorial in order to learn to use Arduino's serial plotter. The replies from this forum have been very educational. I am planning to rewrite using radians. Thanks for this important insight.

Thanks to all who helped educate me on the thinking behind creating a sine wave. I'm now using radians and the included code (and higher baud rate) to more easily create this function.

// Radians
// (Degrees to Radians)
//  90 = 1.571
// 180 = 3.142
// 270 = 4.712
// 360 = 6.283

void setup() {
  // put your setup code here, to run once:

  Serial.begin(57600);
  }

void loop() {
  // put your main code here, to run repeatedly:

  for(int x=0;x<63;x++){
    float y = float(x)/10;
    delay(20);
    Serial.println(sin(y));
  }

}

Just use PI directly.

void setup ()
{
  Serial.begin ( 115200 );
}

void loop ()
{
  for ( float angle = 0; angle < 2 * PI; angle += PI / 180 ) // 1 degree step
  {
    Serial.print ( sin ( angle ) );
    Serial.print ( ( ' ' ) );
    Serial.println ( cos ( angle ) );
    delay ( 20 );
  }
}

1 Like

This little plot function (at bottom of sketch) makes it easy to add plot labels and plot multiple traces:

// Radians
// (Degrees to Radians)
//  90 = 1.571
// 180 = 3.142
// 270 = 4.712
// 360 = 6.283

void setup() {
  // put your setup code here, to run once:

  Serial.begin(57600);
}

void loop() {
  // put your main code here, to run repeatedly:

  for (int x = 0; x < 63; x++) {
    float y = float(x) / 10;
    delay(20);

    plot("cos(y)", cos(y) + 2, false);
    plot("sin(y)", sin(y) + 0, false);
    plot("sin(y+(PI/4))", sin(y + (PI / 4)) - 2, true);
  }
}

void plot(String label, float value, bool last) {
  Serial.print(label); // can be empty
  if (label != "") Serial.print(":");
  Serial.print(value);
  if (last == false) Serial.print(", ");
  else Serial.println();
}

1 Like

Forgot to mention that the plot function generates csv formatted text.
Open the serial monitor, then copy/past into spreadsheets, etc.

Helpful, thanks. Question - is this code-generated waveform which I am able to see on the serial plotter, available from one of the pins - maybe pin 8? (I'm using the MEGA 2560) That is, can I connect to one of the pins and ground on the 2560 with my o-scope and see the same waveform the serial plotter is displaying? Or maybe the serial plotter is using communication pins, not analog output pins - so measuring with meter or o-scope would interfere with the waveform?