Author Topic: Semplice Break-In per CW  (Read 1933 times)

Offline IK2BCP

  • Administrator
  • Newbie
  • *****
  • Posts: 20
Semplice Break-In per CW
« on: November 03, 2015, 12:03:00 AM »
Lo so che è uno spreco immenso, quando basterebbero due o tre porte CMOS, ma ho colto l'occasione sia per far usare a Mario UZQ la sua scheda Arduino, che altrimenti non avrebbe mai usato, sia per cercare di scrivere un programmino che fosse utile per capire qualcosina in più a chi è alle prime armi.
Il codice non è assolutamente scritto in forma concisa ed ottimizzata, ma volutamente in forma espansa e non ottimizzata per renderlo più comprensibile anche ai neofiti.
Ho abbondato di commenti (cosa che faccio raramente...  :-[)
- Selezionate tutto il testo fino alla fine, a partire dalla prima riga che comincia con /*
- Click col tasto destro e copiate quanto selezionato
- Lanciate Arduino e, cliccando col tasto destro nell'editor dell'IDE, incollate
- Commenti, domande, dubbi, ecc. con dei post in questo thread.
73 de Guido, ik2bcp


/*
 *
 * CW Break-In e Semi Break-In
 *
 * IK2BCP - 2015
 *
 * Potenziometro da 10K tra GND e +5V (+3.3V con MEGA, DUE e altre schede che
 * hanno l'I/O a 3,3V), con il cursore al pin ANALOG IN indicato da DELAY_POT
 *
 * Resistenza da 4,7K tra +5V (+3.3V con MEGA, DUE e altre schede che
 * hanno l'I/O a 3,3V) ed il pin DIGITAL indicato da KEY_IN; ingresso per il tasto
 * tra il pin DIGITAL indicato da KEY_IN e GND
 *
 * Resistenza da 4,7K (2,2K con MEGA, DUE e altre schede che hanno l'I/O
 * a 3,3V) tra il pin DIGITAL indicato da KEY_OUT e la base di un transistor BC547C.
 * L'emettitore del transistor a GND ed il collettore all'uscita CW verso
 * la radio.
 *
 * Resistenza da 4,7K (2,2K con MEGA, DUE e altre schede che hanno l'I/O
 * a 3,3V) tra il pin DIGITAL indicato da PTT e la base di un transistor BC547C.
 * L'emettitore del transistor a GND ed il collettore all'uscita PTT verso
 * la radio.
 *
 */

//
// Arduino I/O pin
//
#define DELAY_POT 0
#define KEY_IN 10
#define KEY_OUT 11
#define PTT 12

// LED per lampeggio che indica il corretto funzionamento
#define BLINK_LED 13

#define KEY_FILTER_MS 5  // Filtro antirimbalzo in ms (max. 255)
#define PTT_MIN_MS 10    // Durata minima del PTT in ms (max. 65535)
#define PTT_MAX_MS 2000  // Durata massima del PTT (max. 65535)
#define BLINK_LED_MS 500 // Durata blink del LED in ms (max. 65535)

// Definizione delle variabili globali
unsigned long msCnt;        // Variabile per intercettare lo scadere di ogni ms
unsigned char keyFilter;    // Contatore per filtro antirimbalzo in gresso tasto
unsigned char keyFiltered;  // Variabile con lo stato filtrato del tasto
unsigned long pttMs;        // Contatore per la durata della coda del PTT
unsigned long durataPttMs;  // Variabile che indica la durata in ms della coda del PTT, come regolata dal potenziometro
unsigned int blinkMs;       // Contatore per durata stato alto e basso del LED

void setup()
{
  // Inizializzazione di alcune variabili globali
  keyFilter = 0;      // inizializzo contatore per filtro antirimbalzo
  keyFiltered = LOW;  // inizializzo stato dell'uscita tasto filtrata
  pttMs = 0;          // resetto il contatore per la durata della coda del PTT
  blinkMs = 0;        // inizializzo contatore per lampeggio LED
 
  // Inizializzazione ingresso tasto
  pinMode(KEY_IN, INPUT_PULLUP);

  // Inizializzazione uscita filtrata tasto
  pinMode(KEY_OUT, OUTPUT);
  digitalWrite(KEY_OUT, LOW);

  // Inizializzazione uscita PTT
  pinMode(PTT, OUTPUT);
  digitalWrite(PTT, LOW);

  // Inizializzazione LED lampeggio
  pinMode(BLINK_LED, OUTPUT);
  digitalWrite(BLINK_LED, LOW);

  // Inizializzazione contatore per ms
  msCnt = millis();
}

void loop()
{
  // Definizione delle variabili locali in loop()
  unsigned int key, pot;
 
  // Leggo lo stato del tasto
  key = digitalRead(KEY_IN);
 
  // Se msCnt è diverso dal valore corrente ritornato da millis()
  // vuol dire che è trascorso 1 ms. Questo algoritmo serve
  // per eseguire del codice solo allo scadere di ogni ms
  if(msCnt != millis())
  {
    msCnt = millis();  // preparo msCnt per il prossimo scadere di 1 ms

    blinkMs++;  // incremento il contatore di ms per il lampeggio

    // Se scaduta la durata dello stato alto o basso per il lampeggio
    if(blinkMs == BLINK_LED_MS)
    {
      // reinizializzo il contatore di ms e inverto l'uscita del LED
      blinkMs = 0;
      digitalWrite(BLINK_LED, digitalRead(BLINK_LED)^1);
    }

    // Se lo stato dell'ingresso del tasto è basso (CW)
    if(key == LOW)
    {
      // Se il contatore non è 0
      if(keyFilter)
      {
        keyFilter--;  // decremento il contatore per antirimbalzo

        // Se il contatore è arrivato a 0
        if(keyFilter == 0)
          keyFiltered = LOW;  // lo stato filtrato del tasto diventa basso
      }
    }
    // Se lo stato dell'ingresso del tasto è alto (spazio)
    else
    {
      // Se il contatore non è arrivato al valore massimo
      if(keyFilter < KEY_FILTER_MS)
      {
        keyFilter++;  // incremento il contatore per antirimbalzo

        // Se il contatore è arrivato al valore massimo
        if(keyFilter == KEY_FILTER_MS)
          keyFiltered = HIGH;  // lo stato filtrato del tasto diventa alto
      }
    }
  }

  // Se lo stato filtrato del tasto è basso
  if(keyFiltered == LOW)
  {
    digitalWrite(PTT, HIGH);      // attivo l'uscita PTT
    digitalWrite(KEY_OUT, HIGH);  // attivo l'uscita del tasto filtrato
    pttMs = millis();             // inizializzo il contatore per la durata della coda del PTT
  }
  // Se lo stato filtrato del tasto è alto
  else
    digitalWrite(KEY_OUT, LOW);   // disattivo l'uscita del tasto filtrato

  pot = analogRead(DELAY_POT);  // leggo il valore ADC del potenziometro
  durataPttMs = map(pot, 0, 1023, PTT_MIN_MS, PTT_MAX_MS);  // lo rimappo
 
  // Se il contatore per la durata del PTT non è 0 e non è trascorsa la durata della coda del PTT
  if(pttMs && ((millis() - pttMs) < durataPttMs))
    digitalWrite(PTT, HIGH);  // l'uscita PTT rimane attiva
  // Se il contatore per la durata del PTT è 0 oppure è trascorsa la durata della coda del PTT
  else
  {
    digitalWrite(PTT, LOW);  // disattivo l'uscita PTT
    pttMs = 0;               // resetto il contatore per la durata della coda del PTT
  }
}