/*************************************
Simple Arduino sweep sketch in microseconds
Note: The code is written in a simple blocking way and not optimized. It's a terrible
startingpoint to use in your own code!
PREREQUISITES:
- Know the lower ans upper value of a servo
INSTRUCTIONS
- Fill in 'LowerPos', 'UpperPos' and 'MiddlePos'
- Upload sketch
- Set Serial Monitor to 115200 baud
- Set Serial Monitor to "Both NL & CR"
- Connect a servo to 'ServoPin' (default: pin 9)
- Press "Send" when the servo is positioned at Middle when you are asked
*************************************/
#include <Servo.h>
const byte ServoPin = 10;
//Enter the minimum limit pulse width (in ms)
const unsigned int LowerPos = 520;
//Enter the lower maximum pulse width (ms)
const unsigned int UpperPos = 2480;
//Middle Calculate Formula
const unsigned int MiddlePos = ((UpperPos - LowerPos) / 2) + LowerPos;
// 10,3 Microseconds = 1°
const unsigned int increment10 = 103; //10.3 * 10
//boolean SerialDisplay;
const unsigned int MiddlePosDeg = ((UpperPos - LowerPos) / 2) / increment10;
const unsigned int UpperPosDeg = (((UpperPos - LowerPos) / 2) / increment10) * 2;
Servo testServo;
// variable to store the servo position
int PosUs = MiddlePos;
int PosDeg = MiddlePosDeg;
void setup() {
Serial.begin(115200);
// Serial.display=true
// testServo.writeMicroseconds(MiddlePos);
testServo.attach(ServoPin, LowerPos, UpperPos);
Serial.print("Lower value set to ");
Serial.println(LowerPos);
Serial.print("Upper value set to ");
Serial.print(UpperPos);
Serial.print(" = ");
Serial.print(UpperPosDeg*10);
Serial.println("° ");
Serial.print("Middle value set to ");
Serial.print(MiddlePos);
Serial.print(" = ");
Serial.print(MiddlePosDeg*10);
Serial.println("° ");
Serial.println();
Serial.println("Servo on central location");
Serial.println("Press \"Send\" to continue");
Serial.println();
while(!Serial.available());
clearSerialBuffer();
}
void loop() {
// if (SerialDisplay)
// Serial.println("");
// goes from MiddlePos to UpperPos.
/*Incrementing floating values of a non-integer increment,
* do not add true, because rounding errors accumulate.
* Use the "fixed point" integer value multiplied by 10:*/
for(unsigned int PosUs10 = MiddlePos*10 ; PosUs10 <= UpperPos*10 ; PosUs10 += increment10){
for(unsigned int PosDeg = MiddlePosDeg*10 ; PosDeg <= UpperPosDeg*10 ; PosDeg += 1){
double PosUs = PosUs10 / 10.0;
delay(650);
Serial.print(PosUs);
Serial.print(" = ");
Serial.print(PosDeg);
Serial.print("°, ");
}
}
Serial.println();
Serial.println();
//for(unsigned int PosUs10 = MiddlePos*10 ; PosUs10 >= LowerPos*10 ; PosUs10 -= increment10)
for(unsigned int pos = MiddlePos ; pos >= LowerPos ; pos -= 10)
{
//double PosUs = PosUs10 / 10.0;
delay(650);
Serial.print(pos);
Serial.print(" ");
}
Serial.println();
delay(15000);
Serial.println();
// SerialDisplay=false;
}
void clearSerialBuffer()
{
//clear serial buffer (but do nothing with it)
while(Serial.available())
{
Serial.read();
}
}
C'est normal, tes boucles sont imbriquées. Celle de l'intérieur doit se faire en entier pour chaque valeur de celle de l'extérieur.
Si tu veux obtenir une valeur différente pour chaque valeur d'une variable, il ne te faut qu'une seule boucle. La seconde valeur doit être déduite de la première.
Merci pour cette belle modification.
Je ne sais pas pourquoi, mais l’incrémentation ne va pas jusqu’au bout
Les valeurs sont bien prises en compte, soit :
LowerPos = 520
UpperPos=2480
MiddlePos = ((UpperPos - LowerPos) / 2) + LowerPos; = 1500
Donc l’incrémentation commence bien a 1500 (MiddlePos), et devrait aller au plus proche de 2480 (UpperPos).
Soit aller jusqu’à 2478.50, mais elle s’arrête a 2427 soit 5 incrément trop tôt.
Une idée de ce qui en être la cause ?
C'est ce qui peut arriver quand on a deux limites. Soit on arrête quand une des deux limites est atteinte (c'est ce qui est fait dans le programme) soit on arrête quand les deux limites sont atteintes ou dépassées dans ce cas il faut remplacer le && par un || dans le if.
Bien vu ! c’était bien le cas.
Encore merci à vous deux.
L’affichage PosUs sur la console se fait sur deux chiffres après la virgule (enfin le point) est-il possible de n’afficher qu’un chiffre ?
kamill:
Pourquoi? C'est une pure convention. Ton servo peut très bien varier de 15 à 165 degrés ou de -75 à +75 degrés.
Si le milieu est à 75, tu mets 75
Très bonne remarque!
Mais, le 90 ou le 75 que tu utilises dans ton calcule on n'est pas sensé le connaitre n'ayant au départ que des valeurs en microsecondes.
Si mon calcule est bon pour trouver le milieu en degrés:
MiddlePosDeg = ((UpperPos - LowerPos) / 2) / (increment10/10.0);
MiddlePosDeg = (2300 - 710) / 2) / 10,3
MiddlePosDeg = (1590 / 2) /10,3
MiddlePosDeg = 795 /10,3 = 77, 185 (77°)
De là, calculer UpperPosDeg et LowerPosDeg, mais je ne suis déjà pas sûr de ma logique pour MiddlePosDeg.