Evening all, beginner here. I followed a ocean wave model by a YouTube poster, who controls amplitude, frequency and pattern of the wave through three potentiometers, linked to a singular servo. I am struggling to source/generate a code which enables this to happen? Could any kind people provide a solution for this in terms of code please?
Actually, you supply the code and we can help when you encounter problems.
Your first task, before any code, is to determine the values of the three potentiometers you will be using. Then determine the servo you will be using.
All of the above is necessary BEFORE any code can be developed because you do not know what code will be necessary until then.
Paul
The only part not sufficiently described in the video is how the third knob controls the 'pattern' of the waves.
I would use four or six pots giving frequency and magnitude control over two or three separate waves. Turn the magnitude down to 0 for the waves you aren't using.
@Paul_KD7HB Hi Paul, this is the code I had prior. The 3 values are wavelength (the horizontal distance between two crests or two troughs), amplitude (the vertical distance between trough and crest), and velocity (the speed at which wave crests move across the water). The Units of measurement for each is meters for wavelength and amplitude and meters per second for velocity. The servo is already determined; it is a rotational servo motor I believe. Below is the code I have to date:
/*
Controlling a servo position using a potentiometer (variable resistor)
by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
modified on 8 Nov 2013
by Scott Fitzgerald
http://arduino.cc/en/Tutorial/Knob
*/
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int potpin1 = 1; // analog pin used to connect the potentiometer
int potpin2 = 2; // analog pin used to connect the potentiometer
int potpin3 = 3; // analog pin used to connect the potentiometer
int val1; // variable to read the value from the analog pin
int val2; // variable to read the value from the analog pin
int val3; // variable to read the value from the analog pin
void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
}
void loop()
{
val = analogRead(potpin1); // reads the value of the potentiometer (value between 0 and 1023)
val = analogRead(potpin1);
val = map(val1, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
val = analogRead(potpin2); // reads the value of the potentiometer (value between 0 and 1023)
val = analogRead(potpin2);
val = map(val2, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
val = analogRead(potpin3); // reads the value of the potentiometer (value between 0 and 1023)
val = analogRead(potpin3);
val = map(val3, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
myservo.write(val); // sets the servo position according to the scaled value
delay(15); // waits for the servo to get there
}
Hi John, these values as I understand it are to control, in Oceanographers language, wavelength (the horizontal distance between two crests or two troughs), amplitude (the vertical distance between trough and crest), and velocity (the speed at which wave crests move across the water). The Units of measurement for each is meters for wavelength and amplitude and meters per second for velocity...So I think I would take the 3rd control to the first of these, the wavelength. Would this still work?
The servo pushes the waveboard which suggests three things you can change: How fast it pushes, how often and how far. I suppose that the first gives amplitude, the second frequency and the last, pattern although I'm a little unclear about what pattern means in practice.
That ties back to the three pots. I'd be inclined to ignore them initially and just have the device generate one wave type and live with the fact that you have to recompile to change anything while you test out the mechanics.
Did you try contacting the author of the video - he might share his code, if indeed he hasn't published it already.
I think the third knob is controlling the difference in frequency between alternating wavefronts. It looks like when you turn that knob up you get alternating fast and slow waves.
Here is a first pass at a sketch that will control a servo with three knobs.
#include <Servo.h>
Servo WaveServo; // create servo object to control a servo
const long StepsPerQuarterWave = 100;
const byte FrequencyPotPin = A1; // analog pin used to connect the potentiometer
const byte MagnitudePotPin = A2; // analog pin used to connect the potentiometer
const byte DeltaPotPin = A3; // analog pin used to connect the potentiometer
const byte WaveServoPin = 9;
unsigned long LastStepTime = 0;
boolean DoingF1 = true; // Start with an f1 wave cycle
long StepNumber = 0;
void setup()
{
Serial.begin(115200);
delay(200);
WaveServo.attach(WaveServoPin); // attaches the servo on pin 9 to the servo object
}
void loop()
{
#if 1 // change to 0 for debug
float f0 = 0.3 + (analogRead(FrequencyPotPin) * 10.0) / 1024.0; // Cycles per second: 0.3 to 10.0 (in hundredths)
int m0 = map(analogRead(MagnitudePotPin), 0, 1023, 0, 500); // microseconds from center
float delta = (analogRead(DeltaPotPin) * 0.9) / 1024.0; // Percent difference in frequency between alternate waves
#else
float f0 = 1.0;
int m0 = 500;
float delta = 0.3;
#endif
float f1 = f0 - (f0 * delta);
float f2 = f0 + (f0 * delta);
unsigned long f1MicrosecondsPerStep = (1000000.0 / f1) / (StepsPerQuarterWave * 4);
unsigned long f2MicrosecondsPerStep = (1000000.0 / f2) / (StepsPerQuarterWave * 4);
if (DoingF1)
{
if (micros() - LastStepTime >= f1MicrosecondsPerStep)
{
LastStepTime = micros();
#if 1 // Change to 0 for debug
WaveServo.writeMicroseconds(1500 + angleMicroseconds(StepNumber, m0));
#else
Serial.println(1500 + angleMicroseconds(StepNumber, m0));
#endif
StepNumber++;
if (StepNumber >= StepsPerQuarterWave * 4)
{
StepNumber = 0;
DoingF1 = false;
}
}
}
else
{
// Doing f2
if (micros() - LastStepTime >= f2MicrosecondsPerStep)
{
LastStepTime = micros();
#if 1 // Change to 0 for debug
WaveServo.writeMicroseconds(1500 + angleMicroseconds(StepNumber, m0));
#else
Serial.println(1500 + angleMicroseconds(StepNumber, m0));
#endif
StepNumber++;
if (StepNumber >= StepsPerQuarterWave * 4)
{
StepNumber = 0;
DoingF1 = true;
}
}
}
}
int angleMicroseconds(int StepNumber, int microsecondFromCenter)
{
if (StepNumber < StepsPerQuarterWave)
{
// Rising from 0 to StepsPerQuarterWave (0 to microsecondFromCenter)
return ((long)StepNumber * microsecondFromCenter) / StepsPerQuarterWave;
}
else if (StepNumber < (StepsPerQuarterWave * 3))
{
// Next two quarter cycles, falling from + StepsPerQuarterWave to -StepsPerQuarterWave (500 to -500)
int step = (StepsPerQuarterWave * 2) - StepNumber;
return ((long)step * microsecondFromCenter) / StepsPerQuarterWave;
}
else if (StepNumber < (StepsPerQuarterWave * 4))
{
// Fourth quarter, rising again to zero (-500 to 0)
int step = StepNumber - (StepsPerQuarterWave * 4);
return ((long)step * microsecondFromCenter) / StepsPerQuarterWave;
}
return 0;
}
Thanks John, Got this error from this code, probably means more to you?
Arduino: 1.8.16 (Mac OS X), Board: "Arduino Uno"
Sketch uses 4560 bytes (14%) of program storage space. Maximum is 32256 bytes.
Global variables use 235 bytes (11%) of dynamic memory, leaving 1813 bytes for local variables. Maximum is 2048 bytes.
An error occurred while uploading the sketch
avrdude: ser_open(): can't open device "/dev/cu.usbmodem14201": No such file or directory
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Hi @wildbill Thank you for the input. Ideally need to sim. a number of variables here, simultaneously. I did contact the original author, but at present on holiday.
It's not important now that John has given you some initial code, but I was suggesting that getting a minimal version going would be a nice way to start. You're way beyond that now
@johnwasser Appreciated, I realised I had not copied the code in correctly. Error free now! I will test the code, make a copy and may make some tweaks, at the moment the servo is on a 360 rotation, just need this to be 180 across all three pots.