Posts Tagged ‘Processing’

New code for the motor part of the X-bot

Posted in Arduino, Processing, Self balancing robot on April 22nd, 2011 by x-firm – Comments Off

I have recoded the motor part and added the encoder for the other motor and made a PID for each motor that takes the output from the current PID. This for trying to get the two motors to behave equal. The original PID is only looking on the right motor encoder as before. But I’m calculating the current speed in pulses/10ms for each motor and then using that and the output from the old PID to control the motors for a requested speed in pulses/10ms..

That feels better than just sending a value of 0-255 that has no connection to the speed of the motor that are depending on the surface and battery level.

I have made a new sketch for the bot and a GUI to make settings and testing the motor PIDs you can download it from this links:
Motor_PID_Enc_v2 (Bot code)
Motor_PID_Enc_v2 (GUI)

Calibrating/testing the motors and encoders..

Posted in Arduino, Processing, Self balancing robot on November 24th, 2010 by x-firm – Be the first to comment

I started to check the differences of the motors by using the encoders to try to see the distance the motors turned in a constant time and get a factor for the diff. I drive the motors in both directions in four different speeds 50, 100, 200, 250..

I made a sketch for the Arduino and a GUI sketch in processing based on the Balancing Bot GUI, and thought that this cant be so hard to do just see the diff. and calculate a factor for the faster motor but that was not the case..

The first run gave me the results like in the image below, where the motors behaved very different in forward to backward motion. When going forward for a time constant(2000ms) and then sending the drive_motor(0) the motor continued running in free spin for a short while. But when running backward the motor brakes for a short while.

Click for larger image

Speed   L           R

255    7662   :  7413

-255   -5516  :  -5541

150    6582   :  6386

-150   -4901  :  -4872

50     3342     :  3291

-50    -2747   :  -2705

As you can see the behavior is very different in the two directions..

I changed the drive_motor function like below and tried again and the result was better but is I going about this in the right way?

int Drive_Motor(int torque)  {
  if (torque > 0)  {
    // drive motors forward
    digitalWrite(InA_R, LOW);
    digitalWrite(InB_R, HIGH);
    digitalWrite(InA_L, LOW);
    digitalWrite(InB_L, HIGH);
    forward = true;
  }else if(torque < 0) {     // drive motors backward
    digitalWrite(InB_R, LOW);
    digitalWrite(InA_R, HIGH);
    digitalWrite(InB_L, LOW);
    digitalWrite(InA_L, HIGH);
    torque = abs(torque);
    forward = false;
  }else{
    if(forward){
      digitalWrite(InA_R, HIGH);
      digitalWrite(InB_R, LOW);
      digitalWrite(InA_L, HIGH);
      digitalWrite(InB_L, LOW);
    }else{
      digitalWrite(InA_R, LOW);
      digitalWrite(InB_R, HIGH);
      digitalWrite(InA_L, LOW);
      digitalWrite(InB_L, HIGH);
    }
  }
  //if(torque>5) map(torque,0,255,30,255);
    analogWrite(PWM_R,torque * motorOffsetR);
    analogWrite(PWM_L,torque * motorOffsetL);
    Serial.println(torque,DEC);
}

Now it looks like the Arduino and the motor controller is behaving in the same way in both directions. I need to take some more readings to see if the differences that are left are linear in some way.. It feels like there are a difference between the motors in both directions but also that both motors are going faster forward, and that I think is created by the motor control??..

See image below..

Click for larger image

Heres the Arduino sketch I used..

Heres the Processing sketch I used..

The main part of the Arduino sketch:

// KasBot Encoder test V1  -  Main module       basic version, angles in Quids, 10 bit ADC
/*
  Description:
  The KasBot Encoder test Vx is made for checking that the encoder signal workes and
  to tune the diffrenses from your motors..

  This code is aimed for the Encoder test GUI v1.0

  Version log:

  v1.0  -

*/

#define   InA_R          6                      // INA right motor pin
#define   InB_R          7                      // INB right motor pin
#define   PWM_R          10                     // PWM right motor pin
#define   InA_L          8                      // INA left motor pin
#define   InB_L          9                      // INB left motor pin
#define   PWM_L          11                     // PWM left motor pin
#define encodPinA_R      3                      // encoder A pin left motor
#define encodPinB_R      5                      // encoder B pin right motor
#define encodPinA_L      2                      // encoder A pin left motor
#define encodPinB_L      12                     // encoder B pin right motor

#define LOOPTIME         100                    // PID loop time
#define FORWARD          1                      // direction of rotation
#define BACKWARD         2                      // direction of rotation

#define DELAY_TIME       5000                   //Time to delay after motion
#define RUN_TIME         2000                   //Time to run motor

int speeds[] = {50, 100, 200, 255};
int speedIndex = 0;

int STD_LOOP_TIME  =  9;             

int lastLoopTime = STD_LOOP_TIME;
int lastLoopUsefulTime = STD_LOOP_TIME;
unsigned long loopStartTime = 0;

unsigned long delayStart = 0;

long count_R = 0;                                 // rotation counter right motor
long count_L = 0;                                 // rotation counter left motor

boolean frwMotion = true;                         // motor moves

void setup() {
  pinMode(InA_R, OUTPUT);
  pinMode(InB_R, OUTPUT);
  pinMode(PWM_R, OUTPUT);
  pinMode(InA_L, OUTPUT);
  pinMode(InB_L, OUTPUT);
  pinMode(PWM_L, OUTPUT);

  pinMode(encodPinA_R, INPUT);
  pinMode(encodPinB_R, INPUT);
  digitalWrite(encodPinA_R, HIGH);                      // turn on pullup resistor
  digitalWrite(encodPinB_R, HIGH);
  attachInterrupt(1, rencoder_R, FALLING);

  pinMode(encodPinA_L, INPUT);
  pinMode(encodPinB_L, INPUT);
  digitalWrite(encodPinA_L, HIGH);                      // turn on pullup resistor
  digitalWrite(encodPinB_L, HIGH);
  attachInterrupt(0, rencoder_L, FALLING);

  Serial.begin(19200);
}

void loop() {
// ********* Simple motor test for serial monitor ***********************

  //motorDebugForSerialMonitor();

// *********************** Motor drive **********************************
  //Turns motors on for RUN_TIME and then off for DELAY_TIME
  if((millis() - delayStart) <= RUN_TIME){
    if(frwMotion){
      Drive_Motor(speeds[speedIndex]);
    }else{
      Drive_Motor((speeds[speedIndex] * (-1)));
    }
  }else if((millis() - delayStart) > RUN_TIME){
    Drive_Motor(0);
  }

  if((millis() - delayStart) >= (RUN_TIME + DELAY_TIME)){
    delayStart = millis();
    if(frwMotion){
      frwMotion = false;
    }else{
      speedIndex++;
      frwMotion = true;
    }
    clearCounts();
    if(speedIndex >= 3) speedIndex=0;
  }

 // *********************** print Debug info *****************************
  serialIn_GUI();       //Processing information from a pc
  serialOut_GUI();	//Sending information to pc for debug

 // *********************** loop timing control **************************
  lastLoopUsefulTime = millis()-loopStartTime;
  if(lastLoopUsefulTime<STD_LOOP_TIME)         delay(STD_LOOP_TIME-lastLoopUsefulTime);
  lastLoopTime = millis() - loopStartTime;
  loopStartTime = millis();

}

void clearCounts(){
  count_L = 0;
  count_R = 0;
}

void motorDebugForSerialMonitor()
{
  Drive_Motor(255);
  delay(2000);
  Drive_Motor(0);
  delay(500);
  Serial.print(count_L,DEC);
  Serial.print(" : ");
  Serial.println(count_R,DEC);
  clearCounts();
  delay(4500);

  Drive_Motor(-255);
  delay(2000);
  Drive_Motor(0);
  delay(500);
  Serial.print(count_L,DEC);
  Serial.print(" : ");
  Serial.println(count_R,DEC);
  clearCounts();
  delay(4500);

  Drive_Motor(150);
  delay(2000);
  Drive_Motor(0);
  delay(500);
  Serial.print(count_L,DEC);
  Serial.print(" : ");
  Serial.println(count_R,DEC);
  clearCounts();
  delay(4500);

  Drive_Motor(-150);
  delay(2000);
  Drive_Motor(0);
  delay(500);
  Serial.print(count_L,DEC);
  Serial.print(" : ");
  Serial.println(count_R,DEC);
  clearCounts();
  delay(4500);

  Drive_Motor(50);
  delay(2000);
  Drive_Motor(0);
  delay(500);
  Serial.print(count_L,DEC);
  Serial.print(" : ");
  Serial.println(count_R,DEC);
  clearCounts();
  delay(4500);

  Drive_Motor(-50);
  delay(2000);
  Drive_Motor(0);
  delay(2000);
  Serial.print(count_L,DEC);
  Serial.print(" : ");
  Serial.println(count_R,DEC);
  clearCounts();
  delay(4500);

  while(true){delay(100);}
}

New version of the Balancing Bot GUI

Posted in Arduino, Processing, Self balancing robot on November 17th, 2010 by x-firm – Be the first to comment

New version of the bot code:

KasBotV1
KasBotV1.2_Serial (Use this one when using the Balancing Bot GUI)

New version of the GUI:

BalancingBotGUI v1.2

Currently you will see trends for the following values:
- ACC_X, _Y, GYR_Y
- actAngle, ACC_angle
- pTerm, iTerm, dTerm
- drive

You can also see and change the following values:
- setPoint
- K
- Kp
- Ki
- Kd

The balancing bot GUI beta

Posted in Processing, Self balancing robot on November 5th, 2010 by x-firm – Be the first to comment

Heres the first beta version of the Balancing Bot GUI and it includes one widget that are a dynamic graph…

  • You can add as many graphs as you want and set the size and shape of them.
  • You can maximiz a graph
  • You can also move it in real time

Right now you can only show information from the bot, but I will soon update the GUI with the possibility to change parameters in the bot.

Below is a image of the GUI that are using three Graph widgets:

Heres the code from the example above…

Sketch for Processing IDE:

Download and unzip the folder in your sketch directory. Change the serial port to the corresponding for you computer…

Complete sketch


GUI for balancing robot

Posted in Processing, Self balancing robot on November 3rd, 2010 by x-firm – Be the first to comment

I have started to look on a GUI for a balancing robot and it is specifically aimed for the Arduino code made for the  Balancing Robot for dummise that are driven under this post in the Arduino forum.

I want to have the GUI widget based so all users can customize to only have the things they think is important to see and also be able to reorder things on the screen.

I have made one widget to show the proof of concept that are explained below:

I have planed some more widget like:

  • Menu widget where you can see all minimized widgets and press  on them to show them again.
  • Serial settings widget, open and close the communication and select port
  • Parameter setting widget. To change one or more parameters
  • Bot tilt view, see a graphical representation of the bots tilting angle
  • etc.

Start to a PacMan game

Posted in Processing on November 1st, 2010 by x-firm – Be the first to comment

I started on makeing a PacMan game a evening when I was board but I don’t think It will ever be finished. It was a fun little project where I learned some new things about transformations in processing…

You can try It here (Control PacMan with the arrow-keys)

Success with sensor fusing using kalman filter…

Posted in Arduino, Processing, Self balancing robot on October 30th, 2010 by x-firm – Be the first to comment

I have been reading the Balancing robot for dummies thread and thanks to all good posts there and all answers on my stupid questions. It wasn’t so hard to get it to work..

Here is a video showing the filtered angel in the top and the unfiltered angel from the acc. in the lower part of a sketch made in processing.

The sketch is from -> http://wiki.processing.org/w/Tom_Igoe_Interview

Bar graph to show values from a Arduino

Posted in Arduino, Processing on October 16th, 2010 by x-firm – Be the first to comment

I have made a Bar graph in Processing for showing temperature readings made by a Arduino but can be used for many other things.

You can set the range it should show and also where the zero should be. You can also zoom in and out from the value and set the current value to zero. You can when ever reset the bar to the default value.

You can try it here: Bar

First small project with the Arduino

Posted in Arduino on October 11th, 2010 by x-firm – Be the first to comment

Now I have made my first small project with the Arduino. I wanted to use a 4×20 LCD display to show the temperature readings from a Dallas DS18B20 temperature sensor.

I started to check out the LiquidCrystal library and found a “Hello World” example that I tried with successes. I just followed the example but ended up making some small adjustment with the wiring because different specs. on my LCD display to the one in the example.

I run the LCD display in 4 bit mode like in the example I talked about above with now problems, the library is integrated in the Arduino 0021 IDE that I used..

After that I wonder how I should connect and use the Temperature sensor with the Arduino. And after some checking under the Arduino Playground I found a link to the fantastic Dallas Temperature Control Library that makes it unbelievable easy to use a DS18B20 sensor. You just add a pull up 5kohm resistor between the middle pin and +5V, the other two pins to GND. Then you put a wire between the middle pin and a digital pin on the Arduino(I used pin 7).

The library gives you the possibility to connect more sensors in series and still only uses one pin of the Arduino.

The readings from the sensor is where fast and stable and with the possibility to put more sensors in series this sensor is very impressive.

I also made a fast sketch in Processing to show the values with some graphical controls that I have been working on. They are intended for my future GUI that a should use with my Balancing Robot.

I made a movie that demonstrates the project:

Source code Arduino:
LCD.pde

Source code Processing:
BarContest.pde
BarGraph.pde
Meter.pde

Command Bar

Posted in Processing on October 5th, 2010 by x-firm – Be the first to comment

I made a command bar that works like a ordinary GUI textbox but it buffers the last commands so you can easily and fast repeat a command.

It has all the normal function where you can move the marker left end right with the arrow tangents. If you press up or down you will move true the buffer of commands. It also supports delete and backspace functions.

To run and insert a command press enter after typing it or have selected one from the buffer.

There are some small things left to fix like the buffers should fade out when not moving true the buffer any more.

Here you can test a example: Command Bar test (Activate the textbox by clicking on it)