terça-feira, 25 de setembro de 2018

Módulo SI5351




                     Construção do VFO com Display 2X24


                                  
                                Materiais
                                                            
                                 1-  Placa módulo DDS SI-PROMINI
                                                                     2-Arduino pro mini
                                                                     3-LCD 2X24 
                                                                     4-Rotary encoder
                                                                     5-4 pinos de 18mm
                                                                     6-Barras de pinos M e F
                                                                     7- Trim pots 22K



                                                                  Diagrama

                             Exemplo no arduino uno ,mas segue a mesma configuração no pro mini.
                                                                    
                                                                       Desenho de AK2B



O trim pot  Foi soldado no próprio Display.


 

sábado, 22 de setembro de 2018

Si 5351- Promini

                                Descrição

Gerador de clock Si5351A ! Este módulo foi construido especialmente para trabalhar sobre o Arduino Pro Mini ,nada impede de usar qualquer outra versão de placa .Usa se um cristal de 25MHz ou 27MHz , PLL interno e divisores para que possa gerar praticamente qualquer freqüência, de <8KHz até 150+ MHz.
O DDS  Si5351A é um gerador de clock  controlado  I2C. Ele usa o clock   para acionar vários PLLs e divisores , usando instruções I2C. Ao configurar o PLL e os divisores, você pode criar frequências precisas e arbitrárias. Existem três saídas independentes e cada uma pode ter uma frequência diferente.




Exemplo de esquema 
Exemplo de código



Si5351_VFO.ino
/*
Si5351 VFO

By LA3PNA 27 March 2015
Modified by NT7S 25 April 2015

Modified to be Si5351 Arduino v2 compliant by NT7S 21 Nov 2016

This version uses the new version of the Si5351 library from NT7S.
see: http://arduino.cc/en/Reference/AttachInterrupt for what pins that have interrupts.

UNO and 328 boards: Encoder on pin 2 and 3. Center pin to GND.
Leonardo: Encoder on pin 0 and 1. Center pin to GND.

100nF from each of the encoder pins to gnd is used to debounce

The pushbutton goes to pin 11 to set the tuning rate.
Pin 12 is the RX/TX pin. Put this pin LOW for RX, open or high for TX.
Single transistor switch to +RX will work.

VFO will NOT tune in TX.

LCD connections for for the LinkSprite 16 X 2 LCD Keypad Shield for Arduino.
Change as necessary for your LCD.
IF frequency is positive for sum product (IF = RF + LO) and negative for diff (IF = RF - LO)
VFO signal output on CLK0, BFO signal on CLK2

*/
// Only leave one uncommented for the display you wish to use
#define OLED
//#define LCD
#include <si5351.h>
#include "Wire.h"
// Conditional includes based on which display is defined above
#if defined(LCD)
#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );
#endif
#if defined(OLED)
#include "U8glib.h"
U8GLIB_SSD1306_128X64_2X u8g(U8G_I2C_OPT_NONE); // I2C / TWI
#endif
// Class instantiation
Si5351 si5351;
// interrupt service routine vars
boolean A_set = false;
boolean B_set = false;
volatile unsigned long frequency = 7100000UL; // This will be the frequency it always starts on.
volatile int tx;
unsigned long iffreq = 0; // set the IF frequency in Hz.
const unsigned long freqstep[] = {50, 100, 500, 1000, 5000, 10000}; // set this to your wanted tuning rate in Hz.
int corr = 0; // this is the correction factor for the Si5351, use calibration sketch to find value.
unsigned int lastReportedPos = 1; // change management
static boolean rotating = false; // debounce management
int inData;
int txpin = 12;
int freqsteps = 1;
int stepbutton = 11;
#define arraylength (sizeof(freqstep) / sizeof(freqstep[0]))
// Define hardware pins based on platform
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
int encoderPinA = 0; // right
int encoderPinB = 1; // left
#endif
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
int encoderPinA = 2; // right
int encoderPinB = 3; // left
#endif
// Interrupt on A changing state
void doEncoderA()
{
// debounce
if (rotating) delay (1); // wait a little until the bouncing is done
// Test transition, did things really change?
if (digitalRead(encoderPinA) != A_set) { // debounce once more
A_set = !A_set;
// adjust counter + if A leads B
if (A_set && !B_set) {
if (!tx) {
frequency += freqstep[freqsteps]; // hehre is the amount to increase the freq
}
rotating = false; // no more debouncing until loop() hits again
}
}
}
// Interrupt on B changing state, same as A above
void doEncoderB()
{
if (rotating) delay (1);
if (digitalRead(encoderPinB) != B_set) {
B_set = !B_set;
// adjust counter - 1 if B leads A
if (B_set && !A_set) {
if (!tx) {
frequency -= freqstep[freqsteps]; // here is the amount to decrease the freq
}
rotating = false;
}
}
}
void sprintf_seperated(char *str, unsigned long num)
{
// We will print out the frequency as a fixed length string and pad if less than 100s of MHz
char temp_str[6];
int zero_pad = 0;
// MHz
if(num / 1000000UL > 0)
{
sprintf(str, "%3lu", num / 1000000UL);
zero_pad = 1;
}
else
{
strcat(str, " ");
}
num %= 1000000UL;
// kHz
if(zero_pad == 1)
{
sprintf(temp_str, ",%03lu", num / 1000UL);
strcat(str, temp_str);
}
else if(num / 1000UL > 0)
{
sprintf(temp_str, ",%3lu", num / 1000UL);
strcat(str, temp_str);
zero_pad = 1;
}
else
{
strcat(str, " ");
}
num %= 1000UL;
// Hz
if(zero_pad == 1)
{
sprintf(temp_str, ",%03lu", num);
strcat(str, temp_str);
}
else
{
sprintf(temp_str, ",%3lu", num);
strcat(str, temp_str);
}
strcat(str, " MHz");
}
#if defined(OLED)
void draw_oled(void)
{
char temp_str[21];
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_helvR12);
sprintf_seperated(temp_str, frequency);
u8g.drawStr(0, 32, temp_str);
u8g.setFont(u8g_font_unifont);
sprintf(temp_str, "Step: %5u", freqstep[freqsteps]);
u8g.drawStr(0, 56, temp_str);
}
#endif
#if defined(LCD)
void draw_lcd(void)
{
char temp_str[21];
sprintf_seperated(temp_str, frequency);
lcd.setCursor(0, 0);
lcd.print(temp_str);
lcd.setCursor(6, 1);
sprintf(temp_str, "%5u", freqstep[freqsteps]);
lcd.print(temp_str);
}
#endif
void setup()
{
Serial.begin(9600);
// Set GPIO
pinMode(encoderPinA, INPUT);
pinMode(encoderPinB, INPUT);
pinMode(stepbutton, INPUT);
pinMode(txpin, INPUT);
// Turn on pullup resistors
digitalWrite(encoderPinA, HIGH);
digitalWrite(encoderPinB, HIGH);
digitalWrite(stepbutton, HIGH);
digitalWrite(txpin, HIGH);
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
//Code in here will only be compiled if an Arduino Leonardo is used.
// encoder pin on interrupt 0 (pin 0)
attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 1)
attachInterrupt(1, doEncoderB, CHANGE);
#endif
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Code in here will only be compiled if an Arduino Uno (or older) is used.
// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, doEncoderA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, doEncoderB, CHANGE);
#endif
// Initialize the display
#if defined(LCD)
lcd.begin(16, 2);
lcd.print("Si5351 VFO");
delay(2000);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Step: ");
#endif
#if defined(OLED)
//U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE); // I2C / TWI
// Assign default color value
if (u8g.getMode() == U8G_MODE_R3G3B2)
{
u8g.setColorIndex(255); // white
}
else if (u8g.getMode() == U8G_MODE_GRAY2BIT)
{
u8g.setColorIndex(3); // max intensity
}
else if (u8g.getMode() == U8G_MODE_BW)
{
u8g.setColorIndex(1); // pixel on
}
else if (u8g.getMode() == U8G_MODE_HICOLOR)
{
u8g.setHiColorByRGB(255,255,255);
}
#endif
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0, corr);
si5351.set_freq((frequency + iffreq) * 100ULL, SI5351_CLK0);
si5351.set_freq(iffreq * 100ULL, SI5351_CLK2);
}
void loop()
{
if(digitalRead(txpin))
{
tx = 0;
}
else
{
tx = 1;
}
rotating = true; // reset the debouncer
if (lastReportedPos != frequency)
{
lastReportedPos = frequency;
// Handle LCD
#if defined(LCD)
draw_lcd();
#endif
si5351.set_freq((frequency + iffreq) * 100ULL, SI5351_CLK0);
}
// Handle OLED
#if defined(OLED)
u8g.firstPage();
do
{
draw_oled();
} while(u8g.nextPage());
delay(50);
#endif
if (Serial.available() > 0) // see if incoming serial data:
{
inData = Serial.read(); // read oldest byte in serial buffer:
}
if (inData == 'F')
{
frequency = Serial.parseInt();
inData = 0;
}
if (digitalRead(stepbutton) == LOW )
{
delay(50); // delay to debounce
if (digitalRead(stepbutton) == LOW )
{
freqsteps = freqsteps + 1;
if (freqsteps > arraylength - 1 )
{
freqsteps = 0;
}
delay(50); //delay to avoid many steps at one
}
}
}




Forte 73


Módulo SI5351

                     Cons trução do VFO com Display 2X24                                                                    Materia...