PHP: Problem med FOR-loop mm. *Löst*

Elektronik- och mekanikrelaterad mjukvara/litteratur. (T.ex schema-CAD, simulering, böcker, manualer mm. OS-problem hör inte hit!)
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

PHP: Problem med FOR-loop mm. *Löst*

Inlägg av JimmyAndersson »

Denna tråd började med problem att komma åt serieporten i PHP på en dator med Debian.
Den tråden finns här.


Jag har fått ordning på mycket av koden nu, tack vare Speakman. Stort tack! :)

Kom på att vi glömde den bort-kommenterade for-loopen. Dvs:

Kod: Markera allt

for ($i = $startposition; $i >= $position; $i-=20)
{
$message =chr(0x02).chr(0x30).$i.chr(0x03);
$serial->sendMessage($message);
}
PHP verkar inte gilla att räkna ner sådär. Allt bara stannar upp.
Det fungerar hos 007sweden, men han kör Windows, den stackaren. :)


Att byta for-loopen till t.ex while wend eller nåt likande tror jag inte skulle hjälpa. Det verkar vara i $i-=20 som felet är. 20 ska förresten bytas ut mot en variabel sedan.

edit: Delade på tråden.
edit 2: Lade till "*Löst*" i rubriken.
Senast redigerad av JimmyAndersson 2 februari 2008, 17:03:09, redigerad totalt 2 gånger.
Användarvisningsbild
007sweden
Inlägg: 3500
Blev medlem: 3 mars 2005, 20:18:12
Skype: oo7sweden

Inlägg av 007sweden »

Hm en idé, prova sätt +=$variabel och variabeln sätter du negativ.
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Precis så jag tänkte. Men av någon anledning fungerar det inte ändå.

Att göra såhär är inga problem: $step_down = -10;

Men däremot verkar inte php-koden köras överhuvudtaget när denna kod är med:

Kod: Markera allt

for($i = $startposition;$i >= $position;$i+=$step_down)
{
    $message = chr(0x02).chr(0x30).$i.chr(0x03);
    $serial->sendMessage($message);
}
$i >= $position i for-loopen är väl rätt ?




Jag förresten en annan ändring som fungerade bra:
Låt säga att man skriver in något i inmatningsrutan, trycker Submit och sedan avbryts det. Antingen av av användaren eller något problem. Då töms filen position.txt

Därför gjorde jag såhär i slutet på koden:

Kod: Markera allt

if ($position != "")
     {
     if (!($file_handle = fopen($file,"w")))
             {
             echo "Cannot open file";
             }
             else
                  {   
                  fwrite($file_handle, $position);
                  fclose($file_handle);
                  }
      }
Dvs lade till if($position != "") osv.






En annan grejj:
Jag behöver hålla isär (innehållet från) fyra variabler i position.txt
Hur löser man läsning/skrivning av det i php?

Det jag vill göra är alltså ungefär såhär:

--------
Steg 1:
$a = 1
$b = 2
$c = 3
$d = 4

Steg 2:
Skriv till position.txt som efteråt innehåller t.ex:

1
2
3
4

Steg 3:
Läs sedan filen och lägg varje rads innehåll i varsin variabel.
...eller nåt liknande. :)
--------

Sånt här känner man sig lite borskämd med i perl. Där är det så enkelt att t.ex plocka ut delar ur strängar. :)
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

Vad menar du med att allt stannar upp?

Du kan börja med att slänga in lite utskrifter. Vad händer om du kör det här?

Kod: Markera allt

echo "startposition = $startposition<br>position = $position<br>stepdown = $stepdown";

for($i = $startposition;$i >= $position;$i+=$step_down)
{
    echo 'A';
    $message = chr(0x02).chr(0x30).$i.chr(0x03);
    $serial->sendMessage($message);
    echo 'B';
}
--------------------------

Jämförelsen i if ($position != "") tyder på att $position är en sträng. Om du handskas med $position som ett heltal i resten av din kod så vill du nog testa med is_int() istället.

--------------------------

file() läser in en fil och returnerar en array. Varje element i arrayen motsvarar en rad i filen.
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

"Vad menar du med att allt stannar upp?"

Hm, hur förklarar man det tydligare. Att det inte händer något alls typ..
Knappar man in adressen till en php-fil i webläsaren och trycker Enter så brukar det ju dyka upp något i webläsarfönstret, men det gör det alltså inte.
Det blir med andra ord precis likadant som när man försöker gå in på en sajt som ligger på en jääättteseg server.


Men problemet löste sig för någon minut sedan. Fick en idé om att byta ut for-loopen mot en if-koll, men 007sweden kontrade med att föreslå en while-koll istället. Så nu fungerar det utmärkt. Funderar på om det är en bugg i FOR i PHP5 som visar sig när man räknar neråt.

Så nu ser den delen ut såhär istället:

Kod: Markera allt

while($position >= $i)
{
    $i-=$step;
    $message = chr(0x02).chr(0x30).$i.chr(0x03);
    $serial->sendMessage($message);
}

Det som ska hamna i $position är heltal. Men än så länge finns ingen koll på att man verkligen skriver in heltal i formulärets inmatningsruta. Att jag valde att göra != "" var bara för att jag inte kom på hur man gjorde på något annat sätt. Jag har inte lärt mig riktigt allt i PHP än, men det kommer.

Läste på om is_int() nu. Bra idé. :)

Tack för tipset om file() och arrayen. :tumupp: :)


Ja då har jag inga fler frågor för tillfället, men jag återkommer med resultatet senare. :)
Användarvisningsbild
cykze
EF Sponsor
Inlägg: 1539
Blev medlem: 8 april 2004, 10:40:28
Ort: Uppsala

Inlägg av cykze »

> Men problemet löste sig för någon minut sedan. Fick en idé om att byta ut for-loopen mot en if-koll, men 007sweden kontrade med att föreslå en while-koll istället. Så nu fungerar det utmärkt. Funderar på om det är en bugg i FOR i PHP5 som visar sig när man räknar neråt.

While-koden som du visade upp nu gör inte samma sak som for-loopen du visade tidigare. Skriv ut värdet på $i i loopen så ser du. Du har ju t ex bytt >= mot <= (kolla noggrant).

Och nej, jag tror inte på idéen att for-loopar skulle vara trasiga i PHP5. :)

Kod: Markera allt

while($position >= $i)
{
    $i-=$step;

    echo "$i<br>";
    $message = chr(0x02).chr(0x30).$i.chr(0x03);
    $serial->sendMessage($message);
}

Kod: Markera allt

for($i = $startposition;$i >= $position;$i+=$step_down)
{
    echo "$i<br>";
    $message = chr(0x02).chr(0x30).$i.chr(0x03);
    $serial->sendMessage($message);
}
Användarvisningsbild
007sweden
Inlägg: 3500
Blev medlem: 3 mars 2005, 20:18:12
Skype: oo7sweden

Inlägg av 007sweden »

Höm får fundera mera på detdär. :oops:
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Tror endast detta beror på logiska tankevurpor... att sidan ser ut att ha stannat brukar i själva verket bero på att den fastnat i en loop...

Jag antar att du vill stega både uppåt och neråt (månne det vara en servostyrning?). Om du använder for() måste både steg och villkor ändras. Denna while-loop borde lösa stegning åt båda hållen (finns utrymme för förbättringar):

Kod: Markera allt

$step = 20; //example
$currposition = $startposition; //The old position
$newposition = $position; //The new position
while(abs($newposition - $currposition) > $step)
{
    $message = chr(0x02).chr(0x30).$currposition.chr(0x03);
    $serial->sendMessage($message);

    if($currposition < $newposition )
        $currposition += $step;
    else
        $currposition -= $step;
}
//The final step
$message = chr(0x02).chr(0x30).$newposition .chr(0x03);
$serial->sendMessage($message);
Användarvisningsbild
007sweden
Inlägg: 3500
Blev medlem: 3 mars 2005, 20:18:12
Skype: oo7sweden

Inlägg av 007sweden »

Japp den hade hamnat i en loop, fixxat en fullösning så att man tar sig ur loopen om det blir totalfel värden, får testa din idé senare vid tillfälle.

Edit: Alltså koden fungerar i princip nu. :)
Användarvisningsbild
Icecap
Inlägg: 26612
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

"...koden fungerar i princip nu..."

Det är vad man säger när det bara är mellan 2 dygn och 3 månader till det fungerar rätt...
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Så sant. :D

Eller, fritt översatt:
"Koden fungerar. Nu är det bara två små saker kvar. Att ta reda på varför och att få den att fungera på rätt sätt."


oJsan:
"månne det vara en servostyrning?"

Rätt gissat. Vet inte om Icecap har kikat på koden och känt igen det som ska skickas till serieporten, men annars kan jag berätta hur det ligger till: 007sweden och jag har byggt servostyrningen som ligger på Icecap's freebie-sida. Jag har byggt en mindre version av mitt gamla kamerastyrnings-projekt som satts ihop med Icecap's schema och php-koden i den här tråden.


cykze:
Såg missen med while-loopen nu. :)
Dels >= istället för <= och sedan även att $i = $startposition saknades.

Men varför den fastnar i en loop när man räknar ner med en for-loop förstår jag fortfarande inte. Notera att $step_down är -10. Därav plustecknet i $i+=$step_down. Har även provat att skriva $i-=10 med samma resultat.


Men jag ska testa oJsan's förslag och några andra idéer som dykt upp under dagen.
Användarvisningsbild
Icecap
Inlägg: 26612
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Kul... :D
Användarvisningsbild
speakman
Inlägg: 4838
Blev medlem: 18 augusti 2004, 23:03:32
Ort: Ånge

Inlägg av speakman »

Vad tror du om att skapa en ny tråd, alternativt kraftigt ändra rubriken? :)
Användarvisningsbild
JimmyAndersson
Inlägg: 26417
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Trodde problemet skulle lösa sig snabbt, så jag tyckte att det var onödigt med en ny tråd. Men det blev lite stökigare än jag trodde. Så nu är tråden delad. :)

Se trådens första inlägg för att hitta ursprungstråden.

edit: Kan tillägga att vi även har ett annat problem med koden nu, som yttrar sig i att serieporten skickar betydligt mer än vad vi ville. Vet inte riktigt än vad det beror på, men jag har kopplat upp en dator som visar vad servern skickar ut på serieporten och håller på att gå igenom utdatat. Innan vi vet vad det beror på så kan den här tråden verka lite rörig. :)
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

JimmyAndersson skrev: Men varför den fastnar i en loop när man räknar ner med en for-loop förstår jag fortfarande inte. Notera att $step_down är -10. Därav plustecknet i $i+=$step_down. Har även provat att skriva $i-=10 med samma resultat.
Som sagt, logiska tankevurpor... :) Koden från första inlägget i denna tråd fungerar ypperligt på min server, så länge startposition är större än position.

Följande kod:

Kod: Markera allt

<?php
	echo "Test 1:<p>";
	$startposition = 200;
	$position =  100 ;
	$step = 20;

	for ($i = $startposition; $i >= $position; $i -= $step)
	{
		echo $i.", ";
	}
	echo "<p>End of test 1.<p><p>";

	echo "Test 2:<p>";
	$startposition = 200;
	$position = 100;
	$step = -20;

	for ($i = $startposition; $i >= $position; $i += $step)
	{
		echo $i.", ";
	}
	echo "<p>End of test 2.<p><p>";

	echo "Test 3:<p>";
	$startposition = 100;
	$position = 200;
	$step = 20;

	for ($i = $startposition; $i >= $position; $i -= $step)
	{
		echo $i.", ";
	}
	echo "<p>End of test 3.<p><p>";

?>
...ger följande output från min server:

Kod: Markera allt

Test 1:

200, 180, 160, 140, 120, 100,

End of test 1.

Test 2:

200, 180, 160, 140, 120, 100,

End of test 2.

Test 3:

End of test 3.


Ett par andra tankar kring ert servoprojekt:
Varför skicka alla steps till servot, varför inte bara skicka den nya positionen? Hastigheten, med vilken den kommer att panorera, kommer ju att bero på baudraten... vilket kanske inte är så snyggt.
Hade ju varit betydligt vackrare att skicka "ny position" och "hastighet" till mikrokontrollern, som i sin tur sköter steglängd/hastighet.

Edit: La till "Test 3" för att visa vad som händer när startposition < position.
Skriv svar