https://docs.arduino.cc/language-reference/en/structure/control-structure/if/
!= means does not equal
| means OR
So to start
if (lastS1 does not equal posS1) OR (lastS2 doesnot equal posS2) OR etc. etc.
Tom...
https://docs.arduino.cc/language-reference/en/structure/control-structure/if/
!= means does not equal
| means OR
So to start
if (lastS1 does not equal posS1) OR (lastS2 doesnot equal posS2) OR etc. etc.
Tom...
I mean : The loop()
function (post #15) modifies posS5
but you don't actuate the corresponding servo so you need to add
servoS5.write(posS5);
somewhere.
And the best place for that is below servo4
actuation and above the next instruction which is : if ((lastS1 != posS1) | (lastS2 != ...
To record S5 when it's moved individually, you need to test if its position changed so
if ((lastS1 != posS1) | (lastS2 != posS2) | (lastS3 != posS3) | (lastS4 != posS4))
should become
if ((lastS1 != posS1) | (lastS2 != posS2) | (lastS3 != posS3) | (lastS4 != posS4) | (lastS5 != posS5))
This new Wokwi should reflect that :
How are you powering all five servos?
hi and thanks for your answer.
Yes, all servos are powered, i do not think the problem comes from that. There is something in the code
the problem is there are lots of things in the code for each servo
here are the things for the "Base"
int startBase = 90;
int posBase = 90;
int lastBase = 90;
int minBase = 0;
int maxBase = 150;
Servo servoBase;
servoBase.attach (basePin);
posBase += dx;
posBase = angle;
if (posBase > maxBase) posBase = maxBase;
if (posBase < minBase) posBase = minBase;
servoBase.write (posBase);
if ( (lastBase != posBase) | (lastShoulder != posShoulder)
if (lastBase != posBase) {
buffAdd[buffPos] = posBase;
Serial.print (posBase);
lastBase = posBase;
int angleBase = servoBase.read ();
Serial.print (angleBase);
posBase = startBase;
servoBase.write (posBase);
Thank you very much gcjr for your line of investigation. I have it into account, but for the moment i am working with the changes by Etienne. He is very close to the right code. In fact in the wokwi simulator works perfect, but in my arduino uno is only one problem left to fix. I will explain in response to Etienne
Etienne, really thank you because with your changes i am just about to make it. Now add the S5 to this line of code. In the simulator everything goes as perfect as if Scarlett Johanson greets me in the morning with a smile and french breakfast. But i load to my board and joystick 1 one axis moves S1 and the other moves S2 & S3 simultaneously. The rest is ok, recording and playing of all servos. What can be wrong with this joystick 1???
Your code:
#include <Servo.h>
bool repeatPlaying = false; /* Repeatedly is running recorded cycle */
int delayBetweenCycles = 2000; /* Delay between cycles */
int s1Pin = 11; /* s1 servo */
int s2Pin = 10; /* s2 servo */
int s3Pin = 9; /* s3 servo */
int s4Pin = 6; /* s4 servo */
int s5Pin = 5; /* s5 servo */
int wDirPin = A0; /* s1 - joystick1*/
int xDirPin = A1; /* s2 - joystick1 */
int yDirPin = A3; /* s3 - joystick2 */
int zDirPin = A2; /* s4 - joystick2 */
int gDirPin = A4; /* s5 - joystick3 */
int pinRecord = 2; /* Button record - recommended (A4 is deprecated, will by used for additional joystick) */
int pinPlay = 3; /* Button play - recommended (A5 is deprecated, will by used for additional joystick) */
int pinLedRecord = 13; /* LED - indicates recording (light) or auto play mode (blink ones) */
const int buffSize = 512; /* Size of recording buffer */
int startS1 = 90;
int startS2 = 90;
int startS3 = 90;
int startS4 = 0;
int startS5 = 90;
int posS1 = 90;
int posS2 = 90;
int posS3 = 90;
int posS4 = 0;
int posS5 = 90;
int lastS1 = 90;
int lastS2 = 90;
int lastS3 = 90;
int lastS4 = 90;
int lastS5 = 90;
int minS1 = 0;
int maxS1 = 150;
int minS2 = 0;
int maxS2 = 150;
int minS3 = 0;
int maxS3 = 150;
int minS4 = 0;
int maxS4 = 150;
int minS5 = 0;
int maxS5 = 150;
const int countServo = 5;
int buff[buffSize];
int buffAdd[countServo];
int recPos = 0;
int playPos = 0;
int buttonRecord = HIGH;
int buttonPlay = HIGH;
int buttonRecordLast = LOW;
int buttonPlayLast = LOW;
bool record = false;
bool play = false;
bool debug = false;
String command = "Manual";
int printPos = 0;
int buttonPlayDelay = 20;
int buttonPlayCount = 0;
bool ledLight = false;
Servo servoS1;
Servo servoS2;
Servo servoS3;
Servo servoS4;
Servo servoS5;
void setup() {
Serial.begin(115200);
pinMode(wDirPin, INPUT);
pinMode(xDirPin, INPUT);
pinMode(yDirPin, INPUT);
pinMode(zDirPin, INPUT);
pinMode(gDirPin, INPUT);
pinMode(pinRecord, INPUT_PULLUP);
pinMode(pinPlay, INPUT_PULLUP);
pinMode(pinLedRecord, OUTPUT);
servoS1.attach(s1Pin);
servoS2.attach(s2Pin);
servoS3.attach(s3Pin);
servoS4.attach(s4Pin);
servoS5.attach(s5Pin);
StartPosition();
digitalWrite(pinLedRecord, HIGH);
delay(1000);
digitalWrite(pinLedRecord, LOW);
}
void loop() {
buttonRecord = digitalRead(pinRecord);
buttonPlay = digitalRead(pinPlay);
// Serial.print(buttonRecord);
// Serial.print("\t");
// Serial.println(buttonPlay);
// for testing purposes
if (buttonPlay == LOW)
{
buttonPlayCount++;
if (buttonPlayCount >= buttonPlayDelay)
{
repeatPlaying = true;
}
}
else buttonPlayCount = 0;
if (buttonPlay != buttonPlayLast)
{
if (record)
{
record = false;
}
if (buttonPlay == LOW)
{
play = !play;
repeatPlaying = false;
if (play)
{
StartPosition();
}
}
}
if (buttonRecord != buttonRecordLast)
{
if (buttonRecord == LOW)
{
record = !record;
if (record)
{
play = false;
repeatPlaying = false;
recPos = 0;
}
else
{
if (debug) PrintBuffer();
}
}
}
buttonPlayLast = buttonPlay;
buttonRecordLast = buttonRecord;
float dw = map(analogRead(wDirPin), 0, 1023, -5.0, 5.0);
float dx = map(analogRead(xDirPin), 0, 1023, 5.0, -5.0);
float dy = map(analogRead(yDirPin), 0, 1023, 5.0, -5.0);
float dz = map(analogRead(zDirPin), 0, 1023, 5.0, -5.0);
float dg = map(analogRead(gDirPin), 0, 1023, 5.0, -5.0);
if (abs(dw) < 1.5) dw = 0;
if (abs(dx) < 1.5) dx = 0;
if (abs(dy) < 1.5) dy = 0;
if (abs(dz) < 1.5) dz = 0;
if (abs(dg) < 1.5) dg = 0;
posS1 += dw;
posS2 += dx;
posS3 += dy;
posS4 += dz;
posS5 += dg;
if (play)
{
if (playPos >= recPos) {
playPos = 0;
if (repeatPlaying)
{
delay(delayBetweenCycles);
StartPosition();
}
else
{
play = false;
}
}
bool endOfData = false;
while (!endOfData)
{
if (playPos >= buffSize - 1) break;
if (playPos >= recPos) break;
int data = buff[playPos];
int angle = data & 0xFFF;
int servoNumber = data & 0x7000;
endOfData = data & 0x8000;
switch (servoNumber)
{
case 0x0000:
posS1 = angle;
break;
case 0x1000:
posS2 = angle;
break;
case 0x2000:
posS3 = angle;
break;
case 0x3000:
posS4 = angle;
dz = posS4 - lastS4;
break;
case 0x4000:
posS5 = angle;
dg = posS5 - lastS5;
break;
}
playPos++;
}
}
if (posS1 > maxS1) posS1 = maxS1;
if (posS2 > maxS2) posS2 = maxS2;
if (posS3 > maxS3) posS3 = maxS3;
if (posS4 > maxS4) posS4 = maxS4;
if (posS5 > maxS5) posS5 = maxS5;
if (posS1 < minS1) posS1 = minS1;
if (posS2 < minS2) posS2 = minS2;
if (posS3 < minS3) posS3 = minS3;
if (posS4 < minS4) posS4 = minS4;
if (posS5 < minS5) posS5 = minS5;
servoS1.write(posS1);
servoS2.write(posS2);
servoS3.write(posS3);
// if (dg < -3.0) {
// posS4 = minS4;
// servoS4.write(posS4);
// Serial.println(posS4);
// }
// else if (dg > 3.0) {
// posS4 = maxS4;
// servoS4.write(posS4);
// Serial.println(posS4);
// }
bool waitS4 = false;
if (dz < 0) {
posS4 = minS4;
waitS4 = true;
}
else if (dz > 0) {
posS4 = maxS4;
waitS4 = true;
}
servoS4.write(posS4);
if (play && waitS4)
{
delay(1000);
}
//Serial.println(posS4);
servoS5.write(posS5);
if ((lastS1 != posS1) | (lastS2 != posS2) | (lastS3 != posS3) | (lastS4 != posS4) | (lastS5 != posS5))
{
if (record)
{
if (recPos < buffSize - countServo)
{
int buffPos = 0;
if (lastS1 != posS1)
{
buffAdd[buffPos] = posS1;
buffPos++;
}
if (lastS2 != posS2)
{
buffAdd[buffPos] = posS2 | 0x1000;
buffPos++;
}
if (lastS3 != posS3)
{
buffAdd[buffPos] = posS3 | 0x2000;
buffPos++;
}
if (lastS4 != posS4)
{
buffAdd[buffPos] = posS4 | 0x3000;
buffPos++;
}
if (lastS5 != posS5)
{
buffAdd[buffPos] = posS5 | 0x4000;
buffPos++;
}
buffAdd[buffPos - 1] = buffAdd[buffPos - 1] | 0x8000;
for (int i = 0; i < buffPos; i++)
{
buff[recPos + i] = buffAdd[i];
}
recPos += buffPos;
}
}
command = "Manual";
printPos = 0;
if (play)
{
command = "Play";
printPos = playPos;
}
else if (record)
{
command = "Record";
printPos = recPos;
}
Serial.print(command);
Serial.print("\t");
Serial.print(printPos);
Serial.print("\t");
Serial.print(posS1);
Serial.print("\t");
Serial.print(posS2);
Serial.print("\t");
Serial.print(posS3);
Serial.print("\t");
Serial.print(posS4);
Serial.print("\t");
Serial.print(posS5);
Serial.print("\t");
Serial.print(record);
Serial.print("\t");
Serial.print(play);
Serial.println();
}
lastS1 = posS1;
lastS2 = posS2;
lastS3 = posS3;
lastS4 = posS4;
lastS5 = posS5;
if ( repeatPlaying)
{
ledLight = !ledLight;
}
else
{
if (ledLight)
{
ledLight = false;
}
if (record)
{
ledLight = true;
}
}
digitalWrite(pinLedRecord, ledLight);
delay(50);
}
void PrintBuffer()
{
for (int i = 0; i < recPos; i++)
{
int data = buff[i];
int angle = data & 0xFFF;
int servoNumber = data & 0x7000;
bool endOfData = data & 0x8000;
Serial.print("Servo=");
Serial.print(servoNumber);
Serial.print("\tAngle=");
Serial.print(angle);
Serial.print("\tEnd=");
Serial.print(endOfData);
Serial.print("\tData=");
Serial.print(data, BIN);
Serial.println();
}
}
void StartPosition()
{
int angles1 = servoS1.read();
int angles2 = servoS2.read();
int angles3 = servoS3.read();
int angles4 = servoS4.read();
int angles5 = servoS5.read();
Serial.print(angles1);
Serial.print("\t");
Serial.print(angles2);
Serial.print("\t");
Serial.print(angles3);
Serial.print("\t");
Serial.print(angles4);
Serial.println("\t");
Serial.print(angles5);
Serial.println("\t");
posS1 = startS1;
posS2 = startS2;
posS3 = startS3;
posS4 = startS4;
posS5 = startS5;
servoS1.write(posS1);
servoS2.write(posS2);
servoS3.write(posS3);
servoS4.write(posS4);
servoS5.write(posS5);
}
Why PWM capable? The library says it can do far more servos than the number of PWM pins on an Arduino:
https://docs.arduino.cc/libraries/servo/
The Servo library supports up to 12 motors on most Arduino boards and 48 on the Arduino Mega.
For example:
You're right, servo library obviously doesn't rely on that kind of PWM, no need for PWM capable pin. As it didn't work on astorgallionspain's prototype and as Wokwi highlighted only PWM capable pins while routing the (now hiden) wires, I presumed only those were allowed and didn't check any further. Thanks for rectifying.
How are the joysticks powered ? And, as hallowed31 already asked, how is everything powered ? You can post an explanatory photo of the setup.
Double check your wiring. If nothing's wrong there, add serial messages to see if joystick 1 alters joystick 2 readings. As analogRead() is directly mapped into delta variables, print those delta values: add this code right above Serial.print(command);
:
Serial.print(dx);
Serial.print(tab);
Serial.print(dy);
Serial.print(tab);
as I did (among many other minor changes to save RAM usage) in version 4 of my Wokwi
The first two columns display dx & dy and only one should be non zero if you move only one axis at a time.
thank you very much Etienne. I tried adding the lines
Serial.print(dx);
Serial.print(tab);
Serial.print(dy);
Serial.print(tab);
Serial.print(command);
But it is a step back, now s5 does not work in j3; problem with s2 & s3 in J1 remains the same and now besides J2 also gives problems of overlapping other servos like s5.
In any case i tried the previous code in wokwi simulator with arduino uno and it works perfecly. I do not know what happens in my board with this J1 and s2,s3 working at the same time. I post the wokwi project with the wiring which is same as my hardware model. The power i am using is the 5V card port. The board is usb power 2.4 A. I have also tried with dc jack but result is the same. Thanks for your help because the code works in the simulator perfecly.
Does reverting to the previous version (or modification) solve the new problem. If not, something else went wrong.
Based on your Wokwi, the UNO board supplies power to all the peripherals! Its max current capability is about 400 to 500mA. Are you sure you don't overload it?
How is the board itself powered? USB? External PSU?
As your system doesn't behave as in the simulator, it's probably a hardware problem and Power Supply it the first suspect, breadboard connections being the second...
Thank you very much Etienne.
yes, just load the previous code and the problem comes back to J1 S2&S3 moving together in one axis. The rest is working OK. The wiring lot of times checked so absolutely discard. The power comes from USB port, i have also used the DC built in port, finally i have powered servos with an external power supply and joysticks with the arduino 5v port, but the problem remains. So to this point i think the last check is to try a new board. If someone has 3 joysticks, 5 servos and a few time to spend in this, could check if has my same problem. That would confirm that my board is faulty and save me some money in case it is not. Thanks a lot.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.