Sida 1 av 1

Retunera två variabler via en funktion - Arduino

Postat: 5 maj 2014, 20:24:23
av Al_Bundy
Tja tja bloggen.

Skämt och sido(unga förstår nog skämtet). Jag har skrivit en liten kod där jag ska skriva ut två tal varje sekund ungefär(beror på delay). Ena talet ska uppdateras varje gång den upprepas(1+) och andra talet ska uppdateras (1+) när första talet har uppdaterats 59 gånger.

Kod: Markera allt

struct return_values 
{
  int x;
  int y;
};

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

void loop()
{
  struct return_values t; // Deklarera t
  time_clock(t.x , t.y); //Ur t kan man hämta det som är givet i en struct, t.ex t.x och t.y och använda som argument. 
  Serial.println(t.x); // Kontakta t IGEN och sök upp variabeln x och skriv ut den
  Serial.println(t.y); // samma sak här 
}

void time_clock(int time, int i) // argumentet t.x får variabeln time, int time. 
{

  if (i >= 59)
  {
    time = time++;
    i = 0;
  }
  else
  {
    i = i++;
  }
  delay(1000);
  struct return_values r; // deklarera r
  r.x = time; // skicka ny data till r.x, vilket går till int x i structen. 
  r.y = i; // samma sak här
}
Men jag får bara detta
0
0
0
0
0
0
0
0

Jag vet vad som är fel, men jag vet inte hur jag ska lösa det.
När jag ser denna typ av kod.

Kod: Markera allt

r.x = time; // skicka ny data till r.x, vilket går till int x i structen. 
r.y = i; // samma sak här
Så förväntar jag mig att int x och int y i structen ska få nya värden. Men det får dem inte. Det skickas inte tillbaka.

Re: Retunera två variabler via en funktion - Arduino

Postat: 5 maj 2014, 21:05:34
av Willow
Vad tror du om att skicka in pekare som argument till time_clock() eller låta den returnera din struct?

Re: Retunera två variabler via en funktion - Arduino

Postat: 5 maj 2014, 21:16:48
av EBD
När du deklarerar r i slutet av time_clock så blir det en helt ny struct som inte har något att göra med t som ligger i mainloopen. Den är dessutom bara giltig inne i den funktionen, och försvinner när funktionen avslutas.

Det finns flera sätt att lösa det på, t.ex. med pekare som Willow säger. Ett annat förslag är att deklarera t som en global struct, och använda den i både loop och time_clock.

Några tips:

i = i++ ser inte bra ut. Det fungerar ändå men är inte helt självklart. Skriv endast i++.
Vill du få lite precision så är det bättre att använda ett timerinterrupt för att räkna upp klockan. Då får du processortid över till annat också.

Re: Retunera två variabler via en funktion - Arduino

Postat: 5 maj 2014, 21:20:49
av Kaggen
Du deklarerar ju en ny struct (r) i funktionen time_clock() och skriver dina värden i den. Varför gör du det om du vill att värdena skall hamna i den globala struct du redan deklarerat (t)?

Du kan ju byta ut:

Kod: Markera allt

  r.x = time; // skicka ny data till r.x, vilket går till int x i structen.
  r.y = i; // samma sak här
mot:

Kod: Markera allt

  t.x = time; // skicka ny data till r.x, vilket går till int x i structen.
  t.y = i; // samma sak här
och skippa deklarera (r) öht.

Alternativt snyggare/riktigare att göra som EBD föreslog, skicka pekare istället.

Re: Retunera två variabler via en funktion - Arduino

Postat: 5 maj 2014, 21:26:48
av Al_Bundy
Willow skrev:Vad tror du om att skicka in pekare som argument till time_clock() eller låta den returnera din struct?
Jag har inte börjat med pekare än och vet inte direkt vad det gör. Så jag får låta det vänta.
Kaggen skrev:Du deklarerar ju en ny struct (r) i funktionen time_clock() och skriver dina värden i den. Varför gör du det om du vill att värdena skall hamna i den globala struct du redan deklarerat (t)?

Du kan ju byta ut:

Kod: Markera allt

  r.x = time; // skicka ny data till r.x, vilket går till int x i structen.
  r.y = i; // samma sak här
mot:

Kod: Markera allt

  t.x = time; // skicka ny data till r.x, vilket går till int x i structen.
  t.y = i; // samma sak här
och skippa deklarera (r) öht.

Alternativt snyggare/riktigare att göra som EBD föreslog, skicka pekare istället.
Jaha! Så en struct håller inte i några värden, utan en struct håller i dekelerationer av variabler så man slipper deklarera om dessa igen och igen och igen?

Jag gjorde det nu och det fungerar! Då vet jag vad struct gör! Trodde dem sparade data så man kunde kliva ut ur funktionen, och sedan hämta dessa igen om man känner för det. Då kanske det är klasser jag tänker på då?

Kod: Markera allt

struct return_values 
{
  int x;
  int y;
};

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

void loop()
{
  struct return_values t;
  t.x = 0;
  t.y = 0;
  while(1)
  {
  t = time_clock(t.x , t.y);
  Serial.println(t.x);
  Serial.println(t.y);
  }
}

struct return_values time_clock(int time, int i)
{

  if (i >= 59)
  {
    time = time++;
    i = 0;
  }
  else
  {
    i = i++;
  }
  delay(100);
  struct return_values t = {time, i};
  return t;
}


Re: Retunera två variabler via en funktion - Arduino

Postat: 5 maj 2014, 21:52:27
av Micke_s
Den sista koden ser lite farlig ut. Problemet är att variabler i en funcktion är lokala och läggs på stacken för denna funktion. Detta markeras som lediga när funktionen lämnas.

Risken finns att något annat använder samma minnesarea efter return eftersom detta minne är fritt igen. Fungerar ibland om man har tur, än värre blir det om man har interrupt.

Se min kommentar #

Kod: Markera allt

struct return_values 
{
  int x;
  int y;
};

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

void loop()
{
  struct return_values t;
  t.x = 0;
  t.y = 0;
  while(1)
  {
  t = time_clock(t.x , t.y);
  Serial.println(t.x);
  Serial.println(t.y);
  }
}

struct return_values time_clock(int time, int i)
{

  if (i >= 59)
  {
    time = time++;
    i = 0;
  }
  else
  {
    i = i++;
  }
  delay(100);
  struct return_values t = {time, i}; #Denna variabel kommer bara vara giltig inne i funktionen.
  return t;
}

Re: Retunera två variabler via en funktion - Arduino

Postat: 6 maj 2014, 09:22:55
av Al_Bundy
Så du menar att om delklarerar olika värden t.ex a.x, a.y och b.x, b.y så kan det bli fel?

Re: Retunera två variabler via en funktion - Arduino

Postat: 6 maj 2014, 09:43:37
av Micke_s
Tror jag tänkte lite fel. Bör funka bra eftersom det blir en kopiering. Hade man däremot returnerat en pekare så hade det skitit sig.