I am trying to make a 3d printed eye mechanism like this one but slightly different. I currently am able to drive 2 Servos and a 3rd. What I am attempting to do is have two Servos follow the the Y axis Servo motor and be offset from the where the pupil of the eye is and have that angular offset be adjustable via a potentiometer. I am currently looking at: https://youtu.be/ihXxbQefl1c?si=26vb_4XYsXfYRz03 his code and tried to implement it into mine however I have gotten an error and am at a loss on how to fix it I have seen a few other people with the issues of applying a function to a sensor's input. But I am curious as to why it would work in Youtuber's code and not mine.
My Code:
/* This code is a test for a 3D printed Eye Mechanism and Eye Brow Mechanism this is my first really ever code writing Project I am using youtube.
Tutorials as well as the Stan Winston School tutorials. My Name is Bucky.
According to this paper The Human eye can rotate down vertialcally 30 Deg, and upwards 25deg and left to right 35 off of center
https://biology.stackexchange.com/questions/72511/what-are-the-max-angles-of-human-eyeball-rotation
refrences Nilheim Mechatromics Simplified Eye Mechanism Code
Fix twitching pot signal for eyelid mech
*/
// Servo1 is the First servo
// Servo2 is the second Servo
// ServoE1 is the First Eyelid Servo
// ServoE2 is the Second Eyelid Servo
//EyePot is the Potentionmeter Tied to the Eyelids Eyepot takes place of "trimval" in
// BlinkButton is the button Tied to the Eyelids
#include <Servo.h> // This Command accesses a pre-exsisting Library of Code for Driving the Servo
int ServoPin = 9;
Servo Servo1; // This Command Creates Servo 1 X Axis
Servo Servo2; // This Command Creates Servo 2 Y Axis
Servo ServoE1; // This Command Creates Servo Eyelid 1 takes place of "uplidpluse"
Servo ServoE2; // This Command Creates Servo Eyelid 2 takes place of "lolidpluse"
int joystickyaxis = A1;// Assigns The Y axis of the joy stick to the analog in Pin to Pin 1
int joystickxaxis = A0; // Assigns The X axis of the Joy Stick to the Analog In Pin to spot 0
int Eyepot = A2; // attaches Eye pot to Analog pin 2
void setup() {
Servo1.attach (9); // Attaches Servo to Servo1 to PWM pin 9 for Signal
Servo2.attach (10) ; // Attaches Servo2 to PWM Pin 10 for signal
ServoE1.attach (11); // attaches ServoE1 To PWM Pin 11
ServoE2.attach (12); // attaches ServoE2 To PWM Pin 12
}
void loop() {
//Binds Servo inputs to X and Y Axis
//Binds Servo1 to X axis
int reading = analogRead(joystickxaxis); // tells Arduino to Read the Analog input Value From the joystickxaxis
int angle = map (reading, 0,1023,55,125); // Tells The Arduino to convert the Analog Signal to a given rotational Degree for the servo to understand (note this is limited from 0,180)
Servo1.write(angle); // This takes the signal from the previous interger annd the angle its converted to and tells it send it to Servo1
// Binds Servo2 To Y axis
reading = analogRead(joystickyaxis); // Tells Arduino To read the Analog input from the joystickyaxis
angle = map (reading, 0,1023,60,115); // Tells Arduino to convert Y axis joystick input into rotational angle for servo
Servo2.write(angle); // Takes Signal from Previous Interger sends it to the servo
//Following Eyelid functions
//Upper Eyelid
Eyepot = analogRead (A2);// Reads from A2 pin assigned to Eyepot
Eyepot = map (Eyepot, 0,1023,60,115);
ServoE1 = map (joystickyaxis, 0, 1023, 60,115);
Servo1 += (Eyepot-40); // this Takes whatever out angular output signal from the Eyepot and sets it to be off by 40 Degrees
ServoE1 = constrain (ServoE1, 60, 115);// Constrains the Eyelid to something and makes it so it cant exceed certain angles
}
And here is the Error:
C:\Users\BuckyA\Documents\Arduino\sketch_Printed_Eye_Mech_Test\sketch_Printed_Eye_Mech_Test.ino: In function 'void loop()':
C:\Users\BuckyA\Documents\Arduino\sketch_Printed_Eye_Mech_Test\sketch_Printed_Eye_Mech_Test.ino:49:46: error: no match for 'operator=' (operand types are 'Servo' and 'long int')
ServoE1 = map (joystickyaxis, 0, 1023, 60,115);
^
In file included from C:\Users\BuckyA\Documents\Arduino\sketch_Printed_Eye_Mech_Test\sketch_Printed_Eye_Mech_Test.ino:14:0:
C:\Users\BuckyA\AppData\Local\Arduino15\libraries\Servo\src/Servo.h:106:7: note: candidate: Servo& Servo::operator=(const Servo&)
class Servo
^~~~~
C:\Users\BuckyA\AppData\Local\Arduino15\libraries\Servo\src/Servo.h:106:7: note: no known conversion for argument 1 from 'long int' to 'const Servo&'
C:\Users\BuckyA\AppData\Local\Arduino15\libraries\Servo\src/Servo.h:106:7: note: candidate: Servo& Servo::operator=(Servo&&)
C:\Users\BuckyA\AppData\Local\Arduino15\libraries\Servo\src/Servo.h:106:7: note: no known conversion for argument 1 from 'long int' to 'Servo&&'
C:\Users\BuckyA\Documents\Arduino\sketch_Printed_Eye_Mech_Test\sketch_Printed_Eye_Mech_Test.ino:50:8: error: no match for 'operator+=' (operand types are 'Servo' and 'int')
Servo1 += (Eyepot-40); // this Takes whatever out angular output signal from the Eyepot and sets it to be off by 40 Degrees
~~~~~~~^~~~~~~~~~~~~~
In file included from C:\Users\BuckyA\AppData\Local\Temp\arduino\sketches\06A9D1FC42B4A04622B08C8A23C95EC8\sketch\sketch_Printed_Eye_Mech_Test.ino.cpp:1:0:
C:\Users\BuckyA\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino/Arduino.h:95:39: error: no match for 'operator<' (operand types are 'Servo' and 'int')
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
~~~~~^~~~~~
C:\Users\BuckyA\Documents\Arduino\sketch_Printed_Eye_Mech_Test\sketch_Printed_Eye_Mech_Test.ino:51:11: note: in expansion of macro 'constrain'
ServoE1 = constrain (ServoE1, 60, 115);// Constrains the Eyelid to something and makes it so it cant exceed certain angles
^~~~~~~~~
C:\Users\BuckyA\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.6\cores\arduino/Arduino.h:95:58: error: no match for 'operator>' (operand types are 'Servo' and 'int')
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
~~~~~^~~~~~~
C:\Users\BuckyA\Documents\Arduino\sketch_Printed_Eye_Mech_Test\sketch_Printed_Eye_Mech_Test.ino:51:11: note: in expansion of macro 'constrain'
ServoE1 = constrain (ServoE1, 60, 115);// Constrains the Eyelid to something and makes it so it cant exceed certain angles
^~~~~~~~~
exit status 1
Compilation error: no match for 'operator=' (operand types are 'Servo' and 'long int')
And here is the Youtuber's Code (note, I added my own notes to this as it is my understanding as to what is going on)
// Nilheim Mechatronics Simplified Eye Mechanism Code
// Make sure you have the Adafruit servo driver library installed >>>>> https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library
// X-axis joystick pin: A1
// Y-axis joystick pin: A0
// Trim potentiometer pin: A2
// Button pin: 2
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN 140 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 520 // this is the 'maximum' pulse length count (out of 4096)
uint8_t servonum = 0;
int xval;
int yval;
int lexpulse;
int rexpulse;
int leypulse;
int reypulse;
int uplidpulse;
int lolidpulse;
int trimval;
const int analogInPin = A0;
int sensorValue = 0;
int outputValue = 0;
int switchval = 0;
void setup() {
Serial.begin(9600);
Serial.println("8 channel Servo test!");
pinMode(analogInPin, INPUT);
pinMode(2, INPUT);
pwm.begin();
pwm.setPWMFreq(60); // Analog servos run at ~60 Hz updates
delay(10);
}
// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
double pulselength;
pulselength = 1000000; // 1,000,000 us per second
pulselength /= 60; // 60 Hz
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000000; // convert to us
pulse /= pulselength;
Serial.println(pulse);
// pwm.setPWM(n, 0, pulse);
}
void loop() {
xval = analogRead(A1);
lexpulse = map(xval, 0,1023, 270, 390);
rexpulse = lexpulse;
switchval = digitalRead(2);
yval = analogRead(A0);
leypulse = map(yval, 0,1023, 280, 400);
reypulse = map(yval, 0,1023, 400, 280);
trimval = analogRead(A2);
trimval=map(trimval, 320, 580, -40, 40);
uplidpulse = map(yval, 0, 1023, 280, 420); // Bukcy: Take Upper eyelid and map it refrencing (y axis value of eye, 0, to 1023, signals and angle 280 to 420 angle on servo
uplidpulse += (trimval-40); // Bucky: This takes the trim value and makes it so any Y Input it will always be off by 40 degrees
uplidpulse = constrain(uplidpulse, 280, 400); // Bucky: Take upper Eye lid and constrain it to the Eyelid on angles 280 to 400
lolidpulse = map(yval, 0, 1023, 410, 280);
lolidpulse += (trimval/2); // Bucky: this deivides the signal from the trimvalue for the eyelid by two
lolidpulse = constrain(lolidpulse, 280, 400);
pwm.setPWM(0, 0, lexpulse);
pwm.setPWM(1, 0, leypulse);
pwm.setPWM(2, 0, rexpulse);
pwm.setPWM(3, 0, reypulse);
if (switchval == HIGH) { // Bucky: this is for when you press the button to blink
pwm.setPWM(4, 0, 240); // Bucky: this sends a signal to the eyelids
pwm.setPWM(5, 0, 240);
}
else if (switchval == LOW) { // Bucky: This is for when you dont press the button it wont send a signal
pwm.setPWM(4, 0, uplidpulse);
pwm.setPWM(5, 0, lolidpulse);
}
Serial.println(lexpulse);
delay(5);
}