ho un problema da risolvere.
Sto cercando di simulare dei contraves (selettori decimali/binari) per comandare una scheda che gestisce un vfo di una radio con arduino.
La frequenza dovrà variare da 1 MHz a 30MHz e la risoluzione a 100Hz quindi se il valore fosse rx=30.000.000Hz andrà troncata ai 100Hz quindi rx=rx/100.
Otterrò quindi 300.000 per gestire i 6 contraves.
La mia idea sarebbe quella di creare una funzione
- Codice: Seleziona tutto
void converti(long fr) { // Funzione per scomporre le cifre.
f=fr%10; //100hz
fr=fr/10;
e=fr%10; //1Khz
fr=fr/10;
d=fr%10; //10Khz
fr=fr/10;
c=fr%10; //100Khz
fr=fr/10;
b=fr%10; //1MHz
fr=fr/10;
a=fr%10; //10MHz
}
Ed una seconda funzione con maschera per inviare il codice binario relativo per simulare i contraves dove i vari a,b,c,d,e,f rappresentano i 6 contraves
ed 0/1/2/4 rappresentano gli esponenti base 2 del valore binario che piloteranno i 4 pin in ingresso nella scheda :
- Codice: Seleziona tutto
void inviaBCD(){
digitalWrite(f0, (HIGH &&(f & B0001))); // 100hz
digitalWrite(f1, (HIGH &&(f & B0010)));
digitalWrite(f2, (HIGH &&(f & B0100)));
digitalWrite(f4, (HIGH &&(f & B1000)));
digitalWrite(e0, (HIGH &&(e & B0001))); // 1Khz
digitalWrite(e1, (HIGH &&(e & B0010)));
digitalWrite(e2, (HIGH &&(e & B0100)));
digitalWrite(e4, (HIGH &&(e & B1000)));
digitalWrite(d0, (HIGH &&(d & B0001))); // 10Khz
digitalWrite(d1, (HIGH &&(d & B0010)));
digitalWrite(d2, (HIGH &&(d & B0100)));
digitalWrite(d4, (HIGH &&(d & B1000)));
digitalWrite(c0, (HIGH &&(c & B0001))); // 100Khz
digitalWrite(c1, (HIGH &&(c & B0010)));
digitalWrite(c2, (HIGH &&(c & B0100)));
digitalWrite(c4, (HIGH &&(c & B1000)));
digitalWrite(b0, (HIGH &&(b & B0001))); // 1Mhz
digitalWrite(b1, (HIGH &&(b & B0010)));
digitalWrite(b2, (HIGH &&(b & B0100)));
digitalWrite(b4, (HIGH &&(b & B1000)));
digitalWrite(a0, (HIGH &&(a & B0001))); // 10Mhz
digitalWrite(a1, (HIGH &&(a & B0010)));
}
Simulandolo con Excel queste 2 funzioni girano ottimamente ma con arduino da dei risultati incongruenti.
Ho recuperato un sw di gestione encoder con display lcd seriale per gestire questa variabile che andrà convertita in binaria.
Questa routine è stata presa in rete (autore Richard Visokey AD7C - www.ad7c.com) e gestiva un ad9850 (DDS) per produrre una frequenza, perfettamente funzionante
solo qualche piccolo salto di frequenza dovuto ai contatti di questi encoder meccanici economici.
- Codice: Seleziona tutto
// Include the library code
#include <LiquidCrystal.h>
#include <rotary.h>
#include <EEPROM.h>
//Setup some items
digitalWrite(pin, LOW); }
Rotary r = Rotary(2,3);
// sets the pins the rotary encoder uses.
//Must be interrupt pins.
LiquidCrystal lcd(12, 13, 7, 6, 5, 4);
int_fast32_t rx=7200000; // Starting frequency of VFO
int_fast32_t rx2=1; // variable to hold the updated frequency
int_fast32_t increment = 10;
// starting VFO update increment in Hz.
int buttonstate = 0;
String hertz = "10 Hz";
int hertzPosition = 5;
byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ; //Placeholders
String freq; // string to hold the frequency
int_fast32_t timepassed = millis();
// int to hold the arduino miilis since startup
int memstatus = 1;
// value to notify if memory is current or old. 0=old, 1=current.
int ForceFreq = 1; // Change this to 0 after you upload and run a working sketch to activate the EEPROM memory. YOU MUST PUT THIS BACK TO 0 AND UPLOAD THE SKETCH AGAIN AFTER STARTING FREQUENCY IS SET!
void setup() {
pinMode(A0,INPUT); // Connect to a button that goes to GND on push
digitalWrite(A0,HIGH);
lcd.begin(16, 2);
PCICR |= (1 << PCIE2);
PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
sei();
lcd.setCursor(hertzPosition,1);
lcd.print(hertz);
// Load the stored frequency
if (ForceFreq == 0) {
freq = String(EEPROM.read(0))+String(EEPROM.read(1))+String(EEPROM.read(2))+String(EEPROM.read(3))+String(EEPROM.read(4))+String(EEPROM.read(5))+String(EEPROM.read(6));
rx = freq.toInt();
}
}
void loop() {
if (rx != rx2){
showFreq();
sendFrequency(rx);
rx2 = rx;
}
buttonstate = digitalRead(A0);
if(buttonstate == LOW) {
setincrement();
};
// Write the frequency to memory if not stored and 2 seconds have passed since the last frequency change.
if(memstatus == 0){
if(timepassed+2000 < millis()){
storeMEM();
}
}
}
ISR(PCINT2_vect) {
unsigned char result = r.process();
if (result) {
if (result == DIR_CW){rx=rx+increment;}
else {rx=rx-increment;};
if (rx >=30000000){rx=rx2;}; // UPPER VFO LIMIT
if (rx <=1000000){rx=rx2;}; // LOWER VFO LIMIT
}
}
void setincrement(){
if(increment == 10){increment = 50; hertz = "50 Hz"; hertzPosition=5;}
else if (increment == 50){increment = 100; hertz = "100 Hz"; hertzPosition=4;}
else if (increment == 100){increment = 500; hertz="500 Hz"; hertzPosition=4;}
else if (increment == 500){increment = 1000; hertz="1 kHz"; hertzPosition=6;}
else if (increment == 1000){increment = 2500; hertz="2.5 kHz"; hertzPosition=4;}
else if (increment == 2500){increment = 5000; hertz="5 kHz"; hertzPosition=6;}
else if (increment == 5000){increment = 10000; hertz="10 kHz"; hertzPosition=5;}
else if (increment == 10000){increment = 100000; hertz="100 kHz"; hertzPosition=4;}
else if (increment == 100000){increment = 1000000; hertz="1 MHz"; hertzPosition=6;}
else{increment = 10; hertz = "10 Hz"; hertzPosition=5;};
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(hertzPosition,1);
lcd.print(hertz);
delay(250); // Adjust this delay to speed up/slow down the button menu scroll speed.
};
void showFreq(){
millions = int(rx/1000000);
hundredthousands = ((rx/100000)%10);
tenthousands = ((rx/10000)%10);
thousands = ((rx/1000)%10);
hundreds = ((rx/100)%10);
tens = ((rx/10)%10);
ones = ((rx/1)%10);
lcd.setCursor(0,0);
lcd.print(" ");
if (millions > 9){lcd.setCursor(1,0);}
else{lcd.setCursor(2,0);}
lcd.print(millions);
lcd.print(".");
lcd.print(hundredthousands);
lcd.print(tenthousands);
lcd.print(thousands);
lcd.print(".");
lcd.print(hundreds);
lcd.print(tens);
lcd.print(ones);
lcd.print(" MHz ");
timepassed = millis();
memstatus = 0; // Trigger memory write
};
void storeMEM(){
//Write each frequency section to a EPROM slot. Yes, it's cheating but it works!
EEPROM.write(0,millions);
EEPROM.write(1,hundredthousands);
EEPROM.write(2,tenthousands);
EEPROM.write(3,thousands);
EEPROM.write(4,hundreds);
EEPROM.write(5,tens);
EEPROM.write(6,ones);
memstatus = 1; // Let program know memory has been written
};
Durante la fase di decodifica dandogli in pasto la variabile rx succede che già dalla prima funzione i dati non tornano.
Credo sia un problema di variabili ma non riesco ad uscirne.
Premetto che non sono un programmatore ma prendo pezzi funzionanti qua e là e cerco di adattarli alle mie esigenze.
Scusate la lungaggine ma penso che possa essere utile anche ad altri.
grazie per chi avrà la pazienza di analizzare questi codici.
ciao
Antonio

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)


