Student?

Er du student?

Hvilken skole?

Jeg går spill-programmering på NITH i Oslo.

Jeg er Automasjon 3. års student på Etterstad VGS

Andra året på data teknik i lund...

Jeg skal begynne på spill-programmering på NITH om ca ett år (Førstegangstjenesten først) :slight_smile:

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

[...]har en masteroppgave som omfatter det å bygge en robot arm.

Høres spennende ut!

Bruker arduino duemilanove til å kontrollere motorene i armen.

Stepper-, servo-, ac-, dc motorer?

Syns det er pes:p

Hvorfor det da tro? :slight_smile:

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.

Hvis du holder deg mest mulig unna strings blir alt lettere.

F.eks kan du indikere Motor med en M, Speed med S og Direction med D. Slik trenger du bare parse en byte av gangen.

Videre, dersom alle data holder seg i [0,255] domenet kan du lett komme unna med å kjøre en enkel protokoll som leser inn datapar.

Typisk:

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;

//setup serial
void setup(){
      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();
                  break;
                  case SPEED_HEADER:
                        motorSpeed = Serial.read();
                  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;
            }
      }
}

/*
Use the parameters to control a motor and set its speed and direction
*/
void setMotor( byte id, byte speed, boolean directionLeft ){
  //your code here
  //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");
  //end debug
}

Koden over er ikke testet, men den kompilerer.

Den burde fungere slik at den hele tiden leter etter to mottatte bytes på serial busen.
Finner den at det er to bytes, leser den den første.
Dersom den er M, så lagrer den neste byte [som indikerer id] i en id variabel
S gjør at speed lagre og D lagrer direction
Dersom programmet har mottat tre packets [M,S,D] så vil den kalle en funksjon med disse som parameter.

Din jobb blir å finne ut hva denne funksjonen skal bruke de mottatte dataene til :slight_smile:
Lykke til :slight_smile:

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.

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

Hei igjenn :slight_smile:

Jeg glemte å si noe, som er grunnen til at det ikke fungerer.

M1S100D1 sendes som ASCII [char]
Så Arduino mottar

M
1
S
1
0
0
D
1

Men vi vil ha

M
X
S
Y
D
Z

Der X,Y og Z er variabler for id, speed og direction.

Derfor må du sende denne stringen:
M\1SdD\1

\1 gjør om verdien til 1, dersom du bare skriver 1 vil verdien faktisk være 49
liten d er det samme som 100

Prøv det og se hva som skjer :slight_smile:

[edit]Ser du har noen - '0' i koden. Det kan a) la stå, men da må du endre på logikken jeg nettop beskrev. Husk at dette begrenser området tilgjengelig for forskjellige motorer. b) ta bort og bruke logikken jeg beskrev[/edit]

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???

Det ser ut til at arduino leser ''

Hvilket program/språk bruker du til å sende med?
Du må, på en eller annen måte, encode verdien 1 i index 1 i stringen

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

I C++ ville jeg gjort slik for å encode 1 inn i index 1:

char string[] = "MxSyDz";

string[1] = 1;
string[3] = 100;
string[5] = 1;

I java:

String string = "MxSyDz";

string = string.replace('x',1);
string = string.replace('y',100);
string = string.replace('z',1);

Matlab kan jeg ikke, men kanskje

fprintf('%c%u%c%u%c%u','M',1,'S',100,'D',1)

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?

Du kan se her:
http://code.google.com/p/alexanderbrevig/source/browse/trunk#trunk/Arduino/Utilities/StringToAnything
Og her for eksempel:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253159310/0#2

Jeg går 3. året nå.

Legg meg til msn om du vil løse dette, så hjelper jeg gjerne til med det jeg kan :slight_smile:

a-music-developer-@-hotmail-.-com uten - :slight_smile:

BUMP