Crea sito

Archive for July, 2011

Charting data sent via serial port in real time

Often it is needed to chart in real time the values coming from the serial port (RS-232). In Arduino environment it is a common need. If you have some values, only one possibility is offered by the Arduino IDE: to use the serial monitor. But on the serial monitor, the values are textual and also they are difficult to read during the elaborations. You can use Processing, but Processing is complicated when you like to show many graphics or when you like to see graphic and text values, when you like to customize the graphic. You must program in Java.
I discovered a simple tool made with QT graphic libraries, that needs only a light parametrization for plotting in an easy way the serial values. The sw is SERIALCHART.
Easily it is possible to customize the graphic and modify the colors without become crazy. The sw is explained here. You have to use also an easy configuration file explained here.
I made a test to see in a graphic the values read by a 3-axis accelerometer wired to an Arduino.

The code to read 3 axis from Arduino is very easy:

// read x,y,z accelerometer values

// set input variables
int analogInput0 = 0;
int analogInput1 = 1;
int analogInput2 = 2;

// store input variables
int value0 = 0;
int value1 = 0;
int value2 = 0;

void setup(){

// set input pins
pinMode(analogInput0, INPUT);
pinMode(analogInput1, INPUT);
pinMode(analogInput2, INPUT);

// begin serial port communication
Serial.begin(9600);
}

void loop(){
// read accelerometer values
value0 = analogRead(analogInput0);
value1 = analogRead(analogInput1);
value2 = analogRead(analogInput2);

// print values in the serial port, separated by comma
Serial.print(value0);
Serial.print(",");
Serial.print(value1);
Serial.print(",");
Serial.println(value2);

// wait and loop again
delay(100);   }

The output produced by SerialChart is shown in the picture below, where I inserted also the parametrization made.


Tags: , ,

YASBR – Yet Another Self-Balancing Robot

The self-balancing robot building is today an activity that every robot builder can perform with Arduino.  Searching in Google for self-balancing robot you can find tons of realizations, with tons of different sensors and control systems. So to build a self balancing robot is a standard task for the robot builder, like a simple home rover.

Trying  to be at least original, I though to build a self balancing robot with these goals:

  • low-low-cost
  • simple in the hardware
  • simple in the software

So I tried to build a self-balancing robot using only one sensor: a Sharp IR distance sensor e nothing else. No gyro, no accelerometer, no other sensors. All is self-built, in the DIY pure spirit.

These are the components used:

  • Plexiglass chassis
  • Wheels for servo (Boe-Bot wheels). At first time I tryied to use two trolley wheels, but without success
  • Servos modified
  • Sharp IR sensor 10-80 cm
  • Arduino 2009
  • 2 batteries pack 4×1,2V
  • some screws, jumpers etc.

We are under 100 euros, a good results concerning the cost.

This is the phase of  the chassis  building, transparent and in plexiglass. In particular, the chassis cuts has been made with a simple cutter, after the holes has been made with a drill.

The plexiglass before the cutting:

 

The chassis cutted with holes:

 

 

1st floor – the wheels (the trolley ones):

 

 

 

Here  is the robottino completed and mounted. You can see the IR Sharp sensor, upon a little arm outside the chassis. I built a robot with 3 floors, in order to study the distribution of the weight on the stability.  Actually, I didn’t  make important tests on it. On the Arduino 2009, I put a shield with the breadboard and on the breadboard an accelerometer. Now the accelerometer is not wired, but in the future, perhaps, I will use it.

 

Yasbr picture 2:

 

 

Yasbr picture 3:

 

 

Some construction detail about the robot. The control algoritm uses a PI control, a PID  where the derivative term is equal to zero. The signal coming from the IR sensor is filtered in a very simple mode. 10 values are read, then they are sorted and cancelled the ‘tails’, i.e. the 2 value littlest and 2 values biggest and with the 6 values remaining I made  the average. So there aren’t kalman filter or similar. The IR signal is enough clean to do a simple average. The sensor have a 10-80 cm range and it has a trasfer function voltage-distance similar to an hyperbole in the working range, so I tried to put it in the point of maximum sensibility, in order to obtain the maximum voltage variation compared with the distance.
At the beginning I tried to use only the P term of the PID control (only Kp different to zero). I passed many hours searching  to find the balance, but I never had a success, so I confirmed the theory that says that with the only proportional term you can obtain only some oscillations.Introducing the integral term (Ki different to zero) I obtained an immediate benefice and with some test I found the balance value.

I made some attempts to introduce a disturbance (with a push) to see the rejection of the disturbance. As you can see the situation could be better, because after a few seconds the robot is in resonance, but at the end it can hold in balance. This is due to the lack of the derivative term (Kd) wich serves to limit the oscillations.

 

 

Some considerations: the robottino is extremely sensitive to the change of control coefficients. In fact, changing only 10% of the coefficients Ki and Kp, the robot can’t hold in balance. I can say that I had fortune to find a couple of correct parameters. Putting the weight of the batteries from one floor to another, I couldn’t find the right parameters for the balance. So finding the right parameters is a patience work. I think that  using only one sensor is a ‘limit’ situation in order to get the balance. So my advise is use two or more sensors!

This is the code, commented:

 

// ************************************************************************************

// INITIAL VARIABLES - VARIABILI INIZIALI

// *************************************************************************************
#include "Servo.h" //include servo library
Servo sservo;
Servo dservo;
int value0=0;
float H; // balance IR sensor - valore dell'IR all'equilibrio
int analogInput0 = 0;
float distance=0;

//PID variables - variabili PID
float error=0;
float previousError=0;
float time=0;
float P = 0;  // proportional control - controllo proporzionale
float I = 0;  // integral control - controllo integrale
float D = 0;  // derivative control - controllo derivativo

// PID gain - guadagni dei coefficienti PID
float kP = 45;  // proportional gain - guadagno proporzionale
float kI = 30;  // integral gain - guadagno integrale
float kD = 0;   // derivative gain - guadagno derivativo
int t;

//***********************************************************************************
// SETUP() - INITIAL OPERATION - OPERAZIONI INIZIALI
//***********************************************************************************
void setup() {
Serial.begin(9600); // Sets the baud rate to 9600 - imposta il baud rate a 9600
pinMode(analogInput0, INPUT);   // set the IR Sharp sensor as input - imposta il sensore Sharp come input
sservo.attach(9);  // attaches the servo on pin 9 to the servo object - LEFT - servo sinistro sul pin 9
dservo.attach(10);  // attaches the servo on pin 10 to the servo object - RIGHT - servo destro sul pin 10

// read IR initial value (balance value) - leggi il valore iniziale dell'IR (valore di equilibrio)
delay(300);
readIR();
delay(50);
readIR();
delay(50);

// distance at balance (in volts) - distanza in equilibrio (in volt)
H=distance;
}

// *******************************************************************************
// LOOP() - MAIN CYCLE - CICLO PRINCIPALE
// *******************************************************************************
void loop()
{
calcError(); //calculate vertical position error - calcola l'errore rispetto alla verticale
// loop cycle time calculation - calcolo tempo del ciclo loop
float previousTime = time;
time = millis();
float interval = time - previousTime;
// calculate PID coefficient - calcola i coefficienti del PID
P = error * kP / 1000;
I = I + (P * interval) * kI / 10000;
if (I > 20) I=20; //limit the integral - limita l'integrale
float PID = P + I + D;
if (I > 90) PID = 90; //value PID between -90 and 90
if(PID = -1 && PID < 0) PID = 0; //taglia le micro-correzioni
// move the servos - muovi i servomotori
sservo.write(90 - PID);
dservo.write(90 + PID);
previousError=error;
}
// *********************************************************************************
// readIR() - Read IR sensor - Leggi il valore del sensore IR
// ********************************************************************************
void readIR() {
int impulses=0;
int i, n;
int val[10];
int j, app;
// read n=10 values from IR sharp sensor
n=9;
// read n=10 values from IR sharp sensor - leggi n=10 valore del sensore IR sharp
  for (i=0; i<n; i++){
    val[i]=analogRead(analogInput0);
  }

  // sort 10 values read from IR sharp sensor
  for (i = 1; i <= n; i++)
  {
    app = val[i]; 
    for (j = i - 1; (j >= 0) && (val[j] > app); j--)
      val[j+1] = val[j];
    val[j + 1] = app;
  }
impulses=0;
// consider only 6 values (discard left and right tails) - considera solo 6 valori (elimina le code sinistra e a destra)
for(i=2; i<=n-2; i++)
{
impulses  =  impulses+val[i];
}
distance=impulses/(n+1-4); // calculate 6 values average - calcola la media dei 6 valori
}
// *******************************************************************************
// calcError() - calculate balance error (in volts) - calcola l'errore rispetto all'equilibrio (in volt)
// *******************************************************************************
void calcError()
{
readIR();
error = distance - H;
}

Tags: ,

Simple audio player with Arduino

A small audio chip is available on the market at low cost (20 euros) that allows to build  an audio player managed with buttons or via serial port, for example with Arduino.

 

This chip is manufactured by 4DSystems  (www.4dsystems.com.au), an Australian company (ahhh the globalization!) which works mainly on LCD graphical modules. Among others, the company also produces the SOMO-14D (link), an audio chip that can play back pre-stored audio files such as voice and music from a micro-SD memory card (max. 2 gb).

The files are saved in ADPCM format, that isn’t a popular format, but it is available a practical conversion sw that in a fast mode can convert .WAV, MP3 etc.

The module SOMO-14D can be managed in: SERIAL-MODE and KEY-MODE.

Using the KEY-MODE the chip works stand-alone and it can be piloted with 3 buttons. 3V for the power and a little speaker (0.5W) are enough.

I made the circuit in a breadboard, but I forgot to take a photo, so I  have nothing to show about the KEY-MODE.

The other possibility is to use the SERIAL-MODE, which allows you to drive the chip with a small microcontroller. Arduino is perfect. There are 4-wires connections and then you can use directly the Arduino to set the play, stop etc.

Is available on the internet (link) a sketch that shows all potential of the chip. I got this chip because i’m interested on to make a talking robot.

I searched in internet for a chip that may allows to implement a text-to-speech in italian on Arduino, but without good results. It is possible to use a sw on a PC windows to make the text-to-speech. After that you can save the audio file obtained on the SOMO-14D  to let the robot to say the right word at the right moment.

In particular, I used the the SW DSpeech, that is a good text-to-speech sw.

I made a little video in order to see the SOMO-14D in action with Arduino. I’m sorry for bad video quality, but I’ve taken it with the cell phone

 

 

Tags: , ,