Retunera två variabler via en funktion - Arduino

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Retunera två variabler via en funktion - Arduino

Inlägg 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.
Willow
Inlägg: 131
Blev medlem: 23 november 2006, 21:30:44
Ort: Mölndal

Re: Retunera två variabler via en funktion - Arduino

Inlägg av Willow »

Vad tror du om att skicka in pekare som argument till time_clock() eller låta den returnera din struct?
EBD
Inlägg: 126
Blev medlem: 10 maj 2006, 18:50:48
Ort: Sundsvall

Re: Retunera två variabler via en funktion - Arduino

Inlägg 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å.
Kaggen
Inlägg: 431
Blev medlem: 29 januari 2005, 03:06:02

Re: Retunera två variabler via en funktion - Arduino

Inlägg 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.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Retunera två variabler via en funktion - Arduino

Inlägg 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;
}

Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Retunera två variabler via en funktion - Arduino

Inlägg 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;
}
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Retunera två variabler via en funktion - Arduino

Inlägg 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?
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Retunera två variabler via en funktion - Arduino

Inlägg 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.
Skriv svar