This is my first time ever posting here, so please forgive me if this is the wrong category or if I made another mistake with this post.
I hope that somebody can help me understand why my code/program isn't working, while it worked perfectly fine before adding the 33rd entry to the switch case?
(undoing that, didn't seem to help either)
The project:
I thought it would be a fun idea to built my own little robot, with plans from the internet.
It's a little robot with 3 sg90g micro servo's, a piëzo buzzer and a hc-sr04 ultrasound sensor.
The Arduino is an Arduino nano. I tried 3 different ones: one nano of unknown origin (had it laying around), one (clone) ordered from Amazon which says Az-Delivery on the bottom and an arduino (clone?) ordered from Aliexpress.
I have chosen the settings to use the processor: Atmega328P (Old Bootloader)
Before attempting this I tried some very simple programming in Unity in C#, but I never wrote anything before in C for Arduino.
The code therefore is unoptimized, probably written wrong and I haven't really used any arrays eventhough it probably can use those. I really just stuck to writing code as simple as possible to get it to work with the idea to maybe optimize later when I have a running code and some more understanding of C.
The problem:
When I wrote this, I did so piece-by-piece and I checked functionality of all functions before writing another.
All functions seem to work when it's just a single function and added to Setup() or Loop().
I also briefly got everything to work (at least a little) in the "switch" loop, as seen in the code.
However, it completely stopped working after adding another case to the switch.
The Arduino now only displays "Se" on the serial monitor and stops.
This is also the case when nothing else is hooked onto the Arduino, even the one I just bought.
Can someone please explain what I'm doing wrong? (Except the way I've written the code, I guess that must look horrible )
Is it the "switch" I added to the loop?
Is there some sort of mistake I made in the code? (it does not give any errors)
Or is it because they might be cloned arduino's? (then I'll never buy another of those again)
PS: I've seen that "Delay()" is a bit frowned upon, but I didn't know of a different way to "wait" / "halt code continuation" for the amount of time I used in that function.
//--------------------------- LIBRARIES TO USE ---------------------------//
#include <Servo.h> // Arduino library for servo's.
#include <math.h> // Standard C library for mathematic operations.
#include "pitches.h" // Arduino library to use a piezo buzzer.
//--------------------------- IMPORTANT VARIABLES ---------------------------//
// Servo's and assigned names
Servo baseServo;
Servo neckServo;
Servo headServo;
// Speed and delay settings
int delayBetweenSweepMoves = 500; // Delay between initial sweeping move orders.
int intitialMovementSpeed = 10; // The general delay between movements when facing a set direction. Higher numbers will make movement increment slower; delays movement increments in miliseconds.
// Ultrasonic variables
#define echoPin 6 // Echo pin
#define triggerPin 5 // Trigger pin
//Buzzer
#define buzzerPin 7 // Buzzer pin
// Bools to keep track of reactions, sweeping moves and idles.
bool hasReacted; // Bool to break out of a while loop when reading changes.
// Array that can be used to define random actions and giving the illusion of a 'pet' with a mind of it's own.
//int sweepingMoves[] = {};
// int idleMoves[] = {};
//We can split the actions up in 2 different ararys and then make it so that we only sweep on one iteration and do an idle on the next.
//But for the added random factor we chose not to do so.
int actions[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
int chosenAction;
// Variables for storing distances at locations.
// This is used as a form of 'mapping' the area to interact with changes.
long lowPos0; // Lower position at 0°.
long lowPos45;
long lowPos90;
long lowPos135;
long lowPos180; // Lower position at 180°.
long highPos0; // Position 45° upwards and at 0° relative to the base.
long highPos45;
long highPos90;
long highPos135;
long highPos180; // position 45° upwards and at 180° relative to the base.
long topPos; // Position straight above
//--------------------------- SETUP FUNCTION ---------------------------//
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.flush();
baseServo.attach(2);
neckServo.attach(4);
headServo.attach(3);
Serial.setTimeout(50); // To ensure the Arduino doesn't read/wait for the serial too long
Serial.println("Serial communication started.");
// The initial servo positions
baseServo.write(90);
neckServo.write(90);
headServo.write(90);
// The ultrasonic sensor setup
pinMode(triggerPin, OUTPUT);
pinMode(echoPin, INPUT);
// Reaction bool is set to 'false'. Since it hasn't been able to react yet due to just booting up.
hasReacted = false;
// Initial mapping distances
faceLow90(25);
DoFirstMappingSweep();
faceLow90(10);
delay(5000); // Wait 5 seconds before starting an action.
}
//--------------------------- LOOP FUNCTION ---------------------------//
void loop() {
// put your main code here, to run repeatedly:
chosenAction = random(0, 33);
switch (chosenAction) {
case 0:
Serial.println("CasualSweepLow1");
CasualSweepLow1();
break;
case 1:
Serial.println("CasualSweepLow2");
CasualSweepLow2();
break;
case 2:
Serial.println("CasualSweepLow3");
CasualSweepLow3();
break;
case 3:
Serial.println("CasualSweepLow4");
CasualSweepLow4();
break;
case 4:
Serial.println("CasualSweepLow5");
CasualSweepLow5();
break;
case 5:
Serial.println("CasualSweepHigh1");
CasualSweepHigh1();
break;
case 6:
Serial.println("CasualSweepHigh2");
CasualSweepHigh2();
break;
case 7:
Serial.println("CasualSweepHigh3");
CasualSweepHigh3();
break;
case 8:
Serial.println("CasualSweepHigh4");
CasualSweepHigh4();
break;
case 9:
Serial.println("CasualSweepHigh5");
CasualSweepHigh5();
break;
case 10:
Serial.println("CasualSweepTop");
CasualSweepTop();
break;
case 11:
Serial.println("CasualSweepMixed1");
CasualSweepMixed1();
break;
case 12:
Serial.println("CasualSweepMixed2");
CasualSweepMixed2();
break;
case 13:
Serial.println("CasualSweepMixed3");
CasualSweepMixed3();
break;
case 14:
Serial.println("CasualSweepMixed4");
CasualSweepMixed4();
break;
case 15:
Serial.println("CasualSweepMixed5");
CasualSweepMixed5();
break;
case 16:
Serial.println("CasualSweepMixed6");
CasualSweepMixed6();
break;
case 17:
Serial.println("Dance1");
Dance1();
break;
case 18:
Serial.println("Dance2");
Dance2();
break;
case 19:
Serial.println("Headbang");
Headbang();
break;
case 20:
Serial.println("SwayHead1");
SwayHead1();
break;
case 21:
Serial.println("SwayHead2");
SwayHead2();
break;
case 22:
Serial.println("SwayHead3");
SwayHead3();
break;
case 23:
Serial.println("SwayHead4");
SwayHead4();
break;
case 24:
Serial.println("SwayHead5");
SwayHead5();
break;
case 25:
Serial.println("SitUpIdle");
SitUpIdle();
break;
case 26:
Serial.println("PlayYankeeDoodle");
PlayYankeeDoodle();
break;
case 27:
Serial.println("PlayAuClaireDeLaLune");
PlayAuClaireDeLaLune();
break;
case 28:
Serial.println("Speak1");
Speak1();
break;
case 29:
Serial.println("Speak2");
Speak2();
break;
case 30:
Serial.println("Speak3");
Speak3();
break;
case 31:
Serial.println("Speak4");
Speak4();
break;
case 32:
Serial.println("PlayTwinkleTwinkleLittleStar");
PlayTwinkleTwinkleLittleStar();
break;
}
delay(random(5001, 30001)); // To make sure that your personal buddy doesn't seem like a child that ate too much sugar!
//It can chill for a few seconds (between 5 en 30) before performing the next action.
}
//--------------------------- FUNCTIONS ---------------------------//
//Measure distance to objects in front of the sensor.
int MeasureDistance(int EchoPin, int TriggerPin) { // Calculate distance in cm
long duration, distance;
digitalWrite(TriggerPin, LOW);
delayMicroseconds(2);
digitalWrite(TriggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
duration = pulseIn(EchoPin, HIGH);
distance = (duration / 2) * 0.0344;
Serial.print("Distance: ");
Serial.print(distance);
Serial.print(" cm");
return distance;
}
// Actual movement function to send servo's to the desired configuration.
void MoveTo(Servo movingServo, int positionInDegrees, int speedDelay) {
bool haveToMove = true;
int currentPos = movingServo.read();
int targetPos = positionInDegrees;
int newPos;
while (haveToMove) {
if (currentPos < targetPos) {
movingServo.write(currentPos++);
delay(speedDelay);
}
else if (currentPos > targetPos) {
movingServo.write(currentPos--);
delay(speedDelay);
} else // Then the target position and current position are the same
{
haveToMove = false;
}
}
}
int CalculateDistanceDifference(int distance1, int distance2) {
int difference;
difference = abs(distance1 - distance2);
return difference;
}
float GetRandomDuration(int RandomAmount) {
for (int i = 0; i < RandomAmount; i++) {
return random(2, 8);
}
}
// React to change
void MeasureAndReact(long facingPosition) {
int currentMeasuredDistance;
int distanceDifference;
currentMeasuredDistance = MeasureDistance(echoPin, triggerPin);
distanceDifference = CalculateDistanceDifference(currentMeasuredDistance, facingPosition);
Serial.println(distanceDifference);
if (distanceDifference > 10 && distanceDifference < 200 && currentMeasuredDistance > 10) {
ActCurious();
hasReacted = true;
Serial.println("Has reacted");
} else if (distanceDifference > 50 || currentMeasuredDistance < 10 && distanceDifference > 1) {
ActStartled();
hasReacted = true;
Serial.println("Has reacted");
} else if (distanceDifference > 100 && currentMeasuredDistance < 30 && currentMeasuredDistance > 1) {
ActStartled();
hasReacted = true;
Serial.println("Has reacted");
} else if (distanceDifference > 100 && currentMeasuredDistance < 200 && currentMeasuredDistance > 10) {
ActCurious();
hasReacted = true;
Serial.println("Has reacted");
} else {
hasReacted = false;
Serial.println("Has not reacted");
}
}
//--------------------------- Reactions ---------------------------//
void ActCurious() {
MoveTo(headServo, 45, 20);
MoveTo(headServo, 135, 20);
SpeakCurious();
MoveTo(headServo, 45, 20);
delay(1000);
MoveTo(headServo, 90, 30);
}
void ActStartled() {
MoveTo(headServo, 45, 2);
MoveTo(neckServo, 35, 5);
SpeakStartled1();
MoveTo(neckServo, 90, 5);
MoveTo(neckServo, 35, 5);
SpeakStartled2();
MoveTo(neckServo, 90, 5);
MoveTo(headServo, 135, 2);
MoveTo(neckServo, 35, 5);
SpeakStartled2();
MoveTo(neckServo, 90, 5);
MoveTo(neckServo, 35, 5);
SpeakStartled1();
noTone(buzzerPin); // Just in case. I had an instance where the buzzer kept on going for a little while.
MoveTo(neckServo, 90, 5);
MoveTo(headServo, 45, 2);
delay(500);
MoveTo(headServo, 90, 10);
}
//--------------------------- Personal buddy Behaviours ---------------------------//
//--------------------------- Sweeps ---------------------------//
// Sweeping behaviors. Varrying from pretty thorough to only measuring 1 or 2 points.
// First sweep to map everything
void DoFirstMappingSweep() {
faceLow0(intitialMovementSpeed);
lowPos0 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves); // In order to actually reach a position before going to the next position. Otherwise it'll just try to move to all positions at the same time
faceHigh0(intitialMovementSpeed);
highPos0 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceLow45(intitialMovementSpeed);
lowPos45 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceHigh45(intitialMovementSpeed);
highPos45 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceLow90(intitialMovementSpeed);
lowPos90 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceHigh90(intitialMovementSpeed);
highPos90 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceLow135(intitialMovementSpeed);
lowPos135 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceHigh135(intitialMovementSpeed);
highPos135 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceLow180(intitialMovementSpeed);
lowPos180 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceHigh180(intitialMovementSpeed);
highPos180 = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
faceTop(intitialMovementSpeed);
topPos = (MeasureDistance(echoPin, triggerPin));
delay(delayBetweenSweepMoves);
}
// Sweeps low // (there are 5 actions here)
void CasualSweepLow1() {
bool done = false;
while (!done) {
faceLow180(25);
MeasureAndReact(lowPos180);
if (hasReacted)
break;
faceLow135(25);
MeasureAndReact(lowPos135);
if (hasReacted)
break;
faceLow90(25);
MeasureAndReact(lowPos90);
if (hasReacted)
break;
faceLow45(25);
MeasureAndReact(lowPos45);
if (hasReacted)
break;
faceLow0(25);
MeasureAndReact(lowPos0);
done = true;
}
}
void CasualSweepLow2() {
bool done = false;
while (!done) {
faceLow0(25);
MeasureAndReact(lowPos0);
if (hasReacted)
break;
faceLow45(25);
MeasureAndReact(lowPos45);
if (hasReacted)
break;
faceLow90(25);
MeasureAndReact(lowPos90);
if (hasReacted)
break;
faceLow135(25);
MeasureAndReact(lowPos135);
if (hasReacted)
break;
faceLow180(25);
MeasureAndReact(lowPos180);
done = true;
}
}
void CasualSweepLow3() {
bool done = false;
while (!done) {
faceLow135(25);
MeasureAndReact(lowPos135);
if (hasReacted)
break;
faceLow45(25);
MeasureAndReact(lowPos45);
if (hasReacted)
break;
faceLow90(25);
MeasureAndReact(lowPos90);
done = true;
}
}
void CasualSweepLow4() {
bool done = false;
while (!done) {
faceLow180(25);
MeasureAndReact(lowPos135);
if (hasReacted)
break;
faceLow0(25);
MeasureAndReact(lowPos45);
if (hasReacted)
break;
done = true;
}
}
void CasualSweepLow5() {
faceLow90(25);
MeasureAndReact(lowPos135);
}
// Sweeps high // (there are 6 actions here)
void CasualSweepHigh1() {
bool done = false;
while (!done) {
faceHigh180(25);
MeasureAndReact(highPos180);
if (hasReacted)
break;
faceHigh135(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceHigh90(25);
MeasureAndReact(highPos90);
if (hasReacted)
break;
faceHigh45(25);
MeasureAndReact(highPos45);
if (hasReacted)
break;
faceHigh0(25);
MeasureAndReact(highPos0);
done = true;
}
}
void CasualSweepHigh2() {
bool done = false;
while (!done) {
faceHigh0(25);
MeasureAndReact(highPos0);
if (hasReacted)
break;
faceHigh45(25);
MeasureAndReact(highPos45);
if (hasReacted)
break;
faceHigh90(25);
MeasureAndReact(highPos90);
if (hasReacted)
break;
faceHigh135(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceHigh180(25);
MeasureAndReact(highPos180);
done = true;
}
}
void CasualSweepHigh3() {
bool done = false;
while (!done) {
faceHigh135(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceHigh45(25);
MeasureAndReact(highPos45);
if (hasReacted)
break;
faceHigh90(25);
MeasureAndReact(highPos90);
done = true;
}
}
void CasualSweepHigh4() {
bool done = false;
while (!done) {
faceHigh180(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceHigh0(25);
MeasureAndReact(highPos45);
if (hasReacted)
break;
faceTop(25);
MeasureAndReact(topPos);
done = true;
}
}
void CasualSweepHigh5() {
faceHigh90(25);
MeasureAndReact(highPos135);
}
void CasualSweepTop() {
faceTop(25);
MeasureAndReact(topPos);
}
// Sweeps mixed high and low // (there are 6 actions here)
void CasualSweepMixed1() {
bool done = false;
while (!done) {
faceHigh180(25);
MeasureAndReact(highPos180);
if (hasReacted)
break;
faceLow45(25);
MeasureAndReact(lowPos45);
if (hasReacted)
break;
faceHigh90(25);
MeasureAndReact(highPos90);
if (hasReacted)
break;
faceLow90(25);
MeasureAndReact(lowPos90);
if (hasReacted)
break;
faceHigh0(25);
MeasureAndReact(highPos0);
done = true;
}
}
void CasualSweepMixed2() {
bool done = false;
while (!done) {
faceHigh135(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceLow0(25);
MeasureAndReact(lowPos0);
if (hasReacted)
break;
faceLow180(25);
MeasureAndReact(lowPos180);
if (hasReacted)
break;
faceHigh180(25);
MeasureAndReact(highPos180);
if (hasReacted)
break;
faceHigh90(25);
MeasureAndReact(highPos90);
done = true;
}
}
void CasualSweepMixed3() {
bool done = false;
while (!done) {
faceLow135(25);
MeasureAndReact(lowPos135);
if (hasReacted)
break;
faceHigh45(25);
MeasureAndReact(highPos45);
if (hasReacted)
break;
faceHigh135(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceLow90(25);
MeasureAndReact(lowPos90);
done = true;
}
}
void CasualSweepMixed4() {
bool done = false;
while (!done) {
faceHigh135(25);
MeasureAndReact(highPos135);
if (hasReacted)
break;
faceLow180(25);
MeasureAndReact(lowPos180);
if (hasReacted)
break;
faceTop(25);
MeasureAndReact(topPos);
done = true;
}
}
void CasualSweepMixed5() {
bool done = false;
while (!done) {
faceHigh45(25);
MeasureAndReact(highPos45);
if (hasReacted)
break;
faceLow0(25);
MeasureAndReact(lowPos0);
done = true;
}
}
void CasualSweepMixed6() {
bool done = false;
while (!done) {
faceHigh90(25);
MeasureAndReact(highPos90);
if (hasReacted)
break;
faceLow180(25);
MeasureAndReact(lowPos180);
if (hasReacted)
break;
faceLow0(25);
MeasureAndReact(lowPos0);
done = true;
}
}
//--------------------------- Idles ---------------------------//
// (there are 9 actions here)
void Dance1() {
Serial.println("Dance 1 started.");
faceLow90(10);
MoveTo(baseServo, 60, 8);
MoveTo(neckServo, 60, 8);
MoveTo(neckServo, 90, 8);
MoveTo(baseServo, 120, 8);
MoveTo(neckServo, 60, 8);
MoveTo(neckServo, 90, 8);
MoveTo(baseServo, 70, 8);
MoveTo(neckServo, 35, 8);
MoveTo(neckServo, 90, 8);
MoveTo(baseServo, 110, 8);
MoveTo(neckServo, 35, 8);
MoveTo(neckServo, 90, 8);
MoveTo(baseServo, 35, 8);
MoveTo(neckServo, 55, 8);
MoveTo(neckServo, 75, 8);
MoveTo(baseServo, 135, 8);
MoveTo(neckServo, 75, 8);
MoveTo(neckServo, 55, 8);
MoveTo(baseServo, 70, 8);
MoveTo(neckServo, 35, 8);
MoveTo(neckServo, 90, 8);
MoveTo(baseServo, 110, 8);
MoveTo(neckServo, 35, 8);
MoveTo(neckServo, 90, 8);
Serial.println("Dance 1 ended.");
faceLow90(10);
}
void Dance2() {
Serial.println("Dance 2 started.");
faceLow90(10);
MoveTo(headServo, 45, 1);
MoveTo(baseServo, 75, 5);
MoveTo(neckServo, 30, 5);
MoveTo(neckServo, 75, 5);
MoveTo(headServo, 135, 1);
MoveTo(baseServo, 105, 5);
MoveTo(neckServo, 30, 5);
MoveTo(neckServo, 75, 5);
MoveTo(headServo, 90, 5);
MoveTo(headServo, 35, 1);
MoveTo(headServo, 145, 1);
MoveTo(headServo, 0, 1);
MoveTo(headServo, 180, 1);
MoveTo(headServo, 75, 1);
MoveTo(headServo, 105, 1);
MoveTo(headServo, 90, 5);
MoveTo(headServo, 105, 1);
MoveTo(headServo, 75, 1);
MoveTo(headServo, 180, 1);
MoveTo(headServo, 0, 1);
MoveTo(headServo, 145, 1);
MoveTo(headServo, 35, 1);
MoveTo(headServo, 90, 5);
MoveTo(neckServo, 75, 5);
MoveTo(neckServo, 30, 5);
MoveTo(baseServo, 105, 5);
MoveTo(headServo, 135, 1);
MoveTo(neckServo, 75, 5);
MoveTo(neckServo, 30, 5);
MoveTo(baseServo, 75, 5);
MoveTo(headServo, 45, 1);
faceLow90(10);
Serial.println("Dance 2 ended.");
}
void Headbang() {
Serial.println("Headbang started.");
faceHigh90(10);
for (int i = 0; i < 3; i++) {
MoveTo(neckServo, 85, 2);
MoveTo(headServo, 165, 2);
MoveTo(neckServo, 25, 2);
MoveTo(headServo, 25, 2);
MoveTo(baseServo, 85, 2);
MoveTo(neckServo, 85, 2);
MoveTo(headServo, 165, 2);
MoveTo(neckServo, 25, 2);
MoveTo(headServo, 25, 2);
MoveTo(baseServo, 95, 2);
MoveTo(neckServo, 85, 2);
MoveTo(headServo, 165, 2);
MoveTo(neckServo, 25, 2);
MoveTo(headServo, 25, 2);
MoveTo(baseServo, 90, 2);
}
Serial.println("Headbang ended.");
faceLow90(8);
}
void SwayHead1() {
faceLow45(5);
MoveTo(headServo, 80, 5);
MoveTo(baseServo, 135, 20);
MoveTo(headServo, 110, 5);
MoveTo(baseServo, 45, 20);
faceLow90(10);
}
void SwayHead2() {
faceLow180(5);
MoveTo(headServo, 125, 5);
MoveTo(baseServo, 0, 20);
MoveTo(headServo, 65, 5);
MoveTo(baseServo, 180, 20);
faceLow90(10);
}
void SwayHead3() {
faceHigh45(5);
MoveTo(headServo, 80, 5);
MoveTo(baseServo, 135, 20);
MoveTo(headServo, 110, 5);
MoveTo(baseServo, 45, 20);
faceLow90(10);
}
void SwayHead4() {
faceHigh180(5);
MoveTo(headServo, 125, 5);
MoveTo(baseServo, 0, 20);
MoveTo(headServo, 65, 5);
MoveTo(baseServo, 180, 20);
faceLow90(10);
}
void SwayHead5() {
faceHigh90(5);
MoveTo(headServo, 170, 10);
MoveTo(neckServo, 90, 20);
MoveTo(headServo, 10, 10);
MoveTo(neckServo, 10, 20);
MoveTo(neckServo, 90, 20);
faceLow90(10);
}
void SitUpIdle() {
faceTop(20);
MoveTo(headServo, 25, 10);
MoveTo(headServo, 90, 10);
delay(1000);
MoveTo(headServo, 155, 10);
MoveTo(neckServo, 25, 10);
delay(1000);
faceLow90(20);
}
//--------------------------- Facing Directions ---------------------------//
// Facing directions
void faceLow0(int speed) {
MoveTo(headServo, 90, speed); // Head servo 90° is face straight.
MoveTo(baseServo, 0, speed); // Base at 90° is face forward, 180° is face left, 0° is face right
MoveTo(neckServo, 90, speed); // 90° is look straight forward. You can't really go above this safely since it then translates in facing downwards. 0° is look straight up.
Serial.println("FaceLow0");
}
void faceLow45(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 45, speed);
MoveTo(neckServo, 90, speed);
Serial.println("FaceLow45");
}
void faceLow90(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 90, speed);
MoveTo(neckServo, 90, speed);
}
void faceLow135(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 135, speed);
MoveTo(neckServo, 90, speed);
}
void faceLow180(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 180, speed);
MoveTo(neckServo, 90, speed);
}
void faceHigh0(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 0, speed);
MoveTo(neckServo, 45, speed);
}
void faceHigh45(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 45, speed);
MoveTo(neckServo, 45, speed);
}
void faceHigh90(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 90, speed);
MoveTo(neckServo, 45, speed);
}
void faceHigh135(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 135, speed);
MoveTo(neckServo, 45, speed);
}
void faceHigh180(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 180, speed);
MoveTo(neckServo, 45, speed);
}
void faceTop(int speed) {
MoveTo(headServo, 90, speed);
MoveTo(baseServo, 90, speed);
MoveTo(neckServo, 0, speed);
}
/////////////////////////////////////////////////////////////////////////
//--------------------------- Using melodies---------------------------//
////////////////////////////////////////////////////////////////////////
//For singing melodies and speaking 'words'
// This piece of code comes from the Arduino site and is only edited by me to be used for my project.
void PlayYankeeDoodle() {
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(10, 80), random(2, 25)); // Raising your head whilst saying seems appropriate.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when singing.
delay(500); // We wait half a second to be sure that the Servo's are done moving before singing.
// notes in the melody:
int melody[] = {
NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5,
NOTE_C5, NOTE_E5, NOTE_D5,
NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5,
NOTE_C5, NOTE_B5,
NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5,
NOTE_F5, NOTE_E5, NOTE_D5, NOTE_C5,
NOTE_B5, NOTE_G4, NOTE_A5, NOTE_B5,
NOTE_C5, NOTE_C5
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
4, 4, 4, 4,
4, 4, 2,
4, 4, 4, 4,
2, 2,
4, 4, 4, 4,
4, 4, 4, 4,
4, 4, 4, 4,
4, 4, 4, 4,
2, 2
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 27; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
faceLow90(25); // Reset face orientation after singing.
}
void PlayAuClaireDeLaLune() {
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(10, 80), random(2, 25)); // Raising your head whilst saying seems appropriate.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when singing.
delay(500); // We wait half a second to be sure that the Servo's are done moving before singing.
// notes in the melody:
int melody[] = {
NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5,
NOTE_E5, NOTE_D5,
NOTE_C5, NOTE_E5, NOTE_D5, NOTE_D5,
NOTE_C5,
NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5,
NOTE_E5, NOTE_D5,
NOTE_C5, NOTE_E5, NOTE_D5, NOTE_D5,
NOTE_C5,
NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5,
NOTE_A5, NOTE_A5,
NOTE_D5, NOTE_C5, NOTE_B5, NOTE_A5,
NOTE_G4,
NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5,
NOTE_E5, NOTE_D5,
NOTE_C5, NOTE_E5, NOTE_D5, NOTE_D5,
NOTE_C5
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
4, 4, 4, 4,
2, 2,
4, 4, 4, 4,
1,
4, 4, 4, 4,
2, 2,
4, 4, 4, 4,
1,
4, 4, 4, 4,
2, 2,
4, 4, 4, 4,
1,
4, 4, 4, 4,
2, 2,
4, 4, 4, 4,
1,
4, 4, 4, 4,
2, 2,
4, 4, 4, 4,
1
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 44; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
faceLow90(25); // Reset face orientation after singing.
}
void Speak1() {
// notes in the melody:
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(0, 90), random(2, 25)); // Just a random angle for the neck.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when speaking.
delay(500); // We wait half a second to be sure that the Servo's are done moving before speaking.
int melody[] = {
NOTE_C5, NOTE_C5, NOTE_G4, NOTE_B5
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
8, 4, 8, 3
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 4; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void Speak2() {
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(0, 90), random(2, 25)); // Just a random angle for the neck.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when speaking.
delay(500); // We wait half a second to be sure that the Servo's are done moving before speaking.
// notes in the melody:
int melody[] = {
NOTE_B0, NOTE_D2, NOTE_E4, NOTE_B5
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
4, 8, 8, 4
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 4; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void Speak3() {
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(0, 90), random(2, 25)); // Just a random angle for the neck.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when speaking.
delay(500); // We wait half a second to be sure that the Servo's are done moving before speaking.
// notes in the melody:
int melody[] = {
NOTE_B0, NOTE_D2, NOTE_E4, NOTE_B5, NOTE_D3, NOTE_D3, NOTE_B6
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
4, 8, 8, 4, 8, 8, 4
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 7; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void Speak4() {
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(0, 90), random(2, 25)); // Just a random angle for the neck.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when speaking.
delay(500); // We wait half a second to be sure that the Servo's are done moving before speaking.
// notes in the melody:
int melody[] = {
NOTE_B0, NOTE_D2, NOTE_B0, NOTE_D1, NOTE_D3, NOTE_D2, NOTE_B0
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
4, 8, 4, 8, 8, 2, 4
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 7; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void SpeakCurious() {
// notes in the melody:
int melody[] = {
NOTE_B0, NOTE_B2, NOTE_E2, NOTE_E2, NOTE_B4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
8, 2, 8, 8, 2
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 5; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void SpeakStartled1() {
// notes in the melody:
int melody[] = {
NOTE_B4, NOTE_B4, NOTE_B4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
8, 8, 8
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void SpeakStartled2() {
// notes in the melody:
int melody[] = {
NOTE_B0, NOTE_B0, NOTE_B0
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
8, 8, 8
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 8; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
}
void PlayTwinkleTwinkleLittleStar() {
// Adding some movement in a random direction. This way buddy sings to different locations instead of only facing forward.
MoveTo(baseServo, random(0, 180), random(2, 25));
MoveTo(neckServo, random(10, 80), random(2, 25)); // Raising your head whilst saying seems appropriate.
MoveTo(headServo, random(10, 170), random(2, 25)); // Buddy has a random angle of his head when singing.
delay(500); // We wait half a second to be sure that the Servo's are done moving before singing.
// notes in the melody:
int melody[] = {
NOTE_C5, NOTE_C5, NOTE_G6, NOTE_G6,
NOTE_A6, NOTE_A6, NOTE_G5,
NOTE_F5, NOTE_F5, NOTE_E5, NOTE_E5,
NOTE_D5, NOTE_D5, NOTE_C5,
NOTE_G5, NOTE_G5, NOTE_F5, NOTE_F5,
NOTE_E5, NOTE_E5, NOTE_D5,
NOTE_G5, NOTE_G5, NOTE_F5, NOTE_F5,
NOTE_E5, NOTE_E5, NOTE_D5,
NOTE_C5, NOTE_C5, NOTE_G5, NOTE_G5,
NOTE_A6, NOTE_A5, NOTE_G5,
NOTE_F5, NOTE_F5, NOTE_E5, NOTE_E5,
NOTE_D5, NOTE_D5, NOTE_C5
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
float noteDurations[] = {
4, 4, 4, 4,
4, 4, 2,
4, 4, 4, 4,
4, 4, 2,
4, 4, 4, 4,
4, 4, 2,
4, 4, 4, 4,
4, 4, 2,
4, 4, 4, 4,
4, 4, 2,
4, 4, 4, 4,
4, 4, 2
};
// iterate over the notes of the melody:
for (int thisNote = 0; thisNote < 42; thisNote++) {
// to calculate the note duration, take one second divided by the note type.
//e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
int noteDuration = 1000 / noteDurations[thisNote];
tone(buzzerPin, melody[thisNote], noteDuration);
// to distinguish the notes, set a minimum time between them.
// the note's duration + 30% seems to work well:
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
// stop the tone playing:
noTone(buzzerPin);
}
faceLow90(25); // Reset face orientation after singing.
}