Colpittsoscillator till QRP-sändare

Mina "plättar" var faktiskt riktigt smidiga att jobba med. Denna gång har jag lagt lite större omsorg på att få ner benlängderna också, vilket ger ett lite snyggare intryck.

Det fungerade fint när jag flyttade ner nycklingstransistorn till jord istället, däremot tyckte jag att arduinon tog lite stor plats så jag plockade fram och dammade av min AVR-programmerare STK500 för att programmera en Attiny25 med AVR-Studio för att göra samma jobb.

DSC_0984.jpg

DSC_0983.jpg
 
Nu har jag experimenterat med lite olika transistorer i slutsteget, uteffekten börjar på ca 550mW vid 12v, men sjunker efter en stund till 400mW, förmodligen på grund av värmen. Med en 2n3866 som tål värmen bättre, blir skillnaden mindre. En Attiny45 håller på att programmeras för att nyckla sändaren.

DSC_0018.jpg

DSC_0016.jpg
 
Smidigt & snyggt med Manhattan style. Går det att flytta de utstansade plättarna, ifall man behöver ändra någet i konstruktionen. Eller sitter de hårt fast?
 
Nu är programmeringen klar och allt är inkapslat(så när som på solcellen). Reläet används för att minska tomgångsförbrukningen, det är onödigt att oscillatorn går när den inte behöver sända. Schemat är sändning 1ggr/min "CQ TEST DE SA7CNG", 3ggr om spänningen är över 13v, 2ggr om spänningen är över 12v och 1ggr om spänningen är över 11v. Under 11v sänder den inte alls för att rädda batteriet.

Det tog ett tag att sätta sig in i hur ADC'n fungerar på Attiny45 och koden blev kanske inte extremt välskriven men den fungerar och tar enbart upp 1kb(av 4kb tillgängliga). Nästa steg är att försöka utröna hur länge batteriet håller. Förmodligen runt ett dygn.

DSC_0025.jpg
 
Här är koden, om nu någon sitter med en AVR/ATTiny och undrar hur jag har gjort.

Code:
/*
* GccApplication1.c
*
* Created: 2016-07-04 12:07:23
* Author : Alexander
*/

#define F_CPU 8000000

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

void Dash(void);
void Dot(void);

void Sendcq();

int sekund = 0;
int ggr = 0;
int paustid;

int main(void)
{
    DDRB |= (1 << 0);    //0 = input, 1 = output, PB0 is output, PB4 is input
    DDRB |= (1 << 3);   //PB3 as output.
  
     ADMUX =
     (1 << ADLAR) |     // left shift result
     (0 << REFS1) |     // Sets ref. voltage to VCC, bit 1
     (0 << REFS0) |     // Sets ref. voltage to VCC, bit 0
     (0 << MUX3)  |     // use ADC2 for input (PB4), MUX bit 3
     (0 << MUX2)  |     // use ADC2 for input (PB4), MUX bit 2
     (0 << MUX1)  |     // use ADC2 for input (PB4), MUX bit 1
     (1 << MUX0);       // use ADC2 for input (PB4), MUX bit 0

    ADCSRA =
     (1 << ADEN)  |     // Enable ADC
     (1 << ADPS2) |     // set prescaler to 64, bit 2
     (1 << ADPS1) |     // set prescaler to 64, bit 1
     (0 << ADPS0);      // set prescaler to 64, bit 0

    while(1)
        {
        ADCSRA |= (1 << ADSC);         // start ADC measurement
        while (ADCSRA & (1 << ADSC) ); // wait till conversion complete
      
        while(sekund < 60)
            {
            _delay_ms(1000);
            sekund = sekund + 1;
            }
        sekund = 0;
          
        if (ADCH > 58)
            {
            while(ggr < 4)
                {
                PORTB |= 1 << PB3; //öppna relä
                _delay_ms(1000);
                Sendcq();
                _delay_ms(200);
                PORTB &= ~(1 << PB3); //stäng relä
                ggr = ggr +1;
                }
            ggr = 1;
            }
        else if (ADCH > 54)
            {
            while(ggr < 3)
                {
                PORTB |= 1 << PB3; //öppna relä
                _delay_ms(1000);
                Sendcq();
                _delay_ms(200);
                PORTB &= ~(1 << PB3); //stäng relä
                ggr = ggr +1;
                }
            ggr = 1;
            }
        else if (ADCH > 50)
        {
            while(ggr < 2)
            {
                PORTB |= 1 << PB3; //öppna relä
                _delay_ms(1000);
                Sendcq();
                _delay_ms(200);
                PORTB &= ~(1 << PB3);
                ggr = ggr +1;
            }
            ggr = 1;
        }
        else
        {}
}

}

void Dash(void)
{
    PORTB |= 1 << PB0;
    _delay_ms(300);
    PORTB &= ~(1 << PB0);
    _delay_ms(100);
}
void Dot(void)
{
    PORTB |= 1 << PB0;
    _delay_ms(100);
    PORTB &= ~(1 << PB0);
    _delay_ms(100);

}

void Sendcq(void)
{
    Dash();
    Dot();
    Dash();
    Dot();
    _delay_ms(300);
    Dash();
    Dash();
    Dot();
    Dash();
    _delay_ms(700);
  
    Dash();
    _delay_ms(300);
    Dot();
    _delay_ms(300);
    Dot();
    Dot();
    Dot();
    _delay_ms(300);
    Dash();
    _delay_ms(700);
  
    Dash();
    Dot();
    Dot();
    _delay_ms(300);
    Dot();
    _delay_ms(700);
  
    Dot();
    Dot();
    Dot();
    _delay_ms(300);
    Dot();
    Dash();
    _delay_ms(300);
    Dash();
    Dash();
    Dot();
    Dot();
    Dot();
    _delay_ms(300);
    Dash();
    Dot();
    Dash();
    Dot();
    _delay_ms(300);
    Dash();
    Dot();
    _delay_ms(300);
    Dash();
    Dash();
    Dot();
    _delay_ms(700);
  
}
 
Koden ser bra ut - men varför inte ha makron för tidskonstanterna - skulle vara enklare att byta hastighet och beteende då.
 
Bra idee med justerbar takt!

Nu är kortet lite uppsnyggat, och jag har lagt till en potentiometer för att kunna ställa CW-takten.

DSC_0016.jpg
 
Koden är ändrad så att ett kort tecken är mellan 20-276ms vilket borde betyda 65WPM - 5 WPM

Code:
#define F_CPU 8000000 //Definiera clockfrekvensen, int. RC oscillator.

#include <avr/io.h>
#include <util/delay.h> //Måste inkluderas för _delay_ms()


int speed = 100;

void delay_ms(uint16_t n) {
    while (n--) {
        _delay_ms(1);
    }
}

int main(void)
{
    DDRB |= (1 << 0);    //Set PB0 till output, 1 = output, 0 = input
   
    ADMUX =        //Konfiguera ADC, referens och kanal.
    (1 << ADLAR) |
    (0 << REFS1) |
    (0 << REFS0) |
    (0 << MUX3)  |
    (0 << MUX2)  |
    (1 << MUX1)  |
    (1 << MUX0);

    ADCSRA =        //Konfigurera ADC
    (1 << ADEN)  |
    (1 << ADPS2) |
    (1 << ADPS1) |
    (0 << ADPS0);

    while(1)
    {
        ADCSRA |= (1 << ADSC);         // start ADC measurement
        while (ADCSRA & (1 << ADSC) ); // wait till conversion complete
        speed = ADCH + 20;
       
       
        Sendcq();   
    }
}


void Dash(void)
{
    PORTB |= 1 << PB0;
    delay_ms(3*speed);
    PORTB &= ~(1 << PB0);
    delay_ms(speed);
}
void Dot(void)
{
    PORTB |= 1 << PB0;
    delay_ms(speed);
    PORTB &= ~(1 << PB0);
    delay_ms(speed);

}

void Sendcq(void)
{
    Dash();
    Dot();
    Dash();
    Dot();
    delay_ms(3*speed);
    Dash();
    Dash();
    Dot();
    Dash();
    delay_ms(7*speed);
   
    Dash();
    delay_ms(3*speed);
    Dot();
    delay_ms(3*speed);
    Dot();
    Dot();
    Dot();
    delay_ms(3*speed);
    Dash();
    delay_ms(7*speed);
   
    Dash();
    Dot();
    Dot();
    delay_ms(3*speed);
    Dot();
    delay_ms(7*speed);
   
    Dot();
    Dot();
    Dot();
    delay_ms(3*speed);
    Dot();
    Dash();
    delay_ms(3*speed);
    Dash();
    Dash();
    Dot();
    Dot();
    Dot();
    delay_ms(3*speed);
    Dash();
    Dot();
    Dash();
    Dot();
    delay_ms(3*speed);
    Dash();
    Dot();
    delay_ms(3*speed);
    Dash();
    Dash();
    Dot();
    delay_ms(7*speed);
   
}
 
Back
Top