Problem using a GUI to run a motor

I am using controlP5 on processing to make a GUI that runs a dc motor on Arduino. I’m also using the Adafruit Motor Shield v2 to run the DC motor. The GUI asks for the velocity, time for the motor to run, and the direction and stores them in variables. When the start button is hit it is suppose to send the data to the Arduino. The problem is that the motor is not running. I put some println commands in the processing code to figure out where it stops but all the println commands work. I don’t know if it is a problem with the Arduino code or if it is not sending the data.

Processing Code

import processing.serial.*;
import controlP5.*;

Serial myPort;
ControlP5 cp5;
DropdownList serialPortsList;
Serial serialPort;
final int BAUD_RATE=9600;
ControlTimer c;
Textlabel t;
Textlabel txtlblwhichcom;
Textarea commTextarea;
ListBox commListbox;
Serial[] myPorts=new Serial[1];

int col=color(255);
int segment=4;
String val[];
long current;
long previous;
long timePassed;
String timeMillis;
PrintWriter output;
String photo;
String [] var=new String[4];
String vel;
String time="0";
int timeMeasure;
String dir;
String onOff="0";
int onOffMeasure;
String fileName;
String fileN;
String textValue="";
boolean firstContact=false;
RadioButton rb;

void setup(){
  myPort=new Serial(this, Serial.list()[3], 9600);
  myPort.bufferUntil('\n');
  size(700,500);
  PFont font=createFont("arial", 20);
  String[] portNames=Serial.list();
  cp5=new ControlP5(this);
  serialPortsList=cp5.addDropdownList("Serial ports").setPosition(10,10).setWidth(200);
  for(int i=0;i<portNames.length;i++) serialPortsList.addItem(portNames[i],i);
  
  c=new ControlTimer();
  t=new Textlabel(cp5,"--",100,100);
  c.setSpeedOfTime(1);
  
  cp5.addCheckBox("checkBox")
    .setPosition(250, 330)
    //.setColorBackground(color(255,13,227))
    .setColorForeground(color(120))
    .setColorActive(color(255))
    .setColorLabel(color(255))
    .setSize(40, 40)
    .setItemsPerRow(3)
    .setSpacingColumn(100)
    .setSpacingRow(20)
    .addItem("Photogate 1", 0)
    .addItem("Photogate 2", 50);
  
  cp5.addTextfield("Belt Velocity (mm/s)")
     .setPosition(20,90)
     .setSize(200,40)
     .setFont(font)
     .setFocus(true)
     .setColor(color(255,0,0))
     ;
   
  cp5.addTextfield("Run Time (s)")
     .setPosition(20,160)
     .setSize(200,40)
     .setFont(font)
     .setFocus(false)
     .setColor(color(255,0,0))
     ;
      
  cp5.addTextfield("Text File Name")
     .setPosition(20,230)
     .setSize(200,40)
     .setFont(font)
     .setFocus(false)
     .setColor(color(255,0,0))
     ;           
     
  cp5.addButton("Enter")
     .setValue(0)
     .setPosition(240,90)
     .setSize(80,40)
     .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER)
     ;
   
 cp5.addButton("ENTER")
     .setValue(0)
     .setPosition(240,160)
     .setSize(80,40)
     .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER)
     ;
     
 cp5.addButton("EnteR")
     .setValue(0)
     .setPosition(240,230)
     .setSize(80,40)
     .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER)
     ;    
     
  cp5.addButton("Start")
     .setValue(0)
     .setPosition(120,410)
     .setSize(80,40)
     .setColorBackground(color(9,158,12))
     .setColorLabel(color(0,0,0))
     .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER)
     ;
     
  cp5.addButton("Stop")
     .setValue(0)
     .setPosition(480,410)
     .setSize(80,40)
     .setColorBackground(color(168,8,8))
     .setColorLabel(color(0,0,0))
     .getCaptionLabel().align(ControlP5.CENTER, ControlP5.CENTER)
     ;
     
  rb = cp5.addRadioButton("radioButton")
         .setPosition(480,100)
         .setSize(90,40)
         .setColorForeground(color(120))
         .setColorActive(color(255))
         .setColorLabel(color(255))
         .setItemsPerRow(1)
         .setSpacingColumn(50)
         .addItem("Clockwise",1)
         .addItem("Counter-ClockWise",2)
         ;
  textFont(font);
}

void draw(){
  current=millis();
  background(0);
  fill(255);
  t.setValue(c.toString());
  t.draw(this);
  t.setPosition(480,50);
  
  if(segment==0){
    var[0]=vel;
    var[1]=time;
    var[2]=dir;
    var[3]=onOff;
    timeMeasure=Integer.parseInt(time);
    onOffMeasure=Integer.parseInt(time);
    println("segment 1 end");
    segment=1;
  }
  else if(segment==1){
    for(int x=0;x<4;x++){
      myPort.write(var[x]);
      print("sent ");
      println(var[x]);
    }
    
    segment=2;
    previous=current;
    output=createWriter(fileName);
    println("wrote file");
  }
  else if(segment==2){
    if(myPort.available()>0){
      photo=myPort.readStringUntil('\n');
      output.print(photo);
      timePassed=current-previous;
      timeMillis=str(timePassed);
      output.println(timeMillis);
    }
    
    if((current-previous)>=(timeMeasure*1000)){
      segment=3;
      onOff="0";
      println("segment 2 finished");
    }
  }
  else if(segment==3){
    var[0]="0";
    var[1]="0";
    var[2]="0";
    var[3]=onOff;
    
    for(int x=0;x<4;x++){
      myPort.write(var[x]);
    }
    
    output.flush();
    output.close();
    
    segment=4;
    println("segment 3 finished");
  }
  else{
    segment=4;
    //println("fish");
  }
}

public void Enter(){
  vel=cp5.get(Textfield.class,"Belt Velocity (mm/s)").getText();
  println("Got Velocity");
}

public void ENTER(){
  time=cp5.get(Textfield.class,"Run Time (s)").getText();
  println("Got Time");
}

public void EnteR(){
  fileN=cp5.get(Textfield.class,"Text File Name").getText();
  fileName=fileN+".txt";
  println("Got filename");
}

void radioButton(int a) {
  dir=str(a);
  println("a radio Button event: "+a);
}

public void Start(){
  /*if(mousePressed){
    segment=0;
    println("Mouse Working");
  }*/
  if(current>100){
    println("if statement Working");
    segment=0;
    onOff="1";
  }
}

public void Stop(){
  if(current>100){
    segment=3;
    onOff="0";
 }
 
 
}

void controlEvent(ControlEvent theEvent){
  if(theEvent.isGroup()){
    if(serialPort !=null){
      serialPort.stop();
      serialPort=null;
    }
    
    String portName=serialPortsList.getItem((int)theEvent.getValue()).getName();
    try{
      serialPort=new Serial(this,portName,BAUD_RATE);
    }
    catch(Exception e){
    }
  }
}

Arduino code

#include <Wire.h>
#include <stdlib.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS=Adafruit_MotorShield();

Adafruit_DCMotor *myMotor=AFMS.getMotor(3);

unsigned long Timems=0;
unsigned long Timeus=0;
int Photogate1=HIGH;
int Photogate2=HIGH;
int PhotogatePin1=10;
int PhotogatePin2=12;
int motorPin=3;
float onOff=0;
float var[4];
int index=0;
float volt;
float direct;
long previous;
float vel;
float time;

void setup(){
  Serial.begin(9600);
  AFMS.begin();
  pinMode(motorPin, OUTPUT);
}

void loop(){
  unsigned long current=millis();
  
  if(onOff==0){
     if (Serial.available()){
       float incomingValue=Serial.parseFloat();
       var[index]=incomingValue;
       index++;
     }
     
     if(var[3]==1){
       onOff=var[3];
       previous=current;
     }
  }
  else if(onOff==1){
    vel=var[0];
    time=var[1]*1000;
    direct=var[2];
    volt=vel;
    index=0;
    
    if(direct==1){
      myMotor->run(FORWARD);
    }
    if(direct==2){
      myMotor->run(BACKWARD);
    }
    
    onOff=2;
  }
  else if(onOff==2){
    myMotor->setSpeed(volt);
  
  /*  Photogate1=digitalRead(PhotogatePin1);
    Photogate2=digitalRead(PhotogatePin2);
    
    if(Photogate1==LOW){
      Timems=millis();
      Timeus=micros();
      
      Serial.println("Photogate 1");
      
      delay(100);
    }
    else if(Photogate2==LOW){
      Timems=millis();
      Timeus=micros();
      
      Serial.println("Photogate 2");
      
      delay(100);
    }
    else{
      digitalWrite(Photogate1, HIGH);
      digitalWrite(Photogate2, HIGH);
    }
  }   */
    if(Serial.available()){
      float incomingValue=Serial.parseFloat();
      var[index]=incomingValue;
      index++;
    }
    
    if(var[3]==0){
      onOff=3;
    }
  }
  else{
    vel=var[0];
    time=var[1]*1000;
    direct=var[2];
    onOff=var[3];
    volt=vel;
    index=0;
  }
}

The problem could be anywhere, including the motor, the motor driver and the motor power supply, the connections to the Arduino, the program ...

Forget the GUI and start with the simplest possible Arduino program that is supposed to work, and let us know what happens.

I had already tried out all the things separately and they all work. Anyway I think I found the problem since the motor started moving. It was the Serial.parseFloat() from the Arduino code. Instead of reading each piece of information coming in separately, it read all the data coming in and put it into var[0]. To solve this problem all I had to do was send data from processing in the following form: x100x25y42x. By having the letters there the parseFloat broke it up into four pieces of data. For example o the Processing code I had var[0]="x"+vel and var[1]="y"+time.

I suspect you need a more reliable and robust arrangement for receiving the data from the PC. For example there is no way for the Arduino to know which value it is receiving.

Have a look at the examples in serial input basics. The best thing would be if you could modify the Processing code to suit the third example. You could send <128,7560,F> to mean half-speed for 7560 millisecs and Forward.

These examples are simple, reliable and non-blocking (unlike parseFloat() ) and they read in all the data before trying to do anything with it.

There is also a parse example that shows how the recived data can be assigned to variables

…R