Område 4 · lektion 21
Datablad
LDR:n och NTC:n gick att mäta upp med en multimeter. De flesta givare gör inte det. En ultraljudsgivare svarar med en puls vars längd betyder något, och en fuktgivare svarar med fyrtio bitar i ett eget protokoll – och ingen av dem berättar det själv. Talen finns bara på ett ställe: i tillverkarens datablad. Att kunna läsa ett är en av de förmågor kursen faktiskt bedömer, och den här guiden handlar om vad man letar efter först.
Mål
- Du kan slå upp de sex uppgifter som avgör om en givare passar ditt bygge, och veta i vilken ordning du ska leta.
- Du kan skilja ett absolut gränsvärde från ett rekommenderat arbetsområde, och säga varför skillnaden är viktig.
- Du kan härleda HC-SR04:s omräkning från mikrosekunder till centimeter, och säga varför siffran inte är en konstant.
- Du kan avgöra när ett bibliotek är rätt svar på en givare och när det döljer något du borde förstå.
Genomgång
Vad ett datablad är
Ett datablad är tillverkarens beskrivning av vad en komponent gör och under vilka villkor löftet gäller. Det är inte en handledning, det innehåller sällan exempel, och det är inte skrivet för att läsas från början till slut. Det är en uppslagsbok, och den som försöker läsa den som en bok ger upp på sidan tre.
Sättet att läsa ett datablad är att ha en fråga med sig och leta efter svaret. Frågorna nedan är de sex som avgör om komponenten över huvud taget passar ditt bygge, och de ska besvaras innan du kopplar in något.
| Fråga | Varför den kommer först | Exempel ur verkliga datablad |
|---|---|---|
| Vilken matningsspänning vill den ha? | Fel spänning ger antingen rök eller, värre, tysta felaktiga värden. | HC-SR04: 5 V. DHT11: 3,0–5,5 V. |
| Vilka är de absoluta gränsvärdena? | Det är där komponenten går sönder. Aldrig ett arbetsvärde. | ATmega328P: högst 6,0 V på matningen, 40 mA ur en enskild pinne. |
| Vad är rekommenderat arbetsområde? | Det är där de utlovade egenskaperna faktiskt gäller. | ATmega328P: 1,8–5,5 V matning. |
| Hur ser utsignalen ut? | Avgör om du klarar dig med en pinne och lite kod, eller behöver ett bibliotek. | HC-SR04: en puls vars längd är svaret. DHT: fyrtio bitar i ett eget protokoll. |
| Vilket mätområde och vilken noggrannhet? | Avgör om givaren kan mäta det du tänkt dig, och hur många decimaler du får skriva ut. | DHT11: 0–50 °C, ±2 °C. HC-SR04: ungefär 2–400 cm. |
| Vilka tidskrav finns? | En givare som läses för ofta svarar fel eller inte alls. | DHT11: högst en avläsning per sekund. HC-SR04: minst 60 ms mellan mätningarna. |
Absolut gränsvärde är inte ett arbetsvärde
Den här skillnaden finns i varje halvledardatablad och den missförstås ofta. Ett datablad har två skilda tabeller:
- Absolute Maximum Ratings. Detta är förstörelsegränsen. Tillverkaren lovar bara en sak här: över dessa värden kan komponenten gå sönder. Ingenting sägs om att den fungerar upp till dem.
- Recommended Operating Conditions, ibland kallat arbetsområde. Här gäller alla andra löften i databladet – noggrannhet, hastighet, strömförbrukning.
För ATmega328P, kretsen på ditt Uno-kort, står det 6,0 V som absolut maxvärde för matningen och 1,8–5,5 V som rekommenderat arbetsområde. Kör du på 5,8 V går kretsen troligen inte sönder – och ingenting i databladet säger att den räknar rätt.
Samma sak gäller strömmen ur en pinne. Absolut maxvärde är 40 mA. Arduinos egen rekommendation är 20 mA, alltså halva. Att medvetet arbeta en bit under gränsvärdet kallas derating, och det är ett av yrkets grundhandgrepp – mer om det i avsnittet om industrin nedan.
HC-SR04: tiden som mått på avstånd
Ultraljudsgivaren har fyra ben: matning, jord, Trig och
Echo. Databladet beskriver hela användningen i tre steg:
- Lägg
Trighög i minst 10 mikrosekunder och sedan låg igen. - Modulen sänder ut åtta ultraljudspulser och lägger
Echohög. Echogår låg igen när ekot kommit tillbaka. Pulsens längd är tiden ljudet var på väg.
Det är alltså en tid du får, inte ett avstånd. Omräkningen är fysik du redan kan, och den ska härledas – inte hämtas som en magisk 58:a från internet.
Ljudets hastighet i luft beror på temperaturen, och en användbar approximation är
v = 331 + 0,6 · T (m/s, T i grader Celsius)
Vid 20 °C blir det
v = 331 + 0,6 · 20 = 331 + 12 = 343 m/s
Räkna om till centimeter per mikrosekund, som är de enheter du har:
343 m/s = 34 300 cm/s = 34 300 / 1 000 000 = 0,0343 cm/µs
Men tiden du mätte är tur och retur – ljudet gick fram till föremålet och tillbaka. Avståndet dit är halva sträckan:
0,0343 / 2 = 0,01715 cm/µs
Alltså
avstånd i cm = tiden i µs · 0,01715
eller, om du hellre delar:
1 / 0,01715 = 58,3, alltså cm = µs / 58,3
Där kom 58:an ifrån. Räknat exempel: pulsen var 1500 µs lång.
1500 · 0,01715 = 25,7 cm
58 eller 58,3 – och varför det inte är den stora frågan
Många exempel skriver varaktighet / 58 för att slippa
decimaler. Felet det ger är 58,3 / 58 = 1,005, alltså en halv
procent, vilket på 25 cm blir 1,3 mm. Temperaturen gör mycket mer. Vid
0 °C är ljudhastigheten 331 m/s i stället för 343, alltså
343 / 331 = 1,036 – 3,6 % fel, och samma
1500 µs betyder då 24,8 cm och inte 25,7. Vid 30 °C blir det 349 m/s och
felet 1,7 % åt andra hållet. Mäter du utomhus på vintern och kalibrerade
inomhus är det den här siffran som förklarar avvikelsen.
pulseIn, och en väntan du ska känna till
Att mäta en pulslängd är precis vad pulseIn() gör. Den
väntar på att pinnen ska gå hög, tar tid tills den går låg igen, och
lämnar antalet mikrosekunder som en unsigned long.
const int TRIGG_PIN = 7;
const int EKO_PIN = 8;
const unsigned long TIDSGRANS = 30000UL; // us. Racker till drygt fem meter
const float CM_PER_US = 0.01715; // vid 20 grader, halva vagen
float matAvstand() {
digitalWrite(TRIGG_PIN, HIGH);
delayMicroseconds(10); // databladets tio mikrosekunder
digitalWrite(TRIGG_PIN, LOW);
unsigned long varaktighet = pulseIn(EKO_PIN, HIGH, TIDSGRANS);
if (varaktighet == 0) {
return -1.0; // inget eko inom tidsgransen
}
return varaktighet * CM_PER_US;
}
void setup() {
pinMode(TRIGG_PIN, OUTPUT);
pinMode(EKO_PIN, INPUT);
digitalWrite(TRIGG_PIN, LOW);
Serial.begin(9600);
}
Tre saker i den koden förtjänar en förklaring var.
delayMicroseconds(10) bryter inte mot regeln från
område 3. Regeln var att loop() inte får blockera när
den har mer än en sak att göra. Tio mikrosekunder är kortare än ett
loopvarv och omätbart för allt annat i bygget. Det var precis det
undantaget guiden om tid pekade ut.
Tidsgränsen är ett medvetet val. Utan tredje argumentet
väntar pulseIn i en hel sekund innan den ger upp, och står ett
föremål utanför räckvidden fryser bygget en sekund i taget.
30 000 µs räcker till
30 000 · 0,01715 = 515 cm
alltså drygt fem meter, vilket är mer än modulens 4 m. Räknat åt andra hållet: modulens maxavstånd 400 cm motsvarar
400 / 0,01715 = 23 300 µs = 23 ms
som är den längsta äkta puls du kan få.
pulseIn blockerar ändå. Den räknar i en
slinga och gör ingenting annat under tiden. Den måste dessutom vänta både
på att en pågående puls ska ta slut och på att en ny ska börja, så väntan
kan bli upp emot dubbla tidsgränsen. Med 30 ms gräns blir värsta
fallet ungefär 60 ms, och läser du tio gånger i sekunden utan att få något
eko blir det
10 · 60 ms = 600 ms av varje sekund, alltså 60 % av tiden
Det finns sätt att mäta pulsen utan att blockera, med avbrott, men de ligger utanför den här kursen. Det du ska göra är att veta om det och skriva det i dokumentationen, inte att låtsas att det inte finns.
Databladet säger också att modulen behöver minst 60 ms mellan mätningarna, så att förra ekot hunnit dö ut. Med tidsstämpelmönstret från område 3 blir det ett intervall på 100 ms – tio mätningar i sekunden, med marginal.
DHT: när ett bibliotek är rätt svar
DHT11 och DHT22 mäter temperatur och luftfuktighet i samma kapsel. De har tre använda ben: matning, jord och en enda datapinne. Och det är på den enda datapinnen som problemet sitter.
| DHT11 | DHT22 | |
|---|---|---|
| Temperatur, område | 0 – 50 °C | −40 – 80 °C |
| Temperatur, noggrannhet | ±2 °C | ±0,5 °C |
| Fuktighet, område | 20 – 90 % RH | 0 – 100 % RH |
| Fuktighet, noggrannhet | ±5 % RH | ±2 – 5 % RH |
| Snabbast tillåtna avläsning | en per sekund | en varannan sekund |
Läs noggrannheten en gång till. ±2 °C betyder att en DHT11 som visar 22 °C kan mena allt mellan 20 och 24. Den duger utmärkt till att se att ett rum är varmare än ett annat och inte alls till att hitta en skillnad på en grad. En NTC med en ordentlig tvåpunktskalibrering är faktiskt bättre inom sitt smala område – vilket är värt att veta innan man väljer den dyrare givaren.
Så till datapinnen. Databladet beskriver ett eget protokoll som tillverkaren hittat på:
- Kortet drar pinnen låg i minst 18 millisekunder och släpper den.
- Givaren svarar med cirka 80 µs låg och 80 µs hög.
- Sedan kommer 40 bitar, en efter en. Varje bit inleds med ungefär 50 µs låg. Sedan är pinnen hög i cirka 26 µs om biten är en nolla, och i cirka 70 µs om den är en etta. Bitens värde ligger i pulsens längd, inte i dess nivå.
- De 40 bitarna är fem byte: fuktighet, temperatur och en kontrollsumma, som är summan av de fyra första.
Att skriva det själv är fullt möjligt. Du skulle mäta pulslängder med
micros(), jämföra mot en gräns mitt emellan 26 och 70 – säg
50 µs – bygga ihop bitarna till byte, och kontrollera summan. Det är ett
par kvällars arbete, och det lär dig ingenting du inte redan kan:
det är samma tidmätning som i förra området, bara pilligare.
När ett bibliotek är rätt svar Ta ett bibliotek när det du slipper är ett protokoll – en överenskommelse om tider och bitordning som någon annan hittat på och som du inte har någon anledning att kunna. Skriv själv när det du skulle slippa är fysiken. HC-SR04:s division med 58,3 hör till din förståelse av bygget och ska stå i din kod, med härledningen i din dokumentation. Ett DHT-bibliotek döljer bara en byteström. Skillnaden är inte hur svårt det är utan vad det är du inte längre förstår.
Biblioteket används enligt samma fyrastegsrecept som
Servo.h i språkreferensen:
#include <DHT.h>
const int DHT_PIN = 4;
DHT givaren(DHT_PIN, DHT11); // typen anges nar objektet skapas
const unsigned long DHT_INTERVALL = 2000; // ms, med marginal till databladets krav
unsigned long forraDhtLasningen = 0;
void setup() {
Serial.begin(9600);
givaren.begin();
}
void loop() {
unsigned long nu = millis();
if (nu - forraDhtLasningen >= DHT_INTERVALL) {
forraDhtLasningen = nu;
float temperatur = givaren.readTemperature();
float fuktighet = givaren.readHumidity();
if (isnan(temperatur) || isnan(fuktighet)) {
Serial.println("ingen avlasning"); // givaren svarade inte
} else {
Serial.print(temperatur, 1);
Serial.print(" C ");
Serial.print(fuktighet, 0);
Serial.println(" %");
}
}
}
readTemperature() lämnar NAN – "not a number" –
när avläsningen misslyckades, och isnan() är det enda sättet
att upptäcka det. Ett tal jämför man med ==; ett
NAN är inte lika med någonting alls, inte ens med sig självt.
Utan den kontrollen får du emellanåt en utskrift som ser ut som
nan mitt i en annars fungerande logg, och i värsta fall ett
servo som skickas dit ett NAN pekar.
Lägg också märke till att avläsningen ligger inuti tidsstämpelmönstret. Det är inte kosmetika: läser du en DHT11 varje loopvarv bryter du mot databladets tidskrav, och givaren börjar svara med gamla eller uteblivna värden.
I industrin och i vardagen
I industrin: ingen konstruktör lägger en komponent på dess gränsvärde. Vanan heter derating och innebär att man medvetet arbetar en bit under det databladet tillåter – ofta halva värdet. Skälen är tre: komponenter varierar mellan exemplar, egenskaper glider med temperatur och ålder, och en komponent som blir varm åldras snabbare.
Räkna på lysdioden från bygge 0. Med 5,0 V, en lysdiod som tar 2,0 V och ett motstånd på 220 Ω blir strömmen
I = (5,0 − 2,0) / 220 = 3,0 / 220 = 0,0136 A = 13,6 mA
alltså under Arduinos rekommenderade 20 mA, som i sin tur är hälften av databladets absoluta 40 mA. Effekten i motståndet blir
P = I² · R = 0,0136² · 220 = 0,041 W = 41 mW
Ett kvarts watts motstånd tål 250 mW, så du ligger på
41 / 250 = 0,16 = 16 % av vad motståndet klarar
Det är inte överdrivet försiktigt utan normal praxis. En konstruktion där varje komponent går på 90 % av sitt gränsvärde fungerar på bänken och börjar gå sönder i fält, en efter en, under det andra året. Derating är skillnaden mellan en produkt och en prototyp.
I vardagen: förpackningen till en LED-lampa är ett datablad, tryckt i miniatyr, och den lär ut samma sak som avsnittet ovan: vilket tal är det som betyder något? På kartongen står typiskt 806 lm, 8 W, 2700 K, E27 och 15 000 h. Talet folk letar efter är watten, och det är fel tal – watt är vad lampan kostar i el, inte vad den ger.
Det som ger ljus är lumen. 806 lm är just det tal som valdes för att motsvara den gamla 60-wattsglödlampan. Jämför verkningsgraden:
806 lm / 8 W = 101 lm per watt
806 lm / 60 W = 13,4 lm per watt
101 / 13,4 = 7,5 gånger
2700 K är färgtemperaturen, alltså om ljuset är gulvarmt eller blåvitt – och den siffran gör mer för hur ett rum upplevs än effekten gör. 15 000 h räcker, med tre timmar om dagen, i
15 000 / 3 = 5 000 dygn = 5 000 / 365 = 13,7 år
Samma disciplin som med givaren: leta upp de tal som avgör om saken passar din uppgift, och strunta i resten.
Prova själv
- Sök upp databladet för HC-SR04 och skriv ned de sex uppgifterna ur tabellen i guiden – matning, absoluta gränsvärden, arbetsområde, utsignal, mätområde och noggrannhet, tidskrav. En rad var räcker.
- Koppla in modulen och skriv ut den råa pulslängden i
mikrosekunder, tio gånger i sekunden, utan att räkna om till
centimeter. Håll handen på en meters avstånd och kontrollera att talet
ligger nära
100 / 0,01715 = 5 830 µs. - Lägg till omräkningen och mät upp fem avstånd med en tumstock: 10, 20, 50, 100 och 200 cm. Skriv en tabell med uppmätt och verkligt värde. Ligger felet åt samma håll överallt har du ett systematiskt fel.
- Ställ ett föremål på 3 cm avstånd och sedan på 1 cm. Notera var modulen slutar svara vettigt. Databladet kallar den zonen blind, och gränsen ska stå i din dokumentation om du väljer den här givaren.
- Mät mot en mjuk kudde och mot en hård bok på samma avstånd. Jämför. Mät sedan mot en yta som lutar 45 grader. Skriv en mening om vad ultraljud kräver av det den mäter mot.
- Om du har en DHT: installera biblioteket med Verktyg → Hantera
bibliotek. Svara ja när miljön frågar om följdbiblioteket –
Adafruits
DHT.hbygger på ett andra bibliotek som heter Adafruit Unified Sensor, och svarar du nej stannar kompileringen på ett felmeddelande om ett saknatAdafruit_Sensor.h. Kör sedan exemplet ovan, och prova därefter att flytta avläsningen utanför tidsstämpelblocket så att den sker varje varv. Notera vad som händer med värdena. - Jämför DHT:ns temperatur med din kalibrerade NTC från förra guiden, sida vid sida i samma rum, i tio minuter. Skiljer de mer än ±2 °C? Vilken av dem har du skäl att lita mest på, och varför?
Kontrollfrågor
Vad är skillnaden mellan absolut gränsvärde och rekommenderat arbetsområde?
Gränsvärdet är där komponenten kan gå sönder; det är det enda löftet som ges där. Arbetsområdet är där alla andra löften i databladet gäller – noggrannhet, hastighet, strömförbrukning. Mellan de två finns ett område där komponenten oftast överlever men ingenting är garanterat, och det är det farligaste stället att arbeta på, eftersom det ser ut att fungera.
Härled omräkningen från mikrosekunder till centimeter för HC-SR04.
Ljudhastigheten vid 20 °C är 331 + 0,6 · 20 = 343 m/s, som
är 34 300 cm/s, som är 0,0343 cm/µs. Den mätta
tiden är tur och retur, så avståndet är halva: 0,01715
cm/µs. Alltså cm = µs · 0,01715, eller
µs / 58,3.
Din HC-SR04 svarar 1160 µs. Hur långt bort är föremålet, och hur mycket fel blir det om luften är 0 °C i stället för 20?
1160 · 0,01715 = 19,9 cm. Vid 0 °C är ljudhastigheten
331 m/s, alltså 0,01655 cm/µs, och samma tid betyder då
1160 · 0,01655 = 19,2 cm. Skillnaden är 0,7 cm, alltså
3,6 % – och den är systematisk, så den försvinner inte av att du mäter
fler gånger.
En DHT11 visar 22 °C. Vad vet du?
Att temperaturen med tillverkarens löfte ligger någonstans mellan 20 och 24 °C. Att skriva ut 22,0 med en decimal är därför att påstå mer än givaren kan hålla. Vill du hitta skillnader på en grad har du valt fel givare.
När är ett bibliotek rätt svar, och när är det ett sätt att slippa förstå?
Rätt när det du slipper är ett protokoll – en godtycklig överenskommelse om tider och bitordning, som med DHT. Fel när det du slipper är fysiken i ditt eget bygge, som HC-SR04:s omräkning från tid till avstånd. Frågan att ställa är inte hur svårt det är utan vad du inte längre kan förklara i din redovisning.
Varför står tidsgränsen som tredje argument till
pulseIn?
Utan den väntar funktionen en hel sekund på ett eko som kanske aldrig kommer, och bygget står stilla under tiden. 30 000 µs räcker till drygt fem meter, alltså mer än modulens räckvidd, och gör att ett uteblivet eko kostar upp emot 60 ms i stället för uppemot två sekunder. Funktionen lämnar 0 när tiden gått ut, och det värdet ska koden hantera.
Vanliga fel
- Avståndet blir orimligt stort eller är alltid noll.
TrigochEchoär förväxlade, eller så saknas gemensam jord mellan modulen och kortet. Kontrollera de två sakerna innan koden. - Avståndet hoppar mellan ett rimligt värde och noll. Ekot uteblir ibland – mot en mjuk, lutande eller mycket liten yta. Sålla bort nollorna i stället för att räkna med dem, annars drar de ned varje medelvärde.
- Mätvärdet är systematiskt några procent fel. Temperaturen i luften är inte 20 °C, eller så räknar koden med 58 i stället för 58,3. Båda är systematiska fel och båda syns bara om du mäter mot en tumstock.
- Modulen mäter samma sak flera gånger i rad. Du läser oftare än var 60:e millisekund, och ekot från förra pulsen hinner in. Sätt intervallet till 100 ms.
- Bygget hackar när ingenting är framför givaren.
pulseInväntar ut sin tidsgräns. Sänk gränsen till vad din räckvidd faktiskt kräver, och läs mer sällan. - DHT:n svarar
nanvarje gång. Oftast fel pinne, saknadbegin(), eller fel typ angiven när objektet skapades –DHT11där det skulle ståttDHT22. - DHT:n svarar
nanibland. Den läses för ofta. Databladet säger högst en avläsning per sekund för DHT11 och en varannan för DHT22. Kontrollen medisnan()ska ändå finnas kvar. - Ett tal ur ett datablad förväxlas med ett uppmätt. "Noggrannheten är ±2 °C" är tillverkarens löfte, inte din mätning. Ett bedömt bygge behöver båda, och de ska hållas isär i dokumentationen.
Vidare
Kapitlet Bibliotek i språkreferensen är den här guidens uppslagsdel: fyrastegsreceptet och varningen om att ett bibliotek kan ta hårdvara med sig. Det senare blir konkret i nästa guide, där en LCD lägger beslag på två av de sex analoga pinnarna.
Nästa guide är Visa mätvärdet. Där ska talet du nu kan mäta och kalibrera bli något en människa kan avläsa – och där kravställs bygge 3.