Show Posts
Pages: [1] 2 3
1  Using Arduino / Programming Questions / Using delays inside loop on: April 13, 2014, 07:55:25 am
Hello,
I'm currently working on an arduino code for a line follower competition. The rules say the robot has to wait on many occasions during his circuit. (Like when it detects a red zone it has to wait 4 seconds then keep going).

So inside my loop I have my readSensors() function which should keep reading at regular intervals. How should I implements the delays to make the robot wait without stopping other stuff like readSensors() function ?

First circuit :

Second circuit :


Notice the various stops throughout the circuits.

Thank you
2  Using Arduino / Microcontrollers / I2C communication with a device with a fix adress on: March 11, 2014, 07:06:03 pm
Hello everyone,

I would like to communicate with two or more of these proximity sensors :
https://www.sparkfun.com/products/10901

The datasheet says they have a fix adress (0x13).
My question is : Is it possible to change that adress in order to communicate with two or more sensors using the same SDA and SCL pins ?
If i'm using a Leonardo or a Mega (which have additional I2C pins) can I wire one sensor to SDA and SCL pins and the second sensor to SDA1 and SCL1 pins ?

Then would I be able to communicate with both sensors despite the fix address ?

Thank you very much in advance smiley
3  Using Arduino / Programming Questions / C/C++ Serial communication library on: April 25, 2013, 11:17:45 am
Hello,
I'm looking for a simple and easy-to-use Serial communication library in C or C++

Any suggestions?
4  Using Arduino / Programming Questions / Re: Xbee to Xbee Serial Communication on: May 22, 2011, 08:32:32 am
Yeay it worked when I put the Serial2.read() in a char variable...
Now, why is it printing an " à " when I'm sending  "A" ?  smiley-grin
5  Using Arduino / Programming Questions / Xbee to Xbee Serial Communication on: May 22, 2011, 07:15:40 am
Hi,
So I wanted to see if I could establish a communication between two xbees series 1, each connected ton an arduino...

Sender :
Xbee + Xbee shield + arduino Uno
Code:
void setup()
{
  Serial.begin(57600);
}

void loop()
{
 Serial.print("A");
 delay(1000);
}

Receiver :
Xbee + Xbee shield + arduino Mega 1280
Code:
void setup()
{
 Serial2.begin(57600);
 Serial.begin(57600);
}

void loop()
{
  if (Serial2.available() > 0)
  {
    Serial.println("Serial data received: ");
    while(Serial2.available() > 0)
    {
Serial.println(Serial2.read());
    }
    delay(1000);
  }
}

I connected the sender xbee serial with the receiver arduino on serial2 (TX2 on digital pin 16 ; RX2 on digital pin 17)
And it actually works!
Problem is : I'm sending a letter, and on the other end I'm getting a "224"  smiley-eek
6  Using Arduino / Programming Questions / Re: Using the MsTimer2 library efficiently on: May 16, 2011, 12:32:48 pm
Yeah it works... when I put the dead_reckoning() function in loop...
But I'm afraid of timing problems...so could you explain to me the bit about (millis() - previousLoopTime) * 0.001 ?
How can I use it to adjust the sample time for my fuction??
7  Using Arduino / Programming Questions / Re: Using the MsTimer2 library efficiently on: May 16, 2011, 03:33:29 am
I tried, nothing changed....
And then I tried not using the MsTimer function, the motors worked... smiley-eek
So there's clearly some kind of conflict between Ms timer and the motor commands in the main loop...
8  Using Arduino / Programming Questions / Re: Using the MsTimer2 library efficiently on: May 16, 2011, 01:51:53 am
For the interrupts there's no problem, since I'm using an Arduino Mega, MsTImer3 and my encoders are using each a different interrupt. Actually, when I upload this code, when I push the robot manually forward, backwards, and if I turn it left and right, I can see on the monitor that my dead reckoning works. I see the x,y and theta coordinates changing, and when I make the robot do a full turn on itself, the theta value goes from 0 to 360°, so I think encoders, and the dead reckoning function are all working just fine. But as you see on the loop, I'm telling it to turn on itself whil (theta<360) but motors simply don't run. So I don't understand...
MS timers happens outside the loop, every 5ms, encoders ticks also increment and decrement outside the loop, so what's left in loop is the Serial prints and the motor commands....the serials are working, the motors Not... smiley-eek-blue
9  International / Français / Utillisation de la bibliothèque MsTimer2 on: May 15, 2011, 07:49:00 pm
Bonjour,

Mon projet est de faire de l'odométrie interne en temps réel à l'aide de codeurs rotatifs ...
Ce que j'ai réussi à maîtriser avec mon robot à ce jour:
     - Reconnaître le sens de rotation des roues et incrémenter / décrémenter les pas en conséquence en utilisant les interrupts;
     - Calculer l'absolu les coordonnées (x, y, theta) de mon robot à un instant t;
     - Utilisation de la librairie MsTimer2, pour exécuter la fonction d'odométrie, avec une période de 5 ms;
Le problème, c'est que quand j'ai ajouté à tout ça la commande des moteurs pour faire mon robot aller à un point de coordonnées données... les moteurs ne fonctionnent pas smiley-eek
Voici mon code ...

Code:
#include <MsTimer2.h>

///////////////////////////////////////////////////////
//////////////////////VARIABLES////////////////////////
///////////////////////////////////////////////////////

// variables et pins des codeurs et interrupts
int encoderPinB[2] = {25,22}; // Encoder B pin
long encoderTicks[2];
int odoGPin = 4; // 4 pour la patte Digital 19
int odoDPin = 5; // 5 pour la patte Digital 18

// Définition des constantes
#define COEF_D 11.0184191 // 1 cm    ->  11 pas incrémentaux
#define COEF_ROT 4.352083 // 1 degré ->  4,35 pas
#define PI 3.14159265
#define CONV_RD PI/(180*COEF_ROT) //conversion de teta en pasà teta en radian

//  Définition des variables globales
long distance,distance_precedente ; // dist : distance parcourue à l'instant tn ; distance_precedente : distance parcourue à l'instant tn-1
long orient, orient_precedente, orient_init ; // orient : angle mesuré à l'instant tn , orient_precedente : angle mesuré à l'instant tn-1 ; orient_init : angle initial
float x, y; // coordonnées (x,y) en pas
int x_cm, y_cm ; // coordonnées (x,y) en cm

// Variables et constantes Commande de moteurs
 #define TOPSPEED 200
 #define FORWARD_SPEED 150
 #define TURN_SPEED 60
 // motor Gauche
 int dir1PinA = 13;
 int dir2PinA = 12;
 int speedPinA = 10;
 // motor Droit
 int dir1PinB = 11;
 int dir2PinB = 8;
 int speedPinB = 9;
 int oam_speed[2]={0}; //oam_speed[0] = gauche; oam_speed[1] = droite

  // variables d'odometrie
  int delta_d, delta_orient; // differentiel de distance , differentiel d'angle
  long orient_moy ; // moyenne entre angle et angle précedent
  float orient_moy_radian, delta_orient_radian ; // Les mêmes convertis en rad
  float K=1, dx,dy; // K=1 : interpretation linéaire  ; dx,dy : differentiels en x et y

///////////////////////////////////////////////////////
//////////////////////FUNCTIONS////////////////////////
///////////////////////////////////////////////////////

// Conditions initiales
void fonction_initialisation (float x0, float y0, long teta0)
{
  orient_init = teta0 ;
  orient_precedente = teta0 ;
  x = x0 ;
  y = y0 ;
  distance = 0 ;
  distance_precedente=0 ;
}

// Interruption executée toutes les 5ms
void update()
{
  calcul_xy () ; // La fonction qui nous intéresse

  // Garder l'angle dans un intervalle [0,2*pi]
  while(orient_moy_radian<0){orient_moy_radian+=2*PI;}
  while(orient_moy_radian>2*PI){orient_moy_radian-=2*PI;}
}

//Calcul de x et y
void calcul_xy (void)
{
  distance = ((encoderTicks[1]+encoderTicks[0])/2); // distance en pas parcourue à tn
  orient = orient_init +(encoderTicks[1]-encoderTicks[0]); //correspond à qn mais en pas
  delta_d = distance - distance_precedente; // correspond à L mais en pas
  delta_orient = orient - orient_precedente; // correspond à Dqn mais en pas
  orient_moy = (orient +orient_precedente) / 2;  // correspond à qmoy en pas
  delta_orient_radian = CONV_RD*delta_orient; // correspond à Dqn en rd
  orient_moy_radian = CONV_RD*orient_moy; // correspond à qmoy en rd
 
  dx=K*delta_d*cos(orient_moy_radian);
  dy=K*delta_d*sin(orient_moy_radian);
  x= x + dx; // valeurs exprimées dans le système d’unité robot
  y= y + dy;
  x_cm=(int)(x/COEF_D); // Ce calcul peut être fait en dehors de la fonction
  y_cm=(int)(y/COEF_D); // quand on en a besoin
  orient_precedente = orient ; // actualisation de qn-1
  distance_precedente = distance ; //actualisation de Dn-1
}
// Codeur incrémental gauche
void incL(){   
  if (digitalRead(encoderPinB[0]) == HIGH){ 
     encoderTicks[0]++;
       
  } else { 
     encoderTicks[0]--; // arrêt du moteur         
  } 


// Codeur incrémental droit
void incR(){ 
  if (digitalRead(encoderPinB[1]) == LOW){ 
     encoderTicks[1]++;
         
  } else { 
     encoderTicks[1]--; // arrêt du moteur
  } 
}

void  init_encoders(){
pinMode(encoderPinB[0], INPUT); // Encoder pin B INPUT
pinMode(encoderPinB[1], INPUT); // Encoder pin B INPUT
}

void setup (){
   
  fonction_initialisation(0,0,0);
  // démarrage de la liaison série
  Serial.begin(38400);
  init_motors(); // Motor Pin intialization
  init_encoders(); //Encoders Pin initialization
 
  // attach the odometer interrupt
  attachInterrupt(odoGPin, incL, RISING); //18
  attachInterrupt(odoDPin, incR, RISING); //19
  // utilisation du timer 2 pour gérer l'asservissement
  MsTimer2::set(5, update); // 500ms period
  MsTimer2::start();
}

void loop(){
 
  while(orient_moy_radian*180/PI < 360){
  analogWrite(speedPinA,TOPSPEED);
  analogWrite(speedPinB,TOPSPEED);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, HIGH);
  digitalWrite(dir1PinB, HIGH);
  digitalWrite(dir2PinB, LOW);
  }
   /Serial.print(encoderTicks[0]);
    Serial.print("|");
    Serial.print(encoderTicks[1]);
    Serial.print("\tx = ");
    Serial.print(x_cm);
    Serial.print("| y = ");
    Serial.print(y_cm);
    Serial.print("\tTheta = ");
    Serial.print(orient_moy_radian*180/PI);
    Serial.print("| Pas = ");
    Serial.println(orient_moy);
}
En fait, ce qui marche quand j'uploade ce code, c'est l'incrémentation des codeurs et le calcul d'angle et de coordonnées ( tout marche nickel, et je peux voir les Serial).
Alors pourquoi les moteurs ne tournent pas? Ai-je mal placé les commandes de moteurs?
Merci
10  Using Arduino / Programming Questions / Using the MsTimer2 library efficiently on: May 15, 2011, 04:34:50 pm
Hello,

My project is to achieve dead reckoning using rotary encoders...
What I can successfully do with my robot so far :
     - Recognize the direction of the wheels and increment / decrement encoder ticks accordingly using interrupts;
     - Calculate the absolute (x,y,theta) coordinates of my robot instantly;
     - Using MsTimer2 library, I execute the dead reckoning function with a 5ms period;
Problem is, when I tried adding motor driving, to all this to make my robot go to a certain set of coordinates...the motors don't run smiley-eek
Here's my code...

Code:
#include <MsTimer2.h>

///////////////////////////////////////////////////////
//////////////////////VARIABLES////////////////////////
///////////////////////////////////////////////////////

// Encoder and interrupt pins and variables
int encoderPinB[2] = {25,22}; // Encoder B pin
long encoderTicks[2];
int odoLPin = 4; // interrupt 4 for digital Pin 19
int odoRPin = 5; // interrupt 5 for digital Pin 18

// Constants
#define COEF_Dist 11.0184191 // 1 cm -> 11.0184191 encoder ticks
#define COEF_ROT 4.352083   //  1°    -> 4.35 encoder ticks
#define PI 3.14159265
#define CONV_RD PI/(180*COEF_ROT) // angle conversion from ticks to radian

//  Global variables
long dist,last_dist ; // dist : distance covered at instant tn ; last_dist : distance covered at instant tn-1
long orient, last_orient, orient_init; // orient : current angle at instant tn; last_orient : last angle at instant tn-1
float x, y; // (x,y) coordinates in ticks
int x_cm, y_cm; // (x,y) coordinates in cm

// Motor Driving variables
 #define TOPSPEED 200
 #define FORWARD_SPEED 150
 #define TURN_SPEED 60
 // Left motor
 int dir1PinA = 13;
 int dir2PinA = 12;
 int speedPinA = 10;
 // Right motor
 int dir1PinB = 11;
 int dir2PinB = 8;
 int speedPinB = 9;
 int oam_speed[2]={0}; //oam_speed[0] = left wheel ; oam_speed[1] = right wheel

 // Dead reckoning variables
 int delta_d, delta_orient; // difference in dist ; difference in angle
 long orient_mean; // mean of current and last angle
 float orient_mean_radian, delta_orient_radian;  // radian converted
 float K=1, dx,dy; // differential x ; differential y
 
///////////////////////////////////////////////////////
//////////////////////FUNCTIONS////////////////////////
///////////////////////////////////////////////////////

// Initial Conditions
void init_dead_reckoning (float x0, float y0, long teta0)
{
  orient_init = teta0 ;
  last_orient = teta0 ;
  x = x0 ;
  y = y0 ;
  dist = 0 ;
  last_dist=0 ;
}

// Update function executed every 5 ms
void update()
{
  dead_reckoning () ; // Coordinates calculation

  while(orient_mean_radian<0){orient_mean_radian+=2*PI;} // Keeping angle in a [0, 2*pi] interval
  while(orient_mean_radian>2*PI){orient_mean_radian-=2*PI;}
}

// Dead reckoning
void dead_reckoning (void)
{
  dist = ((encoderTicks[1]+encoderTicks[0])/2); // distance covered at instant tn
  orient = orient_init +(encoderTicks[1]-encoderTicks[0]);
  delta_d = dist - last_dist;
  delta_orient = orient - last_orient;
  orient_mean = (orient +last_orient) / 2;  
  delta_orient_radian = CONV_RD*delta_orient;
  orient_mean_radian = CONV_RD*orient_mean;
  
  dx=K*delta_d*cos(orient_mean_radian);
  dy=K*delta_d*sin(orient_mean_radian);
  x= x + dx; // Values in ticks
  y= y + dy;
  x_cm=(int)(x/COEF_Dist); // This calculus can be done outside the dead_reckoning function
  y_cm=(int)(y/COEF_Dist);
  last_orient = orient ; // Refreshing angle value
  last_dist = dist ; // Refreshing distance value
}
// Left encoder Ticks
void incL(){  
  if (digitalRead(encoderPinB[0]) == HIGH){  
     encoderTicks[0]++;
        
  } else {  
     encoderTicks[0]--;
  }  
}  

// Left encoder Ticks  
void incR(){  
  if (digitalRead(encoderPinB[1]) == LOW){  
     encoderTicks[1]++;
          
  } else {  
     encoderTicks[1]--;
      
  }  
}

void  init_encoders(){
pinMode(encoderPinB[0], INPUT); // Encoder pin B INPUT
pinMode(encoderPinB[1], INPUT); // Encoder pin B INPUT
}

void init_motors(){
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(speedPinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(speedPinB, OUTPUT);
}

// Setup and main loop

void setup (){
  init_dead_reckoning(0,0,0);
  // Serial communication
  Serial.begin(38400);
  init_motors(); // Motor Pin intialization
  init_encoders(); //Encoders Pin initialization
 
  // attach the odometer interrupt
  attachInterrupt(odoLPin, incL, RISING); //18
  attachInterrupt(odoRPin, incR, RISING); //19
  // Timer2 to execute update function
  MsTimer2::set(5, update); // 5ms period
  MsTimer2::start();
}

void loop(){
  
  //  Execute a full revolution then stop
  while(orient_mean_radian*180/PI < 360){
  analogWrite(speedPinA,TOPSPEED);
  analogWrite(speedPinB,TOPSPEED);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, HIGH);
  digitalWrite(dir1PinB, HIGH);
  digitalWrite(dir2PinB, LOW);
  }

  analogWrite(speedPinA,0);
  analogWrite(speedPinB,0);

   /* Serial.print(encoderTicks[0]);
    Serial.print("|");
    Serial.print(encoderTicks[1]);
    Serial.print("\tx = ");
    Serial.print(x_cm);
    Serial.print("| y = ");
    Serial.print(y_cm);
    Serial.print("\tTheta = ");
    Serial.println(orient_mean_radian*180/PI);*/
}

Why aren't the motors working? (I tried them seperately they're running just fine)
I'm clueless
PLease share your insights
Thank you^^


11  Using Arduino / Programming Questions / Re: Using PID library to regulate position on: May 01, 2011, 06:23:57 pm
Thanks for the rep! I've been waiting smiley-grin

Okay! I'll try!

Just a quick question? Am I right to use the map function? Is there a way to avoid using it because I think it takes a lot of time!

Thanks
12  Using Arduino / Programming Questions / Re: Using PID library to regulate position on: May 01, 2011, 10:12:06 am
Up  smiley-mr-green
13  Using Arduino / Programming Questions / Re: Using PID library to regulate position on: May 01, 2011, 06:19:34 am
Up
14  Using Arduino / Programming Questions / Using PID library to regulate position on: April 30, 2011, 07:45:42 pm
Hello,
Here's what I want to do : Use the PID library for arduino http://www.arduino.cc/playground/Code/PIDLibrary , to tell my robot to stop at a certain (x,y) position.

Now, to test the library, I 'm trying to tell one wheel to stop when its encoder ticks reach a certain value.
The code :

Code:
#include <PID_v1.h>

#define encoderPinA 25 // Encoder A pin
#define encoderPinB 24 // Encoder B pin

int encoderStateA ; // Digital State of Encoder A
int encoderStateB ; // Digital State of Encoder B
int lastState=0; // Iast digital state of Encoder
int encoderTicks;

// PID Variables
#define SAMPLE_TIME 25 // Time interval in ms for PID sampling
#define POS_SETPOINT 79 // Analog value corresponding to 1000 ticks
double positionSetPoint, positionInput, positionOutput;     // Define Variables we'll be connecting to
double aggKp=4, aggKi=0.2, aggKd=1; // aggressive PID parameters if there's a large gap between setpoint and input
double consKp=1, consKi=0.01, consKd=0.25; // Conservative PID parameters if input is close to setpoint
PID positionPID(&positionInput, &positionOutput, &positionSetPoint, aggKp, aggKi, aggKd, DIRECT); // Specify the links and initial tuning parameters

 // Motor Driving variables
 #define TOPSPEED 255
 #define FORWARD_SPEED 150
 #define TURN_SPEED 60
 // motor A
 int dir1PinA = 13;
 int dir2PinA = 12;
 int speedPinA = 10;
 // motor B
 int dir1PinB = 11;
 int dir2PinB = 8;
 int speedPinB = 9;
 int speed[2]={0}; //speed[0] = left wheel ; speed[1] = right wheel

void setup(){
  init_motors(); // Motor Pin intialization
  init_positionPID(); // Pid initialization
  init_encoders(); //Encoders Pin initialization
  Serial.begin(38400);
}

void loop(){
//Reads encoders and increments or decrements ticks
readEncoder();
// The input has to be an analog Value (0 to 1023) so this function is to transfer the range of the ticks from 0->25875 to 0->1023
positionInput = map(encoderTicks, 0, 25875, 0, 1023);
//Decides whether to launch PID algorithm
  positionPID.Compute();
// Sets the PID parameters
  if(abs(positionInput-positionSetPoint)<5){
  positionPID.SetTunings(consKp, consKi, consKd);}
  else{
  positionPID.SetTunings(aggKp, aggKi, aggKd);}
  // Robot goes forward till it reaches the setpoint, backwards if it goes above Setpoint
  if(positionInput<=positionSetPoint){
  go_forward(0,positionOutput);
  }else{
  go_backwards(0,positionOutput);
  }
}

void  init_encoders(){
pinMode(encoderPinA, INPUT); // Encoder pin A INPUT
pinMode(encoderPinB, INPUT); // Encoder pin B INPUT
}

void readEncoder(){
encoderStateA = digitalRead(encoderPinA); // lit l'état de la broche en entrée
encoderStateB = digitalRead(encoderPinB);
if(encoderStateA!=lastState){
  lastState=encoderStateA;
  if(encoderStateA==1 && encoderStateB ==1) {
   encoderTicks++;
   Serial.println(encoderTicks);
 }
  else if(encoderStateA==1 && encoderStateB==0) {
   encoderTicks--;
   Serial.println(encoderTicks);
  }
}
}
void go_forward(int left, int right){
  speed[0]=left;
  speed[1]=right;
  analogWrite(speedPinA, speed[0]);
  analogWrite(speedPinB, speed[1]);
  digitalWrite(dir1PinA, HIGH);
  digitalWrite(dir2PinA, LOW);
  digitalWrite(dir1PinB, HIGH);
  digitalWrite(dir2PinB, LOW);
}
void go_backwards(int left, int right){
  analogWrite(speedPinA, speed[0]);
  analogWrite(speedPinB, speed[1]);
  digitalWrite(dir1PinA, LOW);
  digitalWrite(dir2PinA, HIGH);
  digitalWrite(dir1PinB, LOW);
  digitalWrite(dir2PinB, HIGH);
}
void init_positionPID(){
  // initialize the variables we're linked to
  positionInput = 0;
  positionSetPoint = POS_SETPOINT;
  // turn the PID on
  positionPID.SetMode(AUTOMATIC);
  positionPID.SetSampleTime(SAMPLE_TIME);
  }  
void init_motors(){
  pinMode(dir1PinA, OUTPUT);
  pinMode(dir2PinA, OUTPUT);
  pinMode(speedPinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT);
  pinMode(dir2PinB, OUTPUT);
  pinMode(speedPinB, OUTPUT);
}
In this code, as I said I'm only experimenting on the right wheel.
Now the problem is when I use the function readEncoders() alone it works perfectly : Increments when I manually turn the wheel forward, and decrements when I turn backwards. It also works when I tell the motor to turn at a constant speed(still without using PID).
But when I use the PID algorithm, on the Serial monitor I see the ticks going crazy (sometimes decrementing a few times then incrementing again) while the wheel is only going forward, and sometimes they go from like 300 to 540 smiley-grin Missing 240 ticks is a little weird...don't you think? o_O
So if you have any ideas please share^^
Thanks
15  Using Arduino / Programming Questions / Re: Tick generator function on: April 16, 2011, 06:27:33 am
I'll try and keep you posted

1°/ millis()/10
2°/blinkwithoutdelay

Thanks^^
Pages: [1] 2 3