Saturday, September 24, 2011

Preparing for Xbee practical test for distributed embedded systems

Arduino Fio(x4), Arduino Mega(x1), Arduino Ethernet shield(x1), Xbee modules(x5), Xbee shileld(x1), Xbee Explorer(x1)

Saturday, September 10, 2011

Taking action is important

To do something, however small, to make others happier and better, is the highest ambition, the most elevating hope, which can inspire a human being.
- Sir John Lubbock

Thursday, September 8, 2011

Thesis progress

The numbers on the right side are numbers of pages while the numbers in the bottom are the dates.

Sunday, September 4, 2011

Ethics & Robotics

The Three Laws of Robotics (often shortened to The Three Laws or Three Laws) are a set of rules devised by the science fiction author Isaac Asimov and later expanded upon. The rules are introduced in his 1942 short story "Runaround", although they were foreshadowed in a few earlier stories. The Three Laws are:
  1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.
  2. A robot must obey any orders given to it by human beings, except where such orders would conflict with the First Law.
  3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.
Source : Wiki

Friday, September 2, 2011

Thread programming is a key element

Thread programming in writing high speed stream of data is a key point in navigation systems. Effective DAQ system is critical in such systems and the idea of synchronization between different threads and the communication channels between different threads are also very important. More about this later ...

Tuesday, August 23, 2011

Engineers facing the world ...

Engineers believe they can fix everything and in case of failure, they are humble enough to accept carry the guilt personally and mention that it is them who can not solve the challenge, but a challenge always has a solution :-)

I like to be an engineer ;-)

Thursday, August 11, 2011

Monday, August 8, 2011

Nice quote ...

To solve any problem, here are three questions to ask yourself: 
- First, what could I do? - Second, what could I read? - And third, who could I ask?
- Jim Rohn

Friday, August 5, 2011

Climbing patterns

Fast climbing with degrees from 0 - 360 degrees

Slow climbing with either upwards and downwards, or right and left

The combination of these two types of climbing can give a combination of very fast climbing plus precise climbing when needed. Also fast climbing method gives robot the chance to move to directions from 0 - 360 degrees.

Bluetooth Technology

Bluetooth uses very little energy !!! They are used in Tsunami detectors (ZIGBEE tech) ...

Advantages
Disadvantages
High throughput
Device discovery is slow in term of power usage and time
Resilience against interference
Keeping connections open is expensive in term of power usage
????????
??????????

Thursday, August 4, 2011

Infrared Technology

Using Infrared for connecting micro-controllers is one of the available choices of wireless intercommunication between micro-controllers. Here is a short list of challenges and the benefits that using such technology would provide us :
Advantages
  • Very low power requirement, hence it is best suitable for machinery with limited battery capacity, like mobile robots, laptops, pads, phones, etc.
  • Inexpensive -> Not a very important issue in designing a revolutionary system. The redundancy is the most important feature.
  • Very secure. The data flow among the source and target is unidirectional, meaning the direction of the infrared beam ensures that there in no leaked or move to nearby devices as it’s transmitted. 
Disadvantages 
  • Data transmission happens in eye sight. -> Meaning you can not have it in a big robot.
  • Short range communication -> Actually this is an advantage in our case, which brings more security.
  • Easily gets interrupted by obstacle  -> Meaning you can not have it in a robot with several layers between micro-controllers. Almost any kind of obstacle interrupt the signal.
  • Not a good choice under extreme weather conditions(sunlight, rain, pollution etc) -> This is the most negative point for this technology not be used in an offshore robot.
Depending on the area of application Infrared might be or might not be the right choice. E.g. the short range of availability would increase our security a lot, while exactly in Walloid project the harsh weather condition is very common in future platforms. Today, there are many technologies exists that are much better than IR like Bluetooth, Wi-Fi etc.

Tuesday, August 2, 2011

Sunday, July 24, 2011

It is all about making a SYSTEM !!!

After visiting the Mercedes Benz factory in Bremen, and reading some articles/research papers form integrated operation in offshore world, I think the solution is all about System ... A system that can put both human controllers and robots in one system.

Tuesday, June 21, 2011

TAIL IO project

TAIL Integrated Operation, is a project leaded by Statoilhydro, trying to connect offshore platforms to the onshore offices, bringing down the number of staff on platforms and let expert, regardless of where they are, to communicate with the people on site. More about this comes later ...

Source : http://www.statoil.com/en/NewsAndMedia/Multimedia/features/Pages/io.aspx

Tuesday, May 10, 2011

The tolerance issue in 3D printing

These broken parts are gonna delay my work ...

The conjunction between the motor led and the robot body
The broken conjunction on robot body side
The broken conjunction on Motor side
 Totally new printed encoder parts were received on 9th of May 2011, and one of them(picture below) was broken into two pieces while being mounted on the same day
The old broken encoder part(black one) beside the new one that was broken under mounting

Monday, May 9, 2011

Supervisor Meeting

Today I had a very quick supervisor meeting with my supervisor. Results :

  • I got the spare part for encoders, so now I can start to test my positioning code
  • I got some tips about I2C technology(Several cards connected together with the same wire)
  • I will have wired(RxTx, I2C, Dig2Dig, etc) & wireless(Xbee, ...) networking of Arduino cards discussed in my thesis
  • I got tips that there are more products/technologies than Xbee 
  • I get to write more about "Van der Waals" technology & discuss related to the conditions in offshore.

Thursday, May 5, 2011

Finally OpenCV 2.1 & MS VC++ 2008 worked together ...

This is OpenCV helloWord program which is an easy code that just opens one picture. Too sleepy to continue today ... OpenCV 2.2 is too much unstable and I couldn't get to make it work with MS VC++ 2010. Downgrade worked :-)

Good night

Saturday, April 30, 2011

Arduino Nano and new possibilities in electronic design

The new Arduino Nano is the smallest and most versatile Arduino board yet. It contains an ATmega168 micro-controller (w/ boot loader), integrated USB (FTDI chip) w/ Mini-B jack, a full complement of i/o pins, an ICSP programming header, and on-board regulator. Measuring 0.73″ x 1.70″, it’s smaller and cheaper than the combination of Arduino Mini and Mini-USB adapter. 
The possibilities that this state of art design brings to Walloid project can be new electronics design as it is now very easy to have a network of Arduino boards, communicating data, processing things faster, etc ... My previous post about I2C is about the same idea; connecting multiple Arduino boards ...

Thursday, April 28, 2011

I2C

I2C inter micro controller communication

First experiment, failed !!! The problem : Grounds were not connected together !!!

Second experiment, Succeeded :-)

I2C connection between one master Arduino & one Slave Arduino over a serial clock pin (SCL, pin number 4 in the picture down here, YELLOW wire) that the Arduino pulses at a regular interval, and a serial data pin (SDA, Pin number 5 in the picture down here, RED wire) over which data is sent between the two devices. Also make sure that the grounds are connected together.


Master Writer Code - Program for Arduino 1

// Wire Master Writer
// by Nicholas Zambetti 

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include 

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // transmit to device #4
  Wire.send("x is ");        // sends five bytes
  Wire.send(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}


Slave Receiver Code - Program for Arduino 2



// Wire Slave Receiver
// by Nicholas Zambetti 

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include 

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.receive(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.receive();    // receive byte as an integer
  Serial.println(x);         // print the integer
}



Source : http://arduino.cc/en/Tutorial/MasterWriter

Friday, March 18, 2011

New calculations for positioning

Update : 06:01, 18.03.201, I am almost done with the C code on Arduino ... Too sleepy, going back home now ...
I should write a program that can simulate the workspace as I have no idea what are the valid points on workspace that are reachable by the feet.
----------------------
New calculations for positioning, the whole thing could not be easier than this ...



Tuesday, March 15, 2011

I2C Inter Board communication, Arduino

http://www.arduino.cc/playground/Learning/I2C
http://en.wikipedia.org/wiki/I%C2%B2C
http://www.lammertbies.nl/comm/info/I2C-bus.html
http://absences.sofianaudry.com/en/node/10

Kinematic Calculations #2


No results yet ...

Monday, March 14, 2011

OpenCV, finally configured ...

After 3 days struggling and working to make OpenCV to work with any possible programming language on Windows 7, I gave up. Today I thought to try it on my Ubuntu and after couple of hours struggling finally I got it. Now I should learn how to code with processing for image processing, as a possible decision making base for the robot and of course streaming ...
this is a demo from OpenCV C++ sample library...

Sunday, March 13, 2011

Challenges ...

New challenges with the robot arm, while I am working with positioning. The prototype(robot arm) is not totally functional as just one of the three motors work the way it should. Problems with mechanic design, and the motor axle is worn away(3D printer product in plastic) ...

Friday, March 11, 2011

OpenCV & Positioning; Today's focus

Today I'll be focusing on Positioning of a point and OpenCV(Computer Vision) with Processing. I will start to work on positioning and hope to have my first streaming ready by today or early tomorrow morning(before 7:00 a.m.), as I work usually at nights.

Thursday, March 10, 2011

Zero positioning, EEPROM implementation

Today I am planning to finish this one, Will come up here with code.

04:34, 11.03.2011 : I am totally finished with current positioning & Zero Positioning of the robot. I can start to call Walloid a smart system ... Even in case of loosing power, or sudden improper shutdown of program, Walloid will still be able to recover and send commands to the motors without ANY crashing fear. Very effective logging system is another specification of current system.

Java CP
Logging systems which logs everything with time in details(Translating Error codes which exist in my own defined Arduino-Java Protocol)

Arduino code :


/*
*Differences with previous code : 
* 1 - It stops when reaching negative values which result in preventing it to crash with the motor
* 2 - It stops when reaching MAX values which result in preventing the feet to go loose
* 3 - Error protocol ready
* 4 - Current positioning & Zero positioning in place :-)
*/

#include EEPROM.h


byte pinEncA[] = {3,5,7}; // digital inputs
byte pinEncB[] = {2,4,6}; // 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;
int cyclecounter[] = {-1, -1, -1};
int cyclecounterold[] = {-1, -1, -1};

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



void setup(){
  
  Serial.begin(115200);
  //Serial.print("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);
    // just in case to be sure
    digitalWrite(pinDir[i], LOW);
    pinMode(pinEncA[i], INPUT);
    pinMode(pinEncB[i], INPUT);
    digitalWrite(pinEncA[i], LOW);
    digitalWrite(pinEncB[i], LOW);
    //cyclecounter[i] = -1;
    //cyclecounterold[i] = -1;
  }//end of for
  //findCurrentPosition();

}//end of setup()

void loop(){
    commandCenter();
    checkEncoder();
}//end of loop
int value;
void commandCenter(){
  //variables
  int temp = 0;
  if ( Serial.available() > 0 ){
    readValue = Serial.read();
  //delay(50);
    switch (readValue){
      case 'h' : //handshake
        Serial.print("h");
        delay(50);
        break;
      case 'P' : //handshake
        findCurrentPosition();
        delay(50);
        break;        
      case '0' ://motor #0
        int temp__;
        temp__ = 0;
        if(Serial.available() < 0)
          ;
        delay(500);
        temp__ = Serial.read();
        if (temp__ == 102){// -f -> forward
          //Serial.print("*** Right forward ***");
          digitalWrite(pinDir[0], LOW);
          digitalWrite(pinPwm[0], HIGH);
        }//end of if
        else if(temp__ == 98){// -b -> backward
          //Serial.print("*** Right backward ***");
          digitalWrite(pinDir[0], HIGH);
          digitalWrite(pinPwm[0], HIGH);
        }
        else{
          Serial.println("E00");
          //Serial.print(temp__);
        }
        f = false;
        b = false;
        l = true;
        r = false;
        break;
      case '1' ://motor #1
        int temp_;
        if(Serial.available() < 1)
          ;
          delay(500);
          temp_ = Serial.read();
        if (temp_ == 102){// -f
          //Serial.print("*1FW*");
          digitalWrite(pinDir[1], LOW);
          digitalWrite(pinPwm[1], HIGH);
        }//end of if
        else if(temp_ == 98){// -b
          //Serial.print("*1BW*");
          digitalWrite(pinDir[1], HIGH);
          digitalWrite(pinPwm[1], HIGH);
        }
        else{
         
          Serial.println("E00");
          //Serial.print(temp_);
        }
        f = true;
        b = false;
        l = false;
        r = false;
        break;
      case '2' ://l -> left
        temp_ = 0;
        if(Serial.available() < 1)
          ;
          delay(500);
          temp_ = Serial.read();
        if (temp_ == 102){//motor #2
          //Serial.print("*2FW*");
          digitalWrite(pinDir[2], LOW);
          digitalWrite(pinPwm[2], HIGH);
        }//end of if
        else if(temp_ == 98){// -b
          //Serial.print("*2BW*");
          digitalWrite(pinDir[2], HIGH);
          digitalWrite(pinPwm[2], HIGH);
        }
        else{
          Serial.println("E00");
          //Serial.print(temp_);
        }        
        f = false;
        b = false;
        l = false;
        r = true;
        break;
      case 82 : //R->RESET
        Serial.println("R");
        resetAll();
        f = false;
        b = false;
        l = false;
        r = false;
        break;
    }//end of switch  
  } 
  /*
  if (f || b || r || l){
    Serial.print("cycle[i]: ");
    convertToThreeDigits(cycle[i]);
  }//end of if
  */
}//end of commandCenter

//int angleMaalt;

void checkEncoder(){
  int A;
  int B;
  int i;
  for (i = 0; i < 3; i++){
      cyclecounterold[i] = cyclecounter[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;   
    
      switch (cyclecounter[i]){
        case (0) : {
           if ( cyclecounterold[i] == 0){
              ;//Do nothing
           }
           else if ( cyclecounterold[i] == 1){
             if (cycle[i] + 1 > 213){
                 criticalSituation(i, 1);
             }
             else{
                cycle[i]++;
                saveCurrentPosition();
                Serial.print("C");
                Serial.print(i);
                Serial.print("*");            
                convertToThreeDigits(cycle[i]);
             }
           }
           else if ( cyclecounterold[i] == 2){
                Serial.println("E01");//Error reading from Encoder-
            }
           else if ( cyclecounterold[i] == 3){
             if (cycle[i] -1 < 0){
                 criticalSituation(i, 0);
             }
             else{
                cycle[i]--;
                saveCurrentPosition();
                Serial.print("C");
                Serial.print(i);
                Serial.print("*");            
                convertToThreeDigits(cycle[i]);
             }
            }
            else 
                ;//Serial.print("ERROR");
            break;
        }//end of case-0
        case (1) : {
            if ( cyclecounterold[i] == 0){
               if (cycle[i] -1 < 0){
                 criticalSituation(i, 0);
             }
             else{
              cycle[i]--;
              saveCurrentPosition();
              Serial.print("C");
              Serial.print(i);
              Serial.print("*");            
              convertToThreeDigits(cycle[i]);            
             }
            }
            if ( cyclecounterold[i] == 2){
             if (cycle[i] + 1 > 213){
                 criticalSituation(i, 1);
             }
             else{
                cycle[i]++;
                saveCurrentPosition();
                Serial.print("C");
                Serial.print(i);
                Serial.print("*");            
                convertToThreeDigits(cycle[i]);
             }
            }
            else if ( cyclecounterold[i] == 3){
                Serial.println("E01");//Error reading from Encoder-
            }
            else 
                ;//Serial.print("ERROR");
            break;
        }
        case (2) : {
            if ( cyclecounterold[i] == 1){
             if (cycle[i] -1 < 0){
                 criticalSituation(i, 0);
             }
             else{              
              cycle[i]--;
              saveCurrentPosition();
              Serial.print("C");
              Serial.print(i);
              Serial.print("*");            
              convertToThreeDigits(cycle[i]);
             }
            } 
            else if ( cyclecounterold[i] == 2)
              ;
            else if ( cyclecounterold[i] == 3){
             if (cycle[i] + 1 > 213){
                 criticalSituation(i, 1);
             }
             else{
                cycle[i]++;
                saveCurrentPosition();
                Serial.print("C");
                Serial.print(i);
                Serial.print("*");            
                convertToThreeDigits(cycle[i]);
             }
            }
            else if ( cyclecounterold[i] == 0){
                Serial.println("E01");//Error reading from Encoder-
            }
            else 
                ;//Serial.print("ERROR");
            break;
        }//end of case-2
        case(3) : {
            if (cyclecounterold[i] == 0){
             if (cycle[i] + 1 > 213){
                 criticalSituation(i, 1);
             }
             else{
                cycle[i]++;
                saveCurrentPosition();
                Serial.print("C");
                Serial.print(i);
                Serial.print("*");            
                convertToThreeDigits(cycle[i]);
             }
            }
            else if (cyclecounterold[i] == 1){
              Serial.println("E01");//Error reading from Encoder-
            }
            else if ( cyclecounterold[i] == 2){
             if (cycle[i] -1 < 0){
                 criticalSituation(i, 0);
             }
             else{              
              cycle[i]--;
              saveCurrentPosition();
              Serial.print("C");
              Serial.print(i);
              Serial.print("*");            
              convertToThreeDigits(cycle[i]);
             }
            }
            else if ( cyclecounterold[i] == 3)
              ;
            else 
              ;//Serial.print("ERROR");
            break;
        }//end of case-3
      }
  }//end of for
}//end of checkEncoder()

int criticalSituation(int motorNumber, int type){
      digitalWrite(pinPwm[motorNumber], LOW);//Setting all PWM's to LOW
      if (type == 0)
        Serial.println("E02");//*** FATAL ERROR, CRASH POSSIBLE, STOPPING MOTOR ***
      else if (type == 1)
        Serial.println("E03");//*** FATAL ERROR, ROBOT ARM MIGHT GO LOOSE, STOPPING MOTOR ***
      //Serial.print(motorNumber);
      return 0;
}//end of criticalSituation

int resetAll(){
  for (int i=0; i < 3; i++){
          digitalWrite(pinPwm[i], LOW);//Setting all PWM's to LOW
          Serial.print("C");
          Serial.print(i);
          Serial.print("=");
          convertToThreeDigits(cycle[i]);
        }//end of for
        return 0;
}//end of resetAll()


void convertToThreeDigits(int input){
  if (input >= 0 && input < 10){
    /*switch (input){
      case 0 :
        Serial.print("00");
        break;
      case 1 :
        Serial.print("01");
        break;      
      case 2 :
        Serial.print("02");
        break;      
      case 3 :
        Serial.print("03");
        break;      
      case 4 :
        Serial.print("04");
        break;      
      case 5 :
        Serial.print("05");
        break;      
      case 6 :
        Serial.print("06");
        break;      
      case 7 :
        Serial.print("07");
        break;      
      case 8 :
        Serial.print("08");
        break;      
      case 9 :
        Serial.print("09");
        break;      
      default :
        Serial.print("00");
        break;      
    }//end of switch
    */
    Serial.print("00");
    Serial.print(input);
  }
  else if ( input >= 10 && input < 100){
    Serial.print("0");
    Serial.print(input);
  }
  else{
    Serial.print(input);    
  }
}//end of convertToThreeDigits()

void saveCurrentPosition(){
  for (int i = 0; i < 3; i++){
    EEPROM.write(i, cycle[i]);
  }  
}//end of saveCurrentPosition

void findCurrentPosition(){
  for (int i = 0; i < 3; i++){
    value = EEPROM.read(i);
    cycle[i] = value;
    Serial.print("P");
    Serial.print(i);
    Serial.print("*");
    convertToThreeDigits(value);
  }
}//end of findCurrentPosition


Wednesday, March 9, 2011

My status on the 6th day of my holidays that I use for working on my thesis

  • Counter code fixed in Arduino C code
  • Problems with wrong usage of RxTxLibrary(mis match which wasted enough of my time during 6 days ago; unstable connection from Arduino to Java Control System)
  • Java Simulator works fine, just need to finish the fancy java demonstration
  • Logging system works very good
  • Help through HTML file, online
  • Java & Arduino are communicating perfectly
  • Some problems with the prototype feet I have as just one motor functions
  • Working on positioning & zero positioning
  • Safety system for preventing the motor to crash backwards or too much forward

Prevention of motor crash in C, offline Robot


Prevention of motor crash in Java, online Robot, Simulation & Real world



Monday, March 7, 2011

Positioning calculations, Walloid

Update 17.03.2011 : These calculations are totally wrong ... The whole concept is much easier than these things. See the new post about the positioning calculations.
-----------------------------------
Although my supervisor meant that the positioning is happening through very easy geometrical calculation but I struggled a lot to find these equations. I am soon going to code this in my program for Walloid and come up with practical results. I should thank my dear friend Puya Afsharian who helped me a lot in figuring out some of the details.








Saturday, February 19, 2011

Webcam & Processing

Updated, 22nd of February 2011
OpenCV seems to be the perfect tool to do the image processing calculation. A practical example.
---
Hey Shahab,
You should look at the flob library for blob detection. Its listed on the libraries page on processing.org. Its pretty simple to use. Also for better object detection, you might have more luck with openFrameworks, which is c++ based and has a better library for OpenCV.
For my project, I used the flob library and using the OSC protocol (oscp5 library for processing) I sent the data from the webcam to the sound generation program.
Using the OSC protocol you could also use something call openTSPS, by Rockwell Labs, which would be much more easier and exact since its also based on openFrameworks. So sense people with openTSPS and send the data via OSC to your program that controls the micro-controller.
Hope it helps.
Sumit
------------
On Feb 16, 2011, at 3:20 PM, Shahab F. M. wrote:
Hi.
I was wondering if u can give me some tips/tutorial links about webcam & processing. I am working on Walloid as my master thesis.
http://walloid.blogspot.com/
Shahab
Sent from my HTC

Internal Arduino Communication

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1153415010

Thursday, February 17, 2011

Test units(JUnit) on the way ...

Today I got some tips from a very experienced programmer who is a team leader at a leading IT consulting company here at Norway. He advised to me to no matter what have test codes in my java code. No matter what use a version control system and have a structure in my coding. I think as long as I am so keen of having things planned and well-structured I would do implement his ideas into my master thesis to have a much clear expectation from myself and be able to plan better my way ahead. I think this would also give me the chance to do implement white box testing on my code and of-course more things to write about :-)

More structured and better plans a head

I need more of structure on coding and planing for my thesis. Things like simple UML diagrams that makes understanding the whole thing much easier. UML diagrams in different levels for different tasks. I also need test scripting to test my code while running it.
will be updated




Thursday, February 10, 2011

Artificial Intelligence

I am taking an Artificial Intelligence course at department of Informatics(INF5390), where Artificial Intelligence - A Modern Approach is the book. Our lecture believes in this book as a bible for AI and this makes it as a good reference in my master thesis as I see LOTS of similarities between what I have done/do/will do and what I learn here in an academic way. I think I can use this source both as an theory back-up for my master thesis and an explanation of my decision making process in my codes.

Thursday, January 20, 2011

Zero positioning, new ideas

Lately I have been working on mounting an Open Source 3D printer called RepRap(Version 1.0, Darwin). While working on it, I learnt about their brilliant idea for Zero Positioning. They use a tiny beam light sensor(Opto endstop V2.1) which is interrupted by a small stick which is connected to the moving joint. The interrupted state defines that the moving joint is in the zero position.

Picture from : RepRap Blog

Saturday, January 15, 2011

What is EEPROM / E2PROM ?


We do need a way to save the numbers which represents the current situation of the robot actuators somewhere(either at PC or somewhere on Arduino microcontroller, EEPROM here). This post dedicates itself to storing data on Arduino non-volatile memory and use this information for zero positioning of the moving joint. First an introduction to EEPROM from Wikipedia and later code example and links to its API's at Arduino website.

What is EEPROM ?
EEPROM (also written E2PROM and pronounced "e-e-prom," "double-e prom" or simply "e-squared") stands for Electrically Erasable Programmable Read-Only Memory and is a type ofnon-volatile memory used in computers and other electronic devices to store small amounts of data that must be saved when power is removed, e.g., calibration tables or device configuration.
When larger amounts of static data are to be stored (such as in USB flash drives) a specific type of EEPROM such as flash memory is more economical than traditional EEPROM devices. EEPROMs are realized as arrays of floating-gate transistors.
EEPROM is user-modifiable read-only memory (ROM) that can be erased and reprogrammed (written to) repeatedly through the application of higher than normal electrical voltage generated externally or internally in the case of modern EEPROMs. EPROM usually must be removed from the device for erasing and programming, whereas EEPROMs can be programmed and erased in circuit. Originally, EEPROMs were limited to single byte operations which made them slower, but modern EEPROMs allow multi-byte page operations. It also has a limited life - that is, the number of times it could be reprogrammed was limited to tens or hundreds of thousands of times. That limitation has been extended to a million write operations in modern EEPROMs. In an EEPROM that is frequently reprogrammed while the computer is in use, the life of the EEPROM can be an important design consideration. It is for this reason that EEPROMs were used for configuration information, rather than random access memory.*
Practical Information about how to get things to work : 

Source Code : 


#include EEPROM.h

int a = 0;
int value;

void setup()
{
Serial.begin(9600);
for (int i = 0; i < 20; i++){
    Serial.println("***");
    EEPROM.write(i, i);
  }
}

void loop()
{
  value = EEPROM.read(a);

  Serial.print(a);
  Serial.print("\t");
  Serial.print(value);
  Serial.println("***");
  a++;

  if (a == 20){
    a = 0;
    Serial.println("DONE");
    delay(5000000);
  }
}

* : Source : Wikipedia

Thursday, January 13, 2011

Problem of current position in case of loosing power & possible fixes ...

I think I have found my way to bear in mind the current position of the robot in case of the robot loosing power & not being able to drive itself back to the ZERO. The way is to either use the built in EEPROM(512 bytes), or other external storages which can be connected to Arduino. More info about EEPROM :


The 2nd option is to always send the position to the computer and save it somewhere there at the program(Lots of traffic on serial port, higher risk to encounter problem or missing packages).

Too tiered to fix it now ... Later ...

It matters to choose BYTE or INTEGER, BUG fixed + Handshaked protocol added

Just now fixed a bug in my code. Choosing BYTE as my variable type made some confusions on startup for the program as it couldn't initialize the variable with 0 value. The problem was fixed as soon as I changed the type to INTEGER. This resulted in errors in my program as no value made some random cases to launch which was totally wrong. This means that the bug on startup of my program which I talked to my supervisor today about is fixed :-) I was thinking as it just happened on startup to be a noise or some wrong reading from ports on Arduino, but it seems to be just a confusion on defining the variable as byte !!! I have also changed the startup value from 0 to -1 which result in no possible meaningful combination ...

Differences with previous code : Handshake added, Startup bug fixed, Some changes in standard writing to serial port from Arduino side.


//the code is entering saving with Java and we are printing as little as possible in Serial ports
// 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;
int cyclecounter[] = {0, 0, 0};
int cyclecounterold[] = {0, 0, 0};

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



void setup(){
  
  Serial.begin(115200);
  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);
    // just in case to be sure
    digitalWrite(pinDir[i], LOW);
    pinMode(pinEncA[i], INPUT);
    pinMode(pinEncB[i], INPUT);
    digitalWrite(pinEncA[i], LOW);
    digitalWrite(pinEncB[i], LOW);
    cyclecounter[i] = -1;
    cyclecounterold[i] = -1;
  }//end of for

}//end of setup()

void loop(){
    commandCenter();
    checkEncoder();
}//end of loop

void commandCenter(){
  //variables
  int temp = 0;
  if ( Serial.available() > 0 ){
    readValue = Serial.read();
    switch (readValue){
      case 'h' : //handshake
        Serial.println("h");
        break;
      case '0' ://motor #0
        int temp__;
        temp__ = 0;
        if(Serial.available() < 0)
          ;
        delay(500);
        temp__ = Serial.read();
        if (temp__ == 102){// -f -> forward
          Serial.println("*** Right forward ***");
          digitalWrite(pinDir[0], LOW);
          digitalWrite(pinPwm[0], HIGH);
        }//end of if
        else if(temp__ == 98){// -b -> backward
          Serial.println("*** Right backward ***");
          digitalWrite(pinDir[0], HIGH);
          digitalWrite(pinPwm[0], HIGH);
        }
        else{
         
          Serial.print("error ");
          Serial.println(temp__);
        }
        f = false;
        b = false;
        l = false;
        r = true;
        break;
      case '1' ://motor #1
        int temp_;
        if(Serial.available() < 1)
          ;
          delay(500);
          temp_ = Serial.read();
        if (temp_ == 102){// -f
          Serial.println("*1FW*");
          digitalWrite(pinDir[1], LOW);
          digitalWrite(pinPwm[1], HIGH);
        }//end of if
        else if(temp_ == 98){// -b
          Serial.println("*1BW*");
          digitalWrite(pinDir[1], HIGH);
          digitalWrite(pinPwm[1], HIGH);
        }
        else{
         
          Serial.print("error ");
          Serial.println(temp_);
        }
        f = true;
        b = false;
        l = false;
        r = false;
        break;
      case '2' ://l -> left
        temp_ = 0;
        if(Serial.available() < 1)
          ;
          delay(500);
          temp_ = Serial.read();
        if (temp_ == 102){//motor #2
          Serial.println("*2FW*");
          digitalWrite(pinDir[2], LOW);
          digitalWrite(pinPwm[2], HIGH);
        }//end of if
        else if(temp_ == 98){// -b
          Serial.println("*2BW*");
          digitalWrite(pinDir[2], HIGH);
          digitalWrite(pinPwm[2], HIGH);
        }
        else{
         
          Serial.print("error ");
          Serial.println(temp_);
        }        
        f = false;
        b = false;
        l = true;
        r = false;
        break;
      case 82 : //R->RESET
        Serial.println("*** Resetting ***");
        for (int i=0; i < 3; i++){
          digitalWrite(pinPwm[i], LOW);//Setting all PWM's to LOW
          Serial.print("C");
          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;
    
      switch (cyclecounter[i]){
        case (0) : {
           if ( cyclecounterold[i] == 0){
              ;//Do nothing
           }
           else if ( cyclecounterold[i] == 1){
             cycle[i]++;
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);
           }
           else if ( cyclecounterold[i] == 2){
                Serial.println("Error reading from Encoder-");
            }
           else if ( cyclecounterold[i] == 3){
              cycle[i]--;
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);
            }
            else 
                ;//Serial.print("ERROR");
            break;
        }//end of case-0
        case (1) : {
            if ( cyclecounterold[i] == 0){
              cycle[i]++;              
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);
            }
            if ( cyclecounterold[i] == 2){
              cycle[i]--;
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);            
            }
            else if ( cyclecounterold[i] == 3){
                Serial.println("Error reading from Encoder--");
            }
            else 
                ;//Serial.print("ERROR");
            break;
        }
        case (2) : {
            if ( cyclecounterold[i] == 1){
              cycle[i]--;
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);
            } 
            else if ( cyclecounterold[i] == 2)
              ;
            else if ( cyclecounterold[i] == 3){
              cycle[i]++;
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);
            }
            else if ( cyclecounterold[i] == 0){
                Serial.println("Error reading from Encoder---");
            }
            else 
                ;//Serial.print("ERROR");
            break;
        }//end of case-2
        case(3) : {
            if (cyclecounterold[i] == 0){
              cycle[i]--;             
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");
              Serial.println(cycle[i]);
            }
            else if (cyclecounterold[i] == 1){
              Serial.println("Error reading from Encoder----");
            }
            else if ( cyclecounterold[i] == 2){
              cycle[i]++;              
              Serial.print("C");
              Serial.print(i);
              Serial.print("-");            
              Serial.println(cycle[i]);
            }
            else if ( cyclecounterold[i] == 3)
              ;
            else 
              ;//Serial.print("ERROR");
            break;
        }//end of case-3
      }
      
      cyclecounterold[i] = cyclecounter[i];
      
  }//end of for

}//end of checkEncoder()

Wednesday, January 12, 2011

Meeting with my supervisor Mats Høvin, Summary

Today I met my supervisor Mats Høvin(associated professor at IFI,UiO). Here comes a summary of what he thinks I should be focusing on :

  • Handshake protocol. I do not have this protocol & this is something that according to Mats, I better have it implemented in my code
  • Zero Positioning. My suggestion to this challenge is to save the current position all the time either at PC side or at the Arduino non-volatile memory.
  • Sending data packages back & forth in serial communication would possibly result in loss of data packages. How can my code handle this kind of problems ?
  • Error on startup, fix for it ? Is it a programming error, or a hardware error because of Noise on reading inputs from ports ???
  • Sending many bytes and the delays resulting by that
  • The speed control, should be handled in java or Arduino ??? Maybe fast in the beginning and slow down little by little while reaching the end of the axle
  • Play off modus & Should it be target based, or follow every detail from the log blindly ??? Discuss ...
  • Camera candidates & streaming , but not image processing -> Intelligent cameras with output ports(how many???) for sending commands to Arduino according to the image processing done by camera itself.
  • Using WiFi tech & how ??? WiFly component ?
  • Programing a simulator in JAVA (xyz generation and visualization in JAVA)
  • PHP/JAVA Applet GUI & Streaming show on website
  • Multi Arduino card solutions ? Benefits and disadvantages ??? Discuss ...
  • FPGA??? A possible solution instead of Arduino? Discuss ...
  • Different methods to read data from encoders, External interruptions or software methods reading encoders value by analogRead() on loop frequence. Discuss based on Atmel/AVR architecture
  • Positioning in the room & semi-Kinect sensors

Friday, January 7, 2011

Robot foot Control Panel(in Java) for the robot feet, version 0.01

This is the first snapshot of a GUI for the Robot foot Control Panel in Java that I am designing right now. I do not have much trouble with it and it looks promissing :-) Updates of the code and more snapshots come soon ...

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

RxTx API, Java

By clicking on the following link you can have access to the full directory of RxTx library API's in Java :

Thursday, January 6, 2011

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 < 3; i++){
    pinMode(pinDir[i], OUTPUT);
    pinMode(pinPwm[i], OUTPUT);
    //in case, just to be sure ...
    digitalWrite(pinPwm[i], LOW);
    // just in case to be sure
    digitalWrite(pinDir[i], LOW);
    pinMode(pinEncA[i], INPUT);
    pinMode(pinEncB[i], INPUT);
    digitalWrite(pinEncA[i], LOW);
    digitalWrite(pinEncB[i], LOW);
    cyclecounter[i] = 0;
    cyclecounterold[i] = 0;
  }//end of for
  
}//end of setup()

void loop(){
    commandCenter();
    checkEncoder();
}//end of loop

void commandCenter(){
  //variables
  int temp = 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
        int temp_;
        temp_ = 0;
        if(Serial.available() < 1)
          ;
          delay(5);
          temp_ = Serial.read();
        if (temp_ == 102){// -f
          Serial.println("*** Left forward ***");
          digitalWrite(pinDir[2], LOW);
          digitalWrite(pinPwm[2], HIGH);
        }//end of if
        else if(temp_ == 98){// -b
          Serial.println("*** Left backward ***");
          digitalWrite(pinDir[2], HIGH);
          digitalWrite(pinPwm[2], HIGH);
        }
        else Serial.println("*** NOTHING ***");
        f = false;
        b = false;
        l = true;
        r = false;
        break;
      case 114 ://r -> right
        int temp__;
        temp__ = 0;
        if(Serial.available() < 0)
          ;
        delay(5);
        temp__ = Serial.read();
        if (temp__ == 102){// -f
          Serial.println("*** Right forward ***");
          digitalWrite(pinDir[0], LOW);
          digitalWrite(pinPwm[0], HIGH);
        }//end of if
        else if(temp__ == 98){// -b
          Serial.println("*** Right backward ***");
          digitalWrite(pinDir[0], HIGH);
          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++){
          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()