Step Motor Control

395 views
Skip to first unread message

Synn Yong Tan

unread,
Jan 21, 2014, 10:33:24 PM1/21/14
to ioio-...@googlegroups.com
Hi,
I'm trying to do control on step motor. 
My app didn't working but i cannot find out where is the problem.
Can please help me to see the code?

package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.ToggleButton;




public class IOIOSimpleApp extends IOIOActivity {
private ToggleButton toggleButton_;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
toggleButton_ = (ToggleButton) findViewById(R.id.ToggleButton);

}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_, stepperStepCue_ };

private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4));
final ChannelConfig[] config = new ChannelConfig[] {  stepperDirConfig,
stepperStepConfig };

sequencer_ = ioio_.openSequencer(config);

push();
sequencer_.start();
}


@Override
public void loop() throws ConnectionLostException, InterruptedException {
push();
}

private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.pulseWidth = 2;
stepperStepCue_.period = 400;

boolean on = (toggleButton_.isChecked());
if (on) {
 
stepperDirCue_.value = true;
 
   } else {
    stepperDirCue_.value = false;
   }
sequencer_.push(cue_, 62500 / 2);
}
}

@Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
}

Ytai Ben-Tsvi

unread,
Jan 22, 2014, 1:16:05 AM1/22/14
to ioio-...@googlegroups.com
Hi Synn,
I'm happy you're making a brave attempt to use the new library!

I think you forgot to set stepperDirCue_.clk, not sure if this is the only problem.

A few suggestions that can hopefully make your work more effective:
  1. When you ask a question, please provide more information on what is not working. Just saying that the program is not working makes it very hard to help you.
  2. If your program crashes, and in some other cases too, the logcat output (open the Logcat view in Eclipse or type adb logcat in the command shell) might have useful information to help you figure out what's wrong. Use it.
  3. You can add your own log messages in your code, to help you figure out what it's doing, where it's stuck, etc.
  4. You can use step-by-step debugging for even deeper understanding of what's going on.
  5. Try to simplify your program as much as possible for isolating a problem. The program that you sent is a very good example for that!
  6. Try to isolate electrical issues from software issues using an oscilloscope or a logic analyzer if you have them, or otherwise by testing your program against known-good peripherals (for example, replace motor drivers with LEDs, or first check your electronics manually).


--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+...@googlegroups.com.
To post to this group, send email to ioio-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/groups/opt_out.

Synn Yong Tan

unread,
Jan 22, 2014, 1:34:54 AM1/22/14
to ioio-...@googlegroups.com
Hi, Ytai..
Sorry because i not really get the command you meant..
You meant stepperStepCue.clk  or  stepperDirCue_.clk? 
Actually the app is successfully built. But after i connect everything together, the motor is not even rotating.
By the way, the output signal voltage is only 3.3v, right? I have to use the open-drain mode so that i can send 5v output signal.. is that right? 


--
You received this message because you are subscribed to a topic in the Google Groups "ioio-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ioio-users/jxhTI2gAhMk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ioio-users+...@googlegroups.com.

Ytai Ben-Tsvi

unread,
Jan 22, 2014, 3:14:25 AM1/22/14
to ioio-...@googlegroups.com

Please read my last email again

Synn Yong Tan

unread,
Jan 23, 2014, 4:10:16 AM1/23/14
to ioio-...@googlegroups.com
HI, Ytai. I tried my app with oscilloscope. The dir pin is able to work when i connect it to a led and also tried it with oscilloscope.
The problem is there is no pulse output from the step pin after i connected it to oscilloscope. I tried to look over the code but i can't find out where is the problem. 


package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;
import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.ToggleButton;




public class IOIOSimpleApp extends IOIOActivity {
private ToggleButton toggleButton_;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
toggleButton_ = (ToggleButton) findViewById(R.id.ToggleButton);

}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_ , stepperStepCue_ };

private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] {  stepperDirConfig, stepperStepConfig 
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
while (sequencer_.available() > 0) {
push();
}


sequencer_.start();
}



@Override
public void loop() throws ConnectionLostException, InterruptedException {
push();
}

private void push() throws ConnectionLostException, InterruptedException  {
if (toggleButton_.isChecked()) {
 
stepperDirCue_.value = true;
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 2;
stepperStepCue_.period = 400;

 
   } else {
    stepperDirCue_.value = false;
    stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 2;
stepperStepCue_.period = 400;
   }
sequencer_.push(cue_, 62500 / 200);

Ytai Ben-Tsvi

unread,
Jan 23, 2014, 12:30:47 PM1/23/14
to ioio-...@googlegroups.com

Do you have a pull-up attached? Do you actually need open drain? At least for testing purposes I would start with push-pull (aka "normal") mode.

Synn Yong Tan

unread,
Jan 23, 2014, 10:33:52 PM1/23/14
to ioio-...@googlegroups.com
Ya, I need that. My motor drive required 5V input pulse voltage. I actually tried the normal mode. Only the dir pin only to send signal. I tried this by using LED.

Ytai Ben-Tsvi

unread,
Jan 24, 2014, 11:50:36 AM1/24/14
to ioio-...@googlegroups.com
I wouldn't expect you to see anything with an LED on the step channel (duty cycle is 0.5%). I didn't understand from you whether you actually looked at this signal with an oscilloscope after changing it to push-pull.
BTW, which motor driver are you using? Do you have a datasheet?

Synn Yong Tan

unread,
Jan 30, 2014, 12:03:18 PM1/30/14
to ioio-...@googlegroups.com
I'm using Oriental Motor CMD2120P. Yea, i gt the user manual.

Ytai Ben-Tsvi

unread,
Jan 30, 2014, 12:17:58 PM1/30/14
to ioio-...@googlegroups.com
I meant, can you share the datasheet?
Also, can you send me a picture of your setup including the oscilloscope you're using to probe the output?

Synn Yong Tan

unread,
Feb 8, 2014, 1:06:44 AM2/8/14
to ioio-...@googlegroups.com
Inline image 1
The figure above is my connection of IOIO board to the motor. I able to control the direction of the motor. For the rotation of motor, i suspect my pulse width is not wide enough for the motor. So, i plan to set a higher pulse width and see what is the result. 
By the way, how should i set the command code if i want the motor to rotate specific angle?
For example to rotate 30 degree clockwise.
The attached file is the user manual of motor driver.
1898012_10203035290549029_1026359086_n.jpg
High-Torque 2-Phase Stepping Motor Unit CSK Series.pdf

Ytai Ben-Tsvi

unread,
Feb 8, 2014, 1:39:19 AM2/8/14
to ioio-...@googlegroups.com
  1. You're not connecting this right. The "+" connection from each signal on the driver needs to go to 5V and the "-" to the IOIO pin (make sure you're using 5V tolerant pins in open drain mode).
  2. Make sure the pulses you're generating are at least 5us long with at least 5us between pulses.
  3. You can't know the absolute angle with a stepper (unless you add an encoder or some other kind of position feedback). You can know the angle relative to the angle you started at by counting pulses and by looking at the motor data sheet that should tell you how many steps / revolution or degrees / step it moves. Then you need to take any gearing ratio into account (in case this is not direct drive) and also the driver might do "micro-stepping" to increase resolution, which your driver doesn't seem to.
  4. BTW, strange choice for a driver. There are cheap drivers nowadays with much better specs than this one, the size of your fingernail that only cost a few dollars (e.g. http://www.pololu.com/product/2133 note that this one is for a bipolar stepper, which may or may not be compatible with the one you have).
1898012_10203035290549029_1026359086_n.jpg

Synn Yong Tan

unread,
Feb 8, 2014, 10:22:51 AM2/8/14
to ioio-...@googlegroups.com
1)I not really get you for the connection part. The "-" connect to IOIO pin, is it connect to IOIO pin 3 and 4 or to the ground pin of IOIO board?
2)Ya, i will have a absolute encoder for it later. But i meant if i want to the stepper motor to rotate 36 degree, how it can be done for the coding?
For example, if the stepper motor rotate 1.8 degree per step, then we can set the motor to rotate 36 degree by sending 20steps/pulse. 
Can it be done like this ?
1898012_10203035290549029_1026359086_n.jpg

Synn Yong Tan

unread,
Feb 8, 2014, 10:44:31 AM2/8/14
to ioio-...@googlegroups.com
1)I not really get you for the connection part. The "-" connect to IOIO pin, is it connect to IOIO pin 3 and 4 or to the ground pin of IOIO board?
2)Ya, i will have a absolute encoder for it later. But i meant if i want to the stepper motor to rotate 36 degree, how it can be done for the coding?
For example, if the stepper motor rotate 1.8 degree per step, so the motor requires 20 steps to rotate 36 degrees. 
As i know, 1 step is equal to 1 pulse. So we just send 20 pulses to the motor to rotate 36 degrees.
Can it be done like this ?
1898012_10203035290549029_1026359086_n.jpg

Ytai Ben-Tsvi

unread,
Feb 8, 2014, 11:26:54 AM2/8/14
to ioio-...@googlegroups.com
  1. The "+" to 5V and the "-" to the I/O pin (e.g. 3 or 4) in open-drain mode.
  2. I advise you to turn microstepping on for smoother motion. This motor driver has half-stepping, so if you enable it you need 40 steps. Let's say you want to do this motion within 1 second, so you need a 25ms period. To summarize, this will translate into one cue, of duration 62500 (1 second), where the steps channel has its clock set at 2MHz, its period set at 50000 (= 25ms) and its pulse width set at 10 (= 5us) or a little more.
  3. Please read the motor control wiki page for more details.
1898012_10203035290549029_1026359086_n.jpg

Synn Yong Tan

unread,
Feb 11, 2014, 3:53:32 AM2/11/14
to ioio-...@googlegroups.com
Inline image 1
Hi,Ytai..The figure above is my new connection. Is that correct ?
I tested my motor again. But there is only sound from the motor when i connected everything and open the app, but the motor is not rotating. My suspect is the input voltage signal is not sufficient for the driver, or my connection is wrong again. However, whats the possible reason for this is happening?

Synn Yong Tan

unread,
Feb 11, 2014, 7:13:25 AM2/11/14
to ioio-...@googlegroups.com
I found out my connection was wrong. I will try again to find out whether the motor works or not.

Synn Yong Tan

unread,
Feb 13, 2014, 4:20:40 AM2/13/14
to ioio-...@googlegroups.com
I set my code as below to rotate the motor 90 degrees. But why the motor just keep rotating instead of rotate 90 degrees and then stop.

false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] {  stepperDirConfig, stepperStepConfig 
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
while (sequencer_.available() > 0) {
push();
}


sequencer_.start();
}



@Override
public void loop() throws ConnectionLostException, InterruptedException {
push();
}

private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 10;
stepperStepCue_.period = 10000;
if (toggleButton_.isChecked()) {
 
stepperDirCue_.value = true;
 
   } else {
    stepperDirCue_.value = false;
   }
sequencer_.push(cue_, 62500);

Synn Yong Tan

unread,
Feb 13, 2014, 10:10:09 AM2/13/14
to ioio-...@googlegroups.com
as 100steps is required to turn 90 degrees.
I set it to rotate 90 degree in 1second with pulsewidth=10 and period = 10000.

Ytai Ben-Tsvi

unread,
Feb 13, 2014, 11:43:02 AM2/13/14
to ioio-...@googlegroups.com
Your cue is correct.
You're pushing it over and over - that's why you're getting continuous motion.

Synn Yong Tan

unread,
Feb 13, 2014, 1:15:15 PM2/13/14
to ioio-...@googlegroups.com
In order to push the cue just once, i added the numCanPush_=sequencer_.available(); into the code. 
Is this means it just push one time ?
The full code is at below.
int numCanPush_= 1 ;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] {  stepperDirConfig, stepperStepConfig 
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
while (sequencer_.available() > 0) {
push();
}


sequencer_.start();
}



@Override
public void loop() throws ConnectionLostException, InterruptedException {
push();
}

private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 10;
stepperStepCue_.period = 10000;
if (toggleButton_.isChecked()) {
 
stepperDirCue_.value = true;
 
   } else {
    stepperDirCue_.value = false;
   }
sequencer_.push(cue_, 62500);
numCanPush_ = sequencer_.available();

Ytai Ben-Tsvi

unread,
Feb 13, 2014, 8:10:33 PM2/13/14
to ioio-...@googlegroups.com
Why would you do that?
I would get rid of this numCanPush thing and simply call push() once from setup() and never from loop().

Synn Yong Tan

unread,
Feb 17, 2014, 7:28:24 AM2/17/14
to ioio-...@googlegroups.com
Because i need to rotate my motor to different angle due to different condition instead of just rotate once.
By the way, i tried to rotate my motor 360 degrees by set the pulsewidth=500 , period = 5000 and  clock set at 2MHz,
 cue duration = 62500. 
*Steps required to rotate 360 degrees is 400 steps, one step is equal to 0.9 degree.
The motor didn't rotate 360 degrees after i tried. Just to confirm if the setting correct ? or there is something wrong with my motor.

Ytai Ben-Tsvi

unread,
Feb 17, 2014, 3:59:26 PM2/17/14
to ioio-...@googlegroups.com
Your calculations seem correct.
Every time you push a cue, the motor will move by that amount. If you keep pushing the motor will never stop turning. If you want it to only turn when a certain condition is met, only push when the condition is met, or otherwise push a "no-op" cue, i.e. a cue with pulse-width=0.

Synn Yong Tan

unread,
Feb 18, 2014, 8:47:55 AM2/18/14
to ioio-...@googlegroups.com
Hi,Ytai. Here is another problem. The cue should run in the specified cue duration and then stop,right? 
If i set sequencer_.push(cue_, 62500), the rotation of motor should done in 1s,right?
In my case, the rotation of motor took more than that to complete the cue and also didn't rotate according to the angle that was set.

Ytai Ben-Tsvi

unread,
Feb 18, 2014, 11:36:55 AM2/18/14
to ioio-...@googlegroups.com
It is possible that your motor is skipping steps. More voltage / current might help, or simply go a little slower.

Synn Yong Tan

unread,
Feb 19, 2014, 4:13:33 AM2/19/14
to ioio-...@googlegroups.com
Hi,Ytai. I measured the output pulse with oscilloscope, it took exactly the same time to finish the run as the motor fin the rotation. It took about 33seconds. Also the rotation amount is not accurate as well.
But i set my cue duration = 62500 only. Can you help me to see my code whether is there anyplace wrong or my IOIO board problem?
Below is my code. 
package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;
import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.ToggleButton;



public class IOIOSimpleApp extends IOIOActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_, stepperStepCue_ };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] { stepperDirConfig, stepperStepConfig 
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
while (sequencer_.available() > 0) {
push();
}
sequencer_.start();
}
public void loop() throws ConnectionLostException, InterruptedException {
}

private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 5000;
stepperDirCue_.value = true;

Ytai Ben-Tsvi

unread,
Feb 19, 2014, 10:35:09 AM2/19/14
to ioio-...@googlegroups.com

You're push()ing from inside a while loop that repeats 32 times.

Synn Yong Tan

unread,
Feb 19, 2014, 12:11:13 PM2/19/14
to ioio-...@googlegroups.com
How should i modify it ? Is this method correct?
I set the queue size by using this command = > sequencer.setEventQueueSize(newSize);

Ytai Ben-Tsvi

unread,
Feb 19, 2014, 2:22:46 PM2/19/14
to ioio-...@googlegroups.com
I'm sorry, I don't think we'll get very far this way, since my time is very limited.
I strongly recommend you to learn some Java. Here is a great source:

Synn Yong Tan

unread,
Feb 26, 2014, 7:55:05 AM2/26/14
to ioio-...@googlegroups.com
Hi, Ytai. Thanks for your help and the tutorial link given. My app is working now. However, i added another stepper motor and modified the code again. The app is not working now. I tested with oscilloscope, there is no pulse output from 3 of the stepperstepcue pin.
I tried to troubleshoot from logcat but still no solution.
Below is my coding.


package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.Button;
import android.widget.EditText;
import android.view.View;
import android.view.View.OnClickListener;


public class IOIOSimpleApp extends IOIOActivity  {


private Button button;
private Button button1;
private Button button2;
private Button button3;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepperStepACue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepperStepBCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_,stepperStepCue_, stepperStepACue_,stepperStepBCue_  };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepAConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepBConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(11,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] { stepperDirConfig, stepperStepConfig,stepperStepAConfig,stepperStepBConfig,
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();
clockwiseOnButton() ;
anticlockwiseOnButton();
cwiseOnButton();
ccwiseOnButton();

}
public void loop() throws ConnectionLostException, InterruptedException {}
public void clockwiseOnButton() {
 
button = (Button) findViewById(R.id.button1);
 
button.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
final EditText angle = (EditText) findViewById(R.id.editText1);
int degrees = Integer.parseInt(angle.getText().toString());
degrees = 0;
while (degrees> 0) {
        push();
        degrees--;
       }
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void anticlockwiseOnButton() {
 
button1 = (Button) findViewById(R.id.button2);
 
button1.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
final EditText angle1 = (EditText) findViewById(R.id.editText2);
int degrees1 = Integer.parseInt(angle1.getText().toString());
degrees1 = 0;
while (degrees1> 0) {
     push1();
     degrees1--;
}
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void  cwiseOnButton() {
 
button2 = (Button) findViewById(R.id.button3);
 
button2.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
final EditText angle3 = (EditText) findViewById(R.id.editText3);
int numtopush3  = Integer.parseInt(angle3.getText().toString());
numtopush3 = 0;
while (numtopush3> 0) {
     push2();
     numtopush3--;
       }
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void ccwiseOnButton()  {
 
button3 = (Button) findViewById(R.id.button4);
button3.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
try {
final EditText angle4 = (EditText) findViewById(R.id.editText4);
int numtopush4  = Integer.parseInt(angle4.getText().toString());
numtopush4 = 0;
while (numtopush4> 0) {
     push3();
     numtopush4--;
       }
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 3571;
stepperDirCue_.value = true;

sequencer_.push(cue_, 62500/20);
}
private void push1() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period =3571;
stepperDirCue_.value = false;

sequencer_.push(cue_, 62500/20);
}
private void push2() throws ConnectionLostException, InterruptedException  {
stepperStepACue_.clk = Clock.CLK_2M;
stepperStepACue_.pulseWidth = 300;
stepperStepACue_.period = 5000;

sequencer_.push(cue_, 62500/20);
}
private void push3() throws ConnectionLostException, InterruptedException  {
stepperStepBCue_.clk = Clock.CLK_2M;
stepperStepBCue_.pulseWidth = 300;
stepperStepBCue_.period = 5000;

sequencer_.push(cue_, 62500/20);

Ytai Ben-Tsvi

unread,
Feb 26, 2014, 11:42:55 AM2/26/14
to ioio-...@googlegroups.com
From your code:

degrees = 0;
while (degrees> 0) {
  push();
  degrees--;
}

The body of the while never actually runs...

Synn Yong Tan

unread,
Feb 26, 2014, 11:43:40 PM2/26/14
to ioio-...@googlegroups.com
Hm..i deleted the mistake i made. But now the app is stopped.I actually just modified the code which works for one step motor by adding the coding for the 2nd stepper motor,but after that, when i clicked any one of the four buttons, the app is stopped. And the app only stopped when i connected my phone to IOIO board. 
One question to ask as well, because i'm using 3 pins for open drain mode(5V), will the power supply matter ? I use 10V power supply for it.

Ytai Ben-Tsvi

unread,
Feb 27, 2014, 1:03:37 AM2/27/14
to ioio-...@googlegroups.com
You'd need to debug your app. It is hard do it over email. Use a debugger or Log messages to figure out what's wrong.
As for the electrical question, I'm not sure I understand what you're asking exactly: where are you supplying 5V and where are you supplying 10V?

Synn Yong Tan

unread,
Feb 27, 2014, 1:47:26 AM2/27/14
to ioio-...@googlegroups.com
Ok. But the app only stopped when i connected to IOIO board and click on any four of the buttons, so will there be a possibility that the problem is on hardware? because when i didnt connect to IOIO, the buttons can be clicked without crashed.

I use 10V power supply for IOIO and i used 3pins in open drain mode. Is this ok ?

Ytai Ben-Tsvi

unread,
Feb 27, 2014, 11:41:11 AM2/27/14
to ioio-...@googlegroups.com
All your setup() and loop() code only start running when the IOIO is connected, so if you have a bug there it will show up as soon as you connect the IOIO.

There is no problem with a 10V supply or with using the pins in open-drain, as long as you don't expose them to more voltage they are rated for, which is 5V for "5V-tolerant" pins and 3.3V for others.

Synn Yong Tan

unread,
Feb 27, 2014, 11:54:18 AM2/27/14
to ioio-...@googlegroups.com
But i already tried to look over the code and use logcat to debug it..I cant find any reason which make my app stopped when i connected to IOIO and click on the buttons. The weird thing is the problem only occur when i established the connection and click on any four of those buttons, else it is ok in the virtual device or my phone as long as i didnt connect it to IOIO and click those buttons.
OK.Noted. 

Ytai Ben-Tsvi

unread,
Feb 27, 2014, 11:57:24 AM2/27/14
to ioio-...@googlegroups.com
That means that the bug is probably inside the onClick handler.
Are you sure you actually fixed the bug I told you about? What does your fix look like?

Synn Yong Tan

unread,
Feb 27, 2014, 12:06:15 PM2/27/14
to ioio-...@googlegroups.com
yes. I removed those lines. 

package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;


import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.Button;
import android.widget.EditText;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;



public class IOIOSimpleApp extends IOIOActivity  {


private Button button;
private Button button1;
private Button button2;
private Button button3;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button1);
button1 = (Button) findViewById(R.id.button2);
button2 = (Button) findViewById(R.id.button3);
button3 = (Button) findViewById(R.id.button4);
 
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepperStepACue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepperStepBCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperStepACue_,stepperStepBCue_  };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepAConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepBConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(11,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] {stepperDirConfig, stepperStepConfig, stepperStepAConfig, stepperStepBConfig,
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();

sequencer_.start();
clockwiseOnButton();
anticlockwiseOnButton();
cwiseOnButton();
ccwiseOnButton();
 
}
public void loop() throws ConnectionLostException, InterruptedException {
}
public void clockwiseOnButton() {
button.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
Log.d("MotorControl", "check1");
 try {
final EditText angle = (EditText) findViewById(R.id.editText1);
Log.d("MotorControl", "check2");
int degrees = Integer.parseInt(angle.getText().toString());
Log.d("MotorControl", "check3");
while (degrees> 0) {
Log.d("MotorControl", "check4");
        push();
        Log.d("MotorControl", "check5");
        degrees--;
        Log.d("MotorControl", "check6");
       }
} catch (ConnectionLostException e) {
Log.d("MotorControl", "check7");
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("MotorControl", "check8");
} catch (InterruptedException e) {
Log.d("MotorControl", "check9");
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("MotorControl", "check10");
}
}
 
});
 
}
public void anticlockwiseOnButton() {
button1.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
final EditText angle1 = (EditText) findViewById(R.id.editText2);
int degrees1 = Integer.parseInt(angle1.getText().toString());
while (degrees1> 0) {
     push1();
     degrees1--;
}
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void  cwiseOnButton() {
button2.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View v) {
 
 try {
final EditText angle3 = (EditText) findViewById(R.id.editText3);
int numtopush3  = Integer.parseInt(angle3.getText().toString());
while (numtopush3> 0) {
     push2();
     numtopush3--;
       }
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void ccwiseOnButton()  {
button3.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View v) {
 
try {
final EditText angle4 = (EditText) findViewById(R.id.editText4);
int numtopush4  = Integer.parseInt(angle4.getText().toString());

Synn Yong Tan

unread,
Feb 27, 2014, 1:05:14 PM2/27/14
to ioio-...@googlegroups.com
Hey.Ytai. Sorry..this is the code. The previous one missed out {stepperDirCue_,stepperStepCue_,} in Sequencer.ChannelCue[] .

import ioio.lib.api.DigitalOutput;


import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.Button;
import android.widget.EditText;
import android.view.View;
import android.view.View.OnClickListener;



public class IOIOSimpleApp extends IOIOActivity  {


private Button button1;
private Button button2;
private Button button3;
private Button button4;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1= (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button4 = (Button) findViewById(R.id.button4);
 
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepperStepACue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepperStepBCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_,stepperStepCue_, stepperStepACue_,stepperStepBCue_  };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepAConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepperStepBConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(11,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] {stepperDirConfig, stepperStepConfig, stepperStepAConfig, stepperStepBConfig,
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();

sequencer_.start();
clockwiseOnButton();
anticlockwiseOnButton();
cwiseOnButton();
ccwiseOnButton();
 
}
public void loop() throws ConnectionLostException, InterruptedException {}
public void clockwiseOnButton() {
button1.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
try {
final EditText angle = (EditText) findViewById(R.id.editText1);
int degrees = Integer.parseInt(angle.getText().toString());
while (degrees> 0) {
        push();
       
        degrees--;
       
       }
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void anticlockwiseOnButton() {
button2.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
final EditText angle1 = (EditText) findViewById(R.id.editText2);
int degrees1 = Integer.parseInt(angle1.getText().toString());
while (degrees1> 0) {
     push1();
     degrees1--;
}
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void  cwiseOnButton() {
button3.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View v) {
 
 try {
final EditText angle3 = (EditText) findViewById(R.id.editText3);
int numtopush3  = Integer.parseInt(angle3.getText().toString());
while (numtopush3> 0) {
     push2();
     numtopush3--;
       }
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void ccwiseOnButton()  {
button4.setOnClickListener(new OnClickListener() {

Ytai Ben-Tsvi

unread,
Feb 27, 2014, 1:17:18 PM2/27/14
to ioio-...@googlegroups.com
What happens when you try to input 1 degree?
From what I'm seeing, the number of push() operations you're doing is the number of degrees you want to turn which makes no sense. It would also be hanging the main thread of your app if you use large numbers there, which would likely lead to an "application not responding" event.

Synn Yong Tan

unread,
Feb 27, 2014, 1:23:10 PM2/27/14
to ioio-...@googlegroups.com
For the app with only one step motor control, it is able to work, i didn't try on 1 degree but i did tried for 90, 180..it works. 
However, for the two step motors control, i not able to control the actuation of the motors anymore even for the 1st motor is works previously.

Synn Yong Tan

unread,
Feb 27, 2014, 7:22:34 PM2/27/14
to ioio-...@googlegroups.com
Why the method is no make sense? if that is the case, is there other way to do so ?
Is it my method is wrong which lead to the app not able to control the actuation of motors ?

Synn Yong Tan

unread,
Feb 27, 2014, 9:35:14 PM2/27/14
to ioio-...@googlegroups.com
Hi,Ytai. Here is my new finding. I realize that the app only stop when there is more than one channelcuesteps are used. I tried pin by pin. Everyone of them works when there is only one channelcuestep but when there is two channelcuesteps, the app stopped when i conencted to IOIO and click the buttons.

Ytai Ben-Tsvi

unread,
Mar 1, 2014, 4:41:04 PM3/1/14
to ioio-...@googlegroups.com
What I would do is:
  1. First verify that it is not an electrical issue. This is easy: simply swap the control pins between the two motors and see whether it is the same motor that is not working or a different one.
  2. Make a backup of your current app, start stripping the code to a minimum which still demonstrates the problem. In other words, try to find the simplest app which still has the "wrong" behavior. It is very likely that in this process you'll figure out something that you've done wrong in the code. Otherwise, post this simple app on this thread.

Synn Yong Tan

unread,
Mar 2, 2014, 12:03:00 AM3/2/14
to ioio-...@googlegroups.com
Yes. I already tried separate into 3 app for each of the motors. Every app is able send the command to the motor and actuate the motor.
Ya. I tried this method for debugging as well. So, here is what i found out, when i put all channelcues into cue_ , and I connected to IOIO and run the app, the app is stopped when a button is clicked.
The coding is as below, which i already simplified to find the problem. The app is stopped when i insert 2 new channelcuesteps into cue_(i highlighted the line). It seems like i cannot use more than 1 channelcuestep.

package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;


public class IOIOSimpleApp extends IOIOActivity {

private Button button;
private Button button1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepper1StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepper2StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_, stepperStepCue_,stepper1StepCue_ ,stepper2StepCue_ };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));


final ChannelConfig[] config = new ChannelConfig[] { stepperDirConfig, stepperStepConfig 
};
sequencer_ = ioio_.openSequencer(config);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();
clockwiseOnButton() ;
anticlockwiseOnButton();

}
public void loop() throws ConnectionLostException, InterruptedException {
 
}
public void clockwiseOnButton() {
 
button = (Button) findViewById(R.id.button1);
 
button.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
push();
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void anticlockwiseOnButton() {
 
button1 = (Button) findViewById(R.id.button2);
 
button1.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
push1();
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 5000;
stepperDirCue_.value = true;

sequencer_.push(cue_, 62500);
}
private void push1() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 5000;
stepperDirCue_.value = false;

sequencer_.push(cue1_, 62500);

Ytai Ben-Tsvi

unread,
Mar 2, 2014, 3:22:06 AM3/2/14
to ioio-...@googlegroups.com

1. When you say "the app is stopped", what exactly do you mean?
2. Leaving your loop() method empty is a very bad idea. It will cause your app to busy-loop. If you have nothing to put there the best idea is to leave it empty.
3. Where is cue1_ defined and initialized?

...

Synn Yong Tan

unread,
Mar 2, 2014, 3:44:48 AM3/2/14
to ioio-...@googlegroups.com
1.It means the app exited itself. And a pop out message "Unfortunately, IOIO Sample App has stopped"
2. Ok.Thanks for your advice.
The full code is as following. When i clicked on one of any four buttons with IOIO connected, then my app stopped with a pop out message  "Unfortunately, IOIO Sample App has stopped" .

package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;


public class IOIOSimpleApp extends IOIOActivity {

private Button button1, button2, button3, button4;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepper1StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepper2StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_, stepperStepCue_ };
private Sequencer.ChannelCue[] cue1_ = new Sequencer.ChannelCue[] {stepper1StepCue_};
private Sequencer.ChannelCue[] cue2_ = new Sequencer.ChannelCue[] {stepper2StepCue_ };
private Sequencer sequencer_;
final ChannelConfigBinary stepperDirConfig = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(3));
final ChannelConfigSteps stepperStepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(4,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepper1StepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepper2StepConfig = new ChannelConfigSteps(
new DigitalOutput.Spec(12,DigitalOutput.Spec.Mode.OPEN_DRAIN));

final ChannelConfig[] config = new ChannelConfig[] { stepperDirConfig, stepperStepConfig,stepper1StepConfig,stepper2StepConfig };

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
sequencer_ = ioio_.openSequencer(config);
sequencer_.start();
 
clockwiseOnButton();
cclockwiseOnButton();
cwiseOnButton();
ccwiseOnButton();
 
}
public void loop() throws ConnectionLostException, InterruptedException {}
public void clockwiseOnButton() {
 
button1 = (Button) findViewById(R.id.button1);
 
button1.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
push();
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void cclockwiseOnButton() {
 
button2 = (Button) findViewById(R.id.button2);
 
button2.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
push1();
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void cwiseOnButton() {
 
button3 = (Button) findViewById(R.id.button3);
 
button3.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
push2();
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
public void ccwiseOnButton() {
 
button4 = (Button) findViewById(R.id.button4);
 
button4.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
 
 try {
push3();
} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 5000;
stepperDirCue_.value = true;
sequencer_.push(cue_, 62500);
}
private void push1() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 5000;
stepperDirCue_.value = true;
sequencer_.push(cue_, 62500);
}
private void push2() throws ConnectionLostException, InterruptedException  {
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 300;
stepper1StepCue_.period = 5000;
sequencer_.push(cue1_, 62500);
}
private void push3() throws ConnectionLostException, InterruptedException  {
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 300;
stepper2StepCue_.period = 5000;
sequencer_.push(cue2_, 62500);

--

Ytai Ben-Tsvi

unread,
Mar 2, 2014, 5:51:41 PM3/2/14
to ioio-...@googlegroups.com

When an app crashes the logcat output will contain information on what happened, I.e. a stack trace of an uncaught exception. It will tell you exactly what is the problem.

...

Ytai Ben-Tsvi

unread,
Mar 2, 2014, 5:53:57 PM3/2/14
to ioio-...@googlegroups.com

And by the way in this case your problem is that you're pushing cues whose format doesn't match the format of the configuration used for opening the sequencer.

...

Synn Yong Tan

unread,
Mar 2, 2014, 9:28:07 PM3/2/14
to ioio-...@googlegroups.com
Hi,Ytai. Thanks for your help up. 
But can you explain more on the format that you mentioned? I cant really get it and understand.


--

Ytai Ben-Tsvi

unread,
Mar 2, 2014, 11:36:19 PM3/2/14
to ioio-...@googlegroups.com
If the configuration array you used to open the sequencer included a binary channel and a steps channel in this order, then your cues should also have exactly two channels of types binary and steps, in that order.
What you probably want in your case is 6 channels total (3 directions + 3 steps), which means both your configuration and cues need to be of this exact format.


--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+...@googlegroups.com.

Ytai Ben-Tsvi

unread,
Mar 2, 2014, 11:38:32 PM3/2/14
to ioio-...@googlegroups.com
Also, please carefully read the Wiki page about motor control as well as the Java docs associated with the Sequencer interface - you will save both you and me a lot of time. Some of the things you asked about or didn't understand are explained there very clearly.

Synn Yong Tan

unread,
Mar 3, 2014, 1:17:14 AM3/3/14
to ioio-...@googlegroups.com
Ok..thanks. Because another of my motor driver is 2 pulse input, and thats why i thought i dont need to define the binary channel. 
Thanks your previous time on helping me. 


...

[Message clipped]  

Vic Wintriss

unread,
Mar 9, 2014, 7:40:22 PM3/9/14
to ioio-...@googlegroups.com
Ytai:

I can't seem to find the sequencer JavaDocs.  Where are they?

I have your example working with my VicsWagon robot that we will be using again at iARoC 2014 here in San Diego.

Thanks for all the great work that you have been doing with motor control!

Vic


On Tuesday, January 21, 2014 7:33:24 PM UTC-8, Synn Yong Tan wrote:
Hi,
I'm trying to do control on step motor. 
My app didn't working but i cannot find out where is the problem.
Can please help me to see the code?

package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.ToggleButton;




public class IOIOSimpleApp extends IOIOActivity {
private ToggleButton toggleButton_;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
toggleButton_ = (ToggleButton) findViewById(R.id.ToggleButton);

}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperDirCue_, stepperStepCue_ };

private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
...

Ytai Ben-Tsvi

unread,
Mar 10, 2014, 3:00:18 AM3/10/14
to ioio-...@googlegroups.com

The JavaDocs are the comments that are inside the Sequencer.java code. They get converted into HTML, which can be found under the IOIOLib/doc directory in your software bundle.
There's also a wiki page called Motoro Control which has a good introductory material.

--
You received this message because you are subscribed to the Google Groups "ioio-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ioio-users+...@googlegroups.com.
To post to this group, send email to ioio-...@googlegroups.com.
Visit this group at http://groups.google.com/group/ioio-users.
For more options, visit https://groups.google.com/d/optout.

Synn Yong Tan

unread,
Mar 20, 2014, 6:41:11 AM3/20/14
to ioio-...@googlegroups.com
Hi, Ytai. I'm using two pulse input motor driver for my stepper motor. Stepper1StepCue_ is for clockwise of my motor while stepper2StepCue_ is for anticlockwise of my motor. I'm trying to control the direction of motor rotation. I tried the command as below when i attempt to rotate the motor clockwise but the motor is not operate correctly as both of the pulse(stepper1StepCue_ and stepper2StepCue_) are send simultaneously. Is there any way for me to send one pulse only while the other one is set to OFF? 

private void push2() throws ConnectionLostException, InterruptedException  {
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 300;
stepper1StepCue_.period = 5000;
 
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 0;
stepper2StepCue_.period = 5000;

sequencer_.push(cue_, 62500/20);
}


--
You received this message because you are subscribed to a topic in the Google Groups "ioio-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/ioio-users/jxhTI2gAhMk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to ioio-users+...@googlegroups.com.

Ytai Ben-Tsvi

unread,
Mar 20, 2014, 11:40:29 AM3/20/14
to ioio-...@googlegroups.com

Setting the pulse width to 0, as you did, is the correct way to stop.

Synn Yong Tan

unread,
Mar 20, 2014, 11:49:14 AM3/20/14
to ioio-...@googlegroups.com
But with the way i did, the motor is not able to rotate. As the motor driver is not allow me to input two pulse signals simultaneously. I only allow to send single pulse to either clockwise pin or anticlocwise at one time. Is there other way to achieve it ?

Ytai Ben-Tsvi

unread,
Mar 20, 2014, 12:51:24 PM3/20/14
to ioio-...@googlegroups.com
You got me confused. How many motors are there, 1 or 2? How are you trying to get each one of them to turn?

Synn Yong Tan

unread,
Mar 20, 2014, 7:59:28 PM3/20/14
to ioio-...@googlegroups.com

There is only one motor. The motor driver is two pulse input motor driver. It means I have to send pulse signal to clockwise pin to rotate clockwise while sending pulse signal to anticlockwise pin is to rotate anticlockwise. However, I only can send one pulse signal to one of the pins either clockwise pin or anticlockwise pin while the another pin has to be off. Because the motor driver cannot receive two input pulse signals even one of the pulse signal is with 0 pulse width.

Ytai Ben-Tsvi

unread,
Mar 20, 2014, 8:17:44 PM3/20/14
to ioio-...@googlegroups.com
Your description of the motor driver suggests that it is different than the one you originally mentioned (that had a step / direction input). If that's indeed the case,  can you send a datasheet of the new driver?

Also, what do you mean by "the motor driver cannot receive two input pulse signals"? Setting the pulse width to 0 will cause the pin to be constantly low (0 Volt). If that's not what you expect, what do you expect on this pin while the other one is generating pulses?

Synn Yong Tan

unread,
Mar 21, 2014, 12:32:02 AM3/21/14
to ioio-...@googlegroups.com
sorry for didn't make myself clear. This is another motor driver. The model is CSD2130P. 
Inline image 2Inline image 1

yes. but as i set my code as below, the motor did not rotate at all. By right, it should rotate clockwise. (stepper1StepCue_ is for clockwise pin while stepper2StepCue_ is for anticlockwise pin)

Ytai Ben-Tsvi

unread,
Mar 21, 2014, 1:59:56 AM3/21/14
to ioio-...@googlegroups.com

Let's take a step back again, since you've changed some stuff.
Please reduce your code to the minimum profile that doesn't work as you expect (for example, leave only one channel). Send out the code as well as the list output.
Also, it would help if you can use am oscilloscope or a logic analyze to get a capture of what's happening on the I/O pins.

Synn Yong Tan

unread,
Mar 26, 2014, 3:06:56 AM3/26/14
to ioio-...@googlegroups.com
I measured the output of the I/O pins. When i measure both of the pins together with dual channel oscilloscope, there is no pulse detected but the setting code is as below. 
However, when i measured the pin separately, the pin(pin for stepper1StepCue_) can output pulse while the other pin (pin stepper2StepCue_) did not output pulse. 
It means i connect them simultaneously, the pins do not output pulse but when i only connect one pin of them, the pin operates normally.  


Coding>>>>>
                stepper1SttepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 300;
stepper1StepCue_.period = 5000;
 
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 0;
stepper2StepCue_.period = 5000;

Ytai Ben-Tsvi

unread,
Mar 26, 2014, 11:49:40 AM3/26/14
to ioio-...@googlegroups.com
I respect your persistence - I'm sure we can get your project working and I really want to help you, but it is hard for me to do so because of the way you ask your questions. Let me propose a way to ask a question such that I will have the required information to give a useful answer:

I've built the following circuit:
<insert circuit diagram here. please NO photos of the assembled circuit since these photos often make it hard to identify what's connected where and what are the components. A simple hand-drawn diagram that you take a picture of with your phone is great. Make sure to mention what components are being used and add any links to datasheets where applicable>

When I'm running the following code:
<insert code>

I'm seeing the following behavior: <describe behavior or if you're using test equipment, explain what you're measuring and what values you're getting, for example a picture of the scope screen>

But I was expecting <something else>

However, if I'm running the following code:
<insert code>

I'm seeing <this behavior>

etc.

Synn Yong Tan

unread,
Mar 28, 2014, 12:29:11 AM3/28/14
to ioio-...@googlegroups.com
Inline image 1
All the resistors above are 10k resistor. Step motor A uses CSD2130P two pulse input motor driver(user manual is attached). Step motor B is operating correctly.

When I'm running the following code the step motor A is not rotating either clockwise or anticlockwise direction ( captured the output of the pins with oscilloscope, no pulse detected).
 I'm expecting when pin 10 output pulse to CW pin while pin 11 is set to off (pulsewidth=0) and then the motor turn clockwise and vise versa when i want to rotate the motor in anticlockwise direction.



package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import ioio.lib.api.Uart;
import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigBinary;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueBinary;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View;
import android.view.View.OnClickListener;


public class IOIOSimpleApp extends IOIOActivity {

private Button button1;
private TextView angle_;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button1 = (Button) findViewById(R.id.button1);
angle_ = (TextView)findViewById(R.id.angle);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueSteps stepperStepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueBinary stepperDirCue_ = new ChannelCueBinary();
private Sequencer.ChannelCueSteps stepper1StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepper2StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepperStepCue_, stepperDirCue_, stepper1StepCue_, stepper2StepCue_ };
private Sequencer sequencer_;
private Uart input_;
private BufferedReader reader_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigSteps stepperStepConfig_ = new ChannelConfigSteps(
new DigitalOutput.Spec(3,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigBinary stepperDirConfig_ = new Sequencer.ChannelConfigBinary(
false, false, new DigitalOutput.Spec(4));
final ChannelConfigSteps stepper1StepConfig_ = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepper2StepConfig_ = new ChannelConfigSteps(
new DigitalOutput.Spec(11,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfig[] config_ = new ChannelConfig[] {stepperStepConfig_, stepperDirConfig_, stepper1StepConfig_, stepper2StepConfig_   
};
sequencer_ = ioio_.openSequencer(config_);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();
clockwiseOnButton() ;
 
input_ = ioio_.openUart(6, 7, 19200, Uart.Parity.NONE, Uart.StopBits.ONE);
reader_ = new BufferedReader(new InputStreamReader(input_.getInputStream()));

}
public void loop() throws ConnectionLostException, InterruptedException {
String line;
try {
line = reader_.readLine();
double value1 =Double.parseDouble(line.substring(line.length() - 4, line.length()));
double result = (value1+1)*360/8192;
String angle = Double.toString(result);
setText(angle);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
public void clockwiseOnButton() {
button1.setOnClickListener(new OnClickListener() {
 
@Override
public void onClick(View arg0) {
final EditText angle = (EditText) findViewById(R.id.editText1);
int degrees = Integer.parseInt(angle.getText().toString());
final EditText angle1 = (EditText) findViewById(R.id.editText2);
int degrees1 = Integer.parseInt(angle1.getText().toString());
 try {
 while (degrees> 0) {
push();
        degrees--;}
 
     while (degrees < 0) {
   push1();
   degrees++;
        }
while  (degrees1 > 0){
   push2();
   degrees1--;
     }
    while  (degrees1 < 0){
      push3();
      degrees1++;
     }


} catch (ConnectionLostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
 
});
 
}
private void push() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period = 3571;
stepperDirCue_.value = true;
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 0;
stepper1StepCue_.period = 5000;
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 0;
stepper2StepCue_.period = 5000;
sequencer_.push(cue_, 62500/20);
}
private void push1() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 300;
stepperStepCue_.period =3571;
stepperDirCue_.value = false;
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth =0;
stepper1StepCue_.period = 5000;
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 0;
stepper2StepCue_.period = 5000;


sequencer_.push(cue_, 62500/20);
}
private void push2() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 0;
stepperStepCue_.period = 3571;
stepperDirCue_.value = true;
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 300;
stepper1StepCue_.period = 5000;
 
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 0;
stepper2StepCue_.period = 5000;
sequencer_.push(cue_, 62500/20);
}
private void push3() throws ConnectionLostException, InterruptedException  {
stepperStepCue_.clk = Clock.CLK_2M;
stepperStepCue_.pulseWidth = 0;
stepperStepCue_.period = 3571;
stepperDirCue_.value = true;
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth =0;
stepper1StepCue_.period = 5000;
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 300;
stepper2StepCue_.period = 5000;

sequencer_.push(cue_, 62500/20);
}

}

@Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void setText(final String str) {
runOnUiThread(new Runnable() {
@Override
public void run() {
angle_.setText(str);
}
});
}

}

CSD2130P(user manual).rar

Ytai Ben-Tsvi

unread,
Mar 28, 2014, 2:20:28 AM3/28/14
to ioio-...@googlegroups.com
This is much better!

First, electrical comments:
  • All the (+) lines need to go to 5V.
  • Each (-) line needs to go to an I/O pin. All those pins need to be open-drain.
  • You do not need any resistors.
Next is the code. Let's start by simplifying things. Make a backup of your code, then start making changes:
  • Remove all the code that deals with the first (working) motor. You should be left with 2 channels of type Steps in the sequencer (pins 10, 11).
  • Remove the UART stuff.
  • Remove the onClick stuff (BTW, the logic there is probably wrong, since only the first while() will actually run).
  • Call push2() from loop(), unconditionally. Verify that as soon as you run the app the motor turns one way.
  • Then, modify the app to call push3() instead of push2(). Verify that the motor is turning the other way.
  • If this experiment works, we have validated the electrical setup and the sequencer configuration. From that point, you can start incrementing in baby steps towards more complex logic. One of the main sources of problems is that you tried to implement too many things before testing. What often happens in this case is that you have more than one error, so even if you fix one, things still don't work and then you're not sure whether the fix you made is required or not.

Synn Yong Tan

unread,
Mar 28, 2014, 8:52:58 AM3/28/14
to ioio-...@googlegroups.com
Hi,Ytai. I connected the two pulse motor driver as what you told me and removed all the code and left only 2 Step channels in the sequencer.
Then i tried both of the version of app(1st app is call push2() ; 2nd app is call push3()), the motor is not rotating for both of the app(captured the output of the pins, no pulse detected as well).
I actually tried the app with only one step channel before, the motor is able rotate clockwise(connected to CW pins of motor driver). 
The problem (problem that i facing now) came when i tried to put two step channels in my app in order to control the direction of the motor.

The following code is the code with two step channels. I'm expecting to see the motor rotate in clockwise direction for this code.


package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;



public class IOIOSimpleApp extends IOIOActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueSteps stepper1StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCueSteps stepper2StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepper1StepCue_, stepper2StepCue_ };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigSteps stepper1StepConfig_ = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfigSteps stepper2StepConfig_ = new ChannelConfigSteps(
new DigitalOutput.Spec(11,DigitalOutput.Spec.Mode.OPEN_DRAIN));
final ChannelConfig[] config_ = new ChannelConfig[] {stepper1StepConfig_, stepper2StepConfig_   
};
sequencer_ = ioio_.openSequencer(config_);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();
}
public void loop() throws ConnectionLostException, InterruptedException {
push2();
}
private void push2() throws ConnectionLostException, InterruptedException  {
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 300;
stepper1StepCue_.period = 5000;
 
stepper2StepCue_.clk = Clock.CLK_2M;
stepper2StepCue_.pulseWidth = 0;
stepper2StepCue_.period = 5000;
sequencer_.push(cue_, 62500/20);
}
}

Ytai Ben-Tsvi

unread,
Mar 28, 2014, 11:51:52 AM3/28/14
to ioio-...@googlegroups.com
OK, we're narrowing down the possibilities - good!

Next things to check:
  1. Is your code actually running? Add a log message in your push2() method, i.e. Log.d("foo", "push2() is called"); Then run your app and look at the logcat output. If everything is OK, you should see this message appearing in the log 20 times a second.
  2. If it is not running, look for any error message in the log.
  3. If it is running, let's try the following:
    1. Disconnect the motor driver.
    2. Change the code so that the pins are used in NORMAL mode instead of OPEN_DRAIN.
    3. Attach your oscilloscope between pin 10 and GND and see what happens while the app is running. If you don't see 400Hz pulses, please note what is the voltage you're seeing and let me know.

Synn Yong Tan

unread,
Mar 28, 2014, 1:08:51 PM3/28/14
to ioio-...@googlegroups.com
I don't know this information helps or not. When i running app(call push2()), i connected pin 10 to oscilloscope while pin 11 left disconnected (did not connect to anything). I can see pulse output from pin10 through oscilloscope. It appear the same when i running app(call push3()), i connected pin 11 to oscilloscope while pin 10 disconnected, I can see pin11 output pulse through oscilloscope as well. 

Ytai Ben-Tsvi

unread,
Mar 28, 2014, 5:44:46 PM3/28/14
to ioio-...@googlegroups.com

And with both pins connected you're not seeing any pulses?
Is out possible that you have a short circuit somewhere, either in the breadboard or on the actual driver? The easiest way to check is to disconnect both on the IOIO side and measure continuity between the wires that would otherwise go to the IOIO pins.

Synn Yong Tan

unread,
Mar 29, 2014, 12:29:06 AM3/29/14
to ioio-...@googlegroups.com
Yes. By the way, is my code for the sequencer correct ?
The breadboard is okay, the same problem still occurred even i use separate breadboard for both of the pins. Measured pin10 and pin11 with multimeter as well, no short circuit detected. 

Ytai Ben-Tsvi

unread,
Mar 29, 2014, 12:38:26 AM3/29/14
to ioio-...@googlegroups.com
The code is OK. The fact that you're getting different results on pin 10 depending on whether or not pin 11 is connected suggests that this is not a code problem but an electrical one.

Try the following experiment:
  • Disconnect the wires from pins 10, 11. Leave them connected to the motor driver (-) inputs.
  • Leave both (+) lines connected to the IOIO 5V.
  • Measure the voltage between GND and the wire that used to go to pin 10. You should get about 5V.
  • Now, repeat the test while shorting the second wire to GND. You should still be seeing 5V, or otherwise you have a short.
  • Repeat the previous step while swapping the roles between the wires.

Synn Yong Tan

unread,
Mar 31, 2014, 5:05:20 AM3/31/14
to ioio-...@googlegroups.com
Measure voltage between ground and wire that used to go to pin10. Result: 5V
Measure voltage between ground and wire that used to go to 5V Result: 0V
Measure voltage between ground and wire that used to go to pin11. Result: 5V
Measure voltage between ground and wire that used to go to 5V Result: 0V

Is that indicating everything is ok ?

Ytai Ben-Tsvi

unread,
Mar 31, 2014, 11:37:12 AM3/31/14
to ioio-...@googlegroups.com
This is not exactly what I asked about.
Experiment (2) measures the same thing as experiment (1), but with pin 11 (the pin you're NOT measuring) connected to GND.
Experiment (4) measures the same thing as experiment (3), but with pin 10 connected to GND.

Synn Yong Tan

unread,
Apr 1, 2014, 6:35:30 AM4/1/14
to ioio-...@googlegroups.com
Measure voltage between ground and wire that used to go to pin10. Result: 5V
Measure voltage between ground and wire that used to go to pin10, with pin11 connected to GND. Result: 5V

Measure voltage between ground and wire that used to go to pin11. Result: 5V
Measure voltage between ground and wire that used to go to pin11, with pin10 connected to GND. Result: 5V

 The circuit seems ok,right?

Ytai Ben-Tsvi

unread,
Apr 1, 2014, 7:09:56 PM4/1/14
to ioio-...@googlegroups.com

Correct.

Next experiment, make your sequencer code only deal with one channel (for example, pin 10). Open the other pin as digital output, open drain and set it to low (false). Measure the voltage on pin 10 with a scope with and without connecting the wire going to the motor driver to pin 11.

Synn Yong Tan

unread,
Apr 2, 2014, 3:26:06 AM4/2/14
to ioio-...@googlegroups.com
Voltage on pin 10 = 0.3-0.5V with connecting the wire going to the motor driver to pin 11.
Voltage on pin 10 = 0.3-0.5V without connecting the wire going to the motor driver to pin 11.

The same problem still happens. When both of the pins are connected, the motor is not able to rotate. Disconnected the wire of motor driver on pin11 then the motor is rotating.


The code is as following.
package ioio.examples.simple;

import ioio.lib.api.DigitalOutput;

import ioio.lib.api.Sequencer;
import ioio.lib.api.Sequencer.ChannelConfig;
import ioio.lib.api.Sequencer.ChannelConfigSteps;
import ioio.lib.api.Sequencer.ChannelCueSteps;
import ioio.lib.api.Sequencer.Clock;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import android.os.Bundle;
import ioio.lib.util.android.IOIOActivity;



public class IOIOSimpleApp extends IOIOActivity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

class Looper extends BaseIOIOLooper {
private Sequencer.ChannelCueSteps stepper1StepCue_ = new ChannelCueSteps();
private Sequencer.ChannelCue[] cue_ = new Sequencer.ChannelCue[] {stepper1StepCue_ };
private Sequencer sequencer_;

@Override
protected void setup() throws ConnectionLostException, InterruptedException {
final ChannelConfigSteps stepper1StepConfig_ = new ChannelConfigSteps(
new DigitalOutput.Spec(10,DigitalOutput.Spec.Mode.OPEN_DRAIN));
DigitalOutput out_ = ioio_.openDigitalOutput(11, DigitalOutput.Spec.Mode.OPEN_DRAIN, false);
final ChannelConfig[] config_ = new ChannelConfig[] {stepper1StepConfig_,  
};
sequencer_ = ioio_.openSequencer(config_);
sequencer_.waitEventType(Sequencer.Event.Type.STOPPED);
sequencer_.start();
out_.write(false);
}
public void loop() throws ConnectionLostException, InterruptedException {
push2();
}
private void push2() throws ConnectionLostException, InterruptedException  {
stepper1StepCue_.clk = Clock.CLK_2M;
stepper1StepCue_.pulseWidth = 300;
stepper1StepCue_.period = 5000;

Ytai Ben-Tsvi

unread,
Apr 2, 2014, 10:59:57 AM4/2/14
to ioio-...@googlegroups.com

Is that with an oscilloscope? Is the voltage constant?

Synn Yong Tan

unread,
Apr 2, 2014, 12:48:01 PM4/2/14
to ioio-...@googlegroups.com
yes. yes, constant on 0.5V. What it means ?

Ytai Ben-Tsvi

unread,
Apr 2, 2014, 8:08:27 PM4/2/14
to ioio-...@googlegroups.com
How did we get back from seeing pulses on pin 10 when pin 11 is floating to not seeing anything?
Also, can you try with a different pair of pins ("P", 5V-tolerant)? Maybe those pins got fried during some of your attempts and are just acting funny.
Reply all
Reply to author
Forward
0 new messages