Vorige: FrequentieStandaard.   Omhoog: Meettoestellen.   Volgende: PulsTeller.
Inhoudsopgave   Index


Perimeter.


Om een robot-grasmaaier duidelijk te maken waar zijn grenzen liggen, wordt een perimeter gebruikt.
Die bestaat enerzijds uit een draad die enkele centimeters onder de grond wordt gelegd. De zender stuurt een signaal door deze draad.
Anderzijds is de robot uitgerust met enkele sensors, die een seintje geven als ze het signaal van de draad oppikken.

De zender.

De zender moet een klokvast signaal op de perimeter-draad zetten, dat liefst zo goed mogelijk op een sinus gelijkt.
Wie “klokvast” zegt, denkt onmiddelijk aan een kristal. Het motto “waarom moeilijk maken, als het ook met een AVR kan?” indachtig, hebben we hiervoor een ATtiny45 aan het werk gezet. Diens systeem-klok wordt uit een 20MHz-kristal betrokken, hetgeen een stabiele frequentie waarborgt.

PerimeterZender.png


Zoals in het schema hierboven te zien is, gebruikt de 'tiny drie uitgangen om een signaal te produceren. PB0, PB1 en PB2 worden in deze volgorde aangestuurd:


PB2   PB1   PB0
 0     0     0
 0     0     1
 0     1     1
 1     1     1
 1     1     1
 0     1     1
 0     0     1
 0     0     0

Trapspanning.png AfgevlakteTrapspanning.png Het resultaat (zonder C13) ziet er uit zoals het plaatje links toont. C13 haalt de scherpe kantjes weg, hetgeen resulteert in iets dat al wat meer op een sinus lijkt.

TrapspanningNaLC-filter.png L1 en C4 doen ook hun duit in het zakje, en verfraaien het signaal nog wat meer. Het is niet 100% een sinus te noemen, maar de gelijkenis volstaat voor een goede werking.

Het deel, rechts van L1, vormt een eenvoudige eindversterker.
Met P1 kan het gewenste uitgangsniveau naar wens ingesteld worden. Een oscilloscoop is bij het instellen wel handig. Als de uitgangsspanning in de buurt van de voedingsspanning komt, worden de toppen afgekot en lijkt het signaal helemaal niet meer op een sinus.


De broncode.


/*
  Sinusoscillator (of: iets dat er op lijkt) met een ATtiny45

  Pros 2012
*/


#define F_CPU 20000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>


volatile unsigned char  set[8] = { 01377310 };
register unsigned char bits asm("r2");
register unsigned char setcnt asm("r3");

ISR(TIM0_COMPA_vectISR_NAKED)
{                                                               // Compare-interrupt
    PORTB = bits;                                               // Uitgang aanpassen
    setcnt++;                                                   // Counter verhogen
    setcnt &= 7;                                                // setcnt = 0 ... 7
    bits = set[setcnt];                                         // Klaar zetten voor volgende interrupt
    reti();
}


int main(void)
{
    CLKPR = (1 << CLKPCE);
    CLKPR = 0;                                                  // Set max. system-clk
    TCNT0 = 0;
    OCR0A = 61;                                                 // 20000000 / (62 * 8) = 40000Hz
    TCCR0A = _BV(WGM01);                                        // CTC mode
    TCCR0B = _BV(CS00);                                         // Geen prescaler
    TIMSK = _BV(OCIE0A);
    DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2);                      // PB0, PB1 en PB2 = uitgangen
    _delay_ms(5);                                               // Even wachten
    sei();                                                      // Enable global interrupts

    while (1) {
    }
}

Als we een uitgangssignaal van 40kHz willen bekomen in 8 stappen, hebben we voor elke stap iets meer dan 3μS ter beschikking. Veel is dat niet.
Om die reden is er gekozen voor een “Naked” ISR, en zijn de variabelen “bits” en “setcnt” aan een register toegewezen.

Het zender-printje.

PerMetZenderPrintOnder.JPG

Tja, “Periferiemeter” in plaats van “Perimeter”...
Zullen we het maar op een vlaag van verstrooidheid houden?

PerMetZenderPrintOpgebouwd.JPG

De Ontvangers.

Het oppikspoeltje.

PerMetSpoelNaakt.JPG Het signaal wordt opgepikt door een standaard 10mH spoeltje.
Nu is zo'n ding niet helemaal geschikt voor deze taak - daarvoor is de ferriet-kern te klein. Daar kunnen we een mouw aanpassen, door er een groter stuk ferriet op te kleven. De zelfinductie wordt daardoor wat groter: 14mH.
PerMetSpoelIngepakt.JPG Teneinde de spoel weerbestendig te maken, krijgt hij een jasje dat samengesteld is uit smeltlijm en krimpkous.

Het schema van de ontvanger.

PerimeterOntvanger.png

Als we Cx even wegdenken, is de L1/C1-combinatie het gevoeligst voor een frequentie van 42.844kHz.
Dat is iets te hoog, maar op de print is plaats voorzien voor enkele extra-condensators (Cx), waarmee we de resonantiefrequentie dichter bij de zendfrequentie (40kHz) kunnen brengen.

T1, R1, R2, R3 en C3 vormen een simpel versterkertrapje.
De LM567 ―een toondetector― heeft geen nood aan een sterk ingangssignaal, maar het signaal dat L1 produceert is toch wat zwak voor een goede werking.

Het rechterdeel van het schema is een standaard-toepassing voor de LM567. Dat hoeft geen toelichting.

Wat wel toelichting behoeft, is de aanwezigheid van R8 en C4.
De LM567 bevat een oscillator. C9 en C6 kunnen niet helemaal beletten dat er op de positieve voedingsrail sporen van die oscillator terug te vinden zijn. Die kunnen dan ―via het versterkertrapje rond T1― de ingang van de LM567 bereiken. L3 en C4 vormen een effectieve blokkade voor dergelijke stoorpulsen.


Het ontvanger-printje.

PMeterOntvangerprintjeBoven.JPG

PMeterOntvangerprintjeOnder.JPG

Gebruiksaanwijzing.

De zender.

PerimeterZenderAansluiting.png Vermits de zender met een gelijkrichterbrug is uitgevoerd, kan hij zowel met gelijkspanning als met wisselspanning gevoed worden. Bij voeding met gelijkspanning speelt de polariteit geen rol - dat spreekt voor zich.
De opgegeven spanningen mogen een beetje overschreden worden, zowel naar beneden als naar boven, maar liefst niet te veel.

De stroom, die de zender door de perimeter-draad stuurt, kan ingesteld worden met P1. Het is evenwel niet mogelijk, met P1 de stroom tot 0mA terug te brengen.
Als blijkt dat de stroom, met P1 op zijn laagste stand, nog steeds te groot is, kan er met de kniptang ingegrepen worden. Tussen de beide connectors bevindt zich de tweelingweerstand R13. Door één van die weerstanden weg te knippen, wordt de stroom gehalveerd.


De ontvangers.

PerimeterOntvangerAansluiting.png De ontvangers worden gevoed met 5V DC. De LM567 mag maximaal met 9V gevoed worden, maar dan zijn er wijzigingen nodig, wil men de uitgang van de ontvangers met een μC verbinden.

Merk op, dat de uitgang hoog is, als er geen signaal wordt waargenomen.
De LM567 beschikt over een open-collector uitgang. Daar hoort bijgevolg een pull-up weerstand bij. Die bestaat enerzijds uit een LED met een serieweerstand van 560R, en anderzijds uit een weerstand van 10k. Die tweede weerstand is een noodzaak, omdat de spanningsval over de LED belet dat de uitgangsspanning hoger wordt dan 3.5V.


PerimeterSpoelOpstelling.png PerimeterSpoelOpstellingII.png De gevoeligheid van de oppikspoel hangt nauw samen met de stand van die spoel t.o.v. de perimeter-draad.
Links toont de situatie waarbij de perimeter-draad in het verlengde van de spoel ligt. Hierbij blijft de spoel redelijk “doof” voor het signaal van de perimeter-draad.
Bij de situatie rechts is de spoel juist heel gevoelig.


Fouten en verbeteringen.

Condensator-keuze.

Teneinde de ontvanger-printjes zo compact mogelijk te houden, werd voor C10, de frequentiebepalende condensator, een MLCC-type gebruikt. Dat was dom, heel dom.
MLCC's zijn eersteklas ontkoppelcondensators, maar bij deze toepassing was het vrijwel onmogelijk een stabiele centrale frequentie te bekomen.

Met wat kunst-en-vliegwerk is het gelukt C10 te vervangen door een MKP-type. Dat maakt een hemel van verschil!

Intermitterend zenden.

Wanneer een oppik-spoel de zender-draad nadert, zal op zeker ogenblik (bijvoorbeeld op 15cm afstand) de PLL van de LM567 locken. De uitgang wordt dan laag.
Wanneer nu de afstand terug groter wordt, blijft de PLL in gelockte toestand, ook als de afstand groter is dan de 15cm uit ons voorbeeld. Pas bij 20cm (nog steeds een voorbeeld) houdt hij het voor bekeken, en wordt de uitgang terug hoog.
Een vorm van hysteresis, dus. Ongewenste hysteresis, in dit geval.

Wat, als we nu bij de zender korte onderbrekingen inlassen? De LM567 ziet dan telkens het signaal verdwijnen. Dat gebeurt ook wanneer de spoel zich van de lus verwijdert. Eens de afstand groter is dan de 15cm uit ons voorbeeld, lockt de PLL niet meer in.
Gevolg: weg hysteresis.

Voor testdoeleinden is het ideaal, dat de zender naar keuze continue danwel intermitterend kan zenden. Maar hoe maak je die keuze bekend aan de microcontroller, als alle I/O-pinnen bezet zijn?
Daar bestaat een slimme truuk voor. De RESET-pin kan immers ―met de nodige omzichtigheid― als ingang gebruikt worden. Een 3k9-weerstand tussen RESET en GND volstaat om aan te geven dat er intermitterend moet gezonden worden. De bijbehorende broncode ziet u hieronder.


/*
  Sinusoscillator (of: iets dat er op lijkt) met een ATtiny45

  Pros 2012
*/


#define F_CPU 20000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

register unsigned char bits asm("r2");
register unsigned char setcnt asm("r3");
volatile unsigned char  set[8] = { 01377310 };

ISR(TIM0_COMPA_vectISR_NAKED)
{                                                               // Compare-interrupt
    PORTB = bits;                                               // Uitgang aanpassen
    setcnt++;                                                   // Counter verhogen
    setcnt &= 7;                                                // setcnt = 0 ... 7
    bits = set[setcnt];                                         // Klaar zetten voor volgende interrupt
    reti();
}


ISR(TIM1_OVF_vectISR_NAKED)
{
    TCCR0B = 0;
    _delay_us(500);
    TCCR0B = _BV(CS00);
    TIFR |= _BV(TOV1);
    reti();
}


int main(void)
{
    unsigned int            adc;

    CLKPR = (1 << CLKPCE);
    CLKPR = 0;                                                  // Set max. system-clk
    TCNT0 = 0;
    OCR0A = 61;                                                 // 20000000 / (62 * 8) = 40322Hz
    TCCR0A = _BV(WGM01);                                        // CTC mode
    TCCR0B = _BV(CS00);                                         // Geen prescaler
    TIMSK = _BV(OCIE0A);

    // Nagaan of we continue danwel intermitterend moeten zenden
    ADMUX = 0x00;                                               // ADC0 (PB5, RESET) = ADC-ingang
    ADCSRA = _BV(ADEN) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2);
    _delay_ms(200);                                             // Even wachten
    ADCSRA |= _BV(ADSC);                                        // Start dummy conversie
    while ((ADCSRA & _BV(ADSC)) != 0) {                         // Wachten tot conversie voltooid is
    }
    _delay_ms(200);
    ADCSRA |= _BV(ADSC);                                        // Start conversie
    while ((ADCSRA & _BV(ADSC)) != 0) {
    }
    adc = ADC;

    ADCSRA = 0;                                                 // ADC uitschakelen
    if (adc < 900) {                                            // Jumper gesloten?
        TCCR1 = _BV(CS10) | _BV(CS13);                          // CLK = F_CPU / 128
        OCR1A = 255;
        OCR1B = 255;
        OCR1C = 255;
        TIMSK |= _BV(TOIE1);                                    // Enable overflow-interrupt
    }

    DDRB = _BV(PB0) | _BV(PB1) | _BV(PB2);                      // PB0, PB1 en PB2 = uitgangen
    _delay_ms(5);                                               // Even wachten
    sei();                                                      // Enable global interrupts

    while (1) {
    }
}
                

Afstand meten.

Het intermitterend zenden brengt een onverwacht voordeel. Zodra de spoel dicht genoeg in de buurt van de lus is, wordt de uitgang met korte tussenpozen laag.
Maar ... hoe korter de afstand, hoe korter de tussenpozen. Door nu een eenvoudig R/C-laagdoorlaatfilter (10k/10μF) achter elke LM567 te plaatsen, bekomen we telkens een analoge spanning die lager wordt naarmate de afstand verkleint.
Dat laat on toe, op een ruwe manier die afstand in te schatten.



Vorige: FrequentieStandaard.   Omhoog: Meettoestellen.   Volgende: PulsTeller.
Inhoudsopgave   Index

Pros Robaer - 2014