I'm working on a project where a have to control several servos with diferents scenarios, that I send via PC to the arduino. In the PC I created a program with VS that send the scenarios that are in a .txt file. In the arduino I store the file in a buffer and then I convert it into a String.
Now that's where my trouble begins, I can only move it once, it means I can only send one line to make the servo move. My question is, how can I send one line at a time with a String. Is it possible?
Here is the code, only the scenario part, of course:
Servo myservo;
String readString, servo1, servo2;
bool scenario1 = false;
bool scenario2 = false;
bool scenario3 = false;
char line;
if (scenario1 && scenario2 && scenario3)
{
scenario1 = false;
scenario2 = false;
scenario3 = false;
Serial2.println("SCENOK");
Serial.println("SCENOK");
}
case '5': // reception scenario1
scenario1 = true;
scenario();
break;
void scenario() //lecture des scenarios
{
for (int y = scen_min; y < scen_max; y++)
{
if (buffer[y] != ' ');
line = buffer[y];
Serial.print(line);
readString += line;
}
}
void start_servo() //mouvement des servos
{
if (readString.length() > 0)
{
int x = 9;
for (int i = 0; i < readString.length(); i++)
{
servo1 = readString.substring(0, i);
//servo2 = readString.substring(x, x+9);
Serial.println(servo1);
//Serial.println(servo2);
float n = servo1.toFloat();
//n = servo2.toFloat();
if (n <= 1)
{
pos = (n * 1000) + 1000;
}
}
//readString = "";
This is what I tried until now.
If someone could help me, I really apreciate it
it is the most common habit of newbees to just post a part of their code.
In 95% of all cases the bug sits somewhere else than assumed.
So the bare minimum is to post your complete sketch. If you want to speed up solving your problem through getting good answers you add a description in normal words what your servos shall do.
Does "scenario" mean just rotate to a certain position?
or does "scenario" mean multiple servos must run down multiple speed-controlled movements in sync ?
We are talking about details. Please give an overview over your whole project.
in mimimum 70% of all cases knowing the whole thing offers completely different and much better working solutions.
This is like
Newbee: "I want to do better cutting please help me sharpening. "
Expert: Sure I can help you what cutting-tool are you using?
Newbee: a scissor.
Expert: OK take this sharpening tool
Newbee: Yea works great Next question How can I make it cut faster I need to finish faster.
expert: Motorised scissors.
newbee Yea works great though still not fast enough.
expert: Ok can you give an overview about what you are cutting.
newbee: the green of a football-arena.
expert: Oha! take a big mowing tractor with a seven boom spindel-mower and GPS-steering
In the beginning the newbee always just told details.
The expert was assuming the newbee knows that his basic approach is well suited.
which turns out to be very bad suited
that's the reason why it is always a good idea to give an overview and to explain what shall happen in the end.
If you choose a suitable format for the messages then you do not need to convert the received data. Take a look at Serial input basics - updated for ideas, including parsing the received string (lowercase s)
Using the data received in your example how does the Arduino know which servo to move, where to move it to and when it should be moved ? Please provide an interpretation of the data or better still change the format to make it more explicit. What would a typical scenario consist of ? Are you controlling a robot arm by any chance ?
the reason I thought about convert it to a String was because of the formula that I use here
You have that back to front. If you saved the data as a string (lowercase s) then you would not (could not) use those functions but other methods are available
Yes, you are right. I'll post the code, just the part needed because the rest is for other things other than the servos.
What this program is meant to do is, receive a scenario with various servo movements from 1 to 2ms, that's why those values from the data received. The timestamp for the servo movement is 20ms.
This is where i declare all the variables needed and the buffer for data received from the PC
Servo myservo;
String str, servo1, servo2;
char buffer[100]; //buffer for serial data receive from PC
bool scenario1 = false;
bool scenario2 = false;
bool scenario3 = false;
char line;
This is where I process the incoming data
void ReadDataPC (const byte inByte)
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
switch (inByte)
{
case '\n': // end of text
buffer [input_pos] = '\n'; // terminating null byte
// terminator reached! process input_line here ...
DataPC();
// reset buffer next time
input_pos = 0;
break;
case '\r': // discard carriage return
break;
default: // keep adding if not full ... allow terminating null byte
if (input_pos < (MAX_INPUT - 1))
buffer [input_pos++] = inByte;
break;
} // end of switch
} // end of processIncomingByte
void DataPC()
{
Serial.println(buffer[0]);
switch (buffer[0]) // premier case de data recu determine dans quelle cas de config on se trouve
{
case '0': //reception des trame configuration
configuration();
break;
case '1': // cas ou l'operateur n'a pas recu le premier sms on renvoye a nouveau
Send_msg(_message);
break;
case '2': //
config_gsm ();
break;
case '3': // cas ou la config gps a echoué on refait une tentative
config_gps ();
break;
case '4': //
config_servo ();
break;
case '5': // reception scenario1
scenario1 = true;
scenario();
break;
case '6': //reception scenario2
scenario2 = true;
break;
case '7': // reception scenario3
scenario3 = true;
break;
case '8': // start
Serial2.println( "STARTOK");
startOK = true;
Serial.println( "STARTOK");
start_enrg = true;
break;
case '9': // stop
Serial2.println( "STOP");
Serial.println( "STOP");
startOK = false;
compteur10 = 0;
start_enrg = false;
send_enrg = false;
break;
case 'A': // SI LE PC REPOND PRESENT IL PEU ENVOYER LES ENREGISTREMENTS
send_enrg = true;
Serial.println("RECU A");
break;
}
Here is where I go look in the buffer if the file is correctly stored and where I got stuck
void scenario() //lecture des scenarios
{
for (int y = scen_min; y < scen_max; y++)
{
if (buffer[y] != ' ');
line = buffer[y];
str += line;
Serial.print(line);
}
}
Here is where I try to make the servo move, right now I'm just trying with one servo
I suggest that you provide a complete example of the receipt and resulting action of servo commands so that we see exactly what you are doing and how. By all means leave out the parts of the code which do not deal with the servo but make sure that the code compiles
In the little snippets you insist on sending you have only one servo. It is never attached to a pin. 95% of the code in start_servo() is commented out so it's not surprising it doesn't do much. The bit that's left in is useless.
If you want help a complete, compilable program that demonstrates your problem would be useful. Anything else would not.
additional: what you call a "scenario" is simply a single RC-Servo-control-pulse which boils down to a single rectangular-pulse of lenghtes between 1,0 milliseconds and 2,0 milliseconds.
Where of course to keep a servo in position this rectangular pulse must be repeated every 20 milliseconds.
But that is done for you in the backround by the servo-library.
The pulse itself
1,0 milliseconds represents turn servo-horn to the min-position
1,5 milliseconds represents turn servo-horn to the middle-position
2,0 milliseconds represents turn servo-horn to the max-position
I recommend using the common words to be easier to understand.
Of course you can go on trying to "solve" your problem inside your fully code.
I don't recommend that. Modifying your complete code means there are a lot of places that can cause bugs
and you have to check through a lot of more things because you have to check all the combinations.
I recommend the opposite. Write a small testprogram that does nothing more than receiving your string
convert it to an integer representing microseconds and print out this value to the serial monitor.
If this works reliable make it a function "receiveMicroSecs" or whatever name you like.
Then add the function that hands over this value to put the servo in position.
Some people seem to prefer beeing hectical busy hopping around trying this trying that to slow down their progress in finishing their project.
This thread offers some additional things to learn:
expanding your own capabilities in changing your posting / working-style to the way you were asked for.
This is an expansion. Of course you can keep the way you have done it in the postings before.
This is just an offer: Of course you are still free to do whatever you want.
I would recommend replacing your String based code with my SafeString replacement library (from the Arduino library manager)
Lots of examples include with the library.
All the methods are non-blocking so they will not interfer with the rest of your loop. See a detailed tutorial here