Arduino - sw conversione decimale/binario per contraves

di il
5 risposte

Arduino - sw conversione decimale/binario per contraves

Buongiorno a tutti,
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
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 :
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.

La variabile che gli passo è stata inizializzata così:

int_fast32_t rx=7200000; // Starting frequency of VFO

in una fase successiva viene caricata in una EEPROM
  // 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));
   [b] rx = freq.toInt(); [/b] 
  }
}
Come si vede la variabile viene convertita in intero rx = freq.toInt();

Non vorrei che tutte queste modifiche di tipo variabile comportassero un funzionamento anomalo.

grazie per l'attenzione

Antonio

5 Risposte

  • Re: Arduino - sw conversione decimale/binario per contraves

    Le potenze sono f0 f2 e così via
    Cosa sono per te f0 ...?
  • Re: Arduino - sw conversione decimale/binario per contraves

    Ciao Oregon e grazie per l'interesse,
    f0,f1,f2,f4 e a0,a1,a2,a4 e via via....sono i valori che devono assumere i pins di ingresso della scheda che simula i contraves decimali/binari di cui allego immagine.

    Ho provato a far lavorare le routine separatamente la funzione converti(freq) da l'output corretto:

    5
    5
    1
    3
    6
    4

    InviaBCD() invece fa rimanere i led spenti che ho usato per simulare gli stati
    quando invece dovrebbe dare 0101 (5 in decimale)

    Per lo meno ho capito che il tipi di variabile che passavo non era pulita e non era un intero infatti qui va, per lo meno la prima funzione.
    int a=0;int b=0; int c=0; int d=0; int e=0; int f=0; 
    int ff0, ff1, ff2, ff4; 
    
    int a0=38;int a1=39;                         // 10 Mhz BCD
    int b0=40;int b1=41; int b2=42; int b4=43;   // BCD 1Mhz
    int c0=44;int c1=45; int c2=46; int c4=47;   // BCD 100Khz
    int d0=48;int d1=49; int d2=50; int d4=51;   // BCD 10Khz
    int e0=52;int e1=53; int e2=3; int e4=4; // BCD 1Khz
    int f0=4;int f1=5; int f2=6; int f4=7; // BCD 100Hz
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
    
     pinMode(f0, OUTPUT);pinMode(f1, OUTPUT);pinMode(f2, OUTPUT);pinMode(f4, OUTPUT);
    }
    
    void loop() {
    
    float freq=463155;// a,b,c,d,e,f  f=100Hz
      converti(freq);
      inviaBCD();
      
      } 
      
      // put your main code here, to run repeatedly:
    void converti(long fr) {   // Funzione per scomporre le cifre.
      
      //  modifica mio rx collins
      //  g=fr%10;  //10hz
      //fr= fr/10;
     int a=0;int b=0; int c=0; int d=0; int e=0; int f=0; 
     
      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
      Serial.println(f);
       delay(1000);
      Serial.println(e);
       delay(1000);
       Serial.println(d);
        delay(1000);
      Serial.println(c);
       delay(1000);
       Serial.println(b); delay(1000);
      Serial.println(a);
      Serial.println();
      delay(3000);
        } 
    void inviaBCD(){
    
    // Dichiarazione pin BCD per output modif. mio rx Collins
    // verificare pins e tensioni se invertite
     // int g0=9;int g1=10; int g2=11; int g4=12; // BCD 10hz
    
      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)));     
    
      
    //ff0=((HIGH) &&(f & B0001));
    //ff1=((HIGH) &&(f & B0010));
    //ff2=((HIGH) &&(f & B0100));
    //ff4=((HIGH) &&(f & B1000));
    
    // Serial.println(((ff0) ? 1 : 0));
    // Serial.println(((ff1) ? 1 : 0));
    // Serial.println(((ff2) ? 1 : 0));
    // Serial.println(((ff4) ? 1 : 0));
    //  Serial.println(ff0);
    //  Serial.println(ff1);
    //  Serial.println(ff2);
    //  Serial.println(ff4);
    
    digitalWrite(f0, (HIGH &&(f & B0001)));   // 100hz 
      
      delay(3000);
    
    
      } 

    Allegati:
    contraves decimale binario
    contraves decimale binario
  • Re: Arduino - sw conversione decimale/binario per contraves

    Aspetta un attimo ... non capisco cosa tu stia facendo ...

    Quando scrivi
    
    int f0=4;int f1=5; int f2=6; int f4=7;
    
    tu dici che vuoi usare i pin 4, 5, 6 e 7 di Arduino?

    Invece di mostrarci i contraves, facci vedere il collegamento delle uscite di Arduino ai tuoi led.

    [B]Usi il pin 4 sia per e4 che per f0?
  • Re: Arduino - sw conversione decimale/binario per contraves

    Grande Oregon,
    si vede che tra copia e incolla ho fatto dei casini.

    Devo imparare a dividere il codice il piu' possibile per capire dov'e' l'inghippo.

    Purtroppo sono un elettronico prestato alla programmazione e si vede....

    Era proprio l'f0 con la doppia assegnazione.

    Ora va, devo risolvere solo il problema della variabile rx col codice di gestione con encoder meccanico ed lcd seriale per selezionare la frequenza e capire perche' non viene gestito da queste routine o, perlomeno, in modo non corretto.

    Riporto qui il codice ripulito e funzionante per un solo contraves, se potesse essere utile a qualcuno:
    //Decodifica numero decimale e simula contraves binario
    int a=0;int b=0; int c=0; int d=0; int e=0; int f=0; 
    int f0=4;int f1=5; int f2=6; int f4=7; // BCD 100Hz
    
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
    
     pinMode(f0, OUTPUT);pinMode(f1, OUTPUT);pinMode(f2, OUTPUT);pinMode(f4, OUTPUT);
    }
    
    void loop() {
    
    float freq=463155;
    
      converti(freq);
      inviaBCD();
      } 
      
    void converti(long fr) {   // Funzione per scomporre le cifre. 
      //  modifica mio rx collins
      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
      Serial.println(f);
       delay(1000);
      Serial.println(e);
       delay(1000);
       Serial.println(d);
        delay(1000);
      Serial.println(c);
       delay(1000);
       Serial.println(b); delay(1000);
      Serial.println(a);
      Serial.println();
      delay(3000);
        } 
    void inviaBCD(){
      digitalWrite(f0, (HIGH &&(f & B0001)));   // 100hz 
      digitalWrite(f1, (HIGH &&(f & B0010)));    
      digitalWrite(f2, (HIGH &&(f & B0100)));    
      digitalWrite(f4, (HIGH &&(f & B1000)));    
      delay(3000);
      } 
    ciao
    Antonio
  • Re: Arduino - sw conversione decimale/binario per contraves

    Questo e' il sw di gestione encoder con display lcd seriale per gestire questa variabile che andrà convertita in binaria.

    Questa routine è stata recuperata in rete (autore Richard Visokey AD7C - www.ad7c.co) e gestiva un ad9850 (DDS) per produrre una frequenza, perfettamente funzionante l'ho usata in diversi miei progetti nominando sempre l'autore.
    Unico problema solo qualche piccolo salto di frequenza dovuto ai contatti di questi encoder meccanici economici.
    // 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
    };
Devi accedere o registrarti per scrivere nel forum
5 risposte