The project is a robotic arm that is supposed to move in sync with music. The music will be a file on my computer.
I've written some code to control 5 different servos on Arduino UNO, now I would like to communicate between the Arduino and an MQTT broker to be able to play a music file on the computer while starting the Arduino.
Can I use Arduino UNO and an MQTT library or do I have to switch to an ESP8266 nodemcu? This code does not seem to work on the esp, the servos do not move and there is no error.
Here is the UNO code to control the robot:
#include <Servo.h>
int moves[][5] = { // array with each servo's angle for each step/move
// repetition means no move
{1, 45, 45}, // motor 4 and 5: 90 no move, +/- decides direction
{180, 70, 90},
{120, 100, 180}, // 4, 5: 1 unit is 1/4 pi.
/*{1, 100, 180},
{1, 135, 180},
{1, 135, 180},
{1, 100, 180},
{1, 100, 180},
{1, 100, 180}*/
};
int beats[] = { // beats per step/move. nr 0 is getting to start position..
4, 4, 4
};
class Dancer // creates a class to keep all functions necessary
{
Servo servo; // the servo
int pos; // current servo position
int increment; // increment to move for each interval (0, -1 or 1)
float updateInterval; // interval between updates, ms
unsigned long lastUpdate; // last update of position, ms
float bps; // beats per second
float mspb; // milliseconds per beat
int degrees; // degrees to move
long startMillis; // milliseconds at start of each move
int angle; // destination angle
int beats; // beats for said move
int msTot; // total milliseconds
float w;
public:
Dancer(int bpm, float ws) // initiates each servo, and calculates mspb
{
bps = bpm / 60;
mspb = 1000 / bps;
w = ws;
}
void Attach(int pin) // attaches each servo to respective pin in setup
{
servo.attach(pin);
}
void write(int rotate)
{
servo.write(rotate);
}
void contValues(int vinkel) // decide direction and set start time.
// use 'takter'? can be longer and shorter...
{
msTot = vinkel * w; // time for movement
if (vinkel == 90)
{
angle = 90;
}
else if (vinkel > 1)
{
angle = 180;
}
else if (vinkel < 1)
{
angle = 0;
}
startMillis = millis();
}
void Increment(int vinkel, int takter) // calculates increment and updateInterval
{ // by given values (angle and beats)
angle = vinkel;
beats = takter;
msTot = beats * mspb;
pos = servo.read();
if (angle == pos) { // if the servo shouldn't move, increment = 0
// servo increments one time (degrees = 1)
degrees = 1;
increment = 0;
}
else if (angle > pos) { // either ++ or -=1.
degrees = angle - pos;
increment = 1;
}
else if (angle < pos) {
degrees = pos - angle;
increment = -1;
}
updateInterval = msTot / degrees; // time between each update.
startMillis = millis();
}
int Update() { // updates the servo
pos = servo.read();
if (pos == angle) { // if the angle has been reached (ms not precise)
increment = 0;
}
if ((millis() - lastUpdate) >= updateInterval) { // time to update
lastUpdate = millis(); // 'reset' lastUpdate
pos += increment; // increase/decrease pos
servo.write(pos); // update servo
Serial.println(pos); // check the values in monitor
Serial.println(lastUpdate);
Serial.println(updateInterval);
Serial.println(msTot);
}
if ((millis() - startMillis) >= msTot) { // if the total time has run, break while loop
return 1;
}
else { // otherwise, keep looping
return 0;
}
}
int contServo()
{ // update continuous servo
servo.write(angle); // direction, 0, 180 or 90. maxspeed.
if ((millis() - startMillis) > msTot) // if position is reached, stop rotating
{
angle = 90; // stop servo
return 1; // ready
}
else
{
return 0; // keep looping
}
}
};
// end of class
int antalSteg = sizeof(beats) / sizeof(beats[0]); // amount of steps/moves
int bpm = 94; // a song's bpm, different for each
int i = 0; // int to for-loop and iterations.
float w = 0.25; // 1/4 pi / sec. 1 unit is 1/4 pi, 45 deg.
int b; // ints to break while-loop
int s;
int e;
int n;
int h;
Dancer base(bpm, w); // creates an instance of each servomotor/joint
Dancer shoulder(bpm, w); // passing the 'bpm' and 'w' argument
Dancer elbow(bpm, w);
Dancer neck(bpm, w);
Dancer head(bpm, w);
void setup()
{
WiFi.begin(ssid, password);
Serial.begin(9600); // initiate Serial monitor
base.Attach(2); //D4 // calls the function Attach
shoulder.Attach(0); // D3attaches each servo to resp pin
elbow.Attach(16); //D0
neck.Attach(3);
head.Attach(6);
base.write(0);
shoulder.write(0);
elbow.write(0);
delay(2000);
}
void loop()
{
for (i; i < antalSteg; i++) { // iterates for each step
base.Increment(moves[i][0], beats[i]); // calls function Increment
shoulder.Increment(moves[i][1], beats[i]); // passes arguments angle and beats
elbow.Increment(moves[i][2], beats[i]); // from the arrays moves and beats
// neck.Increment(moves[i][3], beats[i]);
// head.Increment(moves[i][4], beats[i]);
b, s, e = 0; // reset the ints to 0
while (b + s + e/* + n + h */< 3) { // loops the Update function
// if all return 1, break loop
b = base.Update();
s = shoulder.Update(); // updates the servo accordingly
e = elbow.Update(); // returns either value 1 or 0
//n = neck.Update();
//h = head.Update();
}
}
}
(Code tags added by Moderator)