Working code example, with documentation!


#1

Hi to all…

I recently purchased and assembled the KA03 kit; apart from mounting the dual H bridge IC this was a breeze… that took all my soldering skills…

anyway, I got it working for a plain DC motor; I haven’t tried the stepper motor option yet…

here is my code…

===

//
// KA03/VMA03 Velleman kit example code; somewhat cleaned up and explained…
//

// active Arduino pins for control; these numbers should correspond with the onboard jumper settings, for each motor…
// this makes it possible to dedicate this shield to free Arduino output ports when combining shields…
// we can actually run 2 motors (A on shield output pins 1 and 2, B on 3 and 4) in this sketch…
// we assume 1/3 to be + and 2/4 - to the DC motors…

int pwm_a = 3; // PWM control { jumpers 3 | 5 | 6 } for motor A…
int dir_a = 2; // direction control { 2 | 4 | 7 } for motor A…
int pwm_b = 9; // PWM control { 9 | 10 | 11 } for motor B…
int dir_b = 8; // direction control { 8 | 12 | 13 } for motor B…

boolean dirFlag_a; // false = clockwise, true = reverse; motor A…
boolean dirFlag_b; // motor B…

void setup() {

pinMode(pwm_a, OUTPUT); // Set control pins to be outputs for motor A…
pinMode(dir_a, OUTPUT); // …
pinMode(pwm_b, OUTPUT); // Set control pins to be outputs for motor B…
pinMode(dir_b, OUTPUT); // …

dirFlag_a = false; // we initially run A clockwise…
dirFlag_b = true; // B counter clockwise…

runMotor(dirFlag_a,“init”,pwm_a,dir_a); // init run A in current direction: the DIR LED should turn up green…
runMotor(dirFlag_b,“init”,pwm_b,dir_b); // init run B in current direction: the DIR LED should turn up red…
}

void loop() {

runMotor(dirFlag_a,“run”,pwm_a,dir_a); // run A in current direction, and reverse: the DIR LED should turn up alternating green/red…
dirFlag_a = !dirFlag_a; // toggle direction flag…

runMotor(dirFlag_b,“run”,pwm_b,dir_b); // run B in current direction, and reverse: the DIR LED should turn up alternating green/red…
dirFlag_b = !dirFlag_b; // toggle direction flag…
}

void runMotor(boolean dirF, String mode, int pwm, int dir) {

if (dirF == false) digitalWrite(dir, LOW);
else digitalWrite(dir, HIGH);

if (mode.equals(“init”)) { // initial run…

analogWrite(pwm, 255); delay(2000); // set motor to jumpstart at 255/255 = 100% duty cycle (max. speed)
analogWrite(pwm, 0); delay(1000); // stop motor, after 2 seconds…
}
else { // run mode…

// we do serial runs of minimum speed (63 = 25%), half speed (127 = 50%) and full speed (255 = 100%)...
//
// please note, that at minimum speed output performance may differ, depending on the type of motor...
// also the DIR LEDS vary in brightness/colour, depending on the output signal and motorload; brighter = higher speed...

delay(2000);                           // adds up to 3 seconds, between alternating runs...

for (int i = 0; i < 3; i++) {

  analogWrite(pwm, pow(2,i+6)-1); delay(1500);   // switch motor on at set speed; allow for catching up momentum...
  analogWrite(pwm, 0);            delay(1000);   // switch off...
}

}
}

===

this works for me, for now… enjoy…


#2

btw…

I am still working, on improving this code… any suggestions might be useful…

regards to all…


#3

refreshed the code, and more documentation…

===

//
// KA03/VMA03 Velleman kit example code; somewhat cleaned up and explained…
//

// active Arduino pins for control; these numbers should correspond with the onboard jumper settings, for each motor…
// this makes it possible to dedicate this shield to free Arduino output ports when combining shields…
// we can actually run 2 motors (A on shield output pins 1 and 2, B on 3 and 4) in this sketch…
// we assume 1/3 to be + and 2/4 - to the DC motors…

// we included procedure runMotor( … ) to run each motor seperately, according to direction and speed,
// in both a setup() { “init” } and loop() { run } protocol, regardless of pin configuration…

int pwm_a = 3; // PWM control { jumpers 3 | 5 | 6 } for motor A…
int dir_a = 2; // direction control { 2 | 4 | 7 } for motor A…
int pwm_b = 9; // PWM control { 9 | 10 | 11 } for motor B…
int dir_b = 8; // direction control { 8 | 12 | 13 } for motor B…

boolean dirFlag_a; // false = clockwise, true = reverse; motor A…
boolean dirFlag_b; // motor B…

void setup() {

pinMode(pwm_a, OUTPUT); // Set control pins to be outputs for motor A…
pinMode(dir_a, OUTPUT); // this should correspond with jumper settings…
pinMode(pwm_b, OUTPUT); // Set control pins to be outputs for motor B…
pinMode(dir_b, OUTPUT); // …

dirFlag_a = false; // we initially run A clockwise…
dirFlag_b = true; // B counter clockwise…

runMotor(dirFlag_a,“init”,pwm_a,dir_a); // init run A in current direction: the DIR LED 1 should turn up green…
runMotor(dirFlag_b,“init”,pwm_b,dir_b); // init run B in current direction: the DIR LED 2 should turn up red…
}

void loop() {

runMotor(dirFlag_a,“run”,pwm_a,dir_a); // run A in current direction, and reverse: the DIR LED should turn up alternating green/red…
dirFlag_a = !dirFlag_a; // toggle direction flag…

runMotor(dirFlag_b,“run”,pwm_b,dir_b); // run B in current direction, and reverse: the DIR LED should turn up alternating green/red…
dirFlag_b = !dirFlag_b; // toggle direction flag…
}

void runMotor(boolean dirF, String mode, int pwm, int dir) {

int runTime = 2000; // run cycle for motor in millis…
int brakeTime = 1000; // brake cycle…

if (dirF == false) digitalWrite(dir, LOW); // set direction clockwise…
else digitalWrite(dir, HIGH); // counter clockwise…

if (mode.equals(“init”)) { // initial run…

analogWrite(pwm, 255); delay(runTime); // set motor to jumpstart at 255/255 = 100% duty cycle (max. speed)
analogWrite(pwm, 0); delay(brakeTime); // stop motor, allow it to stop and brake…
}
else { // run mode…

// we do serial runs of minimum speed (63 = 25%), half speed (127 = 50%) and full speed (255 = 100%)...
//
// please note, that at minimum speed output performance may differ, depending on the type of motor...
// also the DIR LEDS vary in brightness/colour, depending on the output signal and motorload; brighter = higher speed...

delay(brakeTime*2);                        // adds up to 3 brake cycles, between alternating runs; we reverse direction...

for (int i = 0; i < 3; i++) {

  analogWrite(pwm, pow(2,i+6)-1); delay(runTime);    // switch motor on at set speed; allow for catching up momentum...
  analogWrite(pwm, 0);            delay(brakeTime);  // switch off, and brake...
}

}
}

===

mind you: this drives 2 separate DC motors… this code does not include stepper operation…


#4

some design issues:

  • typically, this shield can deliver power to a wide variety of DC motors; due to the possibility of connecting external power, up to 46VDC…

  • on USB, we feed our Arduino as well as our KA03 shield with 5VDC; this will run both boards, plus 2 DC motors up to about 2.5 volts: that is all we have…

  • as I mentioned in the code: at minimum speed, some motors - like the ones supplied with most Arduino kits - operate very poorly and/or won’t even pick up momentum; even without any load…

  • my solution for all this, was connecting an external power supply of 6VDC for KA03; not only can this be supplied by simple batteries, this will also run 2 motors at minimum speed; this all worked nicely… I also tried 9VDC, but that made my motors jump over the table; they can operate up until 6.5VDC, mind that…

  • another option of course, is connect our Arduino to an external power source - of let’s say 6-9VDC - and feed all of this straight from Arduino… I will tinker on that one also…

  • next stop might be stepper motors…

regards to all…


#5

last update…

  • I unhooked Arduino from USB connection - the last code will remain in Flash memory - and hooked it up to 9VDC external from an adapter; on external, Uno will operate from 7-12VDC…

  • as was to be expected, this started running the sketch; this time both Uno and KA03 hooked up to external power, this performs great…

  • at full speed (100% duty cycle = 255 on PWM), you really need to secure your motors; they will jump start into action, haven’t worked out the RPM yet; and the motors carry no load…

  • we may expect, that with 9VDC we can drop below PWM = 63 = 25% duty cycle; maybe as slow as 50, as long as we realize we have less torque and momentum left to work with… and we may soon need gears and such…

for now, this works fine and separate from USB even… now for putting some load on the motors and check RPM’s and torque…

(to be continued)


#6

last update…

for now, my configuration is Arduino on USB (5VDC), and KA03 on external 7.5VDC; this operates all hard- and software nicely…

I extended the sketch, so that our motors are driven from ‘outside’ serial communication; this will either operate via Serial Monitor (Shift-Ctrl-m) or via real outside communication like Bluetooth, Infra Red or Radio Controlled… or a joystick would be nice… anyway, here is the new code… enjoy…

===

//
// KA03/VMA03 Velleman kit example code; somewhat cleaned up and explained…
//

// active Arduino pins for control; these numbers should correspond with the onboard jumper settings, for each motor…
// this makes it possible to dedicate this shield to free Arduino output ports when combining shields…
// we can actually run 2 motors (A on shield output pins 1 and 2, B on 3 and 4) in this sketch…
// we assume 1/3 to be + and 2/4 - to the DC motors…

// we included procedure runMotor( … ) to run each motor seperately, according to direction and speed,
// in both a setup() { “init” } and loop() { “run” } protocol, regardless of pin configuration…

// different protocols are triggered by incoming serial events via Serial Monitor (Shift-Ctrl-m) or outside driven via BlueTooth/IR/RC;
// apart from uploading, activating Serial communication will also reset the sketch and perform setup()…

int pwm_a = 3; // PWM control { jumpers 3 | 5 | 6 } for motor A…
int dir_a = 2; // direction control { 2 | 4 | 7 } for motor A…
int pwm_b = 9; // PWM control { 9 | 10 | 11 } for motor B…
int dir_b = 8; // direction control { 8 | 12 | 13 } for motor B…

char event; // incoming event…

boolean dirFlag_a; // false = clockwise, true = reverse; motor A…
boolean dirFlag_b; // motor B…

void setup() {

Serial.begin(9600); // sets the baud for serial data transmission …
pinMode(13, OUTPUT); // event indicator on digital output pin 13; we may use an outside LED on this pin…

pinMode(pwm_a, OUTPUT); // Set control pins to be outputs for motor A…
pinMode(dir_a, OUTPUT); // this should correspond with jumper settings…
pinMode(pwm_b, OUTPUT); // Set control pins to be outputs for motor B…
pinMode(dir_b, OUTPUT); // …

dirFlag_a = false; // we initially run A clockwise…
dirFlag_b = true; // B counter clockwise…

runMotor(dirFlag_a,“init”,pwm_a,dir_a); // init run A in current direction: the DIR LED 1 should turn up green…
runMotor(dirFlag_b,“init”,pwm_b,dir_b); // init run B in current direction: the DIR LED 2 should turn up red…
}

void loop() {

event = ‘0’; // clear all events…
digitalWrite(13, LOW); // reset indicator…

if (Serial.available() > 0) { // check for incoming data; either sent from Serial Monitor or outside…

event = Serial.read();        // read event; typical event sequences are eg. (1 sets indicator) 2, 3, 4, 0, whereas 0 is inserted automatically...

if (event != '0')
  digitalWrite(13, HIGH);     // event triggered; set indicator, typical at event 1, but all events activate this...

switch(event) {               // do event below...

  case '2': runMotor(dirFlag_a,"run",pwm_a,dir_a);   // run A in current direction, and reverse: the DIR LED1 should turn up alternating green/red...
            dirFlag_a = !dirFlag_a;                  // toggle direction flag...
            break;

  case '3': runMotor(dirFlag_b,"run",pwm_b,dir_b);   // run B in current direction, and reverse: the DIR LED2 should turn up alternating green/red...
            dirFlag_b = !dirFlag_b;                  // toggle direction flag...
            break;

  case '4': runMotor(dirFlag_a,"run",pwm_a,dir_a);   // run A in current direction, and reverse: the DIR LED1 should turn up alternating green/red...
            dirFlag_a = !dirFlag_a;                  // toggle direction flag...
            runMotor(dirFlag_b,"run",pwm_b,dir_b);   // run B in current direction, and reverse: the DIR LED2 should turn up alternating green/red...
            dirFlag_b = !dirFlag_b;                  // toggle direction flag...
            break;
}

}

}

void runMotor(boolean dirF, String mode, int pwm, int dir) {

int runTime = 2000; // run cycle for motor in millis…
int brakeTime = 1000; // brake cycle…

if (dirF == false) digitalWrite(dir, LOW); // set direction clockwise…
else digitalWrite(dir, HIGH); // counter clockwise…

if (mode.equals(“init”)) { // initial run…

analogWrite(pwm, 255); delay(runTime); // set motor to jumpstart at 255/255 = 100% duty cycle (max. speed)
analogWrite(pwm, 0); delay(brakeTime); // stop motor, allow it to stop and brake…
}
else { // run mode…

// we do serial runs of minimum speed (63 = 25%), half speed (127 = 50%) and full speed (255 = 100%)...
//
// please note, that at minimum speed output performance may differ, depending on the type of motor...
// also the DIR LEDS vary in brightness/colour, depending on the output signal and motorload; brighter = higher speed...

delay(brakeTime*2);                        // adds up to 3 brake cycles, between alternating runs; we reverse direction...

for (int i = 0; i < 3; i++) {

  analogWrite(pwm, pow(2,i+6)-1); delay(runTime);    // switch motor on at set speed; allow for catching up momentum...
  analogWrite(pwm, 0);            delay(brakeTime);  // switch off, and brake...
}

}
}

====

to emulate outside behaviour, I use this bit of Processing code, to drive Serial input to Uno/KA03 from outside; this could of course be any source… here I run a simple mouse driven set of events…

====

//
// BlueTooth signal simulator; we emulate outside signalling behaviour via mouse control…
//

import processing.serial.*;

Serial myPort; // create object from Serial class…

void setup() {

size(100,100); // clicking window…

myPort = new Serial(this, Serial.list()[1], 9600); // pick Arduino (= secundary) port on USB…
}

void draw() {

if (mousePressed == true) { //if we clicked in the window

myPort.write('1');         //send a 1; port active...

if (mouseButton == LEFT)   { myPort.write('2'); }
if (mouseButton == RIGHT)  { myPort.write('3'); }
if (mouseButton == CENTER) { myPort.write('4'); }

mousePressed = false;  // avoid multiple clicks, via mouse 'bouncing'...

}
else { //otherwise
myPort.write(‘0’); //send a 0
}
}

====

enjoy and regards to all…