Category Archives: Programming

>Serial data transmission and problem with it being SLOW !!!

>A while ago I was facing a problem reading some inputs from Serial Communication(USB port) in Arduino. The Arduino would work perfect(read all the inputs from Serial Communication Window as planned) if I was having my debug print outs but not if I would remove them(they also could be substituted by Delays) !!! I later tried to find out about them and here was the answer :

“Serial data transmission is slow. The Serial.print statement takes time, which allows time for more data to arrive. You have two choices. Add a delay statement to the while loop, and hope all the data arrives in time is the first choice. The longer you waste time waiting for data, the better your chances of it all arriving in time.

The second choice is to add an end-of-packet marker, and keep appending to temp until that end of packet marker arrives. Only use the data in temp when the end of packet marker has arrived.

The delay masks the issue of not being able to read a complete packet in one pass. If the delay is too small, the whole packet will not arrive before the delay(s) expire. If the delay is too large, you are just wasting time.

The better approach is to add an end of packet marker to the packer, wo you can read the packet as quickly as possible..”

Source : http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1294185714/1#1

>Encoders & Cycles 2, All DC motors are monitored now -> All_Encoders.pde

>This code can monitor the changes in cycles of all the DC motors used in the robot feet.

// Encoders inputs
byte pinEncA[] = {7,5,3}; // digital inputs
byte pinEncB[] = {6,4,2}; // digital inputs

// MOTOR OUTPUTS
byte pinDir[] = {13,8,12}; // digital output, controls direction for motor nr. [x]
byte pinPwm[] = {10,11,9}; // analog output, controls motor speed, nr. [x]

//Global variables
int readValue;
int pwmValue;
int motorDir;
//int channelA = 2;
//int channelB = 3;
int cycle[] = {0, 0, 0};

boolean f = false, b = false, r = false, l = false;
byte cyclecounter[] = {0, 0, 0};
byte cyclecounterold[] = {0, 0, 0};

//13 , 10 right, down
//8 , 11 middle, top
//9, 12 left, down

void setup(){

Serial.begin(9600);
Serial.println("WELCOME TO C1S0");
for (int i=0; i 0 ){
readValue = Serial.read();
switch (readValue){
case 102 ://f -> forward
Serial.println("*** Forward ***");
digitalWrite(pinDir[1], LOW);
digitalWrite(pinPwm[1], HIGH);
f = true;
b = false;
l = false;
r = false;
break;
case 98 ://b -> back
Serial.println("*** Backward ***");
digitalWrite(pinDir[1], HIGH);
digitalWrite(pinPwm[1], HIGH);
f = false;
b = true;
l = false;
r = false;
break;
case 108 ://l -> left
int temp_;
temp_ = 0;
if(Serial.available() right
int temp__;
temp__ = 0;
if(Serial.available() RESET
Serial.println("*** Resetting ***");
for (int i=0; i < 3; i++){
digitalWrite(pinPwm[i], LOW);//Setting all PWM's to LOW
Serial.print("*** Cycle[");
Serial.print(i);
Serial.print("] = ");
Serial.println(cycle[i]);
}//end of for
f = false;
b = false;
l = false;
r = false;
break;
}//end of switch
}
/*
if (f || b || r || l){
Serial.print("cycle[i]: ");
Serial.println(cycle[i]);
}//end of if
*/
}//end of commandCenter

//int angleMaalt;

void checkEncoder(){
int A;
int B;
int i;
for (i = 0; i < 3; i++){
A = digitalRead(pinEncA[i]);
B = digitalRead(pinEncB[i]);

if ( (A==LOW) && (B==LOW) )
cyclecounter[i] = 0;
else if ( (A==LOW) && (B==HIGH) )
cyclecounter[i] = 1;
else if ( (A==HIGH) && (B==HIGH) )
cyclecounter[i] = 2;
else if ( (A==HIGH) && (B==LOW) )
cyclecounter[i] = 3;

if (cyclecounter[i] == 0){
Serial.print("CAME IN AS 0");
if ( cyclecounterold[i] == 0){
Serial.print("Case old is 0");
}
else if ( cyclecounterold[i] == 3){
//angleMaalt++;
Serial.println(cycle[i]);
Serial.print("*** Changed cycle[");
Serial.print(i);
Serial.print("] = ");
cycle[i]--;
Serial.println(cycle[i]);
Serial.println("++++++");
Serial.print("cyccleCounter is : ");
Serial.println(cyclecounter[i]);
Serial.print("cyccleCounterOld is : ");
Serial.println(cyclecounterold[i]);
}
else if ( cyclecounterold[i] == 2){
Serial.println("Error reading from Encoder-");
Serial.println("cyclecounter[i]");
Serial.println(cyclecounter[i]);
Serial.println("cyclecounterold[i]");
Serial.println(cyclecounterold[i]);
}
else Serial.print("CRAP");
}
else if (cyclecounter[i] == 1){
/*if ( cyclecounterold[i] == 2)
angleMaalt--;
else if ( cyclecounterold[i] == 0)
angleMaalt++;
else*/ if ( cyclecounterold[i] == 3){
Serial.println("Error reading from Encoder--");
Serial.println("cyclecounter[i]");
Serial.println(cyclecounter[i]);
Serial.println("cyclecounterold[i]");
Serial.println(cyclecounterold[i]);
}
}
else if (cyclecounter[i] == 2){
/*if ( cyclecounterold[i] == 3)
angleMaalt--;
else if ( cyclecounterold[i] == 1)
angleMaalt++;
else*/ if ( cyclecounterold[i] == 0){
Serial.println("Error reading from Encoder---");
Serial.println("cyclecounter[i]");
Serial.println(cyclecounter[i]);
Serial.println("cyclecounterold[i]");
Serial.println(cyclecounterold[i]);
}
}
else if (cyclecounter[i] == 3){
if (cyclecounterold[i] == 0){
//angleMaalt--;
Serial.println(cycle[i]);
Serial.print("*** Changed cycle[");
Serial.print(i);
Serial.print("] = ");
cycle[i]++;
Serial.println(cycle[i]);
Serial.print("++++++");
Serial.print("cyccleCounter is : ");
Serial.println(cyclecounter[i]);
Serial.print("cyccleCounterOld is : ");
Serial.println(cyclecounterold[i]);
}
/*else if ( cyclecounterold[i] == 2)
angleMaalt++;*/
else if ( cyclecounterold[i] == 1){
Serial.println("Error reading from Encoder----");
Serial.println("cyclecounter[i]");
Serial.println(cyclecounter[i]);
Serial.println("cyclecounterold[i]");
Serial.println(cyclecounterold[i]);
}
}

cyclecounterold[i] = cyclecounter[i];
}//end of for

}//end of checkEncoder()

>Encoders & Cycles

>

Tonight(or better say this morning at 4:00 a.m.) I managed to make a code to finally count the cycles(it takes around 70 cycles for a motor to screw totally open) that the light fork encoder on this foot counts. This code is an alpha version which monitors just one of the DC motors(the one in the middle, motor with index “1″ in the code). 
The challenge to discus here is a limitation in Arduino which I have discussed in my previous post here(few external interruption on Arduino ). Most Arduino boards, so do mine, have just two external interruptions and this makes me not to use this method(which looks to be a perfect one) to monitor the changes on the pins received from the motor driver(changes in A & B state from Motor driver which tells us about the current position of the DC motor connected to it). With external interruptions out of the picture the only way that I came to is to solve this with a software trick. I tried to monitor the changes sent from the encoder which is connected to a moving motors as fast as I can. This is done by placing readFromEncoder() method in loop() method which repeats pretty fast and up to now has given satisfactory results. Check the code down here :



// Encoders inputs
byte pinEncA[] = {7,5,3}; // digital inputs
byte pinEncB[] = {6,4,2}; // digital inputs

// MOTOR OUTPUTS
// digital output, controls direction for motor nr. [x]
byte pinDir[] = {13,8,12};
// analog output, controls motor speed, nr. [x]
byte pinPwm[] = {10,11,9};

//Global variables
int readValue;
int pwmValue;
int motorDir;
int cycle;

boolean f = false, b = false, r = false, l = false;
byte cycleCounter;
byte cycleCounterOld;

void setup(){
Serial.begin(9600);
Serial.println("WELCOME TO C1S0");
for (int i=0; i < 3; i++){
pinMode(pinDir[i], OUTPUT);
pinMode(pinPwm[i], OUTPUT);
//in case, just to be sure ...
digitalWrite(pinPwm[i], LOW);
//in case, just to be sure ...
digitalWrite(pinDir[i], LOW);
pinMode(pinEncA[i], INPUT);
pinMode(pinEncB[i], INPUT);
}//end of for
}//end of setup()

void loop(){

// digitalWrite(pinDir[2], LOW);
// digitalWrite(pinPwm[2], HIGH);
// Serial.println("...");
//if ( Serial.available() > 0 )
commandCenter();
readFromEncoder();
//Serial.print("cycle: ");
//Serial.println(cycle);
}//end of loop

void commandCenter(){
//variables
int temp = 0;
// while (Serial.available() < 0)
// ;
if ( Serial.available() > 0 ){
readValue = Serial.read();
switch (readValue){
case 102 ://f -> forward
Serial.println("*** Forward ***");
digitalWrite(pinDir[1], LOW);
digitalWrite(pinPwm[1], HIGH);
f = true;
b = false;
l = false;
r = false;
break;
case 98 ://b -> back
Serial.println("*** Backward ***");
digitalWrite(pinDir[1], HIGH);
digitalWrite(pinPwm[1], HIGH);
f = false;
b = true;
l = false;
r = false;
break;
case 108 ://l -> left
Serial.println("*** Left ***");
digitalWrite(pinDir[2], LOW);
digitalWrite(pinPwm[2], HIGH);
f = false;
b = false;
l = true;
r = false;
break;
case 114 ://r -> right
Serial.println("*** Right ***");
digitalWrite(pinDir[0], LOW);
digitalWrite(pinPwm[0], HIGH);
f = false;
b = false;
l = false;
r = true;
break;
case 82 : //R->RESET
Serial.println("*** Resetting ***");
for (int i=0; i < 3; i++){
//Setting all PWM's to LOW
digitalWrite(pinPwm[i], LOW);
}//end of for
f = false;
b = false;
l = false;
r = false;
break;
}//end of switch
}
}//end of commandCenter

int angleCount;

void readFromEncoder(){
int A;
int B;

A = digitalRead(pinEncA[1]);
B = digitalRead(pinEncB[1]);
digitalWrite(13, A);

if ( (A==LOW) && (B==LOW) )
cycleCounter = 0;
else if ( (A==LOW) && (B==HIGH) )
cycleCounter = 1;
else if ( (A==HIGH) && (B==HIGH) )
cycleCounter = 2;
else if ( (A==HIGH) && (B==LOW) )
cycleCounter = 3;

switch(cycleCounter)
{
case 0:
if ( cycleCounterOld == 1)
angleCount--;
else if ( cycleCounterOld == 3){
angleCount++;
Serial.print("cycle: ");
Serial.println(cycle);
cycle--;
}
else if ( cycleCounterOld == 2){
Serial.println("Error reading from Encoder");
Serial.println("cycleCounter");
Serial.println(cycleCounter);
Serial.println("cycleCounterOld");
Serial.println(cycleCounterOld);
}
break;

case 1:
if ( cycleCounterOld == 2)
angleCount--;
else if ( cycleCounterOld == 0)
angleCount++;
else if ( cycleCounterOld == 3){
Serial.println("Error reading from Encoder");
Serial.println("cycleCounter");
Serial.println(cycleCounter);
Serial.println("cycleCounterOld");
Serial.println(cycleCounterOld);
}
break;

case 2:
if ( cycleCounterOld == 3)
angleCount--;
else if ( cycleCounterOld == 1)
angleCount++;
else if ( cycleCounterOld == 0){
Serial.println("Error reading from Encoder");
Serial.println("cycleCounter");
Serial.println(cycleCounter);
Serial.println("cycleCounterOld");
Serial.println(cycleCounterOld);
}
break;

case 3:
if ( cycleCounterOld == 0){
angleCount--;
Serial.print("cycle: ");
Serial.println(cycle);
cycle++;
}
else if ( cycleCounterOld == 2)
angleCount++;
else if ( cycleCounterOld == 1){
Serial.println("Error reading from Encoder");
Serial.println("cycleCounter");
Serial.println(cycleCounter);
Serial.println("cycleCounterOld");
Serial.println(cycleCounterOld);
}
break;
}
cycleCounterOld = cycleCounter;
}




The plan a head is to make a complete Arduino code that monitors all three motors and connect it to a Java code. Java code can communicate with Arudino through serial communication and monitors all the three motors, being able to report the current cycle that the motor is right now at.

>External interrupts in Arduino & its limitations

>

Description

Specifies a function to call when an external interrupt occurs. Replaces any previous function that was attached to the interrupt. Most Arduino boards have two external interrupts: numbers 0 (on digital pin 2) and 1 (on digital pin 3). The Arduino Mega has an additional four: numbers 2 (pin 21), 3 (pin 20), 4 (pin 19), and 5 (pin 18).

Parameters

interrupt: the number of the interrupt (int)
function: the function to call when the interrupt occurs; this function must take no parameters and return nothing. This function is sometimes referred to as an interrupt service routine.
mode defines when the interrupt should be triggered. Four contstants are predefined as valid values:
  • LOW to trigger the interrupt whenever the pin is low,
  • CHANGE to trigger the interrupt whenever the pin changes value
  • RISING to trigger when the pin goes from low to high,
  • FALLING for when the pin goes from high to low.

Returns

none

Example

int pin = 13;
volatile int state = LOW;

void setup()
{
pinMode(pin, OUTPUT);
attachInterrupt(0, blink, CHANGE);
}

void loop()
{
digitalWrite(pin, state);
}

void blink()
{
state = !state;
}

RxTx 64 bit on Windows 7

As it is recommended by RxTx official homepage, we can download the 64 bit version from this link(Cloudhopper RxTx page). Later it is just to unzip the file and follow the folloing instruction :

Choose your binary build – x64 or x86 (based on which version of
the JVM you are installing to)

NOTE: You MUST match your architecture. You can’t install the i386
version on a 64-bit version of the JDK and vice-versa.

For a JDK installation:
Copy RXTXcomm.jar —> jrelibext
Copy rxtxSerial.dll —> jrebin
Copy rxtxParallel.dll —> jrebin

and then you are done”

I am using RxTx to communicate with my Arduino boards over serial communication. With this tool I can use Java to directly read the active ports and connect to Arduino cards. This(not needing to use Arduino IDE to show what is coming from the micro-controller) gives me the chance to process the received data and write back the commands automatically.

RXTX API : http://users.frii.com/jarvi/rxtx/doc/index.html

>LATEST NEWS, Working on summer project which is highly related to my thesis

>Right now I am leading a team consist of 7 students, doing a summer-project called Super Crawler(a tank-type robot which roles around with the belt) at Robotica Osloensis(Robotics student community at university of Oslo). My team and I have gained many new experiences(reverse engineering techniques, Programming different motors to work with Arudino boards in C, Communicating with Arduino borads with Java on Serial communication port, signal processing, etc) and have developed  different codes for our purposes. You can read all about it, see the photos & videos and have direct access to our codes on our project worklog. I have also added a RSS-reader on the right side of this weblog about latest news on Super Crawler project …

These experiences would help me a lot in future development of my climbing robot, Walloid :-)