Jump to content
ELFORUM - Forumul electronistilor

## Recommended Posts

Incerc sa realizez un ajutor pentru invatare Morse si cel mai apropiat de ce imi doresc a fost cel de aici:

Este simplu, ofera posibilitatea utilizarii unei chei capacitive si are si ecran LCD pentru vizualizarea carctarelor formate.

Din pacate are un mare minus si anume nu permite schimbarea vitezi decat prin software.

Asa ca as dori modificarea codului pentru a adauga unui potentionetru, care sa modifice valoarea variabilei BAUD DURATION, sa spunem in limitele 50-150 ms. In codul initial valoarea BAUD DURATION este fixa si are  valoarea de 80 ms).

Cum as putea face asta ?

Codul este cel de mai jos:

```/* Iambic keyer with lcd for cw practice
Courtesy SV1OBT and OZ1JHM
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // LCD display pins
const int colums = 16;
const int rows = 2;
int lcdindex = 0;
int line1[colums];
int line2[colums];
bool halt=false;
long startttimelow;
byte U_umlaut =  {B01010,B00000,B10001,B10001,B10001,B10001,B01110,B00000}; // 'Ü'
byte O_umlaut =  {B01010,B00000,B01110,B10001,B10001,B10001,B01110,B00000}; // 'Ö'
byte A_umlaut =  {B01010,B00000,B01110,B10001,B11111,B10001,B10001,B00000}; // 'Ä'
byte AE_capital = {B01111,B10100,B10100,B11110,B10100,B10100,B10111,B00000}; // 'Æ'
byte OE_capital = {B00001,B01110,B10011,B10101,B11001,B01110,B10000,B00000}; // 'Ø'
byte fullblock = {B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111};
byte AA_capital = {B00100,B00000,B01110,B10001,B11111,B10001,B10001,B00000}; // 'Å'
byte emtyblock = {B00000,B00000,B00000,B00000,B00000,B00000,B00000,B00000};

#define DIT_PIN A1
#define DAH_PIN A2
#define EXC_PIN A3
#define LED  13
#define BAUD_DURATION  80  //mSec
#define INTERBAUD_DURATION BAUD_DURATION*1
#define INTERLETTER_DURATION  BAUD_DURATION*2 //extra time after a baud
#define DIT_DURATION BAUD_DURATION
#define DAH_DURATION BAUD_DURATION*3
#define TOUCH_THRESHOLD 5 //how long to wait in uSec, before sampling the touch pin.
#define INTERWORD_DURATION BAUD_DURATION*7
enum{
IDLE,
DIT,
DAH,
PAUSE,
};
int dit,dah;
int state;
char code;
void readDit()
{
digitalWrite(EXC_PIN,HIGH);
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(DIT_PIN)) dit=0; else dit=1;
digitalWrite(EXC_PIN,LOW);
}
void readDah()
{
digitalWrite(EXC_PIN,HIGH);
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(DAH_PIN)) dah=0; else dah=1;
digitalWrite(EXC_PIN,LOW);
}
void setup()
{
lcd.createChar(0, U_umlaut); // German
lcd.createChar(1, O_umlaut); // German, Swedish
lcd.createChar(2, A_umlaut); // German, Swedish
lcd.createChar(3, AE_capital); //  Danish, Norwegian
lcd.createChar(4, OE_capital); //  Danish, Norwegian
lcd.createChar(5, fullblock);
lcd.createChar(6, AA_capital); //  Danish, Norwegian, Swedish
lcd.createChar(7, emtyblock);
lcd.clear();
lcd.begin(colums, rows);
for (int index = 0; index < colums; index++){
line1[index] = 32;
line2[index] = 32;
}
Serial.begin(115200);
Serial.println("Serial is active");
pinMode(EXC_PIN,OUTPUT);
digitalWrite(EXC_PIN,LOW);
pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);
state = 0;
}
void contact(unsigned char state)
{
if(state) {
digitalWrite(LED,HIGH);
analogWrite(11,127); //pin 11 drives an 8 Ohm speaker
}
else{
digitalWrite(LED,LOW);
analogWrite(11,0);
}
}
void loop()
{
switch(state){
case IDLE:
if(halt & (millis() - startttimelow) >INTERWORD_DURATION){
printascii(32);
halt=false;
startttimelow =millis();
}
readDit();
if(dit) {
state = DIT;
}
else{
delayMicroseconds(30);
readDah();
if(dah) {
state = DAH;
}
}
break;
case DIT:
startttimelow =millis();
contact(1);
delay(DIT_DURATION);
contact(0);
delay(INTERBAUD_DURATION);
Serial.print(".");
strcat(code,".");
//now, if dah is pressed go there, else check for dit
readDah();
if(dah){
state = DAH;
}
else{
//read dit now
readDit();
if(dit) {
state = DIT;
}
else {
delay(INTERLETTER_DURATION);
Serial.print("|");
docode();
code = '\0';
state = IDLE;
}
}
break;
case DAH:
startttimelow =millis();
contact(1);
delay(DAH_DURATION);
contact(0);
delay(INTERBAUD_DURATION);
Serial.print("-");
strcat(code,"-");
readDit();
if(dit){
state = DIT;
}
else{
//read dit now
readDah();
if(dah) {
state = DAH;
}
else {
delay(INTERLETTER_DURATION);
Serial.print("|");
docode();
code = '\0';
state = IDLE;
}
}
break;
}//switch
delay(1);
}
void docode(){
if (strcmp(code,".-") == 0) printascii(65);
if (strcmp(code,"-...") == 0) printascii(66);
if (strcmp(code,"-.-.") == 0) printascii(67);
if (strcmp(code,"-..") == 0) printascii(68);
if (strcmp(code,".") == 0) printascii(69);
if (strcmp(code,"..-.") == 0) printascii(70);
if (strcmp(code,"--.") == 0) printascii(71);
if (strcmp(code,"....") == 0) printascii(72);
if (strcmp(code,"..") == 0) printascii(73);
if (strcmp(code,".---") == 0) printascii(74);
if (strcmp(code,"-.-") == 0) printascii(75);
if (strcmp(code,".-..") == 0) printascii(76);
if (strcmp(code,"--") == 0) printascii(77);
if (strcmp(code,"-.") == 0) printascii(78);
if (strcmp(code,"---") == 0) printascii(79);
if (strcmp(code,".--.") == 0) printascii(80);
if (strcmp(code,"--.-") == 0) printascii(81);
if (strcmp(code,".-.") == 0) printascii(82);
if (strcmp(code,"...") == 0) printascii(83);
if (strcmp(code,"-") == 0) printascii(84);
if (strcmp(code,"..-") == 0) printascii(85);
if (strcmp(code,"...-") == 0) printascii(86);
if (strcmp(code,".--") == 0) printascii(87);
if (strcmp(code,"-..-") == 0) printascii(88);
if (strcmp(code,"-.--") == 0) printascii(89);
if (strcmp(code,"--..") == 0) printascii(90);
if (strcmp(code,".----") == 0) printascii(49);
if (strcmp(code,"..---") == 0) printascii(50);
if (strcmp(code,"...--") == 0) printascii(51);
if (strcmp(code,"....-") == 0) printascii(52);
if (strcmp(code,".....") == 0) printascii(53);
if (strcmp(code,"-....") == 0) printascii(54);
if (strcmp(code,"--...") == 0) printascii(55);
if (strcmp(code,"---..") == 0) printascii(56);
if (strcmp(code,"----.") == 0) printascii(57);
if (strcmp(code,"-----") == 0) printascii(48);
if (strcmp(code,"..--..") == 0) printascii(63);
if (strcmp(code,".-.-.-") == 0) printascii(46);
if (strcmp(code,"--..--") == 0) printascii(44);
if (strcmp(code,"-.-.--") == 0) printascii(33);
if (strcmp(code,".--.-.") == 0) printascii(64);
if (strcmp(code,"---...") == 0) printascii(58);
if (strcmp(code,"-....-") == 0) printascii(45);
if (strcmp(code,"-..-.") == 0) printascii(47);
if (strcmp(code,"-.--.") == 0) printascii(40);
if (strcmp(code,"-.--.-") == 0) printascii(41);
if (strcmp(code,".-...") == 0) printascii(95);
if (strcmp(code,"...-..-") == 0) printascii(36);
if (strcmp(code,"...-.-") == 0) printascii(62);
if (strcmp(code,".-.-.") == 0) printascii(60);
if (strcmp(code,"...-.") == 0) printascii(126);
if (strcmp(code,".-.-") == 0) printascii(3);
if (strcmp(code,"---.") == 0) printascii(4);
if (strcmp(code,".--.-") == 0) printascii(6);
halt=true;
}
void sprintascii(int asciinumber){
Serial.println(char(asciinumber));
}
void printascii(int asciinumber){
sprintascii(asciinumber);
int fail = 0;
if (rows == 4 and colums == 16)fail = -4;
if (lcdindex > colums-1){
lcdindex = 0;
if (rows==4){
for (int i = 0; i <= colums-1 ; i++){
lcd.setCursor(i,rows-3);
lcd.write(line2[i]);
line2[i]=line1[i];
}
}
for (int i = 0; i <= colums-1 ; i++){
lcd.setCursor(i+fail,rows-2);
lcd.write(line1[i]);
lcd.setCursor(i+fail,rows-1);
lcd.write(32);
}
}
line1[lcdindex]=asciinumber;
lcd.setCursor(lcdindex+fail,rows-1);
lcd.write(asciinumber);
lcdindex += 1;
}```
##### Share on other sites

O idee. Fara sa presupuna adaugare potentiometru.
Sa poti sa transmiti din key Baud Rate.
Adica , daca transmiti din key 'B100' sa se modifice viteza la 100.
Ce zici ?

##### Share on other sites
Posted (edited)

E o idee, fara discutie, insa in faza de invatare cred ca este mai util ca operatorul sa ajusteze viteza cu un potentiometru.

In faza de invarare e posibil sa fie destul de greu sa transmiti corect "B100". D-asta m-am gandit la potentiometru

Edited by messu
##### Share on other sites
Posted (edited)

Ai dreptate. Daca un incepator seteaza viteza prea mare, posibil sa nu mai poata sa modifice decat cu restart Dar cred totusi ca ideea propusa va face ca incepatorul sa avanseze mai repede.

Edited by Liviu.Mihaiu
##### Share on other sites
Posted (edited)

Trebuie sa definiti un pin analogic pe care legati cursorul potentiometrului, apoi sa cititi valoarea acestuia folosind functia analogRead si sa o transferati catre BAUD DURATION  dupa ce faceti scalarea valorii citite in domeniul  50-150.Scalarea se poate face folosind functia map.
In programul pe care il aveti, BAUD_DURATION este o constanta care influenteaza la randul ei alte constante.

Va trebui ca toate aceste constante sa le declarati variabile de tip intreg, pentru a se modifica in acelasi timp cu modificarea pozitiei potentiometrului(BAUD_DURATION).
In zona de declaratii trebuie sa adaugati ceva in genul:

```int potpin = 0; // pin analogic pentru citirea potentiometrului
int val; // variabila care retine pozitia potentiometrului```

In zona de program adaugati o functie care citeste pozitia potentiometrului si transfera valoarea citita catre
variabila BAUD_DURATION:

```ModificareBaud(){
val = analogRead(potpin); // citeste stare potentiometru
BAUD_DURATION = map(val, 0, 1023, 50, 150); // scalarea valorii citite din domeniul 0-1023 in domeniul 50-150
}```

Apoi apelati aceasta functie in bucla principala a programului.

Edited by Elison
##### Share on other sites

Posted (edited)

Mutumesc pentru sugestii @Elison ! Foarte bune si binevenite (cine stie, stie)

Am modificat codul si deja e bine si s-a compilat fara erori.

Maine fac proba pe placa de test, ca sa vedem cum se comporta si revin cu detalii.

Edited by messu
##### Share on other sites
Posted (edited)

Am facut proba si merge foarte bine.

Multumesc mult pentru ajutor !

Incerc sa definitivez proiectul si sa-l pun la dispozitie pentru toti cei care sint interesati de transmisiile in CW si vor sa invete Morse.

Deocamdata partea de comanda capacitiva nu functioneaza extraordinar, dar o sa incerc sa-i dau de cap. Daca nu va merge , probabil o sa trebuiasca sa trec pe un driver specializat pentru comanda capacitiva (AT42QTxxxx) si, din nou, va trebui modificat codul. Mai vedem ...

Codul, in varianta de acum, un pic "pieptanat" si curatat de chestiile pe care le-am considerat in plus, este acesta :

```/* Iambic keyer with lcd for cw practice
Courtesy SV1OBT and OZ1JHM
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
const int colums = 8; // Pentru LCD 1602 valoarea se va schimba din 8 in 16
const int rows = 2;
int lcdindex = 0;
int line1[colums];
int line2[colums];
bool halt=false;
long startttimelow;
int BAUD_DURATION;
int INTERBAUD_DURATION;
int INTERLETTER_DURATION;
int INTERWORD_DURATION;
int DIT_DURATION;
int DAH_DURATION;
int WPM;

int Maximum_speed_WPM=40; // viteza maxima WPM - se ajusteaza in functie de dorinta
int Minimum_speed_WPM=2;   // viteza minima WPM - se ajusteaza in functie de dorinta

byte emtyblock = {B00000,B00000,B00000,B00000,B00000,B00000,B00000,B00000};

#define DIT_PIN A1 // Pinul pentru PUNCTE
#define DAH_PIN A2 // pinul pentru LINII
#define EXC_PIN A3 //A1 pentru Pro Mini
#define P_WPM   A0 //Potentiometru  pentru WPM
#define LED  13
#define TOUCH_THRESHOLD 5 //how long to wait in uSec, before sampling the touch pin.

enum{
IDLE,
DIT,
DAH,
PAUSE,
};
int dit,dah;
int state;
char code;
void readDit()
{
digitalWrite(EXC_PIN,HIGH);
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(DIT_PIN)) dit=0; else dit=1;
digitalWrite(EXC_PIN,LOW);
}
void readDah()
{
digitalWrite(EXC_PIN,HIGH);
delayMicroseconds(TOUCH_THRESHOLD);
if(digitalRead(DAH_PIN)) dah=0; else dah=1;
digitalWrite(EXC_PIN,LOW);
}
void setup()
{
lcd.clear();
lcd.begin(colums, rows);
for (int index = 0; index < colums; index++){
line1[index] = 32;
line2[index] = 32;
}

pinMode(EXC_PIN,OUTPUT);
digitalWrite(EXC_PIN,LOW);
pinMode(LED,OUTPUT);
digitalWrite(LED,LOW);
state = 0;
}
void contact(unsigned char state)
{
if(state) {
digitalWrite(LED,HIGH);
analogWrite(11,127);    // pinul 11 - Audio OUT - difuzor de ohmi
}
else{
digitalWrite(LED,LOW);
analogWrite(11,0);
}
}
void loop()
{
WPM = analogRead(P_WPM);

// BAUD_DURATION = map(WPM, 0, 1023, 25, 100);
BAUD_DURATION = 60000 / (map(WPM, 0, 1023, Maximum_speed_WPM, Minimum_speed_WPM) * 73);

DIT_DURATION=BAUD_DURATION*1;
DAH_DURATION=BAUD_DURATION*3;
INTERBAUD_DURATION=BAUD_DURATION*1;
INTERLETTER_DURATION=BAUD_DURATION*2;
INTERWORD_DURATION=BAUD_DURATION*7;

switch(state){
case IDLE:
if(halt & (millis() - startttimelow) >INTERWORD_DURATION){
printascii(32);
halt=false;
startttimelow =millis();
}
readDit();
if(dit) {
state = DIT;
}
else{
delayMicroseconds(30);
readDah();
if(dah) {
state = DAH;
}
}
break;
case DIT:
startttimelow =millis();
contact(1);
delay(DIT_DURATION);
contact(0);
delay(INTERBAUD_DURATION);

strcat(code,".");
//now, if dah is pressed go there, else check for dit
readDah();
if(dah){
state = DAH;
}
else{
//read dit now
readDit();
if(dit) {
state = DIT;
}
else {
delay(INTERLETTER_DURATION);

docode();
code = '\0';
state = IDLE;
}
}
break;
case DAH:
startttimelow =millis();
contact(1);
delay(DAH_DURATION);
contact(0);
delay(INTERBAUD_DURATION);

strcat(code,"-");
readDit();
if(dit){
state = DIT;
}
else{
//read dit now
readDah();
if(dah) {
state = DAH;
}
else {
delay(INTERLETTER_DURATION);

docode();
code = '\0';
state = IDLE;
}
}
break;
}//switch
delay(1);
}
void docode(){
if (strcmp(code,".-") == 0) printascii(65);   //A
if (strcmp(code,"-...") == 0) printascii(66); //B
if (strcmp(code,"-.-.") == 0) printascii(67); //C
if (strcmp(code,"-..") == 0) printascii(68);  //D
if (strcmp(code,".") == 0) printascii(69);    //E
if (strcmp(code,"..-.") == 0) printascii(70); //F
if (strcmp(code,"--.") == 0) printascii(71);  //G
if (strcmp(code,"....") == 0) printascii(72); //H
if (strcmp(code,"..") == 0) printascii(73);   //I
if (strcmp(code,".---") == 0) printascii(74); //J
if (strcmp(code,"-.-") == 0) printascii(75);  //K
if (strcmp(code,".-..") == 0) printascii(76); //L
if (strcmp(code,"--") == 0) printascii(77);   //M
if (strcmp(code,"-.") == 0) printascii(78);   //N
if (strcmp(code,"---") == 0) printascii(79);  //O
if (strcmp(code,".--.") == 0) printascii(80); //Q
if (strcmp(code,"--.-") == 0) printascii(81); //P
if (strcmp(code,".-.") == 0) printascii(82);  //R
if (strcmp(code,"...") == 0) printascii(83);  //S
if (strcmp(code,"-") == 0) printascii(84);    //T
if (strcmp(code,"..-") == 0) printascii(85);    //U
if (strcmp(code,"...-") == 0) printascii(86);   //V
if (strcmp(code,".--") == 0) printascii(87);    //W
if (strcmp(code,"-..-") == 0) printascii(88);   //X
if (strcmp(code,"-.--") == 0) printascii(89);   //Y
if (strcmp(code,"--..") == 0) printascii(90);   //Z
if (strcmp(code,".----") == 0) printascii(49);  //1
if (strcmp(code,"..---") == 0) printascii(50);  //2
if (strcmp(code,"...--") == 0) printascii(51);  //3
if (strcmp(code,"....-") == 0) printascii(52);  //4
if (strcmp(code,".....") == 0) printascii(53);  //5
if (strcmp(code,"-....") == 0) printascii(54);  //6
if (strcmp(code,"--...") == 0) printascii(55);  //7
if (strcmp(code,"---..") == 0) printascii(56);  //8
if (strcmp(code,"----.") == 0) printascii(57);  //9
if (strcmp(code,"-----") == 0) printascii(48);  //0
if (strcmp(code,"..--..") == 0) printascii(63); //?
if (strcmp(code,".-.-.-") == 0) printascii(46); //.
if (strcmp(code,"--..--") == 0) printascii(44); //,
if (strcmp(code,"-.-.--") == 0) printascii(33); //!
if (strcmp(code,"---...") == 0) printascii(58); //:
if (strcmp(code,"-....-") == 0) printascii(45); //-
if (strcmp(code,".-.-.") == 0) printascii(43);  //+
halt=true;
}
void sprintascii(int asciinumber){
Serial.println(char(asciinumber));
}
void printascii(int asciinumber){
sprintascii(asciinumber);
int fail = 0;
if (rows == 4 and colums == 16)fail = -4;
if (lcdindex > colums-1){
lcdindex = 0;
if (rows==4){
for (int i = 0; i <= colums-1 ; i++){
lcd.setCursor(i,rows-3);
lcd.write(line2[i]);
line2[i]=line1[i];
}
}
for (int i = 0; i <= colums-1 ; i++){
lcd.setCursor(i+fail,rows-2);
lcd.write(line1[i]);
lcd.setCursor(i+fail,rows-1);
lcd.write(32);
}
}
line1[lcdindex]=asciinumber;
lcd.setCursor(lcdindex+fail,rows-1);
lcd.write(asciinumber);
lcdindex += 1;
}```

Edited by messu
##### Share on other sites

Nu am cum sa editez acum ultima postare. @messufoloseste butonul <> din editor pentru postarea codului, altfel sterg de tot postarea. Ma intreb, cat o fi de greu sa respectam o serie de reguli simple?

##### Share on other sites
Acum 26 minute, nico_2010 a spus:

Nu am cum sa editez acum ultima postare. @messufoloseste butonul <> din editor pentru postarea codului, altfel sterg de tot postarea. Ma intreb, cat o fi de greu sa respectam o serie de reguli simple?

Multumesc pentru atentionare ! N-am stiu regula. Scuze !

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible. Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×

×

• #### Activity

×
• Create New...

## Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.Terms of Use si Guidelines