Hello. I am new to Arduino and I have a problem with controlling it directly from my laptop. I am trying to change a value of variables using serialmonitor while running Arduino. What I managed to do so far is to send a command to the Arduino, but for some unknown reason the main loop is not running continuously; it only runs for a second when a signal is sent. This is my code so far. I would appreciate a lot if some one could direct me the right way please.
#include <Servo.h>
Servo servo_1;
Servo servo_2;
Servo servo_3;
//introducing variables
unsigned long serialdata;
int inbyte;
int VAnalog = 0;
int V = 3; // variable to control speed
int Ampl = 180; // variable to control aplitude
int PD = 0.1; // phase difference variable from 0 to 1
int Drown = 0;
int pos1_old = 0;
int Turn = 0;
int pos1 = 90;
int pos2 = 90;
int pos3 = 90;
void setup()
{
servo_1.attach(9, 800, 2200);
servo_2.attach(10, 800, 2200);
servo_3.attach(11, 800, 2200);
Serial.begin(9600);
}
void loop()
{
// VAnalog = analogRead(1);
// V = map(VAnalog, 0, 1023, 0, 7);
// {
getSerial();
switch(serialdata)
{
case 1:
{
//digital write
getSerial();
switch (serialdata)
{
case 1:
{
getSerial();
V = serialdata;
break;
}
}
}
}
float value = millis()/(V*400.0);
if(Drown == 0)
{
pos1 = 90.0+(Ampl/2)*sin((value+0.075)*PI);
servo_1.write(pos1);
pos2 = 90.0-(Ampl/2)*sin(value*PI);
servo_2.write(pos2);
}
if(Drown != 0)
{
pos1_old = 90.0+(Ampl/2)*sin(value*PI);
if(pos1_old < 90)
{
pos1 = 90.0+(Ampl/(2*Drown))*sin((value+0.075)*PI);
pos2 = 90.0-(Ampl/(2*Drown))*sin(value*PI);
}
else
{
pos1 = 90.0+(Ampl/2)*sin((value+0.075)*PI);
pos2 = 90.0-(Ampl/2)*sin(value*PI);
}
servo_1.write(pos1);
servo_2.write(pos2);
}
pos3 = 90.0+(Ampl/3)*sin(value*PI);
servo_3.write(pos3);
}
long getSerial()
{
serialdata = 0;
while (inbyte != '/')
{
inbyte = Serial.read();
if (inbyte > 0 && inbyte != '/')
{
serialdata = serialdata * 10 + inbyte - '0';
}
}
inbyte = 0;
return serialdata;
}
This part is blocking, meaning code execution will get stuck in this while loop until you receive a '/'.
Instead of using a blocking while loop, you should be using an if statement to see if there is any Serial data available. You would probably also want a "temoporary serialData" variable that is copied to serialData only after you receive the deliminating character.
Arrch thank you for the answer. I changed the while statement to if statement, and now the loop is running, however, I can't change the V variable with a serial monitor now. I think the problem lies in your second proposition, but I am not sure how to implement this?
You're still not checking if there is available data before reading from the serial port (Serial.available()). The psuedo code would look something like this:
if serial data available
read data
if data is deliminator
set serial variable to temp serial variable
set temp serial variable to 0
else
do arithemetic with temp serial variable
Alternatively, you can make it easier on yourself by using Serial.parseInt()
Servo test code that captures servo position commands sent from the serial monitor.
//zoomkat 11-22-12 simple delimited ',' string parse
//from serial port input (via serial monitor)
//and print result out serial port
//multi servos added
String readString;
#include <Servo.h>
Servo myservoa, myservob, myservoc, myservod; // create servo object to control a servo
void setup() {
Serial.begin(9600);
//myservoa.writeMicroseconds(1500); //set initial servo position if desired
myservoa.attach(6); //the pin for the servoa control
myservob.attach(7); //the pin for the servob control
myservoc.attach(8); //the pin for the servoc control
myservod.attach(9); //the pin for the servod control
Serial.println("multi-servo-delimit-test-dual-input-11-22-12"); // so I can keep track of what is loaded
}
void loop() {
//expect single strings like 700a, or 1500c, or 2000d,
//or like 30c, or 90a, or 180d,
//or combined like 30c,180b,70a,120d,
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
if (readString.length() >1) {
Serial.println(readString); //prints string to serial port out
int n = readString.toInt(); //convert readString into a number
// auto select appropriate value, copied from someone elses code.
if(n >= 500)
{
Serial.print("writing Microseconds: ");
Serial.println(n);
if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
if(readString.indexOf('c') >0) myservoc.writeMicroseconds(n);
if(readString.indexOf('d') >0) myservod.writeMicroseconds(n);
}
else
{
Serial.print("writing Angle: ");
Serial.println(n);
if(readString.indexOf('a') >0) myservoa.write(n);
if(readString.indexOf('b') >0) myservob.write(n);
if(readString.indexOf('c') >0) myservoc.write(n);
if(readString.indexOf('d') >0) myservod.write(n);
}
readString=""; //clears variable for new input
}
}
else {
readString += c; //makes the string readString
}
}
}
zoomkat thats awesome and seems like a possible solution for what Im trying to do getting in serial from vvvv. Im trying to get some very basic values in via vvvv and I have the option to intersperese or use whatever delimiter I need. Ive got some servo movement but its pretty jumpy..am i missing something to make this work correctly?
I attached the v4 file in case you happen to deal with it.