Show Posts
Pages: [1] 2
1  Forum 2005-2010 (read only) / Syntax & Programs / Re: PID Library motor control example? on: November 12, 2009, 11:49:55 am
Okey! Thanks!

Suby, I looked up the link you posted on AN696. It's a pretty big solution and it was a bit difficult for me to understand all of the logic and functions in the solution. Would the complete solution be too much in Arduino? It seems difficult to make something based on the entire solutions. I'm trying to do a lot of things in arduino. Two arduino's will control two motors each. So how to create this function as simple and correct as possible? Where comes position_error and speed_error from? I know how a pid/p controller works basically of course, but have problems thinking out how to solve it in arduino. So I'm not sure I understand all of your examples here.
2  Forum 2005-2010 (read only) / Syntax & Programs / Re: PID Library motor control example? on: November 11, 2009, 09:56:53 am
I know I probably only need a P - regulator.
Suby, would you recommend that I create my own method and not use the PID-libary and set the I and D variables to 0? I didn't quite understand the feedforward explanation.
Looked it up on wikipedia but what do feedforward means in my situation?
Why do I need to have time stamps when I can do it in the void loop().
Shouldn't that be enough?
3  Forum 2005-2010 (read only) / Syntax & Programs / Re: PID Library motor control example? on: November 10, 2009, 07:23:51 am
I'm looking for the same thing roypardi. Have you found something yet? I'm builidng a robotic arm and need PID controll for both speed and accuracy for position with encoder.

I had a look at the PID library with front end on the playground but not sure how to use it with an DC motor and encoder.
4  Forum 2005-2010 (read only) / Syntax & Programs / Re: string to int (pwm) on: November 04, 2009, 08:45:51 am
I want to send a string from example matlab to arduino. If I'm controlling a motor with pwm I want to send for example "255" from matlab (fprintf('255')). This will come as a string to arduino and I want to convert it from 255 as a string to 255 as an int. Then I can send the int with the value 255 to my motor and it will be set to run at full speed.

I'm sorry to say but Nigel here has some errors in his code. It should be info = Serial.read(); instead. I tried this and it gave me strange high numbers that I can't use.

I've also tried char * string but then you have to set it to something and it will then be a problem when I want to send a string thru the serialport. It is also impossible to set the char * string directly like this:
string = Serial.read().
5  Forum 2005-2010 (read only) / Syntax & Programs / Re: reading from serial to array (char string[]) on: November 04, 2009, 01:13:17 pm
Okey.
So do I have to fill up string[32] with 32 characters?
Why do I need to set the size? Is there no sort of dynamic array in Arduino?
 
I'm sending something like this from matlab: "M:1;S:100;D1" where M is for motor, S is for speed and D is for direction. I'm trying to control a robotic arm with 4 motors on.
So you see that the number of characters in the text will depend on for example the speed. If the speed is only 50 there is only two character instead of three as in 100.
How do I append a NULL to the end of the array?

Code:
int byteAvailable = Serial.available();
        for(int i = 0; i < byteAvailable; i++)//-1=stringsluttsignal
        {
            string[i] = Serial.read();
            if(string[i] == 'M')
            {
                motor_number[0] = Serial.read();
                delay(10);
            }
        and so on...

I thougth sizeof() was a brilliant function to use. I haven't tried this with sending text from matlab yet, but it compiled and uploaded to the board without any errors so thanks a lot so far smiley
6  Forum 2005-2010 (read only) / Syntax & Programs / reading from serial to array (char string[]) on: November 04, 2009, 12:15:09 pm
Hey!

I don't see why this won't work:

Code:
char string[] = "";
char byteToRead;

void setup() {
   Serial.begin(9600);
}

void loop(){
   if(Serial.available()){
      string[] = Serial.read();
      //this won't work either:
      //byteToRead = Serial.read();
      //string[] = byteToRead;
      for(int i = 0; i < sizeof(string) - 1; i++){
         if(string[i] == 'M'){
            do something
         }
      }
   }
}


I'm trying to go through a string I get from serialcom. and look for letters/digits etc. in the text, one step at the time. Since this code above don't work, what is working?

7  Forum 2005-2010 (read only) / Interfacing / Re: controlling arduino with software like matlab etc on: November 03, 2009, 01:18:14 pm
I now know how to send simple data fram matlab to arduino but the problem now is that I don't know how to separate the commands/strings from matlab in arduino. i. e.

Matlab:
s1 = serial('COM3', 'BaudRate', 9600, 'Parity', 'none', 'DataBits', smiley-cool;
fopen(s1);
fprintf(s1, 'Hello World!') - or if I'm going to control 4 motors:
fprintf(s1, 100(motorspeed), 1(as in motor no. 1), 0(as in direction 1 of 2 on motor 1)) and perhaps
fscanf(s1) - if I'm going to read something from the arduino back to matlab

In Arduino - I know the setup() and loop() methods, this is just some of the code:
char info;
  if(Serial.available())
  {
      info = Serial.read();
  }
  Serial.println('I want to send something back to matlab');

I can for instance send the char '8' from matlab to arduino and let the motors run when char info detects the char '8' but that solves nothing because then all my motors will run and I will not be able to control them separately. I'm thinking on splitting the string I get from matlab and separate the words/integers to each motor but I don't know if it's possible yet.
8  Forum 2005-2010 (read only) / Interfacing / controlling arduino with software like matlab etc on: October 27, 2009, 08:09:41 am
I'm building a robot-arm with 4 dc motors and two arduino usb boards (duemilanove). I can control two and two motors on each arduino with for example tera term but I need to control and calculate the motors together to get a robot arm.

I know matlab can communicate with several serial ports (COM) on hardware like:

s = serial('COM1');
fopen(s)

but I dont know how to communicate and control the digital pins on the arduinos with matlab. Especially if I allready have some setup-code in the arduino processing language and only want to control the motors together from a more high-level programming/script language.

I have used the arduino processing language to control the motors until now that I need a more complex algorithm to control all the 4 motors together in an arm.

I know about the arduinoTarget scripts for matlab but I had some problems with the installationscript and it looked like the scripts only was for one arduino at the time.

I'm open for suggestions on other software to use for this purpuse but I think matlab is pretty good on calculations as well when I have to calculate the forward and inversekinematics for the robotic arm.

Please help!
9  Forum 2005-2010 (read only) / Scandinavia / Re: Student? on: November 05, 2009, 10:35:28 am
Ok skjønner greia her. Jeg kan jo ikke gjøre "M1S100D1" om på en slik måte:
string[1] = 1;
string[3] = 100;
string[5] = 1;
for da setter jeg jo verdiene som motoren skal ha i koden selv.
Men spiller vel ingen rolle om jeg sender fra matlab eller serial monitor i arduino enda vel? om jeg sender en string fra serial monitor skal vel den se rimelig lik ut som den stringen jeg ville sendt fra matlab, skulle den vel ikke?


Jeg har prøvd dette:
char* motor_speed = "";
char* motor_direction = "";
char* motor_number = "";
char string[12];
char byteToRead;

og i loopen gjort:
if (Serial.available())
    {
           int byteAvailable = Serial.available();
        //string[] = byteToRead; //fungerer ikke
        for(int i = 0; i < byteAvailable; i++)//-1=stringsluttsignal
        {
            string = Serial.read();
            if(string == 'M')
            {
                motor_number[0] = Serial.read();
                delay(10);
                motor = atoi(motor_number);

Her gjør atoi() om string til int slik jeg forstod det, men fungerte heller ikke optimalt.
dvs. at jeg fikk motorene til å røre på seg av og til og ikke stabilt slik jeg ville ha det.
Vært borti den metoden å gjøre det på?


Hvilket årstrinn på NITH - Spillprogrammering går du nå? Drevet med programmering før
du begynte på NITH eller?
10  Forum 2005-2010 (read only) / Scandinavia / Re: Student? on: November 05, 2009, 10:08:27 am
Nå bruker jeg jo bare serial monitor i arduino, men har sendt fra matlab også og fikk det til å funke. eneste da var at jeg testet på '8' og økte hastigheten på motorene med 10 for hver '8' jeg fikk så sendte jeg fra matlab fprintf('888888') og så gikk motorene fullfart.

hvordan enkode verien 1 i index 1 i stringen? vet ikke helt om jeg skjønner hva du mener der? Har tonnevis med andre filer jeg har prøvd å feilet med i 4 dager nå:(

Har postet flere steder på forumet men virker alltid som om det jeg skriver inn blir lest på feil måte hele tiden:p Kommer et skritt nærmere med en ting, men lengre i fra med en annen ting hele tiden:p
11  Forum 2005-2010 (read only) / Scandinavia / Re: Student? on: November 05, 2009, 09:57:42 am
Ok. Jeg sender inn sånn som du sier og mottar: Recieved: ID: 92 Speed: 100 Left: no
Prøvde også med M\1S\dD\1 og M\1\S\d\D\1. Av og til får jeg også at speed er 92 - samme som id. Går det litt fort i svingene for arduino her eller? Vil bare termineres maks 3 ganger dessverre. Det fungerer altså fremdeles ikke:(

Jeg bruker logikken slik som du beskrev nå igjen. Men er jo veldig kinkig å måtte vite ascii verdiene for tall hele tiden. Er jo tenkt at jeg skal sende verdier fra et annet program, som feks matlab eller maxmsp til arduino så den kan prosessere å flytte motorene til riktige posisjoner i forskjellige hastigheter. Men vet at jeg kan konvertere fra byte til int - som burde gjøres slik at motoren kan lese verdiene på en skikkelig måte. Eller gjør den det allerede med bare bytes???
12  Forum 2005-2010 (read only) / Scandinavia / Re: Student? on: November 05, 2009, 08:47:45 am
Takk for tipset! Prøvde det og fikk ingen kompileringsfeil som du sa:)
Jeg tok og gjorde noen endring med tanke på at jeg vil ha int og ikke byte verdier inn til motorene. Men det fungerer fremdeles ikke. Får ingen respons på motorene og når jeg sender inn "M1S100D1" så blir resultatet id: 1 speed: 1 directionLeft: no.
Den looper 3 ganger og så vil den ikke mer selv om jeg gir den mer input. Har også prøvd å endre direction men den sier "no" uansett.

Code:
const byte MESSAGE_PACKET_LENGTH = 3; // motor,speed,direction

const byte MOTOR_ID_HEADER = 'M';
const byte SPEED_HEADER = 'S';
const byte DIRECTION_HEADER = 'D';

//counter for keeping track of the number of packets recieved
byte packetsRecieved = 0;

//data used to store info about the next action to make
byte motorID = 0;
byte motorSpeed = 0;
boolean motorDirectionLeft = false;

//pins
int IN1_Motor1 = 10; //retning 1 motor
int IN2_Motor1 = 11; //retning 2 motor
int IN1_Motor2 = 8;
int IN2_Motor2 = 9;
int D2_Motor1 = 7; //pwm hastighetsregulator
int D2_Motor2 = 6;
int D1 = 12; //
int EN = 13; //Enable signal

//setup serial
void setup()
{
      pinMode (IN1_Motor1, OUTPUT);
      pinMode (IN2_Motor1, OUTPUT);
      pinMode (IN1_Motor2, OUTPUT);
      pinMode (IN2_Motor2, OUTPUT);
      pinMode (D2_Motor1, OUTPUT);
      pinMode (D2_Motor2, OUTPUT);
      pinMode (D1, OUTPUT);
      pinMode (EN, OUTPUT);
      Serial.begin(9800);
}

void loop()
{
      if (Serial.available()>=MESSAGE_PACKET_LENGTH)
      {
            packetsRecieved++; //recieved a new package
            
            byte recieved = Serial.read();

          switch (recieved)
            {
                  case MOTOR_ID_HEADER:
                    motorID = Serial.read()- '0';
                  break;
              
                  case SPEED_HEADER:
                  motorSpeed = Serial.read()- '0';
                  break;
                  
                  case DIRECTION_HEADER:
                    motorDirectionLeft = Serial.read()==0 ? false : true;
                  break;
            
                  default:
                  //error has occured
                  packetsRecieved--;
                  break;
            }

          /*
          If you have recieved enough data to make a desicion
          */
          if ( packetsRecieved == (MESSAGE_PACKET_LENGTH-1) )
            {
                  //act upon the data recieved
                  setMotor(motorID,motorSpeed,motorDirectionLeft);
                  //reset data
                  motorID = 0;
                  motorSpeed = 0;
                  motorDirectionLeft = 0;
            }
      }
      digitalWrite(EN, HIGH);
      digitalWrite(D1, LOW);
      delay(100);
}

/*
Use the parameters to control a motor and set its speed and direction
*/
void setMotor( byte id, byte speed, boolean directionLeft )
{
      //your code here
      if(id == '1')
      {
            if(directionLeft == true)
            {
                  digitalWrite(IN1_Motor1, HIGH);
                  digitalWrite(IN2_Motor1, LOW);
            }
            else
            {
                  digitalWrite(IN1_Motor1, LOW);
                  digitalWrite(IN2_Motor1, HIGH);
            }
            
            analogWrite(D2_Motor1, speed);
      }
      if(id == '2')
      {
            if(directionLeft == true)
            {
                  digitalWrite(IN1_Motor2, HIGH);
                  digitalWrite(IN2_Motor2, LOW);
            }
            else
            {
                  digitalWrite(IN1_Motor2, LOW);
                  digitalWrite(IN2_Motor2, HIGH);
            }
            analogWrite(D2_Motor2, speed);
      }
      //debug
      Serial.print("Recieved: ");
      Serial.print("ID: ");
      Serial.print(id,DEC);
      Serial.print(" Speed: ");
      Serial.print(speed,DEC);
      Serial.print(" Left: ");
      Serial.print(directionLeft?"yes":"no");
      Serial.println("");
      //end debug
}


Tok en liten titt på profilen din og ser du har drevet mye med arduino:)
Jeg har holdt på med arduino siden september bare og syns det i starten var latterlig enkelt:p
13  Forum 2005-2010 (read only) / Scandinavia / Re: Student? on: November 04, 2009, 12:33:09 pm
Bruker dc-motorer med en motordriver for hver av motorene. Ligger på sparkfun alt sammen. Skal koble til enkodere straks så jeg kan bestemme hvor mye motorene skal rotere av gangen.

At det er pes sier seg jo selv. Nå holder jeg jo på med å prøve å sende data som en string fra matlab og splitte den opp i arduino. som feks: "motor:1, speed:100, direction:1". Og bare det virker jo som et mareritt å få til med rammeverket til arduino:s

Så skal man jo lage en algoritme sånn at motorene går uavhengig av hverandre og sånn at armen blir funksjonell samtidig som den ikke går inn i seg selv.
14  Forum 2005-2010 (read only) / Scandinavia / Re: Student? on: November 04, 2009, 08:04:49 am
Jeg har gått på spillprogrammering på NITH og har bachelor derfra i 2008. Går nå siste året på master i informatikk med retning robotikk ved UIO og har en masteroppgave som omfatter det å bygge en robot arm. Bruker arduino duemilanove til å kontrollere motorene i armen. Syns det er pes:p
15  Forum 2005-2010 (read only) / Interfacing / Re: Motor and encoder test program on: June 23, 2010, 06:19:48 am
Yo and hello again!

I solved the problem with the cycle measuring over 700 pulses or something. When I use both interrupt routines (1 for the a channel and 1 for the b channel on the encoder) I simply divides cycle by 4. (2 if I only use one interrupt routine)

But I can't get the motor to stop when the encoder has reach its specific position. I try to do this with a while in positionMotor() but it seems like it's ignoring the while and just do as in run().

Code:
void setup()
{
      pinMode(a, INPUT);
      digitalWrite(a, HIGH);//
      pinMode(b, INPUT);
      digitalWrite(b, HIGH);//
      pinMode(IN1, OUTPUT);
      pinMode(IN2, OUTPUT);
      pinMode(D2, OUTPUT);
      pinMode(EN, OUTPUT);
      attachInterrupt(0, encoderA, CHANGE);
      attachInterrupt(1, encoderB, CHANGE);
      Serial.begin(9600);
}

void loop()
{
run();
}

void encoderA()//the same with the b channel
{
      if(digitalRead(a) == HIGH)
      {
            if(digitalRead(b) == LOW)
            {
                  cycle = cycle + 1;
            }
            else
            {
                  cycle = cycle - 1;
            }
      }
      else
      {
            if(digitalRead(b) == HIGH)
            {
                  cycle = cycle + 1;
            }
            else
            {
                  cycle = cycle - 1;
            }
      }
}

void run()
{
      degree = 180*5;
      velocity = 100;
      positionMotor(degree);
      delay(5000);
      stopMotor();
      delay(1000);
      degree = -160*5;
      positionMotor(degree);
      delay(5000);
      stopMotor();
      delay(1000);
}

void stopMotor()
{
      digitalWrite(EN, LOW);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
}

void startMotor(int pos, int Speed)
{
      digitalWrite(EN, HIGH);
      if(pos < 0)
      {
            digitalWrite(IN1, HIGH);
            digitalWrite(IN2, LOW);
      }
      else
      {
            digitalWrite(IN1, LOW);
            digitalWrite(IN2, HIGH);
      }
      analogWrite(D2, Speed);
}

void positionMotor(int pos)
{
      currentCycle = cycle / 4;
      startMotor(pos, velocity);

      while(pos == currentCycle)
      {
      stopMotor();
      }
}
Pages: [1] 2