Område 6 · lektion 33
Systematisk felsökning
Den första meningen i den här kursen var att den som aldrig mätt en spänning felsöker genom att byta komponenter. Nu står du med ett eget system som inte gör vad du tänkt, och det är där skillnaden märks. Att byta delar är att gissa snabbt. Att mäta är att veta långsamt — och den som mäter är oftast klar först.
Mål
- Du kan formulera ett fel som tre påståenden: vad som skulle hända, vad som händer, och vad som skiljer.
- Du kan halvera en signalkedja i stället för att gå igenom den från början, och veta varför det går fortare.
- Du kan skriva en minsta testskiss som provar en enda del av systemet.
- Du kan känna igen kursens vanligaste felbilder på symtomet.
Genomgång
Byt inte. Mät.
Att byta en komponent tar två minuter och ger ett av två svar: felet fanns där, eller så vet du fortfarande ingenting. Att mäta i en punkt tar också två minuter, men halverar antalet möjliga fel oavsett vad mätaren visar. Ett bytesförsök som inte hjälper är bortkastat; en mätning som visar rätt värde är lika värdefull som en som visar fel.
Att byta har dessutom en baksida Varje byte lägger till en möjlig ny felkälla: en tråd som hamnade i fel hål, en komponent som vändes fel, en lödning som lossnade. Efter fem byten felsöker du ett annat system än det du började med. Det är därför en ändring i taget, med resultatet nedskrivet, är den enda metod som håller när felet inte hittas på fem minuter.
Tre påståenden innan du rör någonting
Skriv dem. På papper, inte i huvudet. De tar en minut och de flyttar arbetet från "det fungerar inte" till en fråga som går att undersöka:
- Vad skulle hända? "Servot ska gå till 90 grader när råvärdet passerar 400."
- Vad händer i stället? "Servot rycker till och går tillbaka. Varje gång, inte ibland."
- Vad är skillnaden? "Rörelsen påbörjas, alltså är beslutet rätt och signalen kommer fram. Den avbryts, alltså faller något bort under rörelsen."
Det tredje påståendet är det som gör jobbet. I exemplet har du redan uteslutit givaren, tröskeln och koden fram till beslutet — och pekat ut matningen, som är det som brukar falla bort just när ett servo börjar dra ström. Tio sekunders tänkande som ersatte en halvtimmes byten.
Halvera kedjan i stället för att gå igenom den
Ditt system är en kedja med sex länkar: givaren, råvärdet, beslutet, styrsignalen, drivsteget och aktuatorn. Går du från början och kontrollerar en länk i taget behöver du i värsta fall sex mätningar. Mäter du i mitten först behöver du tre — och tre räcker även i värsta fall.
| Mätning | Var | Utfall | Vad du vet efteråt |
|---|---|---|---|
| 1 | Mitt i kedjan: skriv ut styrsignalen på Serial |
Rätt värde | Hela första halvan fungerar. Felet ligger i drivsteg eller aktuator |
| 1 | Samma punkt | Fel värde | Felet ligger i givare, råvärde eller beslut. Andra halvan är oskyldig |
| 2 | Mitt i den halva som var fel | — | Nu återstår två länkar |
| 3 | Mellan de två | — | Felet är lokaliserat |
Sex länkar, tre mätningar. Tolv länkar hade krävt fyra. Det är samma halvering som gör att man hittar ett ord i en ordbok utan att bläddra från sida ett, och den är kraftfullast precis när systemet är stort — alltså nu, i slutprojektet.
Mätpunkterna, i den ordning de lönar sig
Innan du mäter något finstilt: gå igenom de fyra grova punkterna. De tar en minut tillsammans och förklarar de flesta fel i den här kursen.
- Matningen. Mät spänningen där komponenten sitter, inte vid batteriet. Ett batteri som visar 6,0 V i vila kan visa 4,1 V där servot sitter under rörelse, och det är den senare siffran som gäller.
- Den gemensamma nollan. Mät resistansen mellan kortets GND och den andra matningens minuspol. Ska vara nära noll ohm. Är den inte det behöver du inte leta vidare — du har hittat felet.
- Signalen där den lämnar kortet. Mät på pinnen. Rätt nivå där och fel funktion i andra änden betyder att felet ligger efter kortet.
- Mekaniken för hand, med strömmen av. Går det runt? Ett stumt lager, en skruv i vägen eller ett kugghjul som kärvar ger en elektrisk symtombild — hög ström, kortet startar om — som lurar dig att felsöka i fel halva.
Minsta testskiss
Den starkaste metoden i hela guiden, och den som används minst: ta bort allt utom en enda del och prova den för sig. Skriv av skissen nedan och byt ut pinnen mot din egen. Den gör ingenting annat än att visa vad givaren levererar.
// Minsta testskiss – provar EN sak i taget.
// Ligger i en egen fil, inte i projektskissen. Den ska förbli kort.
const int GIVARE_PIN = A0;
void setup() {
Serial.begin(9600);
}
void loop() {
int ravarde = analogRead(GIVARE_PIN);
Serial.println(ravarde);
delay(200); // här är delay rätt: skissen gör inget annat
}
Visar den ett värde som ändras när du täcker för givaren är givaren, spänningsdelaren, ledningarna och den analoga ingången friska — fyra länkar uteslutna på två minuter. Visar den 0 eller 1023 oavsett vad du gör sitter felet i någon av de fyra, och du behöver aldrig titta på resten av systemet. Gör samma sak åt andra hållet med aktuatorn: en skiss som bara svänger servot mellan två lägen, utan givare och utan beslut.
Att delay är tillåtet här är själva poängen
I projektskissen blockerar delay() allt annat, precis som
guiden om tid
säger. I en testskiss finns inget annat att blockera. Att testskissen får
vara enkel är hela skälet till att den är användbar — den innehåller för lite
för att kunna vara fel.
Serial som mätinstrument
Multimetern mäter volt. Serial mäter vad programmet tror. De
två tillsammans avgör om felet sitter i verkligheten eller i din bild av
den. Skriv av mönstret och lägg det i din egen loop:
// Felsökningsutskrift: råvärde, tillstånd och tid, en rad per varv.
// Läggs in tillfälligt, tas bort eller kommenteras ut när felet är hittat.
void skriv_lage(int ravarde, int lage) {
Serial.print(millis()); // tidsstämpel – visar OM koden går runt
Serial.print(" ravarde=");
Serial.print(ravarde);
Serial.print(" lage=");
Serial.print(lage);
Serial.print(" troskel=");
Serial.println(TROSKEL_MORKT);
}
Tre saker syns i den utskriften som inte syns någon annanstans. Tidsstämpeln visar om loopen går runt alls, och hur fort — står talet stilla har något blockerat. Råvärdet bredvid tröskeln visar om beslutet borde ha fattats, vilket är en annan fråga än om det fattades. Läget visar vad systemet minns, och ett system som hoppar mellan två lägen varje varv är den vanligaste orsaken till att en mekanism darrar i stället för att röra sig.
En ändring i taget, nedskriven
När felet inte hittas på fem minuter går metoden över i den enda som håller: en ändring, ett prov, en rad i anteckningen. Raden behöver tre kolumner — vad du ändrade, vad du trodde skulle hända, vad som hände. Det är tråkigt och det är snabbast, och det ger dessutom rakt av det avsnitt i dokumentationen som heter "vad som gick fel på vägen" och som annars skrivs på minnet i slutet av maj.
Symtomtabellen
Kursens felbilder samlade. Leta upp symtomet, inte orsaken — det är symtomet du har.
| Symtom | Trolig orsak | Kontrollera så här |
|---|---|---|
| Slumpmässigt beteende, blir bättre när du håller i sladden | Gemensam nolla saknas, eller glapp | Mät resistansen mellan de två matningarnas minuspoler. Nära noll ohm krävs |
| Kortet startar om när något börjar röra sig | Brownout: matningen orkar inte startrycket | Mät spänningen vid aktuatorn under rörelse, inte i vila |
| Ingenting händer, uppladdningen misslyckas | Något sitter på pinne 0 eller 1, eller fel port vald | Koppla ur allt utom USB och ladda upp en tom skiss |
| Motorn går bara för fullt eller inte alls | PWM på en pinne utan PWM, eller på 9/10 med servobiblioteket | Flytta till pinne 3, 5, 6 eller 11. Se pinnbudgeten |
| Mekanismen rycker fram och tillbaka vid gränsen | Råvärdet darrar över och under en enda tröskel | Två trösklar med mellanrum, och medelvärde av flera prov som i kalibreringsguiden |
| Systemet reagerar en gång och sedan aldrig mer | Tillståndet fastnade i ett läge det inte kan lämna | Skriv ut läget varje varv. Saknas övergången tillbaka? |
| Knappen räknar flera tryck på ett | Kontaktstuds | Se guiden om digital ingång |
| Råvärdet ligger på 0 eller 1023 hela tiden | Spänningsdelaren är bruten, eller givaren är kortsluten | Mät spänningen på den analoga ingången med multimeter |
| Mekanismen går tom men står stilla med last | För liten momentmarginal | Räkna om utväxlingen, eller minska trummans radie |
| Något blir varmt | Ström där det inte ska vara ström, eller mekanik som kärvar | Stäng av. Känn efter var. Mät strömmen innan du sätter på igen |
| Serial visar ingenting | Fel hastighet i monitorn, eller Serial.begin saknas |
9600 i både koden och monitorns lista |
| Koden kompilerar inte efter en liten ändring | Ett tecken, oftast en klammer eller ett semikolon | Läs första felmeddelandet, inte det sista. Se C++ efter Python |
I industrin och i vardagen
Industrin: felsökning mot klockan
En stillastående produktionslina kostar pengar per minut — i en biltillverkning
räknas det i tiotusentals kronor i timmen. Därför felsöker underhållspersonal
aldrig genom att byta delar. De går till styrsystemets larmlogg, läser vilken
givare som senast bytte läge och när, och jämför med det förlopp som skulle ha
skett. Loggen är precis den tidsstämplade utskriften du gör med
Serial, fast permanent inbyggd. Ett vanligt utfall är att larmet
säger "cylinder 4 nådde inte ändläge inom 1,2 s" — och då är felsökningen redan
halverad innan någon rört maskinen, eftersom både förväntan och utfallet står
skrivna.
Vardagen: proppen som gick
Strömmen försvann i halva lägenheten. Den som gissar går och köper en ny säkring. Den som halverar slår ifrån allt, slår på jordfelsbrytaren, och kopplar sedan in apparaterna en och en tills den slår ifrån igen — och vet efter fem försök vilken av tjugo apparater som är trasig, i stället för att efter fem byten ha en låda nya säkringar och samma fel. Det är exakt samma metod som de tre mätningarna i en kedja med sex länkar, och den fungerar av samma skäl: varje prov utesluter hälften, oavsett hur det går.
Prova själv
- Skriv de tre påståendena om det fel du har just nu. Vad skulle hända, vad händer, vad skiljer. Har du inget fel för tillfället: ta det senaste du löste och skriv dem i efterhand, för att se hur de ser ut.
- Rita din signalkedja som sex rutor och sätt ett kryss mitt i. Det är där du mäter först. Skriv ned vilken halva som blir oskyldig i vartdera utfallet, innan du mäter.
- Gör de fyra grova mätningarna i tur och ordning: matning under drift, gemensam nolla, signalen på pinnen, mekaniken för hand.
- Skriv en minsta testskiss för din givare. Egen fil. Kontrollera att råvärdet ändras när du påverkar givaren.
- Skriv en minsta testskiss för din aktuator. Bara två lägen, inget beslut. Nu vet du om ändarna av kedjan fungerar.
- Lägg in tidsstämplad utskrift av råvärde, tröskel och läge i projektskissen. Titta särskilt på om tiden mellan raderna är jämn.
- För felsökningslogg med tre kolumner under resten av projektet: vad du ändrade, vad du trodde, vad som hände. Den blir ett avsnitt i dokumentationen.
- Prova att provocera fram felet. Ett fel som inte går att återskapa går inte att laga. Kan du få det att inträffa varje gång vet du något om orsaken redan där.
Kontrollfrågor
Varför är en mätning som visar rätt värde lika mycket värd som en som visar fel?
Därför att båda utesluter lika många möjligheter. En mätning mitt i kedjan som visar rätt värde friar hela första halvan; en som visar fel friar hela andra. Det är bara byten som är asymmetriska — ett byte som inte hjälper har inte uteslutit något alls, det har bara visat att just den komponenten troligen var hel. Därför lönar sig mätning även när du är säker på var felet sitter.
Ditt servo rycker till och går tillbaka varje gång tröskeln passeras. Vilken halva av kedjan är oskyldig, och varför?
Första halvan. Att rörelsen påbörjas betyder att givaren läser, att beslutet fattas och att styrsignalen kommer fram — annars hade ingenting hänt alls. Felet ligger alltså i det som händer när strömmen börjar dras: matningen faller ihop, kortet startar om eller går tillbaka till utgångsläget. Mät spänningen vid servot under rörelsen. Symtomet "det börjar men fullföljs inte" är nästan alltid ett effektproblem, inte ett logikproblem.
Tidsstämpeln i din utskrift hoppar från 4 210 till 6 480. Vad har hänt?
Något tog 2,3 sekunder. Det är inte en normal loop. Antingen ligger det ett
delay() i vägen, eller så väntar koden på något — en
while-slinga, eller en pulseIn mot en HC-SR04 som
inte får något eko och går till sin tidsgräns. Under de 2,3 sekunderna läser
systemet ingen knapp och fattar inga beslut, vilket förklarar varför det
känns "trögt" eller "missar tryck". Se
Tid utan delay.
Varför ska testskissen ligga i en egen fil i stället för att du kommenterar bort halva projektskissen?
Därför att bortkommenterad kod fortfarande är en del av filen: klamrar kan hamna fel, en variabel som fanns försvinner, och du felsöker plötsligt ett tredje system som varken är projektet eller testet. En egen fil på femton rader kan inte innehålla det fel du letar efter, och det är just den egenskapen som gör svaret entydigt. Den ska dessutom finnas kvar — du kommer att vilja prova givaren igen.
Du har ändrat tre saker och nu fungerar det. Vad är problemet?
Att du inte vet vad som var fel, alltså inte heller om det är lagat. Två av ändringarna kan ha varit onödiga och den tredje kan ha dolt felet i stället för att lösa det — och då kommer det tillbaka, gärna under redovisningen. Ta bort ändringarna en i taget tills felet återkommer. Det tar fem minuter och ger dig både orsaken och en rad i dokumentationen som är värd mer än "det löste sig".
Vanliga fel
- Flera ändringar mellan två prov. Då vet du inte vilken som gjorde skillnad, och du kan inte gå tillbaka. En i taget.
- Byte i stället för mätning. Särskilt frestande när reservdelen ligger i lådan. Ett byte som inte hjälper har uteslutit nästan ingenting och kan ha lagt till ett nytt fel.
- Mätning på fel ställe. Spänning vid batteriet i stället för vid komponenten, i vila i stället för under drift. Det är där skillnaden finns.
- Felsökning i koden när symtomet är elektriskt. Kortet startar om, alltså läser man koden en gång till. Symtomet pekar på matningen, och koden är oskyldig.
- Mekaniken kontrolleras aldrig. Ett kärvande lager ger hög ström och brownout, vilket ser ut som ett elfel. Vrid runt för hand med strömmen av — det tar tio sekunder.
- Inget skrivs ned. Efter fyrtio minuter minns du inte vilka kombinationer du provat, och börjar om.
- Felet går inte att återskapa och lämnas därhän. Ett sporadiskt fel är nästan alltid ett glapp, en gemensam nolla på gränsen eller en matning som ligger precis för lågt. Det försvinner inte av sig självt.
- Det sista felmeddelandet läses först. Kompilatorns första fel är oftast det äkta; resten är följdfel av samma tecken.
Vidare
Utskrifterna bygger på Serial och millis(), som
står i språkreferensens kapitel om tid.
Tillståndet som skrivs ut har sitt mönster i
Tillstånd,
och funktionen skriv_lage följer mönstret i
Funktioner.
Felsökningsloggen du för nu är råmaterial till nästa pass. Vad som gör en dokumentation noggrann i stället för enkel står i Dokumentationens grad, som är lektion 34. Kraven du ska pricka av står kvar på bygge 5:s sida.
Tillbaka till område 6 eller till kursens material.